#include "mtp_daemon_db.h"
#include "mtp_daemon_util.h"
-#define DEVICED_BUS_NAME "org.tizen.system.deviced"
-#define DEVICED_OBJECT_PATH "/Org/Tizen/System/DeviceD"
-#define DEVICED_INTERFACE_NAME DEVICED_BUS_NAME
-
-#define DEVICED_PATH_USBHOST DEVICED_OBJECT_PATH"/Usbhost"
-#define DEVICED_INTERFACE_USBHOST DEVICED_INTERFACE_NAME".Usbhost"
-
-#define SIGNAL_USB_HOST_CHANGED "ChangedDevice"
-
-static GDBusConnection *g_usb_bus;
-static int g_usb_handler;
-
-typedef enum {
- USB_HOST_REMOVED = 0,
- USB_HOST_ADDED = 1,
- USB_MAX,
-} usbhost_state;
-
-typedef void (*device_changed_cb)(const char *dev_path, int bus_no, int port_no,
- usbhost_state host_status, void *user_data);
-
-typedef struct _device_cb_data device_cb_data;
-
-struct _device_cb_data {
- device_changed_cb usr_cb;
- void *usr_data;
-};
-
-device_cb_data *g_usb_cb_data = NULL;
-
static void __print_device_list(mtp_context *mtp_ctx)
{
int slot;
} while (check_count++ < 100);
}
-static bool __parsing_usb_devpath(const char *devpath, int *busno, int *portno)
-{
- int devpath_len = 0;
- char bus[4] = {0,};
- char port[4] = {0,};
-
- devpath_len = strlen(devpath);
-
- if (devpath_len < 8)
- return false;
-
- strncpy(bus, &devpath[devpath_len - 7], 3);
- strncpy(port, &devpath[devpath_len - 3], 3);
-
- *busno = atoi(bus);
- *portno = atoi(port);
-
- return true;
-}
-
-static void __dbus_usb_host_event_cb(GDBusConnection* connection,
- const gchar* sender_name,
- const gchar* object_path,
- const gchar* interface_name,
- const gchar* signal_name,
- GVariant* parameters,
- gpointer user_data)
-{
- GVariant *state_value;
- GVariant *devpath_value;
- GVariant *device_class_value;
-
- const char *devpath = NULL;
- int state = -1;
- int device_class = 0;
- int busno = 0;
- int portno = 0;
- gsize size = 0;
- device_cb_data *cb_data = (device_cb_data *)user_data;
- void *usr_cb = cb_data->usr_cb;
- void *usr_data = cb_data->usr_data;
-
- state_value = g_variant_get_child_value(parameters, 0);
- state = g_variant_get_int32(state_value);
- g_variant_unref(state_value);
-
- devpath_value = g_variant_get_child_value(parameters, 1);
- devpath = g_variant_get_string(devpath_value, &size);
- g_variant_unref(devpath_value);
-
- device_class_value = g_variant_get_child_value(parameters, 2);
- device_class = g_variant_get_int32(device_class_value);
- g_variant_unref(device_class_value);
-
- if (devpath == NULL) {
- MTP_LOGE("devpath is NULL");
- return;
- }
-
- if (device_class != 0x06) {
- MTP_LOGE("The usb class is not mtp class : %d", device_class);
- return;
- }
-
- if (__parsing_usb_devpath(devpath, &busno, &portno) == false) {
- MTP_LOGE("devpath parsing failed: %s", devpath);
- return;
- }
-
- if (busno > 0 && portno > 0)
- ((device_changed_cb)usr_cb)(devpath, busno, portno, state, usr_data);
-}
-
-static int __dbus_subscribe_usb_host_event(device_changed_cb usr_callback, void *usr_data)
-{
- int ret = MTP_ERROR_NONE;
- GError *error = NULL;
-
- g_usb_cb_data = malloc(sizeof(device_cb_data));
- if (g_usb_cb_data == NULL) {
- MTP_LOGE("malloc failed");
- return MTP_ERROR_OUT_OF_MEMORY;
- }
-
- g_usb_cb_data->usr_cb = usr_callback;
- g_usb_cb_data->usr_data = usr_data;
-
- if (g_usb_bus == NULL) {
- g_usb_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!g_usb_bus) {
- MTP_LOGE("Failed to connect to the g D-BUS daemon: %s", error->message);
- g_error_free(error);
- ret = MTP_ERROR_PLUGIN_FAIL;
- goto ERROR;
- }
- }
-
- /* listening to messages from all objects as no path is specified */
- g_usb_handler = g_dbus_connection_signal_subscribe(
- g_usb_bus,
- NULL,
- DEVICED_INTERFACE_USBHOST,
- SIGNAL_USB_HOST_CHANGED,
- NULL,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- __dbus_usb_host_event_cb,
- g_usb_cb_data,
- NULL);
-
- return MTP_ERROR_NONE;
-
-ERROR:
-
- if (g_usb_bus != NULL) {
- g_object_unref(g_usb_bus);
- g_usb_bus = NULL;
- }
-
- g_free(g_usb_cb_data);
-
- MTP_LOGE("ERROR");
-
- return ret;
-}
-
-void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no, usbhost_state host_status, void *user_data)
+int __usb_host_status_changed_cb(struct libusb_context *ctx,
+ struct libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
+ int bus_no, dev_no;
int slot;
int num_of_devices;
mtp_context *mtp_ctx = (mtp_context *)user_data;
LIBMTP_mtpdevice_t *device;
mtp_device_info *device_info;
- MTP_LOGI("usb status: %d, bus_no : %03d, port_no : %03d", host_status, bus_no, port_no);
+ bus_no = libusb_get_bus_number(dev);
+ dev_no = libusb_get_device_address(dev);
- if (host_status == USB_HOST_ADDED) {
+ MTP_LOGI("bus_no : %03d, dev_no : %03d", bus_no, dev_no);
+
+ if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
+ MTP_LOGI("device added");
usleep(200000);
LIBMTP_Detect_Raw_Devices(&raw_devices, &num_of_devices);
for (slot = 0; slot < num_of_devices; slot++) {
- if (bus_no == raw_devices[slot].bus_location && port_no == raw_devices[slot].portnum) {
+ if (bus_no == raw_devices[slot].bus_location && dev_no == raw_devices[slot].devnum) {
int empty_slot = 0;
char usb_node[256] = {0,};
device_info->device = device;
device_info->bus_location = raw_devices[slot].bus_location;
device_info->device_number = raw_devices[slot].devnum;
- device_info->port_number = raw_devices[slot].portnum;
device_info->model_name = LIBMTP_Get_Modelname(device);
mtp_ctx->device_list->device_info_list[empty_slot] = device_info;
}
}
g_free(raw_devices);
- } else if (host_status == USB_HOST_REMOVED) {
+ } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
+ MTP_LOGI("device removed");
while (1) {
if (g_async_queue_length(mtp_ctx->c_queue) < 0 && mtp_ctx->is_processing == false)
break;
for (slot = 1; slot < MTP_MAX_SLOT; slot++) {
device_info = mtp_ctx->device_list->device_info_list[slot];
if (device_info && bus_no == device_info->bus_location &&
- port_no == device_info->port_number) {
+ dev_no == device_info->device_number) {
int device_id = -1;
device_id = mtp_daemon_util_get_device_id(device_info->device, mtp_ctx);
if (device_id < 0) {
MTP_LOGE("device_id: %d", device_id);
- return;
+ return 0;
}
LIBMTP_Release_Device(device_info->device);
mtp_daemon_gdbus_emit_event(MTP_INITIATOR_EVENT_TURNED_OFF, 0, mtp_ctx);
g_main_loop_quit(mtp_ctx->main_loop);
}
+
+ return 0;
}
static void* __event_thread(gpointer dev, gpointer data)
device_info->device = device;
device_info->bus_location = rawdevices[device_index].bus_location;
device_info->device_number = rawdevices[device_index].devnum;
- device_info->port_number = rawdevices[device_index].portnum;
device_info->model_name = LIBMTP_Get_Modelname(device);
char *device_version = LIBMTP_Get_Deviceversion(device);
return ret;
}
-int usb_host_set_event_cb(device_changed_cb usr_callback, void *usr_data)
+static gpointer __dispatch_event(gpointer user_data)
{
- int ret = MTP_ERROR_NONE;
+ mtp_context* mtp_ctx = (mtp_context*)user_data;
- ret = __dbus_subscribe_usb_host_event(usr_callback, usr_data);
+ if (mtp_ctx == NULL) {
+ MTP_LOGE("create thread failed");
+ g_thread_exit(NULL);
- return ret;
-}
+ return NULL;
+ }
-int usb_host_unset_event_cb(void)
-{
- if (g_usb_bus == NULL)
- return MTP_ERROR_NONE;
+ MTP_LOGE("dispatch thread created");
- g_dbus_connection_signal_unsubscribe(g_usb_bus, g_usb_handler);
- g_object_unref(g_usb_bus);
- g_usb_bus = NULL;
+ while (1) {
+ MTP_LOGE("dispatch event");
+ libusb_handle_events_completed(mtp_ctx->usb_ctx, NULL);
+ }
- /*Release Callback*/
- g_free(g_usb_cb_data);
+ g_thread_exit(NULL);
- return MTP_ERROR_NONE;
+ return NULL;
}
mtp_error_e mtp_daemon_event_init(mtp_context *mtp_ctx)
{
+ int ret = LIBUSB_SUCCESS;
int slot;
RETV_IF(mtp_ctx == NULL, MTP_ERROR_INVALID_PARAMETER);
return MTP_ERROR_NO_DEVICE;
/* usb event setting */
- usb_host_set_event_cb(__usb_host_status_changed_cb, mtp_ctx);
+ ret = libusb_init(&(mtp_ctx->usb_ctx));
+ if (ret != LIBUSB_SUCCESS) {
+ MTP_LOGE("libusb_init failed : %d", ret);
+ return MTP_ERROR_PLUGIN_FAIL;
+ }
+
+ ret = libusb_hotplug_register_callback(mtp_ctx->usb_ctx,
+ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
+ 0, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
+ LIBUSB_HOTPLUG_MATCH_ANY, __usb_host_status_changed_cb, mtp_ctx, &mtp_ctx->usb_callback_handle);
+
+ mtp_ctx->usb_event_thread = g_thread_try_new("dispatch", __dispatch_event, mtp_ctx, NULL);
+
+ if (ret != LIBUSB_SUCCESS) {
+ MTP_LOGE("libusb_hotplug_register_callback failed");
+ return MTP_ERROR_PLUGIN_FAIL;
+ }
/* create thread pool */
mtp_ctx->device_list->threads