Sync with Tizen 4.0 branch 27/169327/1 accepted/tizen/unified/20180206.064225 submit/tizen/20180206.043529
authorJihoon Jung <jh8801.jung@samsung.com>
Tue, 6 Feb 2018 04:30:06 +0000 (13:30 +0900)
committerJihoon Jung <jh8801.jung@samsung.com>
Tue, 6 Feb 2018 04:31:26 +0000 (13:31 +0900)
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
Change-Id: Id97b4c76b88926884cb687a0f6c675c1e3404b7e

packaging/99-mtp.rules
packaging/mtp-initiator.spec
src/daemon/CMakeLists.txt
src/daemon/include/mtp_daemon.h
src/daemon/include/mtp_daemon_event.h
src/daemon/mtp_daemon.c
src/daemon/mtp_daemon_db.c
src/daemon/mtp_daemon_event.c

index 51550e5f88a74dc8257a2644c28bd6c1940888b5..f5105bfaa326d3ad190a80590589b01d90f62691 100644 (file)
@@ -1,3 +1 @@
-ACTION=="add", SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:08*:*", RUN+="/usr/bin/systemctl start mtp-initiator.service"
 ACTION=="add", SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", RUN+="/usr/bin/systemctl start mtp-initiator.service"
-
index 3d608e509a7fba61e40d91dd29ea199a3ca01945..26a6bfb583172ff24dc4b082efe6f3ad3b0429e3 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       mtp-initiator
 Summary:    mtp(media transfer protocol) initiator
-Version:    1.4.27
+Version:    1.4.28
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
@@ -17,6 +17,7 @@ BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(capi-base-common)
 Buildrequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(libusb-1.0)
 BuildRequires:  python
 BuildRequires:  python-xml
 Requires:  security-config
index dfd85c710838d08917428e05fe3d8546f37f295a..91d924f6113bf3c3b362a6e74f2ce2c8cd3b9acd 100755 (executable)
@@ -24,7 +24,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src/daemon)
 include_directories(${CMAKE_SOURCE_DIR}/src/daemon/include)
 
 INCLUDE(FindPkgConfig)
-       pkg_check_modules(mtp_pkgs REQUIRED glib-2.0 gio-2.0 libmtp dlog gio-unix-2.0 sqlite3 capi-base-common libtzplatform-config)
+       pkg_check_modules(mtp_pkgs REQUIRED glib-2.0 gio-2.0 libmtp dlog gio-unix-2.0 sqlite3 capi-base-common libtzplatform-config libusb-1.0)
 
 FOREACH(flag ${mtp_pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index 6d9d5ae2486cff6bc1ed4879bad08f84f19041c6..0e378cceec5dd2bcad2329be05f635df95e7ebe3 100755 (executable)
@@ -33,6 +33,7 @@
 #include <libmtp.h>
 #include <tzplatform_config.h>
 #include "mtp_gdbuslib.h"
+#include <libusb.h>
 
 #define MTP_DBUS_SERVICE       "org.tizen.mtp"
 #define MTP_DBUS_MANAGER_PATH          "/org/tizen/mtp/manager"
@@ -126,7 +127,6 @@ struct _mtp_device_info {
        LIBMTP_mtpdevice_t *device;
        int bus_location;
        int device_number;
-       int port_number;
        char *model_name;
        char *stitching_engine_version;
 };
@@ -156,6 +156,11 @@ struct _mtp_context {
 
        /* db variable */
        sqlite3 *db;
+
+       /* usb event callback handle */
+       libusb_context *usb_ctx;
+       libusb_hotplug_callback_handle usb_callback_handle;
+       GThread *usb_event_thread;
 };
 
 struct _mtp_queue_data {
index 5ae954e50d2de9289a1d74f1f608070effca6786..5dc4a04019fabad0140390889e7015b4d414b1f1 100755 (executable)
@@ -20,6 +20,5 @@
 #include "mtp_daemon.h"
 
 mtp_error_e mtp_daemon_event_init(mtp_context* mtp_ctx);
-int usb_host_unset_event_cb(void);
 
 #endif
index 75918a4bfde91905def34ef21b7bd44bd8f372c8..6454f2f72d277c52444e0376f51283a616f02471 100755 (executable)
@@ -61,7 +61,8 @@ static mtp_error_e __daemon_deinitalize(mtp_context *mtp_ctx)
 
        RETV_IF(mtp_ctx == NULL, MTP_ERROR_INVALID_PARAMETER);
 
-       usb_host_unset_event_cb();
+       if (mtp_ctx->usb_callback_handle != 0)
+               libusb_hotplug_deregister_callback(NULL, mtp_ctx->usb_callback_handle);
 
        ret = mtp_daemon_db_deinit(mtp_ctx);
        if (ret != MTP_ERROR_NONE)
@@ -70,6 +71,12 @@ static mtp_error_e __daemon_deinitalize(mtp_context *mtp_ctx)
        if (mtp_ctx->c_thread != NULL)
                g_thread_unref(mtp_ctx->c_thread);
 
+       if (mtp_ctx->usb_event_thread != NULL)
+               g_thread_unref(mtp_ctx->usb_event_thread);
+
+       if (mtp_ctx->usb_ctx != NULL)
+               libusb_exit(mtp_ctx->usb_ctx);
+
        g_main_loop_unref(mtp_ctx->main_loop);
        g_free(mtp_ctx);
 
index acabf8186bfdd929e90c6062348d8b958641e7c6..59bd49913fad5714660d6dcfbd51cfefd58cb478 100755 (executable)
@@ -137,6 +137,7 @@ MTPObjectInfo* mtp_daemon_db_get_object_info(int mtp_device,
                sql_ret = sqlite3_prepare_v2(mtp_ctx->db, sql, strlen(sql), &stmt, NULL);
                if (stmt == NULL) {
                        MTP_LOGE("sqlite3_prepare_v2 failed, %d, %s", sql_ret, sqlite3_errmsg(mtp_ctx->db));
+                       sqlite3_free(sql);
                        g_free(object_info);
                        return NULL;
                }
@@ -144,6 +145,8 @@ MTPObjectInfo* mtp_daemon_db_get_object_info(int mtp_device,
                sql_ret = sqlite3_step(stmt);
                if (sql_ret != SQLITE_ROW) {
                        MTP_LOGE("sqlite3_step failed, %d", sql_ret);
+                       sqlite3_finalize(stmt);
+                       sqlite3_free(sql);
                        g_free(object_info);
                        return NULL;
                }
@@ -204,6 +207,8 @@ bool mtp_daemon_db_is_exist(int mtp_device, int mtp_storage, int object_handle,
                sql_ret = sqlite3_step(stmt);
                if (sql_ret != SQLITE_ROW) {
                        MTP_LOGE("sqlite3_step failed, %d", sql_ret);
+                       sqlite3_finalize(stmt);
+                       sqlite3_free(sql);
                        return false;
                }
 
index 5861ca89f1be8e5820b8e476109fc3dee610283d..2ee290001c492bcc15c8c3926ecc14679d2dd0a5 100755 (executable)
 #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;
@@ -91,134 +61,10 @@ static void __wait_smack_labeling(char *usb_node)
        } 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;
@@ -226,13 +72,17 @@ void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no,
        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,};
 
@@ -258,7 +108,6 @@ void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no,
                                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;
@@ -271,7 +120,8 @@ void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no,
                        }
                }
                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;
@@ -287,13 +137,13 @@ void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no,
                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);
@@ -317,6 +167,8 @@ void __usb_host_status_changed_cb(const char *dev_path, int bus_no, int port_no,
                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)
@@ -422,7 +274,6 @@ mtp_error_e __device_list_init(mtp_context *mtp_ctx)
                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);
 
@@ -446,32 +297,32 @@ mtp_error_e __device_list_init(mtp_context *mtp_ctx)
        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);
@@ -484,7 +335,23 @@ mtp_error_e mtp_daemon_event_init(mtp_context *mtp_ctx)
                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