diff options
author | Paweł Szewczyk <p.szewczyk@samsung.com> | 2016-02-10 13:32:13 +0100 |
---|---|---|
committer | Taeyoung Kim <ty317.kim@samsung.com> | 2016-08-02 22:19:13 -0700 |
commit | 2d451eeaf595ed4ee38925b43b8acc036f639c17 (patch) | |
tree | 4119fe8937919085f4c073c9f1363e92e8b21cff | |
parent | 7a1eea1a0ce2fce63cc02725bf0290542eae6348 (diff) | |
download | deviced-2d451eeaf595ed4ee38925b43b8acc036f639c17.tar.gz deviced-2d451eeaf595ed4ee38925b43b8acc036f639c17.tar.bz2 deviced-2d451eeaf595ed4ee38925b43b8acc036f639c17.zip |
usbhost: Add API for handling device attach/detach
Change-Id: Ie333f7b403721f7b0611c57d172a930d1b1fc456
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
-rw-r--r-- | src/deviced/dd-usbhost.h | 77 | ||||
-rw-r--r-- | src/libdeviced/usbhost.c | 185 | ||||
-rw-r--r-- | src/usbhost/usb-host.c | 12 |
3 files changed, 216 insertions, 58 deletions
diff --git a/src/deviced/dd-usbhost.h b/src/deviced/dd-usbhost.h index eff38b0d..9bae8ae6 100644 --- a/src/deviced/dd-usbhost.h +++ b/src/deviced/dd-usbhost.h @@ -36,6 +36,24 @@ extern "C" { * @{ */ +#include <limits.h> +struct usbhost_device { + char devpath[PATH_MAX]; /* unique info. */ + int baseclass; + int subclass; + int protocol; + int vendorid; + int productid; + char *manufacturer; + char *product; + char *serial; +}; + +enum usbhost_state { + USB_HOST_REMOVED, + USB_HOST_ADDED, +}; + /** * @par Description: * This API is used to initialize usbhost signal \n @@ -100,6 +118,37 @@ int register_usb_storage_change_handler( /** * @par Description: + * This API is used to register usbhost signal \n + * @param[in] device_changed callback function which is called when the device is connected/disconnected + * @param[in] data parameter of the callback function + * @return 0 on success, negative if failed + * @par Example + * @code + * ... + * if (init_usbhost_signal() < 0) + * printf("Failed to initialize usbhost signal\n"); + * + * if (register_usb_device_change_handler(device_cb, data) < 0) { + * printf("Failed to register device handler\n"); + * deinit_usbhost_signal(); + * return; + * } + * + * // Do something + * + * if (unregister_usb_device_changed_handler() < 0) + * printf("Failed to unregister device changed signal\n"); + * + * deinit_usbhost_signal(); + * ... + * @endcode + */ +int register_usb_device_change_handler( + void (*device_changed)(struct usbhost_device *device, int state, void *data), + void *data); + +/** + * @par Description: * This API is used to unregister usbhost signal \n * @return 0 on success, negative if failed * @par Example @@ -127,6 +176,34 @@ int unregister_usb_storage_change_handler(void); /** * @par Description: + * This API is used to unregister usb connect/disconnect signal handler\n + * @return 0 on success, negative if failed + * @par Example + * @code + * ... + * if (init_usbhost_signal() < 0) + * printf("Failed to initialize usbhost signal\n"); + * + * if (register_usb_device_change_handler(device_cb, data) < 0) { + * printf("Failed to register device signal\n"); + * deinit_usbhost_signal(); + * return; + * } + * + * // Do something + * + * if (unregister_usb_device_change_handler() < 0) + * printf("Failed to unregister storage signal\n"); + * + * deinit_usbhost_signal(); + * ... + * @endcode + */ +int unregister_usb_device_change_handler( + void (*device_changed)(struct usbhost_device *device, int state, void *data)); + +/** + * @par Description: * This API is used to request usb storage information \n * @return 0 on success, negative if failed * @par Example diff --git a/src/libdeviced/usbhost.c b/src/libdeviced/usbhost.c index 747be174..fae5d8a8 100644 --- a/src/libdeviced/usbhost.c +++ b/src/libdeviced/usbhost.c @@ -24,6 +24,8 @@ #include "log.h" #include "common.h" #include "dbus.h" +#include "dd-usbhost.h" +#include "core/list.h" #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) @@ -33,27 +35,32 @@ #define METHOD_REQUEST_STORAGE_UNMOUNT "StorageUnmount" #define METHOD_REQUEST_STORAGE_FORMAT "StorageFormat" #define SIGNAL_NAME_USB_STORAGE_CHANGED "usb_storage_changed" +#define SIGNAL_NAME_USB_DEVICE_CHANGED "ChangedDevice" #define RETRY_MAX 5 +union action { + void (*storage)(char *type, char *path, int mount, void *param); + void (*device)(struct usbhost_device *device, int state, void *data); +}; + struct signal_handler { - char *name; + const char *name; E_DBus_Signal_Handler *handler; - void (*action)(char *type, char *path, int mount, void *param); + union action action; void *data; }; -static struct signal_handler handlers[] = { - { SIGNAL_NAME_USB_STORAGE_CHANGED , NULL, NULL, NULL }, -}; +static dd_list *handlers; static E_DBus_Connection *conn = NULL; static int register_edbus_signal_handler(const char *path, const char *interface, const char *name, E_DBus_Signal_Cb cb, - void (*action)(char *type, char *path, int mount, void *param), + union action action, void *data) { - int i, ret; + int ret; + struct signal_handler *handler = NULL; if (!conn) { _E("Use init_usbhost_signal() first to use this function"); @@ -61,45 +68,39 @@ static int register_edbus_signal_handler(const char *path, const char *interface goto out; } - for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) { - if (strncmp(handlers[i].name, name, strlen(name))) - continue; - break; - } - if (i >= ARRAY_SIZE(handlers)) { - _E("Failed to find \"storage_changed\" signal"); - ret = -1; - goto out; - } - - if (handlers[i].handler) { - _E("The handler is already registered"); - ret = -1; + handler = calloc(1, sizeof(*handler)); + if (!handler) { + _E("No memory"); goto out; } - - handlers[i].handler = e_dbus_signal_handler_add(conn, NULL, path, + handler->name = name; + handler->handler = e_dbus_signal_handler_add(conn, NULL, path, interface, name, cb, NULL); - if (!(handlers[i].handler)) { + if (!(handler->handler)) { _E("fail to add edbus handler"); ret = -1; goto out; } - handlers[i].action = action; - handlers[i].data = data; + + handler->action = action; + handler->data = data; + + DD_LIST_APPEND(handlers, handler); return 0; out: + free(handler); return ret; } static void storage_signal_handler(void *data, DBusMessage *msg) { - int i; char *type, *path; int mount; DBusError err; + dd_list *elem; + struct signal_handler *handler; if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_USB_STORAGE_CHANGED) == 0) { _E("The signal is not for storage changed"); @@ -117,18 +118,55 @@ static void storage_signal_handler(void *data, DBusMessage *msg) return; } - for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) { - if (strcmp(handlers[i].name, SIGNAL_NAME_USB_STORAGE_CHANGED)) + DD_LIST_FOREACH(handlers, elem, handler) { + if (strcmp(handler->name, SIGNAL_NAME_USB_STORAGE_CHANGED)) continue; - break; + + if (handler->action.storage) + handler->action.storage(type, path, mount, handler->data); } - if (i >= ARRAY_SIZE(handlers)) { - _E("Failed to find \"storage_changed\" signal"); +} + +static void device_signal_handler(void *data, DBusMessage *msg) +{ + char *path; + struct usbhost_device device; + int state; + DBusError err; + struct signal_handler *handler; + dd_list *element; + + if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_USB_DEVICE_CHANGED) == 0) { + _E("The signal is not ChangedDevice"); return; } - if (handlers[i].action) - handlers[i].action(type, path, mount, handlers[i].data); + dbus_error_init(&err); + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INT32, &device.baseclass, + DBUS_TYPE_INT32, &device.subclass, + DBUS_TYPE_INT32, &device.protocol, + DBUS_TYPE_INT32, &device.vendorid, + DBUS_TYPE_INT32, &device.productid, + DBUS_TYPE_STRING, &device.manufacturer, + DBUS_TYPE_STRING, &device.product, + DBUS_TYPE_STRING, &device.serial, + DBUS_TYPE_INVALID) == 0) { + _E("Failed to get device info"); + return; + } + + strncpy(device.devpath, path, PATH_MAX); + + DD_LIST_FOREACH(handlers, element, handler) { + if (strcmp(handler->name, SIGNAL_NAME_USB_DEVICE_CHANGED)) + continue; + + if (handler->action.device) + handler->action.device(&device, state, handler->data); + } } API int init_usbhost_signal(void) @@ -158,18 +196,20 @@ API int init_usbhost_signal(void) API void deinit_usbhost_signal(void) { - int i; + dd_list *n, *next; + struct signal_handler *handler; if (!conn) return; - for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) { - if (handlers[i].handler) { - e_dbus_signal_handler_del(conn, handlers[i].handler); - handlers[i].handler = NULL; + DD_LIST_FOREACH_SAFE(handlers, n, next, handler) { + DD_LIST_REMOVE(handlers, handler); + if (handler->handler) { + e_dbus_signal_handler_del(conn, handler->handler); + handler->handler = NULL; } - handlers[i].action = NULL; - handlers[i].data = NULL; + + free(handler); } e_dbus_connection_close(conn); @@ -185,36 +225,77 @@ API int request_usb_storage_info(void) } API int register_usb_storage_change_handler( - void (*storage_changed)(char *type, char *path, int mount, void *), + void (*storage_changed)(char *type, char *path, int mount, void *param), void *data) { + union action action; if (!storage_changed) return -EINVAL; + action.storage = storage_changed; return register_edbus_signal_handler(DEVICED_PATH_USBHOST, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_USB_STORAGE_CHANGED, storage_signal_handler, - storage_changed, + action, + data); +} + +API int register_usb_device_change_handler( + void (*device_changed)(struct usbhost_device *device, int state, void *data), + void *data) +{ + union action action; + if (!device_changed) + return -EINVAL; + + action.device = device_changed; + return register_edbus_signal_handler(DEVICED_PATH_USBHOST, + DEVICED_INTERFACE_USBHOST, + SIGNAL_NAME_USB_DEVICE_CHANGED, + device_signal_handler, + action, data); } API int unregister_usb_storage_change_handler(void) { - int i; + dd_list *n, *next; + struct signal_handler *handler; - for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) { - if (strcmp(handlers[i].name, SIGNAL_NAME_USB_STORAGE_CHANGED)) + DD_LIST_FOREACH_SAFE(handlers, n, next, handler) { + if (strcmp(handler->name, SIGNAL_NAME_USB_STORAGE_CHANGED)) continue; - if (handlers[i].handler == NULL) + if (handler->handler == NULL) continue; - e_dbus_signal_handler_del(conn, handlers[i].handler); - handlers[i].handler = NULL; - handlers[i].action = NULL; - handlers[i].data = NULL; - return 0; + e_dbus_signal_handler_del(conn, handler->handler); + DD_LIST_REMOVE(handlers, handler); + free(handler); } + + return 0; +} + +API int unregister_usb_device_change_handler( + void (*device_changed)(struct usbhost_device *device, int state, void *data)) +{ + dd_list *n, *next; + struct signal_handler *handler; + + DD_LIST_FOREACH_SAFE(handlers, n, next, handler) { + if (strcmp(handler->name, SIGNAL_NAME_USB_DEVICE_CHANGED)) + continue; + if (handler->handler == NULL) + continue; + if (handler->action.device != device_changed) + continue; + + e_dbus_signal_handler_del(conn, handler->handler); + DD_LIST_REMOVE(handlers, handler); + free(handler); + } + return -1; } diff --git a/src/usbhost/usb-host.c b/src/usbhost/usb-host.c index 99c10685..e4a48b87 100644 --- a/src/usbhost/usb-host.c +++ b/src/usbhost/usb-host.c @@ -29,6 +29,7 @@ #include "core/device-notifier.h" #include "core/udev.h" #include "core/list.h" +#include "core/device-idler.h" #define USB_INTERFACE_CLASS "bInterfaceClass" #define USB_INTERFACE_SUBCLASS "bInterfaceSubClass" @@ -45,7 +46,7 @@ #define ROOTPATH tzplatform_getenv(TZ_SYS_VAR) #define POLICY_FILENAME "usbhost-policy" -const char *POLICY_FILEPATH; +char *POLICY_FILEPATH; /** * Below usb host class is defined by www.usb.org. @@ -582,7 +583,6 @@ static int read_policy(void) FILE *fp; struct policy_entry *entry; char *line = NULL, value_str[256]; - char *p; int ret = -1; int count = 0; size_t len; @@ -608,7 +608,7 @@ static int read_policy(void) goto out; } - ret = sscanf(line, "%d %s %04x %02x %02x %02x %04x %04x %04x %s\n", + ret = sscanf(line, "%d %s %04hx %02hhx %02hhx %02hhx %04hx %04hx %04hx %s\n", &entry->creds.uid, entry->creds.sec_label, &entry->device.bcdUSB, @@ -831,7 +831,7 @@ static int creds_read_label(DBusMessageIter *iter, char **dest) static int get_caller_credentials(DBusMessage *msg, struct user_credentials *cred) { - char *cid; + const char *cid; char *key; char *arr[1]; DBusMessage *reply; @@ -846,7 +846,7 @@ static int get_caller_credentials(DBusMessage *msg, struct user_credentials *cre return -1; } - arr[0] = cid; + arr[0] = (char *)cid; reply = dbus_method_sync_with_reply(DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, @@ -929,7 +929,7 @@ static DBusMessage *open_device(E_DBus_Object *obj, DBusMessage *msg) DBusError err; dbus_bool_t dbus_ret; int ret = 0, fd = -1; - const char *path; + char *path; struct user_credentials cred; dbus_error_init(&err); |