Merge "Modified resource properties for /tizen/d2d-service" into tizen
authorPark <jpark0@samsung.com>
Mon, 16 Jan 2017 09:01:12 +0000 (01:01 -0800)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Mon, 16 Jan 2017 09:01:12 +0000 (01:01 -0800)
21 files changed:
common/Types.h
daemon/DbusServer.cpp
daemon/IServiceProvider.h
daemon/RequestHandler.cpp
daemon/ServiceManager.cpp
daemon/discovery_provider/SmartviewDiscoveryProvider.cpp
daemon/service_provider/AppCommServiceProvider.cpp
daemon/service_provider/AppCommServiceProvider.h
daemon/service_provider/RemoteAppControlServiceProvider.cpp
daemon/service_provider/RemoteAppControlServiceProvider.h
lib/conv_lib_json.cpp
lib/conv_lib_json.h
lib/conv_lib_service.cpp
lib/dbus_client.cpp
lib/include/d2d_conv_internal.h
msf_tizen_client/include/Service.h
msf_tizen_client/src/Channel.cpp
msf_tizen_client/src/MSFDSearchProvider.cpp
msf_tizen_client/src/Search.cpp
msf_tizen_client/src/Service.cpp
msf_tizen_client/src/mDNSSearchProvider.cpp

index 637a500..72da8a5 100644 (file)
@@ -34,6 +34,7 @@
 #define DBUS_PATH              "/org/tizen/d2dconv"
 #define DBUS_IFACE             "org.tizen.d2dconv"
 #define DBUS_TIMEOUT   3000000
+#define DBUS_TIMEOUT_CALL      3000
 
 #define METHOD_REQUEST "Request"
 #define METHOD_RESPOND "Respond"
@@ -66,6 +67,7 @@
 #define CONV_SUBJECT_COMMUNICATION_STOP        "conv/communication/stop"
 #define CONV_SUBJECT_COMMUNICATION_GET "conv/communication/get"
 #define CONV_SUBJECT_COMMUNICATION_SET "conv/communication/set"
+#define CONV_SUBJECT_COMMUNICATION_CHECK_STATE "conv/communication/check_state"
 
 #define CONV_SUBJECT_COMMUNICATION_WRITE       "conv/communication/write"
 #define CONV_SUBJECT_COMMUNICATION_READ        "conv/communication/read"
index 2b18185..fbe3f6f 100755 (executable)
@@ -243,7 +243,7 @@ void conv::DbusServer::publish(const char* dest, int reqId, const char* subject,
        _D("before g_dbusConnection_call..");
        GError *err = NULL;
        g_dbus_connection_call(dbusConnection, dest, DBUS_PATH, DBUS_IFACE,
-                       METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err);
+                       METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT_CALL, NULL, NULL, &err);
 
        if (err != NULL) {
                _D("dbusConnection_call Error msg : %s", err->message);
index 239d20b..905253c 100644 (file)
@@ -33,6 +33,7 @@ namespace conv {
                        virtual int readRequest(Request* requestObj) = 0;
                        virtual int publishRequest(Request* requestObj) = 0;
                        virtual int registerRequest(Request* requestObj) = 0;
+                       virtual int checkStateRequest(Request* requestObj) = 0;
                        virtual int loadServiceInfo(Request* requestObj) = 0;
                        virtual int getServiceInfoForDiscovery(Json* jsonObj) = 0;
                        int checkActivationState() {
index bf5338c..3e9f1db 100755 (executable)
@@ -68,7 +68,8 @@ int conv::RequestHandler::handleRequest(Request* requestObj)
                if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_DISCOVERY_START) || !strcmp(requestObj->getSubject(), CONV_SUBJECT_DISCOVERY_STOP))
                        return discovery_manager::handleRequest (requestObj);
                else if ( !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_START) || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_STOP)
-                               || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_SET) || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_GET) )
+                               || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_SET) || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_GET)
+                               || !strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_CHECK_STATE))
                        result = service_manager::handleRequest(requestObj);
                else if ( !strcmp(requestObj->getSubject(), CONV_SUBJECT_CONNECTION_START) || !strcmp(requestObj->getSubject(), CONV_SUBJECT_CONNECTION_STOP) )
                        result = connection_manager::handleRequest(requestObj);
index a491b17..2ebac3b 100755 (executable)
@@ -187,6 +187,8 @@ int conv::ServiceManager::handleRequest(Request* requestObj)
                                error = (*it)->publishRequest(requestObj);
                        } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_RECV)) {
                                return (*it)->registerRequest(requestObj);
+                       } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_COMMUNICATION_CHECK_STATE)) {
+                               error = (*it)->checkStateRequest(requestObj);
                        }
                        IF_FAIL_CATCH_TAG(error == CONV_ERROR_NONE, _E, "service manager request handle error");
                }
index 0d6c92a..23c869b 100755 (executable)
@@ -143,7 +143,7 @@ conv::SmartViewDevice* conv::SmartviewDiscoveryProvider::convertIntoConvDevice(S
        if ( !strcmp(CONV_SMART_TV, smartview_service->getType().c_str()) ) {
                device_info->setType(CONV_DEVICE_TYPE_TV);
        } else {
-               device_info->setType(CONV_DEVICE_TYPE_MOBILE);
+               device_info->setType(smartview_service->getType().c_str());
        }
 
        return device_info;
index 48ab640..801f8a1 100755 (executable)
@@ -172,8 +172,8 @@ int conv::AppCommServiceProvider::startRequest(Request* requestObj)
        for (ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
                _D("iteration");
                if ( (*iter) != NULL && !(*iter)->uri.compare(uri) && !(*iter)->channelId.compare(channelId) ) {
-                       if ( (*iter)->state == APP_COMM_STATE_STARTED || (*iter)->state == APP_COMM_STATE_STARTING ) {
-                               _D("already started or now starting");
+                       if ( (*iter)->state == APP_COMM_STATE_STARTED ) {
+                               _D("already started");
                                return CONV_ERROR_INVALID_OPERATION;
                        } else {
                                _D("appInfo exists but no application instance");
@@ -462,6 +462,7 @@ int conv::AppCommServiceProvider::registerRequest(Request* requestObj)
                _D("subscribe requested");
                break;
        case REQ_UNSUBSCRIBE:
+               delete svcInfo->registeredRequest;
                svcInfo->registeredRequest = NULL;
                requestObj->reply(CONV_ERROR_NONE);
                delete requestObj;
@@ -475,6 +476,39 @@ int conv::AppCommServiceProvider::registerRequest(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
+int conv::AppCommServiceProvider::checkStateRequest(Request* requestObj)
+{
+       _D("communcation/check_state requested");
+       AppCommServiceInfo *svcInfo = reinterpret_cast<AppCommServiceInfo*>(requestObj->getServiceInfo());
+
+       Json channel;
+       requestObj->getChannelFromDescription(&channel);
+
+       string uri, channelId;
+
+       channel.get(NULL, CONV_JSON_URI, &uri);
+       channel.get(NULL, CONV_JSON_CHANNEL_ID, &channelId);
+
+       IF_FAIL_RETURN_TAG(!uri.empty() || svcInfo->isLocal, CONV_ERROR_INVALID_PARAMETER, _E, "uri is empty");
+       IF_FAIL_RETURN_TAG(!channelId.empty(), CONV_ERROR_INVALID_PARAMETER, _E, "channelId is empty");
+
+       for (ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
+               _D("%s, %s", (*iter)->uri.c_str(), (*iter)->channelId.c_str());
+               if ( (*iter) != NULL && !(*iter)->uri.compare(uri) && !(*iter)->channelId.compare(channelId) ) {
+                       if ( (*iter)->state == APP_COMM_STATE_STARTED ) {
+                               _D("service is started");
+                               return CONV_ERROR_NONE;
+                       } else {
+                               _D("service is not started");
+                               return CONV_ERROR_INVALID_OPERATION;
+                       }
+               }
+       }
+
+       _D("no service found");
+       return CONV_ERROR_INVALID_OPERATION;
+}
+
 int conv::AppCommServiceProvider::getServiceInfoForDiscovery(Json* jsonObj)
 {
        jsonObj->set(NULL, CONV_JSON_DISCOVERY_SERVICE_TYPE, CONV_SERVICE_APP_TO_APP_COMMUNICATION);
index e10f3da..ecdf5c2 100755 (executable)
@@ -38,6 +38,7 @@ namespace conv {
                        int readRequest(Request* requestObj);
                        int publishRequest(Request* requestObj);
                        int registerRequest(Request* requestObj);
+                       int checkStateRequest(Request* requestObj);
                        int loadServiceInfo(Request* requestObj);
                        int getServiceInfoForDiscovery(Json* jsonObj);
                        int handleVconfUpdate(keynode_t *node);
index 0375bc3..ba6777b 100755 (executable)
@@ -312,8 +312,13 @@ static int __access_control(iotcon_request_h request, iotcon_attributes_h attrib
        if (!strcmp(CONV_ACCESS_CONTROL_REQUEST, access_request_type)) {
 #if defined(_D2D_INTERNAL_ACL_)
                ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
+#if defined(_TV_) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_TV)
+               _D("Internal ACL for Odroid.");
+               acManagerPolicy = ACMANAGER_POLICY_P;
+#else
+               _D("Internal ACL for Mobile & Wearable.");
                IF_FAIL_RETURN_TAG(AddACLDevice(macAddress, deviceName, ip.c_str(), &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "AddACLDevice failed");
-
+#endif
                if (acManagerPolicy == ACMANAGER_POLICY_P) {
                        _D("PERMITTED");
                        policy = CONV_ACCESS_CONTROL_PERMITTED;
@@ -416,8 +421,13 @@ static int __app_control_launch(iotcon_request_h request, iotcon_attributes_h at
 
 #if defined(_D2D_INTERNAL_ACL_)
        ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U;
-
+#if defined(_TV_) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_TV)
+       _D("Internal ACL for Odroid.");
+       acManagerPolicy = ACMANAGER_POLICY_P;
+#else
+       _D("Internal ACL for Mobile & Wearable.");
        IF_FAIL_RETURN_TAG(GetACLState(macAddress, &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "ACL check failed");
+#endif
        if (acManagerPolicy == ACMANAGER_POLICY_P) {
                _D("PERMITTED");
        } else {
@@ -689,6 +699,11 @@ static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error
        iotcon_response_result_e response_result;
        iotcon_representation_h repr;
 
+       if (!response) {
+               _D("response is NULL");
+               return;
+       }
+
        conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(user_data);
 
        ret = iotcon_response_get_result(response, &response_result);
@@ -879,6 +894,21 @@ int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
+int conv::RemoteAppControlServiceProvider::checkStateRequest(Request* requestObj)
+{
+       _D("communcation/check_state requested");
+
+       RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
+
+       if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
+               _D("not started");
+               return CONV_ERROR_INVALID_OPERATION;
+       } else {
+               _D("started");
+               return CONV_ERROR_NONE;
+       }
+}
+
 int conv::RemoteAppControlServiceProvider::readRequest(Request* requestObj)
 {
        return CONV_ERROR_NONE;
@@ -901,6 +931,11 @@ static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
        response_cb_info_s cb_info;
        cb_info.requestObj = NULL;
 
+       if (!response) {
+               _D("response is NULL");
+               return;
+       }
+
        ret = iotcon_response_get_representation(response, &repr);
        IF_FAIL_CATCH_TAG(ret == IOTCON_ERROR_NONE, _E, "iotcon_response_get_representation() Failed(%d)", ret);
 
@@ -948,7 +983,8 @@ static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
                if (appcontrol_result == IOTCON_ERROR_NONE) {
                        payload.set(NULL, CONV_JSON_APP_CONTROL_RESULT, resultStr.c_str());
                }
-               result.set(NULL, CONV_JSON_DESCRIPTION, cb_info.requestObj->getDescription());
+               description = cb_info.requestObj->getDescription();
+               result.set(NULL, CONV_JSON_DESCRIPTION, description);
                result.set(NULL, CONV_JSON_PAYLOAD, payload);
 
                cb_info.requestObj->publish(CONV_ERROR_NONE, result, 0, NULL);
@@ -975,7 +1011,8 @@ CATCH:
                        payload.set(NULL, CONV_JSON_APP_CONTROL_REQUEST, appctl_request_char);
                }
 
-               result.set(NULL, CONV_JSON_DESCRIPTION, cb_info.requestObj->getDescription());
+               description = cb_info.requestObj->getDescription();
+               result.set(NULL, CONV_JSON_DESCRIPTION, description);
                result.set(NULL, CONV_JSON_PAYLOAD, payload);
 
                cb_info.requestObj->publish(CONV_ERROR_INVALID_OPERATION, result, 0, NULL);
@@ -1058,6 +1095,16 @@ int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
        switch (requestObj->getType()) {
        case REQ_SUBSCRIBE:
                if (svcInfo->registeredRequest != NULL) {
+                       for (std::map<int, response_cb_info_s>::iterator it = response_cb_map.begin(); it != response_cb_map.end(); ++it) {
+                               if (((response_cb_info_s)it->second).requestObj == svcInfo->registeredRequest) {
+                                       response_cb_info_s cbInfo;
+                                       cbInfo.req_id = ((response_cb_info_s)it->second).req_id;
+                                       cbInfo.requestObj = requestObj;
+
+                                       it->second = cbInfo;
+                               }
+                       }
+
                        delete svcInfo->registeredRequest;
                }
                svcInfo->registeredRequest = requestObj;
@@ -1065,6 +1112,17 @@ int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
                _D("subscribe requested");
                break;
        case REQ_UNSUBSCRIBE:
+               for (std::map<int, response_cb_info_s>::iterator it = response_cb_map.begin(); it != response_cb_map.end(); ++it) {
+                       if (((response_cb_info_s)it->second).requestObj == svcInfo->registeredRequest) {
+                               response_cb_info_s cbInfo;
+                               cbInfo.req_id = ((response_cb_info_s)it->second).req_id;
+                               cbInfo.requestObj = NULL;
+
+                               it->second = cbInfo;
+                       }
+               }
+
+               delete svcInfo->registeredRequest;
                svcInfo->registeredRequest = NULL;
                requestObj->reply(CONV_ERROR_NONE);
                delete requestObj;
index 455838b..354f1ca 100644 (file)
@@ -45,6 +45,7 @@ namespace conv {
                        int readRequest(Request* requestObj);
                        int publishRequest(Request* requestObj);
                        int registerRequest(Request* requestObj);
+                       int checkStateRequest(Request* requestObj);
                        int loadServiceInfo(Request* requestObj);
                        int getServiceInfoForDiscovery(Json* jsonObj);
                        int handleVconfUpdate(keynode_t *node);
index f19c77c..9447ec0 100755 (executable)
@@ -162,6 +162,12 @@ bool json::operator!=(const json& rhs)
        return !operator==(rhs);
 }
 
+bool json::isEmpty()
+{
+       json emptyJson;
+       return nodeEquals(json_node, emptyJson.json_node);
+}
+
 char* json::dupCstr()
 {
        IF_FAIL_RETURN_TAG(json_node, NULL, _E, "Json object not initialized");
index ae5fe00..019923b 100644 (file)
@@ -72,6 +72,7 @@ public:
 
        bool operator==(const json& rhs);
        bool operator!=(const json& rhs);
+       bool isEmpty();
 
        char* dupCstr();
        std::string str();
index 6a3d55f..ea99bf7 100755 (executable)
@@ -82,24 +82,33 @@ static void conv_subject_cb(const char* subject, int req_id, int error, json dat
        service_handle->service_type = convert_string_to_type(service_type);
        service_handle->is_local = is_local;
        service_handle->connection_state = CONV_SERVICE_CONNECTION_STATE_CONNECTED;
+       conv_channel_h channel_handle = NULL;
+       conv_payload_h payload_handle = NULL;
 
-       conv_channel_h channel_handle = new(std::nothrow) _conv_channel_handle();
-       IF_FAIL_VOID_TAG(channel_handle, _E, "Memory allocation failed");
+       if (!channel.isEmpty()) {
+               channel_handle = new(std::nothrow) _conv_channel_handle();
+               IF_FAIL_VOID_TAG(channel_handle, _E, "Memory allocation failed");
+               channel_handle->jchannel = channel;
+       }
 
-       channel_handle->jchannel = channel;
+       if (!payload.isEmpty() || binary_length > 0) {
+               payload_handle = new(std::nothrow) _conv_payload_handle();
+               IF_FAIL_VOID_TAG(payload_handle, _E, "Memory allocation failed");
 
-       conv_payload_h payload_handle = new(std::nothrow) _conv_payload_handle();
-       IF_FAIL_VOID_TAG(payload_handle, _E, "Memory allocation failed");
+               payload_handle->jpayload = payload;
+               payload_handle->binary_length = binary_length;
+               payload_handle->binary = binary;
+       }
 
-       payload_handle->jpayload = payload;
-       payload_handle->binary_length = binary_length;
-       payload_handle->binary = binary;
        conv_error_e conv_error = (conv_error_e)error;
-
        callback_info->cb(service_handle, channel_handle, conv_error, payload_handle, callback_info->user_data);
 
-       delete payload_handle;
-       delete channel_handle;
+       if (payload_handle) {
+               delete payload_handle;
+       }
+       if (channel_handle) {
+               delete channel_handle;
+       }
        delete service_handle;
 }
 
@@ -488,6 +497,7 @@ static int conv_service_unset_connected_cb(conv_service_h handle)
 
        json description;
        json service = handle->jservice;
+       json device = handle->jdevice;
 
        std::string service_type = convert_type_to_string(handle->service_type);
        if (service_type.empty())
@@ -495,6 +505,7 @@ static int conv_service_unset_connected_cb(conv_service_h handle)
 
        description.set(NULL, CONV_JSON_SERVICE, service);
        description.set(NULL, CONV_JSON_TYPE, service_type);
+       description.set(NULL, CONV_JSON_DEVICE, device);
        description.set(NULL, CONV_JSON_IS_LOCAL, handle->is_local);
 
        int req_id;
@@ -674,5 +685,44 @@ conv_service_e convert_string_to_type(std::string type_name)
        }
        return service_type;
 }
+
+EXTAPI int conv_service_is_started(conv_service_h handle, conv_channel_h channel_handle, bool* started)
+{
+       ASSERT_NOT_NULL(handle);
+       ASSERT_NOT_NULL(started);
+
+       IF_FAIL_RETURN_TAG(conv::util::is_feature_supported(), CONV_ERROR_NOT_SUPPORTED, _E, "Not supported");
+
+       *started = false;
+
+       int req_id;
+
+       json description;
+       json channel;
+       json payload;
+
+       if (channel_handle != NULL)
+               channel = channel_handle->jchannel;
+
+       json service = handle->jservice;
+       json device = handle->jdevice;
+       std::string type = convert_type_to_string(handle->service_type);
+       if (type.empty())
+               return CONV_ERROR_INVALID_PARAMETER;
+
+       description.set(NULL, CONV_JSON_SERVICE, service);
+       description.set(NULL, CONV_JSON_CHANNEL, channel);
+       description.set(NULL, CONV_JSON_DEVICE, device);
+       description.set(NULL, CONV_JSON_TYPE, type);
+       description.set(NULL, CONV_JSON_IS_LOCAL, handle->is_local);
+
+       int err = conv::dbus_client::request(REQ_WRITE, &req_id, CONV_SUBJECT_COMMUNICATION_CHECK_STATE, description.str().c_str(), 0, NULL);
+       IF_FAIL_RETURN_TAG(err == CONV_ERROR_NONE, err, _E, "Failed to get started status");
+
+       *started = true;
+
+       return CONV_ERROR_NONE;
+}
+
 //LCOV_EXCL_STOP
 
index 02556d5..a413967 100755 (executable)
@@ -65,7 +65,7 @@ static void handle_response(const gchar *sender, GVariant *param, GDBusMethodInv
        g_variant_get(param, "(i&si&si@a(y))", &req_id, &subject, &error, &data, &length, &binary_array);
        _D("[Response] ReqId: %d, Subject: %s, Error: %d", req_id, subject, error);
        const unsigned char *binary = (const unsigned char*)g_variant_get_data(binary_array);
-       _D("%s", binary);
+
        response_cb_map_t::iterator it = response_cb_map->find(subject);
        IF_FAIL_VOID_TAG(it!= response_cb_map->end(), _E, "Unknown subject'%s'", subject);
        it->second(subject, req_id,  error, data, length, binary);
index 7758179..4538560 100755 (executable)
@@ -270,6 +270,23 @@ int conv_payload_set_binary(conv_payload_h handle, int length, const unsigned ch
  */
 int conv_payload_get_binary(conv_payload_h handle, int* length, const unsigned char** value);
 
+/**
+ * @brief              Gets service start status.
+ * @since_tizen 3.0
+ *
+ * @param[in]  handle                          The service handle
+ * @param[in]  channel_handle          The channel handle
+ * @param[out] started                         The boolean value of service started check
+ *
+ * @return             0 on success, otherwise a negative error value
+ * @retval             #CONV_ERROR_NONE                                        Successful
+ * @retval             #CONV_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval             #CONV_ERROR_NOT_SUPPORTED               Not supported
+ * @retval             #CONV_ERROR_NO_DATA                             No Data
+ *
+ */
+int conv_service_is_started(conv_service_h handle, conv_channel_h channel_handle, bool* started);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 4f26512..4986fc7 100755 (executable)
@@ -66,7 +66,6 @@ class Service
 public:
        Service();
        Service(string, string, string, string, string);
-       static Result_Base *Resulturi;
        Result_Base *Resultdevice;
 
        position findServiceValue(string, char *);
@@ -83,11 +82,11 @@ public:
        static void getByURI(string, Result_Base*);
        static void getByURI(string, long, Result_Base *result);
        static void getById(string id, Result_Base *result);
-       static int curl_service_calling(string uri, long, void *);
+       static int curl_service_calling(string uri, long, void *, Result_Base *);
        //static Search *search();
        static size_t createdata(char *buf, size_t size, size_t nmemb, void *up);
-       static void createdata_process(string data,  void *);
-       static int json_parse_service(const char *in,  void *);
+       static void createdata_process(string data,  void *, Result_Base *);
+       static int json_parse_service(const char *in,  void *, Result_Base *);
        static Service create(ServiceInfo);
        static Service create(map<string, string>);
        Channel *createChannel(string uri);
index a233859..eafe6c9 100755 (executable)
@@ -1055,9 +1055,6 @@ int Channel::callback_lws_mirror(struct lws *wsi,
                this_ptr->handleWsiDestroy();
                break;
 
-       case LWS_CALLBACK_GET_THREAD_ID:
-        return pthread_self();
-
        case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED:
        case LWS_CALLBACK_ADD_POLL_FD:
        case LWS_CALLBACK_DEL_POLL_FD:
@@ -1073,6 +1070,7 @@ int Channel::callback_lws_mirror(struct lws *wsi,
        case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
        case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
        case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
+       case LWS_CALLBACK_GET_THREAD_ID:
                break;
 
        default:
@@ -1169,8 +1167,9 @@ void Channel::publishMessage(string event, const char *data, Json::Value to,
 void Channel::publishMessage(string method, string event, const char *data,
                                                        Json::Value to, const unsigned char payload[],
                                                        int payload_size, void *user_data) {
-       if (data)
+       if (data) {
                MSF_DBG("data len %d, payload len %d", strlen(data), payload_size);
+       }
 
        if (!isWebSocketOpen()) {
                handleError(string(), Error::create("Not Connected"));
@@ -1446,6 +1445,10 @@ void Channel::writeRequest()
        MSF_DBG("writeRequest start");
        if (wsi_mirror != NULL) {
                lws_callback_on_writable(wsi_mirror);
+               if (pthread_self() != socketThreadId) {
+                       MSF_DBG("current thread is different from websocket thread => lws_cancel_service()");
+                       lws_cancel_service(lws_get_context(wsi_mirror)); // to exit from poll() inside of lws_service()
+               }
        }
 }
 
index baa13ff..6f17c20 100755 (executable)
@@ -106,6 +106,9 @@ void MSFDSearchProvider::start()
        if (searching) {
                stop();
        }
+
+       aliveMap.clear();
+
        clearServices();
 
        createMSFD();
index ad830ec..fe0e5c8 100755 (executable)
@@ -115,6 +115,12 @@ Search::Search()
        searching_now = false;
        searchListener = NULL;
 
+       int i;
+
+       for (i=0; i < NUM_OF_THREADS; i++) {
+               threads[i] = 0;
+       }
+
        search_list.push_back(this);
 }
 
@@ -149,24 +155,11 @@ Service Search::getServiceById(string id)
 bool Search::start()
 {
        MSF_DBG("Search::start()");
-       if (searching_now == false) {
-               if (search_ref_count == 0) {
-                       search_ref_count++;
-
-                       searching_now = true;
 
+       search_ref_count++;
+       searching_now = true;
 
-                       startDiscovery();
-               } else {
-                       search_ref_count++;
-
-                       searching_now = true;
-
-                       if (searchListener != NULL) {
-                               searchListener->onStart();
-                       }
-               }
-       }
+       startDiscovery();
 
        return true;
 }
@@ -176,15 +169,9 @@ bool Search::stop()
        MSF_DBG("search stop");
        if (searching_now == true) {
                search_ref_count--;
-               searching_now = false;
 
-               if (search_ref_count == 0) {
-                       stopDiscovery();
-               } else {
-                       if (searchListener != NULL) {
-                               searchListener->onStop();
-                       }
-               }
+               stopDiscovery();
+               searching_now = false;
        }
 
        return true;
@@ -236,14 +223,18 @@ void Search::startDiscovery()
 
        provider_mdns.start();
 
-       ret = pthread_create(&threads[MSFD_THREAD_NUMBER], NULL, pt_startMSFD, NULL);
-       if (ret == -1) {
-               MSF_DBG("MSFD thread create failed");
+       if ( threads[MSFD_THREAD_NUMBER] == 0 ) {
+               ret = pthread_create(&threads[MSFD_THREAD_NUMBER], NULL, pt_startMSFD, NULL);
+               if (ret == -1) {
+                       MSF_DBG("MSFD thread create failed");
+               }
        }
 
-       ret = pthread_create(&threads[UPDATE_THREAD_NUMBER], NULL, pt_update_alivemap, NULL);
-       if (ret == -1) {
-               MSF_DBG("update thread create failed");
+       if ( threads[UPDATE_THREAD_NUMBER] == 0 ) {
+               ret = pthread_create(&threads[UPDATE_THREAD_NUMBER], NULL, pt_update_alivemap, NULL);
+               if (ret == -1) {
+                       MSF_DBG("update thread create failed");
+               }
        }
 
        onStart();
@@ -267,6 +258,9 @@ void Search::stopDiscovery()
        pthread_cancel(threads[UPDATE_THREAD_NUMBER]);
        pthread_join(threads[UPDATE_THREAD_NUMBER], NULL);
 
+       threads[MSFD_THREAD_NUMBER] = 0;
+       threads[UPDATE_THREAD_NUMBER] = 0;
+
        MSF_DBG("MSFD thread joined");
        MSF_DBG("update alivemap thread joined");
 }
index dfd3f3c..579abd0 100755 (executable)
@@ -30,8 +30,6 @@ string Service::NAME_PROPERTY       = "fn";
 string Service::TYPE_PROPERTY       = "md";
 string Service::ENDPOINT_PROPERTY   = "se";
 
-Result_Base *Service::Resulturi = NULL;
-
 Service Service::local_service;
 
 bool Service::success_get_id = false;
@@ -168,7 +166,7 @@ position Service::findServiceValue(string substrng, char *strng)
 
 void Service::getDeviceInfo(Result_Base *dev_result)
 {
-       curl_service_calling(uri, 5000, dev_result);
+       curl_service_calling(uri, 5000, dev_result, NULL);
 }
 
 string Service::getUniqueId(string address)
@@ -195,7 +193,9 @@ string Service::getUniqueId(string address)
        GetLocalServiceCallback r1Service;
        string remote_uri = "http://" + address + "/api/v2/";
        success_get_id = false;
+       MSF_DBG("calling getByUri");
        getByURI(remote_uri, 5000, &r1Service);
+       MSF_DBG("called getByUri");
 
        if (success_get_id) {
                MSF_DBG("remote_device_id[%s] for address[%s]", remote_device_id.c_str(), address.c_str());
@@ -248,14 +248,16 @@ void Service::getByURI(string uri, long timeout, Result_Base *result)
 {
        MSF_DBG("getByURI() uri = %s", uri.c_str());
 
-       Resulturi = result;
+       MSF_DBG("calling curl_service_calling");
        //Resultdevice = NULL;
-       curl_service_calling(uri, timeout, NULL);
-       Resulturi = NULL;
+       curl_service_calling(uri, timeout, NULL, result);
+       MSF_DBG("called curl_service_calling");
+       MSF_DBG("getByURI end");
 }
 
-int Service::curl_service_calling(string uri, long timeout, void *dev_result_ptr)
+int Service::curl_service_calling(string uri, long timeout, void *dev_result_ptr, Result_Base *result)
 {
+       MSF_DBG("curl_service_calling start");
        CURL *curl;
        CURLcode res;
        struct curl_slist *headers = NULL;
@@ -278,18 +280,19 @@ int Service::curl_service_calling(string uri, long timeout, void *dev_result_ptr
 
         if ((res != CURLE_OK) || (read_data == NULL)) {
             MSF_DBG("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
-            createdata_process("", dev_result_ptr);
+            createdata_process("", dev_result_ptr, result);
             if (read_data) {
                 free(read_data);
             }
         } else {
-            createdata_process(string(read_data), dev_result_ptr);
+               MSF_DBG("calling createdata_process");
+            createdata_process(string(read_data), dev_result_ptr, result);
             free(read_data);
         }
 
                curl_easy_cleanup(curl);
        }
-
+       MSF_DBG("curl_service_calling end");
        return 0;
 }
 
@@ -306,13 +309,13 @@ size_t Service::createdata(char *buf, size_t size, size_t nmemb, void *up)
     return size*nmemb;
 }
 
-void Service::createdata_process(string data, void *dev_result_ptr)
+void Service::createdata_process(string data, void *dev_result_ptr, Result_Base* result)
 {
        if (data.length() != 0) {
-               json_parse_service(data.c_str(), dev_result_ptr);
+               json_parse_service(data.c_str(), dev_result_ptr, result);
        } else {
-               if (Resulturi != NULL) {
-                       Resulturi->onError(Error::create("Timeout"));
+               if (result != NULL) {
+                       result->onError(Error::create("Timeout"));
                }
                if (dev_result_ptr != NULL) {
                        (static_cast<Result_Base*> (dev_result_ptr))->onError(Error::create("Not Found"));
@@ -320,8 +323,9 @@ void Service::createdata_process(string data, void *dev_result_ptr)
        }
 }
 
-int Service::json_parse_service(const char *in, void *ptr)
+int Service::json_parse_service(const char *in, void *ptr, Result_Base* result)
 {
+       MSF_DBG("json_parse_service start");
        JsonParser *parser = json_parser_new();
 
        if (json_parser_load_from_data(parser, in, -1, NULL)) {
@@ -367,10 +371,13 @@ int Service::json_parse_service(const char *in, void *ptr)
                retService.SecureConnectionSupport = true;
        }
 
-       if ((Resulturi!= NULL)) {
-               Resulturi->onSuccess(retService);
+       if ((result != NULL)) {
+               MSF_DBG("json_parse_service");
+               result->onSuccess(retService);
        }
 
+       MSF_DBG("json_parse_service end");
+
        return 0;
 }
 
index 7384522..0990295 100755 (executable)
@@ -241,6 +241,8 @@ void mDNSSearchProvider::start()
                g_service = 0;
        }
 
+       aliveMap.clear();
+
        int rv = dnssd_initialize();
        if (rv != DNSSD_ERROR_NONE) {
                MSF_DBG("mDNS is not initialzed.");