+ OCStackApplicationResult listenResListCallback(void* ctx, OCDoHandle /*handle*/,
+ OCClientResponse* clientResponse)
+ {
+ if (!ctx || !clientResponse)
+ {
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ ClientCallbackContext::ListenResListContext* context =
+ static_cast<ClientCallbackContext::ListenResListContext*>(ctx);
+
+ if (clientResponse->result != OC_STACK_OK)
+ {
+ oclog() << "listenResListCallback(): failed to create resource. clientResponse: "
+ << clientResponse->result
+ << std::flush;
+
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+ {
+ oclog() << "listenResListCallback(): clientResponse payload was null or the wrong type"
+ << std::flush;
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ auto clientWrapper = context->clientWrapper.lock();
+
+ if (!clientWrapper)
+ {
+ oclog() << "listenResListCallback(): failed to get a shared_ptr to the client wrapper"
+ << std::flush;
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ try
+ {
+ ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+ reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+
+ OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
+ std::thread exec(context->callback, container.Resources());
+ exec.detach();
+ }
+ catch (std::exception &e)
+ {
+ oclog() << "Exception in listenResListCallback(), ignoring response: "
+ << e.what() << std::flush;
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OCStackResult InProcClientWrapper::ListenForResourceList(
+ const std::string& serviceUrl,
+ const std::string& resourceType,
+ OCConnectivityType connectivityType,
+ FindResListCallback& callback, QualityOfService QoS)
+ {
+ if (!callback)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult result;
+ ostringstream resourceUri;
+ resourceUri << serviceUrl << resourceType;
+
+ ClientCallbackContext::ListenResListContext* context =
+ new ClientCallbackContext::ListenResListContext(callback, shared_from_this());
+ OCCallbackData cbdata;
+ cbdata.context = static_cast<void*>(context),
+ cbdata.cb = listenResListCallback;
+ cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListContext*)c;};
+
+ auto cLock = m_csdkLock.lock();
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = OCDoResource(nullptr, OC_REST_DISCOVER,
+ resourceUri.str().c_str(),
+ nullptr, nullptr, connectivityType,
+ static_cast<OCQualityOfService>(QoS),
+ &cbdata,
+ nullptr, 0);
+ }
+ else
+ {
+ delete context;
+ result = OC_STACK_ERROR;
+ }
+ return result;
+ }
+
+ OCStackApplicationResult listenResListWithErrorCallback(void* ctx, OCDoHandle /*handle*/,
+ OCClientResponse* clientResponse)
+ {
+ if (!ctx || !clientResponse)
+ {
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ ClientCallbackContext::ListenResListWithErrorContext* context =
+ static_cast<ClientCallbackContext::ListenResListWithErrorContext*>(ctx);
+
+ OCStackResult result = clientResponse->result;
+ if (result != OC_STACK_OK)
+ {
+ oclog() << "listenResListWithErrorCallback(): failed to create resource. clientResponse: "
+ << result << std::flush;
+
+ //send the error callback
+ std::string uri;
+ if(NULL != clientResponse->resourceUri)
+ {
+ uri = clientResponse->resourceUri;
+ }
+ std::thread exec(context->errorCallback, uri, result);
+ exec.detach();
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+ {
+ oclog() << "listenResListWithErrorCallback(): clientResponse payload was null or the wrong type"
+ << std::flush;
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ auto clientWrapper = context->clientWrapper.lock();
+
+ if (!clientWrapper)
+ {
+ oclog() << "listenResListWithErrorCallback(): failed to get a shared_ptr to the client wrapper"
+ << std::flush;
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ try
+ {
+ ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+ reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+
+ OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
+ std::thread exec(context->callback, container.Resources());
+ exec.detach();
+ }
+ catch (std::exception &e)
+ {
+ oclog() << "Exception in listenResListWithErrorCallback(), ignoring response: "
+ << e.what() << std::flush;
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OCStackResult InProcClientWrapper::ListenForResourceListWithError(
+ const std::string& serviceUrl,
+ const std::string& resourceType,
+ OCConnectivityType connectivityType,
+ FindResListCallback& callback,
+ FindErrorCallback& errorCallback, QualityOfService QoS)
+ {
+ if (!callback)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult result;
+ ostringstream resourceUri;
+ resourceUri << serviceUrl << resourceType;
+
+ ClientCallbackContext::ListenResListWithErrorContext* context =
+ new ClientCallbackContext::ListenResListWithErrorContext(callback, errorCallback,
+ shared_from_this());
+ if (!context)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ OCCallbackData cbdata;
+ cbdata.context = static_cast<void*>(context),
+ cbdata.cb = listenResListWithErrorCallback;
+ cbdata.cd = [](void* c){delete (ClientCallbackContext::ListenResListWithErrorContext*)c;};
+
+ auto cLock = m_csdkLock.lock();
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = OCDoResource(nullptr, OC_REST_DISCOVER,
+ resourceUri.str().c_str(),
+ nullptr, nullptr, connectivityType,
+ static_cast<OCQualityOfService>(QoS),
+ &cbdata,
+ nullptr, 0);
+ }
+ else
+ {
+ delete context;
+ result = OC_STACK_ERROR;
+ }
+ return result;
+ }
+
+#ifdef WITH_MQ
+ OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/,
+ OCClientResponse* clientResponse)
+ {
+ ClientCallbackContext::MQTopicContext* context =
+ static_cast<ClientCallbackContext::MQTopicContext*>(ctx);
+
+ if (!clientResponse || !context)
+ {
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ std::string resourceURI;
+ if(NULL != clientResponse->resourceUri)
+ {
+ resourceURI = clientResponse->resourceUri;
+ }
+
+ if (clientResponse->result != OC_STACK_OK)
+ {
+ oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
+ << clientResponse->result
+ << std::flush;
+
+ std::thread exec(context->callback, clientResponse->result,
+ resourceURI, nullptr);
+ exec.detach();
+
+ return OC_STACK_DELETE_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_DELETE_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, clientResponse->result,
+ resourceURI, resource);
+ exec.detach();
+ }
+ }
+ catch (std::exception &e)
+ {
+ oclog() << "Exception in listCallback, ignoring response: "
+ << e.what() << std::flush;
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ OCStackResult InProcClientWrapper::ListenForMQTopic(const OCDevAddr& devAddr,
+ const std::string& resourceUri,
+ const QueryParamsMap& queryParams,
+ const HeaderOptions& headerOptions,
+ MQTopicCallback& callback,
+ QualityOfService QoS)
+ {
+ oclog() << "ListenForMQTopic()" << std::flush;
+
+ if (!callback)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ ClientCallbackContext::MQTopicContext* context =
+ new ClientCallbackContext::MQTopicContext(callback, shared_from_this());
+ OCCallbackData cbdata;
+ cbdata.context = static_cast<void*>(context),
+ cbdata.cb = listenMQCallback;
+ cbdata.cd = [](void* c){delete (ClientCallbackContext::MQTopicContext*)c;};
+
+ std::string uri = assembleSetResourceUri(resourceUri, queryParams);
+
+ OCStackResult result = OC_STACK_ERROR;
+ auto cLock = m_csdkLock.lock();
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+ result = OCDoResource(
+ nullptr, OC_REST_GET,
+ uri.c_str(),
+ &devAddr, nullptr,
+ CT_DEFAULT,
+ static_cast<OCQualityOfService>(QoS),
+ &cbdata,
+ assembleHeaderOptions(options, headerOptions),
+ headerOptions.size());
+ }
+ else
+ {
+ delete context;
+ }
+
+ return result;
+ }
+#endif
+
+ OCStackApplicationResult listenDeviceCallback(void* ctx,
+ OCDoHandle /*handle*/,