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;
49 char *board_name = NULL;
50 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 if (name == NULL && board_name == NULL)
110 for (i = 0; i < (int) ipc_devices_count; i++) {
111 // Eliminate index if neither name nor board name can be checked
112 if (ipc_devices[i].name == NULL && ipc_devices[i].board_name == NULL)
115 // Eliminate index if the name doesn't match
116 if (name != NULL && ipc_devices[i].name != NULL && strcmp(name, ipc_devices[i].name) != 0)
119 // Eliminate index if the board name doesn't match
120 if (board_name != NULL && ipc_devices[i].board_name != NULL && strcmp(board_name, ipc_devices[i].board_name) != 0)
123 // Keep index but don't break yet since we may have a better match with kernel version
126 if (kernel_version == NULL || ipc_devices[i].kernel_version == NULL)
129 if (kernel_version != NULL && ipc_devices[i].kernel_version != NULL && strcmp(kernel_version, ipc_devices[i].kernel_version) != 0)
132 // Everything matches this particular index
145 if (board_name != NULL)
148 if (kernel_version != NULL)
149 free(kernel_version);
157 struct ipc_client *ipc_client_create(int type)
159 struct ipc_client *client = NULL;
160 unsigned int device_index;
163 if (type < 0 || type > IPC_CLIENT_TYPE_RFS)
166 rc = ipc_device_detect();
170 device_index = (unsigned int) rc;
171 if (device_index > ipc_devices_count)
174 client = (struct ipc_client *) calloc(1, sizeof(struct ipc_client));
178 case IPC_CLIENT_TYPE_RFS:
179 client->ops = ipc_devices[device_index].rfs_ops;
181 case IPC_CLIENT_TYPE_FMT:
182 client->ops = ipc_devices[device_index].fmt_ops;
188 client->gprs_specs = ipc_devices[device_index].gprs_specs;
189 client->nv_data_specs = ipc_devices[device_index].nv_data_specs;
191 // Handlers can be modified
192 client->handlers = (struct ipc_client_handlers *) calloc(1, sizeof(struct ipc_client_handlers));
194 if (ipc_devices[device_index].handlers != NULL)
195 memcpy(client->handlers, ipc_devices[device_index].handlers, sizeof(struct ipc_client_handlers));
200 if (client != NULL) {
209 int ipc_client_destroy(struct ipc_client *client)
214 if (client->handlers != NULL)
215 free(client->handlers);
217 memset(client, 0, sizeof(struct ipc_client));
223 int ipc_client_transport_handlers_register(struct ipc_client *client,
224 int (*open)(void *transport_data, int type),
225 int (*close)(void *transport_data),
226 int (*read)(void *transport_data, void *data, size_t size),
227 int (*write)(void *transport_data, const void *data, size_t size),
228 int (*poll)(void *transport_data, struct timeval *timeout),
229 void *transport_data)
231 if (client == NULL || client->handlers == NULL)
235 client->handlers->read = read;
237 client->handlers->write = write;
239 client->handlers->poll = poll;
241 client->handlers->open = open;
243 client->handlers->close = close;
244 if (transport_data != NULL)
245 client->handlers->transport_data = transport_data;
250 int ipc_client_power_handlers_register(struct ipc_client *client,
251 int (*power_on)(void *power_data), int (*power_off)(void *power_data),
254 if (client == NULL || client->handlers == NULL)
257 if (power_on != NULL)
258 client->handlers->power_on = power_on;
259 if (power_off != NULL)
260 client->handlers->power_off = power_off;
261 if (power_data != NULL)
262 client->handlers->power_data = power_data;
267 int ipc_client_gprs_handlers_register(struct ipc_client *client,
268 int (*gprs_activate)(void *gprs_data, unsigned int cid),
269 int (*gprs_deactivate)(void *gprs_data, unsigned int cid), void *gprs_data)
271 if (client == NULL || client->handlers == NULL)
274 if (gprs_activate != NULL)
275 client->handlers->gprs_activate = gprs_activate;
276 if (gprs_deactivate != NULL)
277 client->handlers->gprs_deactivate = gprs_deactivate;
278 if (gprs_data != NULL)
279 client->handlers->gprs_data = gprs_data;
284 void ipc_client_log(struct ipc_client *client, const char *message, ...)
289 if (client == NULL || client->log_callback == NULL || message == NULL)
292 va_start(args, message);
293 vsnprintf((char *) &buffer, sizeof(buffer), message, args);
294 client->log_callback(client->log_data, buffer);
298 int ipc_client_log_callback_register(struct ipc_client *client,
299 void (*log_callback)(void *log_data, const char *message), void *log_data)
304 client->log_callback = log_callback;
305 client->log_data = log_data;
310 int ipc_client_boot(struct ipc_client *client)
312 if (client == NULL || client->ops == NULL || client->ops->boot == NULL)
315 return client->ops->boot(client);
318 int ipc_client_send(struct ipc_client *client, unsigned char mseq,
319 unsigned short command, unsigned char type, const void *data, size_t size)
321 struct ipc_message message;
323 if (client == NULL || client->ops == NULL || client->ops->send == NULL)
326 memset(&message, 0, sizeof(message));
329 message.command = command;
331 message.data = (void *) data;
334 return client->ops->send(client, &message);
337 int ipc_client_recv(struct ipc_client *client, struct ipc_message *message)
339 if (client == NULL || client->ops == NULL || client->ops->recv == NULL || message == NULL)
342 return client->ops->recv(client, message);
345 int ipc_client_open(struct ipc_client *client)
347 if (client == NULL || client->handlers == NULL || client->handlers->open == NULL)
350 return client->handlers->open(client->handlers->transport_data, client->type);
353 int ipc_client_close(struct ipc_client *client)
355 if (client == NULL || client->handlers == NULL || client->handlers->close == NULL)
358 return client->handlers->close(client->handlers->transport_data);
361 int ipc_client_poll(struct ipc_client *client, struct timeval *timeout)
363 if (client == NULL || client->handlers == NULL || client->handlers->poll == NULL)
366 return client->handlers->poll(client->handlers->transport_data, timeout);
369 int ipc_client_power_on(struct ipc_client *client)
371 if (client == NULL || client->handlers == NULL || client->handlers->power_on == NULL)
374 return client->handlers->power_on(client->handlers->power_data);
377 int ipc_client_power_off(struct ipc_client *client)
379 if (client == NULL || client->handlers == NULL || client->handlers->power_off == NULL)
382 return client->handlers->power_off(client->handlers->power_data);
385 int ipc_client_gprs_activate(struct ipc_client *client, unsigned int cid)
387 if (client == NULL || client->handlers == NULL || client->handlers->gprs_activate == NULL)
390 return client->handlers->gprs_activate(client->handlers->gprs_data, cid);
393 int ipc_client_gprs_deactivate(struct ipc_client *client, unsigned int cid)
395 if (client == NULL || client->handlers == NULL || client->handlers->gprs_deactivate == NULL)
398 return client->handlers->gprs_deactivate(client->handlers->gprs_data, cid);
401 int ipc_client_data_create(struct ipc_client *client)
403 if (client == NULL || client->handlers == NULL || client->handlers->data_create == NULL)
406 return client->handlers->data_create(&client->handlers->transport_data, &client->handlers->power_data, &client->handlers->power_data);
409 int ipc_client_data_destroy(struct ipc_client *client)
411 if (client == NULL || client->handlers == NULL || client->handlers->data_destroy == NULL)
414 return client->handlers->data_destroy(client->handlers->transport_data, client->handlers->power_data, client->handlers->power_data);
417 char *ipc_client_gprs_get_iface(struct ipc_client *client, unsigned int cid)
419 if (client == NULL || client->gprs_specs == NULL || client->gprs_specs->gprs_get_iface == NULL)
422 return client->gprs_specs->gprs_get_iface(cid);
425 int ipc_client_gprs_get_capabilities(struct ipc_client *client,
426 struct ipc_client_gprs_capabilities *capabilities)
428 if (client == NULL || client->gprs_specs == NULL || client->gprs_specs->gprs_get_capabilities == NULL)
431 return client->gprs_specs->gprs_get_capabilities(capabilities);
434 char *ipc_client_nv_data_path(struct ipc_client *client)
436 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_path == NULL)
439 return client->nv_data_specs->nv_data_path;
442 char *ipc_client_nv_data_md5_path(struct ipc_client *client)
444 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_md5_path == NULL)
447 return client->nv_data_specs->nv_data_md5_path;
450 char *ipc_client_nv_data_backup_path(struct ipc_client *client)
452 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_backup_path == NULL)
455 return client->nv_data_specs->nv_data_backup_path;
458 char *ipc_client_nv_data_backup_md5_path(struct ipc_client *client)
460 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_backup_md5_path == NULL)
463 return client->nv_data_specs->nv_data_backup_md5_path;
466 char *ipc_client_nv_data_secret(struct ipc_client *client)
468 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_secret == NULL)
471 return client->nv_data_specs->nv_data_secret;
474 size_t ipc_client_nv_data_size(struct ipc_client *client)
476 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_size == 0)
479 return client->nv_data_specs->nv_data_size;
482 size_t ipc_client_nv_data_chunk_size(struct ipc_client *client)
484 if (client == NULL || client->nv_data_specs == NULL || client->nv_data_specs->nv_data_chunk_size == 0)
487 return client->nv_data_specs->nv_data_chunk_size;
490 // vim:ts=4:sw=4:expandtab