X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fsrc%2FInProcClientWrapper.cpp;h=8a892c6d8c68c252dc26f8337198bad8b6ebf71f;hb=9b75b21e041df26d6026e00f37a270f48d1d8e65;hp=f4b48fd47526fe3d04abd612944b5e11a1a8d02e;hpb=632666ef557d61eee5ef438a2af51d760cace39f;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/src/InProcClientWrapper.cpp b/resource/src/InProcClientWrapper.cpp index f4b48fd..8a892c6 100644 --- a/resource/src/InProcClientWrapper.cpp +++ b/resource/src/InProcClientWrapper.cpp @@ -37,7 +37,7 @@ namespace OC // if the config type is server, we ought to never get called. If the config type // is both, we count on the server to run the thread and do the initialize - if(m_cfg.mode == ModeType::Client) + if (m_cfg.mode == ModeType::Client) { OCTransportFlags serverFlags = static_cast(m_cfg.serverConnectivity & CT_MASK_FLAGS); @@ -45,7 +45,7 @@ namespace OC static_cast(m_cfg.clientConnectivity & CT_MASK_FLAGS); OCStackResult result = OCInit1(OC_CLIENT, serverFlags, clientFlags); - if(OC_STACK_OK != result) + if (OC_STACK_OK != result) { throw InitializeException(OC::InitException::STACK_INIT_ERROR, result); } @@ -57,7 +57,7 @@ namespace OC InProcClientWrapper::~InProcClientWrapper() { - if(m_threadRun && m_listeningThread.joinable()) + if (m_threadRun && m_listeningThread.joinable()) { m_threadRun = false; m_listeningThread.join(); @@ -65,7 +65,7 @@ namespace OC // only stop if we are the ones who actually called 'init'. We are counting // on the server to do the stop. - if(m_cfg.mode == ModeType::Client) + if (m_cfg.mode == ModeType::Client) { OCStop(); } @@ -77,7 +77,7 @@ namespace OC { OCStackResult result; auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); result = OCProcess(); @@ -87,7 +87,7 @@ namespace OC result = OC_STACK_ERROR; } - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { // TODO: do something with result if failed? } @@ -99,7 +99,7 @@ namespace OC OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse) { - if(clientResponse->payload == nullptr || + if (clientResponse->payload == nullptr || ( clientResponse->payload->type != PAYLOAD_TYPE_DEVICE && clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM && @@ -116,13 +116,15 @@ namespace OC //OCPayloadDestroy(clientResponse->payload); std::vector::const_iterator it = oc.representations().begin(); - if(it == oc.representations().end()) + if (it == oc.representations().end()) { return OCRepresentation(); } // first one is considered the root, everything else is considered a child of this one. OCRepresentation root = *it; + root.setDevAddr(clientResponse->devAddr); + root.setUri(clientResponse->resourceUri); ++it; std::for_each(it, oc.representations().end(), @@ -132,13 +134,13 @@ namespace OC } - OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult listenCallback(void* ctx, OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::ListenContext* context = static_cast(ctx); - if(clientResponse->result != OC_STACK_OK) + if (clientResponse->result != OC_STACK_OK) { oclog() << "listenCallback(): failed to create resource. clientResponse: " << clientResponse->result @@ -147,7 +149,7 @@ namespace OC return OC_STACK_KEEP_TRANSACTION; } - if(!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY) + if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY) { oclog() << "listenCallback(): clientResponse payload was null or the wrong type" << std::flush; @@ -156,53 +158,161 @@ namespace OC auto clientWrapper = context->clientWrapper.lock(); - if(!clientWrapper) + if (!clientWrapper) { oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper" << std::flush; return OC_STACK_KEEP_TRANSACTION; } - ListenOCContainer container(clientWrapper, clientResponse->devAddr, - reinterpret_cast(clientResponse->payload)); - // loop to ensure valid construction of all resources - for(auto resource : container.Resources()) - { - std::thread exec(context->callback, resource); - exec.detach(); + try{ + ListenOCContainer container(clientWrapper, clientResponse->devAddr, + reinterpret_cast(clientResponse->payload)); + // loop to ensure valid construction of all resources + + for(auto resource : container.Resources()) + { + std::thread exec(context->callback, resource); + exec.detach(); + } + } + catch (std::exception &e){ + oclog() << "Exception in listCallback, ignoring response: " + << e.what() << std::flush; } return OC_STACK_KEEP_TRANSACTION; } + OCStackApplicationResult listenErrorCallback(void* ctx, OCDoHandle /*handle*/, + OCClientResponse* clientResponse) + { + if (!ctx || !clientResponse) + { + return OC_STACK_KEEP_TRANSACTION; + } + + ClientCallbackContext::ListenErrorContext* context = + static_cast(ctx); + if (!context) + { + return OC_STACK_KEEP_TRANSACTION; + } + + OCStackResult result = clientResponse->result; + if (result == OC_STACK_OK) + { + if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY) + { + oclog() << "listenCallback(): clientResponse payload was null or the wrong type" + << std::flush; + return OC_STACK_KEEP_TRANSACTION; + } + + auto clientWrapper = context->clientWrapper.lock(); + + if (!clientWrapper) + { + oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper" + << std::flush; + return OC_STACK_KEEP_TRANSACTION; + } + + ListenOCContainer container(clientWrapper, clientResponse->devAddr, + reinterpret_cast(clientResponse->payload)); + // loop to ensure valid construction of all resources + for (auto resource : container.Resources()) + { + std::thread exec(context->callback, resource); + exec.detach(); + } + return OC_STACK_KEEP_TRANSACTION; + } + + std::string resourceURI = clientResponse->resourceUri; + std::thread exec(context->errorCallback, resourceURI, result); + exec.detach(); + return OC_STACK_DELETE_TRANSACTION; + } + OCStackResult InProcClientWrapper::ListenForResource( - const std::string& serviceUrl, // unused + const std::string& serviceUrl, const std::string& resourceType, OCConnectivityType connectivityType, FindCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; + ostringstream resourceUri; + resourceUri << serviceUrl << resourceType; ClientCallbackContext::ListenContext* context = new ClientCallbackContext::ListenContext(callback, shared_from_this()); + OCCallbackData cbdata; + cbdata.context = static_cast(context), + cbdata.cb = listenCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;}; + + auto cLock = m_csdkLock.lock(); + if (cLock) + { + std::lock_guard lock(*cLock); + result = OCDoResource(nullptr, OC_REST_DISCOVER, + resourceUri.str().c_str(), + nullptr, nullptr, connectivityType, + static_cast(QoS), + &cbdata, + nullptr, 0); + } + else + { + delete context; + result = OC_STACK_ERROR; + } + return result; + } + + OCStackResult InProcClientWrapper::ListenErrorForResource( + const std::string& serviceUrl, + const std::string& resourceType, + OCConnectivityType connectivityType, + FindCallback& callback, FindErrorCallback& errorCallback, + QualityOfService QoS) + { + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + + ostringstream resourceUri; + resourceUri << serviceUrl << resourceType; + + ClientCallbackContext::ListenErrorContext* context = + new ClientCallbackContext::ListenErrorContext(callback, errorCallback, + shared_from_this()); + if (!context) + { + return OC_STACK_ERROR; + } + OCCallbackData cbdata( static_cast(context), - listenCallback, - [](void* c){delete static_cast(c);} + listenErrorCallback, + [](void* c){delete static_cast(c);} ); + OCStackResult result; auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); result = OCDoResource(nullptr, OC_REST_DISCOVER, - resourceType.c_str(), + resourceUri.str().c_str(), nullptr, nullptr, connectivityType, static_cast(QoS), &cbdata, @@ -215,8 +325,104 @@ namespace OC } return result; } +#ifdef WITH_MQ + OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/, + OCClientResponse* clientResponse) + { + ClientCallbackContext::ListenContext* context = + static_cast(ctx); + + if (!clientResponse) + { + return OC_STACK_KEEP_TRANSACTION; + } + + if (clientResponse->result != OC_STACK_OK) + { + oclog() << "listenMQCallback(): failed to create resource. clientResponse: " + << clientResponse->result + << std::flush; + + return OC_STACK_KEEP_TRANSACTION; + } + + auto clientWrapper = context->clientWrapper.lock(); + if (!clientWrapper) + { + oclog() << "listenMQCallback(): failed to get a shared_ptr to the client wrapper" + << std::flush; + return OC_STACK_KEEP_TRANSACTION; + } + + try{ + ListenOCContainer container(clientWrapper, clientResponse->devAddr, + (OCRepPayload *) clientResponse->payload); + + // loop to ensure valid construction of all resources + for (auto resource : container.Resources()) + { + std::thread exec(context->callback, resource); + exec.detach(); + } + } + catch (std::exception &e){ + oclog() << "Exception in listCallback, ignoring response: " + << e.what() << std::flush; + } + + + return OC_STACK_KEEP_TRANSACTION; + } + + OCStackResult InProcClientWrapper::ListenForMQTopic( + const OCDevAddr& devAddr, + const std::string& resourceUri, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + FindCallback& callback, QualityOfService QoS) + { + oclog() << "ListenForMQTopic()" << std::flush; + + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + + ClientCallbackContext::ListenContext* context = + new ClientCallbackContext::ListenContext(callback, shared_from_this()); + OCCallbackData cbdata; + cbdata.context = static_cast(context), + cbdata.cb = listenMQCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenContext*)c;}; + + std::string uri = assembleSetResourceUri(resourceUri, queryParams); + + OCStackResult result = OC_STACK_ERROR; + auto cLock = m_csdkLock.lock(); + if (cLock) + { + std::lock_guard lock(*cLock); + OCHeaderOption options[MAX_HEADER_OPTIONS]; + result = OCDoResource( + nullptr, OC_REST_GET, + uri.c_str(), + &devAddr, nullptr, + CT_DEFAULT, + static_cast(QoS), + &cbdata, + assembleHeaderOptions(options, headerOptions), + headerOptions.size()); + } + else + { + delete context; + } + + return result; + } +#endif - OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult listenDeviceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::DeviceListenContext* context = @@ -238,32 +444,34 @@ namespace OC } OCStackResult InProcClientWrapper::ListenForDevice( - const std::string& serviceUrl, // unused + const std::string& serviceUrl, const std::string& deviceURI, OCConnectivityType connectivityType, FindDeviceCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; + ostringstream deviceUri; + deviceUri << serviceUrl << deviceURI; ClientCallbackContext::DeviceListenContext* context = new ClientCallbackContext::DeviceListenContext(callback, shared_from_this()); - OCCallbackData cbdata( - static_cast(context), - listenDeviceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + + cbdata.context = static_cast(context), + cbdata.cb = listenDeviceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::DeviceListenContext*)c;}; auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); result = OCDoResource(nullptr, OC_REST_DISCOVER, - deviceURI.c_str(), + deviceUri.str().c_str(), nullptr, nullptr, connectivityType, static_cast(QoS), &cbdata, @@ -280,7 +488,7 @@ namespace OC void parseServerHeaderOptions(OCClientResponse* clientResponse, HeaderOptions& serverHeaderOptions) { - if(clientResponse) + if (clientResponse) { // Parse header options from server uint16_t optionID; @@ -303,7 +511,137 @@ namespace OC } } - OCStackApplicationResult getResourceCallback(void* ctx, OCDoHandle handle, +#ifdef WITH_MQ + OCStackApplicationResult createMQTopicCallback(void* ctx, OCDoHandle /*handle*/, + OCClientResponse* clientResponse) + { + ClientCallbackContext::CreateMQTopicContext* context = + static_cast(ctx); + OCRepresentation rep; + HeaderOptions serverHeaderOptions; + + if (!clientResponse) + { + return OC_STACK_DELETE_TRANSACTION; + } + + std::string createdUri; + OCStackResult result = clientResponse->result; + if (OC_STACK_OK == result || + OC_STACK_RESOURCE_CREATED == result) + { + parseServerHeaderOptions(clientResponse, serverHeaderOptions); + try + { + rep = parseGetSetCallback(clientResponse); + } + catch(OC::OCException& e) + { + result = e.code(); + } + + bool isLocationOption = false; + for (auto headerOption : serverHeaderOptions) + { + if (HeaderOption::LOCATION_PATH_OPTION_ID == headerOption.getOptionID()) + { + createdUri += "/"; + createdUri += headerOption.getOptionData(); + if (!isLocationOption) + { + isLocationOption = true; + } + } + } + + if (!isLocationOption) + { + createdUri = clientResponse->resourceUri; + } + } + + auto clientWrapper = context->clientWrapper.lock(); + + if (!clientWrapper) + { + oclog() << "createMQTopicCallback(): failed to get a shared_ptr to the client wrapper" + << std::flush; + return OC_STACK_DELETE_TRANSACTION; + } + + try{ + if (OC_STACK_OK == result || + OC_STACK_RESOURCE_CREATED == result) + { + ListenOCContainer container(clientWrapper, clientResponse->devAddr, + createdUri); + for (auto resource : container.Resources()) + { + std::thread exec(context->callback, serverHeaderOptions, rep, result, resource); + exec.detach(); + } + } + else + { + std::thread exec(context->callback, serverHeaderOptions, rep, result, nullptr); + exec.detach(); + } + } + catch (std::exception &e){ + oclog() << "Exception in createMQTopicCallback, ignoring response: " + << e.what() << std::flush; + } + return OC_STACK_DELETE_TRANSACTION; + } + + OCStackResult InProcClientWrapper::PutMQTopicRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& rep, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + MQCreateTopicCallback& callback, QualityOfService QoS) + { + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + OCStackResult result; + ClientCallbackContext::CreateMQTopicContext* ctx = + new ClientCallbackContext::CreateMQTopicContext(callback, shared_from_this()); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = createMQTopicCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::CreateMQTopicContext*)c;}; + + std::string url = assembleSetResourceUri(uri, queryParams); + + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + OCHeaderOption options[MAX_HEADER_OPTIONS]; + + result = OCDoResource(nullptr, OC_REST_PUT, + url.c_str(), &devAddr, + assembleSetResourcePayload(rep), + CT_DEFAULT, + static_cast(QoS), + &cbdata, + assembleHeaderOptions(options, headerOptions), + headerOptions.size()); + } + else + { + delete ctx; + result = OC_STACK_ERROR; + } + + return result; + } +#endif + OCStackApplicationResult getResourceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::GetContext* context = @@ -312,7 +650,7 @@ namespace OC OCRepresentation rep; HeaderOptions serverHeaderOptions; OCStackResult result = clientResponse->result; - if(result == OC_STACK_OK) + if (result == OC_STACK_OK) { parseServerHeaderOptions(clientResponse, serverHeaderOptions); try @@ -336,24 +674,24 @@ namespace OC const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, GetCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; ClientCallbackContext::GetContext* ctx = new ClientCallbackContext::GetContext(callback); - OCCallbackData cbdata( - static_cast(ctx), - getResourceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = getResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::GetContext*)c;}; + std::string uri = assembleSetResourceUri(resourceUri, queryParams); auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); OCHeaderOption options[MAX_HEADER_OPTIONS]; @@ -377,7 +715,8 @@ namespace OC } - OCStackApplicationResult setResourceCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult setResourceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::SetContext* context = @@ -388,7 +727,8 @@ namespace OC OCStackResult result = clientResponse->result; if (OC_STACK_OK == result || OC_STACK_RESOURCE_CREATED == result || - OC_STACK_RESOURCE_DELETED == result) + OC_STACK_RESOURCE_DELETED == result || + OC_STACK_RESOURCE_CHANGED == result) { parseServerHeaderOptions(clientResponse, serverHeaderOptions); try @@ -409,24 +749,79 @@ namespace OC std::string InProcClientWrapper::assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams) { - if(uri.back() == '/') + if (!uri.empty()) { - uri.resize(uri.size()-1); + if (uri.back() == '/') + { + uri.resize(uri.size() - 1); + } } ostringstream paramsList; - if(queryParams.size() > 0) + if (queryParams.size() > 0) { paramsList << '?'; } - for(auto& param : queryParams) + for (auto& param : queryParams) { paramsList << param.first <<'='< 0) + { + paramsList << '?'; + } + + for (auto& param : queryParams) + { + for (auto& paramList : param.second) + { + paramsList << param.first << '=' << paramList; + if (paramList != param.second.back()) + { + paramsList << '&'; + } + } + paramsList << ';'; + } + + std::string queryString = paramsList.str(); + + if (queryString.empty()) + { + return uri; + } + + if (queryString.back() == ';') { queryString.resize(queryString.size() - 1); } @@ -439,6 +834,11 @@ namespace OC { MessageContainer ocInfo; ocInfo.addRepresentation(rep); + for(const OCRepresentation& r : rep.getChildren()) + { + ocInfo.addRepresentation(r); + } + return reinterpret_cast(ocInfo.getPayload()); } @@ -447,25 +847,26 @@ namespace OC const std::string& uri, const OCRepresentation& rep, const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, PostCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback); - OCCallbackData cbdata( - static_cast(ctx), - setResourceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = setResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;}; + std::string url = assembleSetResourceUri(uri, queryParams); auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); OCHeaderOption options[MAX_HEADER_OPTIONS]; @@ -473,7 +874,7 @@ namespace OC result = OCDoResource(nullptr, OC_REST_POST, url.c_str(), &devAddr, assembleSetResourcePayload(rep), - CT_DEFAULT, + connectivityType, static_cast(QoS), &cbdata, assembleHeaderOptions(options, headerOptions), @@ -495,23 +896,23 @@ namespace OC const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, PutCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; ClientCallbackContext::SetContext* ctx = new ClientCallbackContext::SetContext(callback); - OCCallbackData cbdata( - static_cast(ctx), - setResourceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = setResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::SetContext*)c;}; + std::string url = assembleSetResourceUri(uri, queryParams).c_str(); auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); OCDoHandle handle; @@ -535,14 +936,15 @@ namespace OC return result; } - OCStackApplicationResult deleteResourceCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult deleteResourceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::DeleteContext* context = static_cast(ctx); HeaderOptions serverHeaderOptions; - if(clientResponse->result == OC_STACK_OK) + if (clientResponse->result == OC_STACK_OK) { parseServerHeaderOptions(clientResponse, serverHeaderOptions); } @@ -554,24 +956,26 @@ namespace OC OCStackResult InProcClientWrapper::DeleteResource( const OCDevAddr& devAddr, const std::string& uri, - const HeaderOptions& headerOptions, DeleteCallback& callback, QualityOfService QoS) + const HeaderOptions& headerOptions, + DeleteCallback& callback, + QualityOfService /*QoS*/) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } OCStackResult result; ClientCallbackContext::DeleteContext* ctx = new ClientCallbackContext::DeleteContext(callback); - OCCallbackData cbdata( - static_cast(ctx), - deleteResourceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = deleteResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::DeleteContext*)c;}; + auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { OCHeaderOption options[MAX_HEADER_OPTIONS]; @@ -595,7 +999,8 @@ namespace OC return result; } - OCStackApplicationResult observeResourceCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult observeResourceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::ObserveContext* context = @@ -604,7 +1009,7 @@ namespace OC HeaderOptions serverHeaderOptions; uint32_t sequenceNumber = clientResponse->sequenceNumber; OCStackResult result = clientResponse->result; - if(clientResponse->result == OC_STACK_OK) + if (clientResponse->result == OC_STACK_OK) { parseServerHeaderOptions(clientResponse, serverHeaderOptions); try @@ -619,7 +1024,7 @@ namespace OC std::thread exec(context->callback, serverHeaderOptions, attrs, result, sequenceNumber); exec.detach(); - if(sequenceNumber == OC_OBSERVE_DEREGISTER) + if (sequenceNumber == OC_OBSERVE_DEREGISTER) { return OC_STACK_DELETE_TRANSACTION; } @@ -632,7 +1037,7 @@ namespace OC const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, ObserveCallback& callback, QualityOfService QoS) { - if(!callback) + if (!callback) { return OC_STACK_INVALID_PARAM; } @@ -640,11 +1045,11 @@ namespace OC ClientCallbackContext::ObserveContext* ctx = new ClientCallbackContext::ObserveContext(callback); - OCCallbackData cbdata( - static_cast(ctx), - observeResourceCallback, - [](void* c){delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = observeResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;}; + OCMethod method; if (observeType == ObserveType::Observe) @@ -664,7 +1069,7 @@ namespace OC auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); OCHeaderOption options[MAX_HEADER_OPTIONS]; @@ -689,15 +1094,15 @@ namespace OC OCStackResult InProcClientWrapper::CancelObserveResource( OCDoHandle handle, - const std::string& host, // unused - const std::string& uri, // unused + const std::string& /*host*/, + const std::string& /*uri*/, const HeaderOptions& headerOptions, QualityOfService QoS) { OCStackResult result; auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); OCHeaderOption options[MAX_HEADER_OPTIONS]; @@ -715,7 +1120,8 @@ namespace OC return result; } - OCStackApplicationResult subscribePresenceCallback(void* ctx, OCDoHandle handle, + OCStackApplicationResult subscribePresenceCallback(void* ctx, + OCDoHandle /*handle*/, OCClientResponse* clientResponse) { ClientCallbackContext::SubscribePresenceContext* context = @@ -738,31 +1144,30 @@ namespace OC const std::string& host, const std::string& resourceType, OCConnectivityType connectivityType, SubscribeCallback& presenceHandler) { - if(!presenceHandler) + if (!presenceHandler) { return OC_STACK_INVALID_PARAM; } ClientCallbackContext::SubscribePresenceContext* ctx = new ClientCallbackContext::SubscribePresenceContext(presenceHandler); - OCCallbackData cbdata( - static_cast(ctx), - subscribePresenceCallback, - [](void* c) - {delete static_cast(c);} - ); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = subscribePresenceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::SubscribePresenceContext*)c;}; + auto cLock = m_csdkLock.lock(); std::ostringstream os; - os << host << OC_PRESENCE_URI;; + os << host << OC_RSRVD_PRESENCE_URI; - if(!resourceType.empty()) + if (!resourceType.empty()) { os << "?rt=" << resourceType; } - if(!cLock) + if (!cLock) { delete ctx; return OC_STACK_ERROR; @@ -779,7 +1184,7 @@ namespace OC OCStackResult result; auto cLock = m_csdkLock.lock(); - if(cLock) + if (cLock) { std::lock_guard lock(*cLock); result = OCCancel(handle, OC_LOW_QOS, NULL, 0); @@ -792,6 +1197,50 @@ namespace OC return result; } + OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const QueryParamsList& queryParams, + OCConnectivityType connectivityType, + ObserveCallback& callback) + { + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + OCStackResult result; + + ClientCallbackContext::ObserveContext* ctx = + new ClientCallbackContext::ObserveContext(callback); + OCCallbackData cbdata; + cbdata.context = static_cast(ctx), + cbdata.cb = observeResourceCallback; + cbdata.cd = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;}; + + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + + std::ostringstream os; + os << host << OCF_RSRVD_DEVICE_PRESENCE_URI; + std::string url = assembleSetResourceUri(os.str(), queryParams); + + result = OCDoResource(handle, OC_REST_OBSERVE, + url.c_str(), nullptr, + nullptr, connectivityType, + OC_LOW_QOS, &cbdata, + nullptr, 0); + } + else + { + delete ctx; + result = OC_STACK_ERROR; + } + + return result; + } + OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos) { qos = m_cfg.QoS; @@ -803,20 +1252,161 @@ namespace OC { int i = 0; - if( headerOptions.size() == 0) + if ( headerOptions.size() == 0) { return nullptr; } for (auto it=headerOptions.begin(); it != headerOptions.end(); ++it) { - options[i] = OCHeaderOption(OC_COAP_ID, - it->getOptionID(), - it->getOptionData().length() + 1, - reinterpret_cast(it->getOptionData().c_str())); + options[i] = OCHeaderOption(); + options[i].protocolID = OC_COAP_ID; + options[i].optionID = it->getOptionID(); + options[i].optionLength = it->getOptionData().length() + 1; + strcpy((char*)options[i].optionData, (it->getOptionData().c_str())); i++; } return options; } + + std::shared_ptr cloneDevice(const OCDPDev_t* dev) + { + if (!dev) + { + return nullptr; + } + + OCDPDev_t* result = new OCDPDev_t(*dev); + result->prm = new OCPrm_t[dev->prmLen]; + memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen); + return std::shared_ptr(new OCDirectPairing(result)); + } + + void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList) + { + while(list) + { + dpList.push_back(cloneDevice(list)); + list = list->next; + } + } + + OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime, + GetDirectPairedCallback& callback) + { + if (!callback || 0 == waittime) + { + return OC_STACK_INVALID_PARAM; + } + + OCStackResult result = OC_STACK_ERROR; + const OCDPDev_t *list = nullptr; + PairedDevices dpDeviceList; + + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + + list = OCDiscoverDirectPairingDevices(waittime); + if (NULL == list) + { + result = OC_STACK_NO_RESOURCE; + oclog() << "findDirectPairingDevices(): No device found for direct pairing" + << std::flush; + } + else { + convert(list, dpDeviceList); + std::thread exec(callback, dpDeviceList); + exec.detach(); + result = OC_STACK_OK; + } + } + else + { + result = OC_STACK_ERROR; + } + + return result; + } + + OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback) + { + if (!callback) + { + return OC_STACK_INVALID_PARAM; + } + + OCStackResult result = OC_STACK_ERROR; + const OCDPDev_t *list = nullptr; + PairedDevices dpDeviceList; + + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + + list = OCGetDirectPairedDevices(); + if (NULL == list) + { + result = OC_STACK_NO_RESOURCE; + oclog() << "findDirectPairingDevices(): No device found for direct pairing" + << std::flush; + } + else { + convert(list, dpDeviceList); + std::thread exec(callback, dpDeviceList); + exec.detach(); + result = OC_STACK_OK; + } + } + else + { + result = OC_STACK_ERROR; + } + + return result; + } + + void directPairingCallback(void *ctx, OCDPDev_t *peer, + OCStackResult result) + { + + ClientCallbackContext::DirectPairingContext* context = + static_cast(ctx); + + std::thread exec(context->callback, cloneDevice(peer), result); + exec.detach(); + } + + OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr peer, + const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback) + { + if (!peer || !callback) + { + oclog() << "Invalid parameters" << std::flush; + return OC_STACK_INVALID_PARAM; + } + + OCStackResult result = OC_STACK_ERROR; + ClientCallbackContext::DirectPairingContext* context = + new ClientCallbackContext::DirectPairingContext(callback); + + auto cLock = m_csdkLock.lock(); + if (cLock) + { + std::lock_guard lock(*cLock); + result = OCDoDirectPairing(static_cast(context), peer->getDev(), + pmSel, const_cast(pinNumber.c_str()), directPairingCallback); + } + else + { + delete context; + result = OC_STACK_ERROR; + } + return result; + } }