mot-agent: Add retry mechanism for disc_mot_enb_devs
authorSaurav Babu <saurav.babu@samsung.com>
Wed, 14 Feb 2018 14:12:28 +0000 (19:42 +0530)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:48 +0000 (19:38 +0900)
Signed-off-by: Saurav Babu <saurav.babu@samsung.com>
src/mot-agent/introspection/ma.xml
src/mot-agent/ma-service-interface.c
src/mot-agent/ma-service-interface.h
src/mot-agent/ma-subowner.c

index efa6a34..bebece0 100644 (file)
@@ -95,6 +95,9 @@
         <signal name="disc_mot_enb_devs_done">\r
             <arg type="aa{sv}" name="list" direction="out"/>\r
         </signal>\r
+        <signal name="mot_enb_devs_added">\r
+            <arg type="a{sv}" name="device" direction="out"/>\r
+        </signal>\r
         <signal name="disc_mowned_devs_done">\r
             <arg type="aa{sv}" name="list" direction="out"/>\r
         </signal>\r
index 9298a8b..87f2a6c 100644 (file)
@@ -570,6 +570,11 @@ void ma_notify_mowned_devs(GVariant *devices)
        net_ma_emit_disc_mowned_devs_done(ma_dbus_get_object(), devices);\r
 }\r
 \r
+void ma_notify_mot_enb_dev_added(GVariant *device)\r
+{\r
+       net_ma_emit_mot_enb_devs_added(ma_dbus_get_object(), device);\r
+}\r
+\r
 static void _ma_dbus_deinit(ma_service *service)\r
 {\r
        ma_check_null_ret("service", service);\r
index e608201..438653c 100644 (file)
@@ -49,6 +49,7 @@ gboolean ma_service_interface_init(ma_service *service);
 void ma_service_interface_deinit(ma_service *service);\r
 void ma_notify_mot_env_devs(GVariant *devices);\r
 void ma_notify_mowned_devs(GVariant *devices);\r
+void ma_notify_mot_enb_dev_added(GVariant *device);\r
 \r
 #ifdef __cplusplus\r
 }\r
index 5ee81b4..a6f26b2 100755 (executable)
 #define CALLBACK_TIMEOUT_10S 10 * 1000 /**< 10 sec = 10 * 1000 * 1ms */
 #define CALLBACK_TIMEOUT_5S 5 * 1000 /**< 5sec = 5 * 1000 * 1ms */
 
+#define RETRY_INTERVAL 100
+#define MAX_RETRY_COUNT 20
+
 //#define TIMEOUT_USED
 #define DEBUG_UUID
 
+static int _disc_mot_enb_devs(ma_service *service, int timeout);
+
 /* '_' for separaing from the same constant variable in srmresourcestrings.c  */
 static const char* SVR_DB_FILE_NAME = "oic_svr_db_ma.dat";
 static const char* PRVN_DB_FILE_NAME = "oic_pdm_ma.db";
@@ -134,6 +139,7 @@ typedef struct _ma_subowner {
        char *rnd_pin; /**< Random PIN */
        int rnd_pin_len; /**< Random PIN length */
 
+       int g_motdev_retry_cnt; /* MOT Enabled discovery retry count */
 } ma_subowner_s;
 
 ma_subowner_s *g_client;
@@ -858,29 +864,131 @@ static gboolean _ma_timeout_cb(gpointer data)
        return G_SOURCE_REMOVE;
 }
 #endif
+
+static gboolean __retry_device_discovery(gpointer data)
+{
+       ma_req_cb_s *con = (ma_req_cb_s *)data;
+
+       if (con->cid == MA_DISC_MOT_ENB_DEVS) {
+               MA_LOGI("Retry to find MOT enabled devices retry count %d",
+                               g_client->g_motdev_retry_cnt);
+               _disc_mot_enb_devs(con->userdata, con->timeout);
+       }
+
+       return FALSE;
+}
+
+static void _update_mot_dev_list(ma_req_cb_s *con, OCProvisionDev_t *list)
+{
+       OCProvisionDev_t *iter = NULL;
+       OCProvisionDev_t *dev_list;
+       GVariantBuilder builder;
+
+       if (con->cid == MA_DISC_MOT_ENB_DEVS)
+               dev_list = g_client->g_motdev_list;
+       else if (con->cid == MA_DISC_MOWNED_DEVS)
+               dev_list = g_client->g_mowned_list;
+       else
+               return;
+
+       iter = list;
+
+       while (iter) {
+               OicUuid_t *uuid = &iter->doxm->deviceID;
+
+               if (!_get_dev_by_uuid(dev_list, uuid)) {
+                       MA_LOGD("Add device %s to list", _get_readable_uuid(uuid));
+                       OCProvisionDev_t *temp2;
+                       OCProvisionDev_t *temp = iter;
+                       temp->next = NULL;
+                       temp2 = PMCloneOCProvisionDev(temp);
+                       temp2->next = dev_list;
+                       dev_list = temp2;
+
+                       /* Notify Mot Enabled Device added */
+                       g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+                       g_variant_builder_add(&builder, "{sv}", "deviceId",
+                                                         g_variant_new_string(_get_readable_uuid(uuid)));
+                       g_variant_builder_add(&builder, "{sv}", "adapter",
+                                                         g_variant_new_uint32(iter->endpoint.adapter));
+                       g_variant_builder_add(&builder, "{sv}", "flags",
+                                                         g_variant_new_int32(iter->endpoint.flags));
+                       g_variant_builder_add(&builder, "{sv}", "port",
+                                                         g_variant_new_uint16(iter->endpoint.port));
+                       g_variant_builder_add(&builder, "{sv}", "addr",
+                                                         g_variant_new_string(iter->endpoint.addr));
+                       g_variant_builder_add(&builder, "{sv}", "ifindex",
+                                                         g_variant_new_int32(iter->endpoint.ifindex));
+                       g_variant_builder_add(&builder, "{sv}", "routeData",
+                                                         g_variant_new_string(iter->endpoint.routeData));
+                       g_variant_builder_add(&builder, "{sv}", "remoteId",
+                                                         g_variant_new_string(iter->endpoint.remoteId));
+
+                       g_variant_builder_add(&builder, "{sv}", "connType",
+                                                         g_variant_new_uint32(iter->connType));
+                       g_variant_builder_add(&builder, "{sv}", "securePort",
+                                                         g_variant_new_uint16(iter->securePort));
+#ifdef WITH_TCP
+                       g_variant_builder_add(&builder, "{sv}", "tcpPort",
+                                                         g_variant_new_uint16(iter->tcpPort));
+#endif
+                       g_variant_builder_add(&builder, "{sv}", "secVer",
+                                                         g_variant_new_string(iter->secVer));
+                       g_variant_builder_add(&builder, "{sv}", "devStatus",
+                                                         g_variant_new_uint32(iter->devStatus));
+
+                       ma_notify_mot_enb_dev_added(g_variant_builder_end(&builder));
+               } else {
+                       MA_LOGD("Device %s already exist", _get_readable_uuid(uuid));
+               }
+
+               iter = iter->next;
+       }
+
+       if (con->cid == MA_DISC_MOT_ENB_DEVS)
+               g_client->g_motdev_list = dev_list;
+       else if (con->cid == MA_DISC_MOWNED_DEVS)
+               g_client->g_mowned_list = dev_list;
+}
+
 static gpointer _disc_mot_env_devs_func(gpointer data)
 {
        int ret = OC_STACK_OK;
+       OCProvisionDev_t *list = NULL;
        ma_req_cb_s *con = (ma_req_cb_s *)data;
        ma_check_null_ret_error("con", con, NULL);
 
        MA_LOGI("Discovering Multiple Ownership Transfer enabled Devices on Network..");
 
-       /* delete mot device lists before updating them */
-       _remove_mot_client();
+       g_client->g_motdev_retry_cnt += 1;
 
        g_mutex_lock(&iotivity_mutex);
-       OCDiscoverMultipleOwnerEnabledDevices(con->timeout, &g_client->g_motdev_list);
+       OCDiscoverMultipleOwnerEnabledDevices(con->timeout, &list);
        g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret) {
                MA_LOGE( "OCDiscoverMultipleOwnerEnalbedDevices API error");
                goto DISC_MOT_ENB_DEVS_END;
        }
 
-       __notify_found_devs(con);
+       _update_mot_dev_list(con, list);
+
+       if (list)
+               OCDeleteDiscoveredDevices(list);
+
+       /* Notify Found Devices when first discovery try is finished */
+       if (g_client->g_motdev_retry_cnt == 1)
+               __notify_found_devs(con);
+
+       if (g_client->g_motdev_retry_cnt <= MAX_RETRY_COUNT) {
+               g_timeout_add(RETRY_INTERVAL, __retry_device_discovery, con);
+
+               return NULL;
+       }
 
 DISC_MOT_ENB_DEVS_END:
 
+       g_client->g_motdev_retry_cnt = 0;
+
        _request_cleanup(con);
 
        g_thread_exit(GINT_TO_POINTER (1));
@@ -891,11 +999,10 @@ DISC_MOT_ENB_DEVS_END:
 static int _disc_mot_enb_devs(ma_service *service, int timeout)
 {
        ma_req_cb_s *con = NULL;
+
        con = g_malloc0(sizeof(ma_req_cb_s));
        if (NULL == con) {
                MA_LOGE( "g_malloc0() Fail=%d", errno);
-               /* Unset d2ds status 'pending' */
-               g_atomic_int_set(&service->pending, 0);
                return MA_ERROR_OUT_OF_MEMORY;
        }
 
@@ -2521,18 +2628,20 @@ int ma_request_get_ownerid(ma_service *service, gchar **uuid_str)
 
 int ma_request_disc_mot_enb_devs(ma_service *service, int timeout)
 {
-       int ret =MA_ERROR_NONE;
+       int ret = MA_ERROR_NONE;
 
        ma_check_null_ret_error("service", service, FALSE);
 
        MA_LOGD("[IPC] Discovery MOT enabled devices");
 
-       /* If we are working now? */
-       if (g_atomic_int_get(&service->pending))
+       if (g_client->g_motdev_retry_cnt > 0) {
+               MA_LOGI("Previous discovery is ongoing, reset retry count");
+               g_client->g_motdev_retry_cnt = 0;
                return MA_ERROR_IN_PROGRESS;
+       }
 
-       /* Set d2ds status 'pending' */
-       g_atomic_int_set(&service->pending, 1);
+       /* delete mot device lists before updating them */
+       _remove_mot_client();
 
        ret = _disc_mot_enb_devs(service, timeout);