ffs: Fix issues related to starting/stopping ffs 08/172908/3
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Mon, 12 Mar 2018 13:00:16 +0000 (14:00 +0100)
committersaerome kim <saerome.kim@samsung.com>
Fri, 6 Apr 2018 03:58:35 +0000 (03:58 +0000)
In case of ffs we rely on events from ep0, which makes vconf events
reduntant. This requires selecting transport as soon as possible and
using that info at initialization of other components.

Change-Id: I9b164edcd883ae94061b29d5ae494521bf79cc71
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
include/transport/mtp_usb_driver.h
src/mtp_event_handler.c
src/mtp_init.c
src/transport/mtp_usb_driver.c
src/transport/mtp_usb_driver_ffs.c

index 968616a7c6405d9c44dfe7b8641e579c83f69dbe..51253d503f33e29b0f503e75ce93851df6778226 100755 (executable)
@@ -83,6 +83,7 @@ typedef enum {
 /* Maximum repeat count for USB error recovery */
 #define MTP_USB_ERROR_MAX_RETRY                5
 
+mtp_bool _transport_select_driver(void);
 mtp_bool _transport_init_usb_device(void);
 void _transport_deinit_usb_device(void);
 void *_transport_thread_usb_write(void *arg);
index 417c7482e0317632d4347ebb321d122e71cebde9..b021a75154c7ab6a8b0b2c868a67886a80ce800d 100755 (executable)
@@ -60,22 +60,30 @@ mtp_bool _eh_register_notification_callbacks(void)
        mtp_int32 ret;
        phone_status_t val = 0;
 
-       _util_get_usb_status(&val);
-       _util_set_local_usb_status(val);
-       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
-                       __handle_usb_notification, NULL);
-       if (ret < 0) {
-               ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_SYSMAN_USB_STATUS);
-               return FALSE;
-       }
+       /* For FFS transport we rely on ep0 events */
+       if (_transport_get_type() == MTP_TRANSPORT_FFS) {
+               DBG("Using FFS transport, assuming established connection");
+               _util_set_local_usb_status(MTP_PHONE_USB_DISCONNECTED);
+               _util_set_local_usbmode_status(1);
+       } else {
+               DBG("Using legacy transport, registering vconf notifier");
+               _util_get_usb_status(&val);
+               _util_set_local_usb_status(val);
+               ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
+                               __handle_usb_notification, NULL);
+               if (ret < 0) {
+                       ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_SYSMAN_USB_STATUS);
+                       return FALSE;
+               }
 
-       _util_get_usbmode_status(&val);
-       _util_set_local_usbmode_status(val);
-       ret = vconf_notify_key_changed(VCONFKEY_USB_CUR_MODE,
-                       __handle_usb_mode_notification, NULL);
-       if (ret < 0) {
-               ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_USB_CUR_MODE);
-               return FALSE;
+               _util_get_usbmode_status(&val);
+               _util_set_local_usbmode_status(val);
+               ret = vconf_notify_key_changed(VCONFKEY_USB_CUR_MODE,
+                               __handle_usb_mode_notification, NULL);
+               if (ret < 0) {
+                       ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_USB_CUR_MODE);
+                       return FALSE;
+               }
        }
 
        _util_get_lock_status(&val);
@@ -106,12 +114,13 @@ mtp_bool _eh_handle_usb_events(mtp_uint32 type)
                        return TRUE;
                }
 
-               is_usb_inserted = 1;
                /* check USB connection state */
-               if (MTP_PHONE_USB_DISCONNECTED == _util_get_local_usb_status()) {
+               if (_transport_get_type() != MTP_TRANSPORT_FFS &&
+                               MTP_PHONE_USB_DISCONNECTED == _util_get_local_usb_status()) {
                        ERR("USB is disconnected. So just return.");
                        return FALSE;
                }
+               is_usb_inserted = 1;
 
                _transport_set_usb_discon_state(FALSE);
                _transport_set_cancel_initialization(FALSE);
index 02a7b1b7c3fdc35f5a4c921b0e585c83b1477aeb..c2643beaab62e2d63d8973f2e746347ae7d41d9d 100755 (executable)
@@ -32,6 +32,7 @@
 #include "mtp_transport.h"
 #include "mtp_util.h"
 #include "mtp_media_info.h"
+#include "mtp_usb_driver.h"
 
 /*
  * GLOBAL AND EXTERN VARIABLES
@@ -489,6 +490,11 @@ int main(int argc, char *argv[])
 {
        mtp_int32 ret;
 
+       if (_transport_select_driver() == FALSE) {
+               ERR("_transport_select_driver fail");
+               return MTP_ERROR_GENERAL;
+       }
+
        if (_eh_register_notification_callbacks() == FALSE) {
                ERR("_eh_register_notification_callbacks() Fail");
                return MTP_ERROR_GENERAL;
index 6fde0251ed05290986d3b2186bf4b90dfb93e447..a856151eb000786b1d19dc8e97d07e79d5e12a11 100644 (file)
@@ -23,17 +23,26 @@ static const mtp_usb_driver_t *usb_driver;
 /*
  * FUNCTIONS
  */
-mtp_bool _transport_init_usb_device(void)
+mtp_bool _transport_select_driver(void)
 {
        if (access(MTP_DRIVER_PATH, F_OK) == 0) {
                usb_driver = &mtp_usb_driver_slp;
-       } else if (access(MTP_EP0_PATH, F_OK) == 0 || sd_listen_fds(0) >= 4) {
+               DBG("SLP driver selected");
+               return TRUE;
+       }
+
+       if (access(MTP_EP0_PATH, F_OK) == 0 || sd_listen_fds(0) >= 4) {
                usb_driver = &mtp_usb_driver_ffs;
-       } else {
-               ERR("No suport for USB gadgets in kernel");
-               return FALSE;
+               DBG("FFS driver selected");
+               return TRUE;
        }
 
+       ERR("No suport for USB gadgets in kernel");
+       return FALSE;
+}
+
+mtp_bool _transport_init_usb_device(void)
+{
        return usb_driver->transport_init_usb_device();
 }
 
index 091daa8f64a22130b107abd02bdde0735686093f..39abc2d7c0545dc9fc915e7e0e6e5e7bbc00b569 100755 (executable)
@@ -33,6 +33,7 @@
 #include "mtp_thread.h"
 #include "mtp_transport.h"
 #include "mtp_event_handler.h"
+#include "mtp_init.h"
 #include <sys/prctl.h>
 #include <systemd/sd-daemon.h>
 
@@ -75,6 +76,7 @@ static mtp_bool __io_init()
        int ret;
 
        if (sd_listen_fds(0) >= 4) {
+               DBG("socket-activated");
                g_usb_ep0 = SD_LISTEN_FDS_START;
                g_usb_ep_in = SD_LISTEN_FDS_START + 1;
                g_usb_ep_out = SD_LISTEN_FDS_START + 2;
@@ -428,6 +430,15 @@ static void *ffs_transport_thread_usb_control(void *arg)
                            event.u.setup.wLength);
                        __setup(g_usb_ep0, &event.u.setup);
                        break;
+               case FUNCTIONFS_ENABLE:
+                       DBG("ENABLE");
+                       _util_set_local_usb_status(MTP_PHONE_USB_CONNECTED);
+                       break;
+               case FUNCTIONFS_DISABLE:
+                       DBG("DISABLE");
+                       _util_set_local_usb_status(MTP_PHONE_USB_DISCONNECTED);
+                       _eh_send_event_req_to_eh_thread(EVENT_USB_REMOVED, 0, 0, NULL);
+                       break;
                }
        } while (status > 0);
 
@@ -463,6 +474,8 @@ static mtp_int32 __handle_usb_read_err(mtp_int32 err,
                                ERR("_transport_init_usb_device Fail");
                                continue;
                        }
+               } else if (err < 0 && errno == ESHUTDOWN) {
+                       DBG("ESHUTDOWN");
                } else {
                        ERR("Unknown error : %d, errno [%d] \n", err, errno);
                        break;
@@ -483,10 +496,11 @@ static void __clean_up_msg_queue(void *mq_id)
 {
        mtp_int32 len = 0;
        msgq_ptr_t pkt = { 0 };
-       msgq_id_t l_mqid = *(msgq_id_t *)mq_id;
+       msgq_id_t l_mqid;
 
        ret_if(mq_id == NULL);
 
+       l_mqid = *(msgq_id_t *)mq_id;
        _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
        while (TRUE == _util_msgq_receive(l_mqid, (void *)&pkt,
                                          sizeof(msgq_ptr_t) - sizeof(long), 1, &len)) {