2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5 * Copyright (C) 2011 Simon Busch <morphis@gravedo.de>
6 * Copyright (C) 2013-2014 Paul Kocialkowsk <contact@paulk.fr>
8 * libsamsung-ipc is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
13 * libsamsung-ipc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * 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 = read(fd, &buffer, sizeof(buffer));
76 line = strtok(buffer, "\n");
77 while (line != NULL) {
78 if (strncmp(line, "Hardware", 9) == 9) {
82 while (*c != '\n' && *c != '\0') {
89 board_name = strdup(p);
93 line = strtok(NULL, "\n");
97 #ifdef IPC_DEVICE_KERNEL_VERSION
98 kernel_version = strdup(IPC_DEVICE_KERNEL_VERSION);
100 memset(&utsname, 0, sizeof(utsname));
104 kernel_version = strdup(utsname.release);
107 for (i = 0; i < (int) ipc_devices_count; i++) {
108 // Eliminate index if the name doesn't match
109 if (name != NULL && ipc_devices[i].name != NULL && strcmp(name, ipc_devices[i].name) != 0)
112 // Eliminate index if the board name doesn't match
113 if (board_name != NULL && ipc_devices[i].board_name != NULL && strcmp(board_name, ipc_devices[i].board_name) != 0)
116 // Keep index but don't break yet since we may have a better match with kernel version
119 if (kernel_version == NULL || ipc_devices[i].kernel_version == NULL)
122 if (kernel_version != NULL && ipc_devices[i].kernel_version != NULL && strcmp(kernel_version, ipc_devices[i].kernel_version) != 0)
125 // Everything matches this particular index
135 if (board_name != NULL)
138 if (kernel_version != NULL)
139 free(kernel_version);
147 struct ipc_client *ipc_client_create(int type)
149 struct ipc_client *client = NULL;
150 unsigned int device_index;
153 if (type < 0 || type > IPC_CLIENT_TYPE_RFS)
156 rc = ipc_device_detect();
160 device_index = (unsigned int) rc;
161 if (device_index > ipc_devices_count)
164 client = (struct ipc_client *) calloc(1, sizeof(struct ipc_client));
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 can be modified
182 client->handlers = (struct ipc_client_handlers *) calloc(1, sizeof(struct ipc_client_handlers));
184 if (ipc_devices[device_index].handlers != NULL)
185 memcpy(client->handlers, ipc_devices[device_index].handlers, sizeof(struct ipc_client_handlers));
190 if (client != NULL) {
199 int ipc_client_destroy(struct ipc_client *client)
204 if (client->handlers != NULL)
205 free(client->handlers);
207 memset(client, 0, sizeof(struct ipc_client));
213 int ipc_client_transport_handlers_register(struct ipc_client *client,
214 int (*open)(void *transport_data, int type),
215 int (*close)(void *transport_data),
216 int (*read)(void *transport_data, void *data, size_t size),
217 int (*write)(void *transport_data, const void *data, size_t size),
218 int (*poll)(void *transport_data, struct timeval *timeout),
219 void *transport_data)
221 if (client == NULL || client->handlers == NULL)
225 client->handlers->read = read;
227 client->handlers->write = write;
229 client->handlers->poll = poll;
231 client->handlers->open = open;
233 client->handlers->close = close;
234 if (transport_data != NULL)
235 client->handlers->transport_data = transport_data;
240 int ipc_client_power_handlers_register(struct ipc_client *client,
241 int (*power_on)(void *power_data), int (*power_off)(void *power_data),
244 if (client == NULL || client->handlers == NULL)
247 if (power_on != NULL)
248 client->handlers->power_on = power_on;
249 if (power_off != NULL)
250 client->handlers->power_off = power_off;
251 if (power_data != NULL)
252 client->handlers->power_data = power_data;
257 int ipc_client_gprs_handlers_register(struct ipc_client *client,
258 int (*gprs_activate)(void *gprs_data, int cid),
259 int (*gprs_deactivate)(void *gprs_data, int cid), void *gprs_data)
261 if (client == NULL || client->handlers == NULL)
264 if (gprs_activate != NULL)
265 client->handlers->gprs_activate = gprs_activate;
266 if (gprs_deactivate != NULL)
267 client->handlers->gprs_deactivate = gprs_deactivate;
268 if (gprs_data != NULL)
269 client->handlers->gprs_data = gprs_data;
274 void ipc_client_log(struct ipc_client *client, const char *message, ...)
279 if (client == NULL || client->log_callback == NULL || message == NULL)
282 va_start(args, message);
283 vsnprintf((char *) &buffer, sizeof(buffer), message, args);
284 client->log_callback(client->log_data, buffer);
288 int ipc_client_log_callback_register(struct ipc_client *client,
289 void (*log_callback)(void *log_data, const char *message), void *log_data)
294 client->log_callback = log_callback;
295 client->log_data = log_data;
300 int ipc_client_boot(struct ipc_client *client)
302 if (client == NULL || client->ops == NULL || client->ops->boot == NULL)
305 return client->ops->boot(client);
308 int ipc_client_send(struct ipc_client *client, unsigned char mseq,
309 unsigned short command, unsigned char type, const void *data, size_t size)
311 struct ipc_message message;
313 if (client == NULL || client->ops == NULL || client->ops->send == NULL)
316 memset(&message, 0, sizeof(message));
319 message.command = command;
321 message.data = (void *) data;
324 return client->ops->send(client, &message);
327 int ipc_client_recv(struct ipc_client *client, struct ipc_message *message)
329 if (client == NULL || client->ops == NULL || client->ops->recv == NULL || message == NULL)
332 return client->ops->recv(client, message);
335 int ipc_client_open(struct ipc_client *client)
337 if (client == NULL || client->handlers == NULL || client->handlers->open == NULL)
340 return client->handlers->open(client->handlers->transport_data, client->type);
343 int ipc_client_close(struct ipc_client *client)
345 if (client == NULL || client->handlers == NULL || client->handlers->close == NULL)
348 return client->handlers->close(client->handlers->transport_data);
351 int ipc_client_poll(struct ipc_client *client, struct timeval *timeout)
353 if (client == NULL || client->handlers == NULL || client->handlers->poll == NULL)
356 return client->handlers->poll(client->handlers->transport_data, timeout);
359 int ipc_client_power_on(struct ipc_client *client)
361 if (client == NULL || client->handlers == NULL || client->handlers->power_on == NULL)
364 return client->handlers->power_on(client->handlers->power_data);
367 int ipc_client_power_off(struct ipc_client *client)
369 if (client == NULL || client->handlers == NULL || client->handlers->power_off == NULL)
372 return client->handlers->power_off(client->handlers->power_data);
375 int ipc_client_gprs_activate(struct ipc_client *client, int cid)
377 if (client == NULL || client->handlers == NULL || client->handlers->gprs_activate == NULL)
380 return client->handlers->gprs_activate(client->handlers->gprs_data, cid);
383 int ipc_client_gprs_deactivate(struct ipc_client *client, int cid)
385 if (client == NULL || client->handlers == NULL || client->handlers->gprs_deactivate == NULL)
388 return client->handlers->gprs_deactivate(client->handlers->gprs_data, cid);
391 int ipc_client_data_create(struct ipc_client *client)
393 if (client == NULL || client->handlers == NULL || client->handlers->data_create == NULL)
396 return client->handlers->data_create(&client->handlers->transport_data, &client->handlers->power_data, &client->handlers->power_data);
399 int ipc_client_data_destroy(struct ipc_client *client)
401 if (client == NULL || client->handlers == NULL || client->handlers->data_destroy == NULL)
404 return client->handlers->data_destroy(client->handlers->transport_data, client->handlers->power_data, client->handlers->power_data);
407 char *ipc_client_gprs_get_iface(struct ipc_client *client, int cid)
409 if (client == NULL || client->gprs_specs == NULL || client->gprs_specs->gprs_get_iface == NULL)
412 return client->gprs_specs->gprs_get_iface(cid);
415 int ipc_client_gprs_get_capabilities(struct ipc_client *client,
416 struct ipc_client_gprs_capabilities *capabilities)
418 if (client == NULL || client->gprs_specs == NULL || client->gprs_specs->gprs_get_capabilities == NULL)
421 return client->gprs_specs->gprs_get_capabilities(capabilities);
424 char *ipc_client_nv_data_path(struct ipc_client *client)
426 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_path == NULL)
429 return client->nv_data_specs->nv_data_path;
432 char *ipc_client_nv_data_md5_path(struct ipc_client *client)
434 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_md5_path == NULL)
437 return client->nv_data_specs->nv_data_md5_path;
440 char *ipc_client_nv_data_backup_path(struct ipc_client *client)
442 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_backup_path == NULL)
445 return client->nv_data_specs->nv_data_backup_path;
448 char *ipc_client_nv_data_backup_md5_path(struct ipc_client *client)
450 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_backup_md5_path == NULL)
453 return client->nv_data_specs->nv_data_backup_md5_path;
456 char *ipc_client_nv_data_secret(struct ipc_client *client)
458 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_secret == NULL)
461 return client->nv_data_specs->nv_data_secret;
464 size_t ipc_client_nv_data_size(struct ipc_client *client)
466 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_size == 0)
469 return client->nv_data_specs->nv_data_size;
472 size_t ipc_client_nv_data_chunk_size(struct ipc_client *client)
474 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_chunk_size == 0)
477 return client->nv_data_specs->nv_data_chunk_size;
480 // vim:ts=4:sw=4:expandtab