2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
5 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
7 * libsamsung-ipc is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 2 of the License, or
10 * (at your option) any later version.
12 * libsamsung-ipc is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
33 #include <sys/ioctl.h>
35 #include <sys/types.h>
36 #include <asm/types.h>
37 #include <sys/utsname.h>
39 #include <samsung-ipc.h>
42 #include "ipc_devices.h"
44 int ipc_device_detect(void)
46 char buffer[4096] = { 0 };
47 struct utsname utsname;
48 char *board_name = NULL;
49 char *kernel_version = NULL;
58 #ifdef IPC_DEVICE_NAME
59 name = strdup(IPC_DEVICE_NAME);
62 #ifdef IPC_DEVICE_BOARD_NAME
63 board_name = strdup(IPC_DEVICE_BOARD_NAME);
65 // Read board name from cpuinfo
67 fd = open("/proc/cpuinfo", O_RDONLY);
71 length = sizeof(buffer);
72 length = read(fd, &buffer, length);
77 line = strtok(buffer, "\n");
78 while (line != NULL) {
79 if (strncmp(line, "Hardware", 9) == 9) {
83 while (*c != '\n' && *c != '\0') {
90 board_name = strdup(p);
94 line = strtok(NULL, "\n");
98 #ifdef IPC_DEVICE_KERNEL_VERSION
99 kernel_version = strdup(IPC_DEVICE_KERNEL_VERSION);
101 memset(&utsname, 0, sizeof(utsname));
105 kernel_version = strdup(utsname.release);
108 for (i = 0; i < ipc_devices_count; i++) {
109 // Eliminate index if the name doesn't match
110 if (name != NULL && ipc_devices[i].name != NULL && strcmp(name, ipc_devices[i].name) != 0)
113 // Eliminate index if the board name doesn't match
114 if (board_name != NULL && ipc_devices[i].board_name != NULL && strcmp(board_name, ipc_devices[i].board_name) != 0)
117 // Keep index but don't break yet since we may have a better match with kernel version
120 if (kernel_version == NULL || ipc_devices[i].kernel_version == NULL)
123 if (kernel_version != NULL && ipc_devices[i].kernel_version != NULL && strcmp(kernel_version, ipc_devices[i].kernel_version) != 0)
126 // Everything matches this particular index
136 if (board_name != NULL)
139 if (kernel_version != NULL)
140 free(kernel_version);
148 struct ipc_client *ipc_client_create(int client_type)
150 struct ipc_client *client;
151 int device_index = -1;
153 device_index = ipc_device_detect();
155 if (device_index < 0 || device_index > ipc_devices_count)
158 if (client_type < 0 || client_type > IPC_CLIENT_TYPE_RFS)
161 client = (struct ipc_client *) malloc(sizeof(struct ipc_client));
162 memset(client, 0, sizeof(struct ipc_client));
164 client->type = client_type;
168 case IPC_CLIENT_TYPE_RFS:
169 client->ops = ipc_devices[device_index].rfs_ops;
171 case IPC_CLIENT_TYPE_FMT:
172 client->ops = ipc_devices[device_index].fmt_ops;
178 client->gprs_specs = ipc_devices[device_index].gprs_specs;
179 client->nv_data_specs = ipc_devices[device_index].nv_data_specs;
181 // Handlers are subject to be modified
182 client->handlers = (struct ipc_handlers *) malloc(sizeof(struct ipc_handlers));
183 memset(client->handlers, 0, sizeof(struct ipc_handlers));
185 if (ipc_devices[device_index].handlers != 0)
186 memcpy(client->handlers, ipc_devices[device_index].handlers, sizeof(struct ipc_handlers));
191 int ipc_client_destroy(struct ipc_client *client)
196 if (client->handlers != NULL)
197 free(client->handlers);
199 memset(client, 0, sizeof(struct ipc_client));
205 void ipc_client_log(struct ipc_client *client, const char *message, ...)
210 if (client == NULL || client->log_callback == NULL || message == NULL)
213 va_start(args, message);
214 vsnprintf(buffer, 4096, message, args);
215 client->log_callback(client->log_data, buffer);
219 int ipc_client_set_log_callback(struct ipc_client *client,
220 void (*log_callback)(void *log_data, const char *message), void *log_data)
225 client->log_callback = log_callback;
226 client->log_data = log_data;
231 int ipc_client_set_transport_handlers(struct ipc_client *client,
232 int (*open)(void *transport_data, int type),
233 int (*close)(void *transport_data),
234 int (*read)(void *transport_data, void *buffer, unsigned int length),
235 int (*write)(void *transport_data, void *buffer, unsigned int length),
236 int (*poll)(void *transport_data, struct timeval *timeout),
237 void *transport_data)
239 if (client == NULL || client->handlers == NULL)
243 client->handlers->read = read;
245 client->handlers->write = write;
247 client->handlers->poll = poll;
249 client->handlers->open = open;
251 client->handlers->close = close;
252 if (transport_data != NULL)
253 client->handlers->transport_data = transport_data;
258 int ipc_client_set_power_handlers(struct ipc_client *client,
259 int (*power_on)(void *power_data),
260 int (*power_off)(void *power_data),
263 if (client == NULL || client->handlers == NULL)
266 if (power_on != NULL)
267 client->handlers->power_on = power_on;
268 if (power_off != NULL)
269 client->handlers->power_off = power_off;
270 if (power_data != NULL)
271 client->handlers->power_data = power_data;
276 int ipc_client_set_gprs_handlers(struct ipc_client *client,
277 int (*gprs_activate)(void *gprs_data, int cid),
278 int (*gprs_deactivate)(void *gprs_data, int cid),
281 if (client == NULL || client->handlers == NULL)
284 if (gprs_activate != NULL)
285 client->handlers->gprs_activate = gprs_activate;
286 if (gprs_deactivate != NULL)
287 client->handlers->gprs_deactivate = gprs_deactivate;
288 if (gprs_data != NULL)
289 client->handlers->gprs_data = gprs_data;
294 int ipc_client_bootstrap(struct ipc_client *client)
296 if (client == NULL || client->ops == NULL ||
297 client->ops->bootstrap == NULL)
300 return client->ops->bootstrap(client);
303 int ipc_client_send(struct ipc_client *client, const unsigned short command,
304 const char type, unsigned char *data, const int length, unsigned char mseq)
306 struct ipc_message_info request;
308 if (client == NULL || client->ops == NULL || client->ops->send == NULL)
313 request.group = IPC_GROUP(command);
314 request.index = IPC_INDEX(command);
316 request.length = length;
319 return client->ops->send(client, &request);
322 int ipc_client_recv(struct ipc_client *client,
323 struct ipc_message_info *response)
325 if (client == NULL || client->ops == NULL || client->ops->recv == NULL)
328 return client->ops->recv(client, response);
331 void ipc_client_response_free(struct ipc_client *client,
332 struct ipc_message_info *response)
334 if (response == NULL)
337 if (response->data != NULL && response->length > 0) {
338 free(response->data);
339 response->data = NULL;
342 memset(response, 0, sizeof(struct ipc_message_info));
345 int ipc_client_open(struct ipc_client *client)
347 if (client == NULL || client->handlers == NULL ||
348 client->handlers->open == NULL)
351 return client->handlers->open(client->handlers->transport_data, client->type);
354 int ipc_client_close(struct ipc_client *client)
356 if (client == NULL || client->handlers == NULL ||
357 client->handlers->close == NULL)
360 return client->handlers->close(client->handlers->transport_data);
363 int ipc_client_poll(struct ipc_client *client, struct timeval *timeout)
365 if (client == NULL || client->handlers == NULL ||
366 client->handlers->poll == NULL)
369 return client->handlers->poll(client->handlers->transport_data, timeout);
372 int ipc_client_power_on(struct ipc_client *client)
374 if (client == NULL || client->handlers == NULL ||
375 client->handlers->power_on == NULL)
378 return client->handlers->power_on(client->handlers->power_data);
381 int ipc_client_power_off(struct ipc_client *client)
383 if (client == NULL || client->handlers == NULL ||
384 client->handlers->power_off == NULL)
387 return client->handlers->power_off(client->handlers->power_data);
390 int ipc_client_gprs_activate(struct ipc_client *client, int cid)
392 if (client == NULL || client->handlers == NULL ||
393 client->handlers->gprs_activate == NULL)
396 return client->handlers->gprs_activate(client->handlers->gprs_data, cid);
399 int ipc_client_gprs_deactivate(struct ipc_client *client, int cid)
401 if (client == NULL || client->handlers == NULL ||
402 client->handlers->gprs_deactivate == NULL)
405 return client->handlers->gprs_deactivate(client->handlers->gprs_data, cid);
408 int ipc_client_data_create(struct ipc_client *client)
410 if (client == NULL || client->handlers == NULL ||
411 client->handlers->data_create == NULL)
414 return client->handlers->data_create(&client->handlers->transport_data,
415 &client->handlers->power_data, &client->handlers->power_data);
418 int ipc_client_data_destroy(struct ipc_client *client)
420 if (client == NULL || client->handlers == NULL ||
421 client->handlers->data_destroy == NULL)
424 return client->handlers->data_destroy(client->handlers->transport_data,
425 client->handlers->power_data, client->handlers->power_data);
428 char *ipc_client_gprs_get_iface(struct ipc_client *client, int cid)
430 if (client == NULL || client->gprs_specs == NULL ||
431 client->gprs_specs->gprs_get_iface == NULL)
434 return client->gprs_specs->gprs_get_iface(cid);
437 int ipc_client_gprs_get_capabilities(struct ipc_client *client,
438 struct ipc_client_gprs_capabilities *capabilities)
440 if (client == NULL || client->gprs_specs == NULL ||
441 client->gprs_specs->gprs_get_capabilities == NULL)
444 return client->gprs_specs->gprs_get_capabilities(capabilities);
447 // vim:ts=4:sw=4:expandtab