1 //******************************************************************
\r
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
\r
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
7 // Licensed under the Apache License, Version 2.0 (the "License");
\r
8 // you may not use this file except in compliance with the License.
\r
9 // You may obtain a copy of the License at
\r
11 // http://www.apache.org/licenses/LICENSE-2.0
\r
13 // Unless required by applicable law or agreed to in writing, software
\r
14 // distributed under the License is distributed on an "AS IS" BASIS,
\r
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 // See the License for the specific language governing permissions and
\r
17 // limitations under the License.
\r
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
26 #include "ocpayload.h"
\r
27 #include "provisioninghandler.h"
\r
29 // External includes
\r
31 #include "camutex.h"
\r
32 #include "cathreadpool.h"
\r
34 #include "oic_malloc.h"
\r
38 * @var g_provisioningMutex
\r
39 * @brief Mutex to synchronize access to g_caDtlsContext.
\r
41 static ca_mutex g_provisioningMutex = NULL;
\r
42 static ca_cond g_provisioningCond = NULL;
\r
43 bool g_provisioningCondFlag = false;
\r
45 static EnrolleeNWProvInfo_t* netProvInfo;
\r
49 * @brief Callback for providing provisioning status callback to application
\r
51 static OCProvisioningStatusCB cbData = NULL;
\r
52 static ca_thread_pool_t g_threadPoolHandle = NULL;
\r
54 OCStackResult InitProvisioningHandler() {
\r
55 OCStackResult ret = OC_STACK_ERROR;
\r
56 /* Initialize OCStack*/
\r
57 if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
\r
58 OIC_LOG(ERROR, TAG, "OCStack init error");
\r
62 g_provisioningMutex = ca_mutex_new();
\r
64 OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
\r
66 if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
\r
67 OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
\r
68 return OC_STACK_ERROR;
\r
71 g_provisioningCond = ca_cond_new();
\r
72 if (NULL == g_provisioningCond) {
\r
73 OIC_LOG(DEBUG, TAG, "Failed to create condition");
\r
74 ca_mutex_free(g_provisioningMutex);
\r
75 ca_thread_pool_free(g_threadPoolHandle);
\r
76 return OC_STACK_ERROR;
\r
79 char *string = "listeningFunc invoked in a thread";
\r
81 != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
\r
83 OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
\r
84 ca_thread_pool_free(g_threadPoolHandle);
\r
85 ca_mutex_unlock(g_provisioningMutex);
\r
86 ca_mutex_free(g_provisioningMutex);
\r
87 ca_cond_free(g_provisioningCond);
\r
88 return OC_STACK_ERROR;
\r
93 OCStackResult TerminateProvisioningHandler() {
\r
94 OCStackResult ret = OC_STACK_ERROR;
\r
95 if (OCStop() != OC_STACK_OK) {
\r
96 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
99 ca_mutex_lock(g_provisioningMutex);
\r
100 g_provisioningCondFlag = true;
\r
101 //ca_cond_signal(g_provisioningCond);
\r
102 ca_mutex_unlock(g_provisioningMutex);
\r
104 ca_mutex_free(g_provisioningMutex);
\r
105 g_provisioningMutex = NULL;
\r
107 ca_thread_pool_free(g_threadPoolHandle);
\r
108 g_threadPoolHandle = NULL;
\r
114 void listeningFunc(void *data) {
\r
115 while (!g_provisioningCondFlag) {
\r
116 OCStackResult result;
\r
118 ca_mutex_lock(g_provisioningMutex);
\r
119 result = OCProcess();
\r
120 ca_mutex_unlock(g_provisioningMutex);
\r
122 if (result != OC_STACK_OK) {
\r
123 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
126 // To minimize CPU utilization we may wish to do this with sleep
\r
131 OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
\r
132 OCClientResponse * clientResponse) {
\r
133 ProvisioningInfo *provInfo;
\r
135 if (clientResponse) {
\r
136 OIC_LOG_V(INFO, TAG, "Put Response");
\r
138 OIC_LOG_V(INFO, TAG,
\r
139 "ProvisionEnrolleeResponse received Null clientResponse");
\r
140 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
141 DEVICE_NOT_PROVISIONED);
\r
143 return OC_STACK_DELETE_TRANSACTION;
\r
146 if (clientResponse->payload) {
\r
148 if(clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
\r
150 OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
\r
151 return OC_STACK_DELETE_TRANSACTION;
\r
154 OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);
\r
157 OIC_LOG_V(DEBUG, TAG, "Failed To parse");
\r
158 return OC_STACK_DELETE_TRANSACTION;
\r
164 if(OCRepPayloadGetPropInt(input,OC_RSRVD_ES_PS,&ps)) {
\r
167 OIC_LOG_V(DEBUG, TAG, "PS is proper");
\r
168 input = input->next;
\r
172 OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
\r
173 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
174 DEVICE_NOT_PROVISIONED);
\r
176 return OC_STACK_DELETE_TRANSACTION;
\r
181 if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN,&tnn)){
\r
182 if(!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))
\r
184 OIC_LOG_V(DEBUG, TAG, "SSID is proper");
\r
185 input = input->next;
\r
189 OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
\r
190 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
191 DEVICE_NOT_PROVISIONED);
\r
193 return OC_STACK_DELETE_TRANSACTION;
\r
197 if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD,&cd)){
\r
198 if(!strcmp(cd,netProvInfo->netAddressInfo.WIFI.pwd))
\r
200 OIC_LOG_V(DEBUG, TAG, "Password is proper");
\r
201 input = input->next;
\r
205 OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
\r
206 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
207 DEVICE_NOT_PROVISIONED);
\r
209 return OC_STACK_DELETE_TRANSACTION;
\r
213 OCRepPayloadValue* val = input->values;
\r
217 case OCREP_PROP_NULL:
\r
218 OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);
\r
220 case OCREP_PROP_INT:
\r
221 OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);
\r
223 case OCREP_PROP_DOUBLE:
\r
224 OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);
\r
226 case OCREP_PROP_BOOL:
\r
227 OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
\r
229 case OCREP_PROP_STRING:
\r
230 OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);
\r
232 case OCREP_PROP_OBJECT:
\r
233 // Note: Only prints the URI (if available), to print further, you'll
\r
234 // need to dig into the object better!
\r
235 OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
\r
237 case OCREP_PROP_ARRAY:
\r
238 switch(val->arr.type)
\r
240 case OCREP_PROP_INT:
\r
241 OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld",
\r
243 val->arr.dimensions[0], val->arr.dimensions[1],
\r
244 val->arr.dimensions[2]);
\r
246 case OCREP_PROP_DOUBLE:
\r
247 OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld",
\r
249 val->arr.dimensions[0], val->arr.dimensions[1],
\r
250 val->arr.dimensions[2]);
\r
252 case OCREP_PROP_BOOL:
\r
253 OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld",
\r
255 val->arr.dimensions[0], val->arr.dimensions[1],
\r
256 val->arr.dimensions[2]);
\r
258 case OCREP_PROP_STRING:
\r
259 OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld",
\r
261 val->arr.dimensions[0], val->arr.dimensions[1],
\r
262 val->arr.dimensions[2]);
\r
264 case OCREP_PROP_OBJECT:
\r
265 OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",
\r
267 val->arr.dimensions[0], val->arr.dimensions[1],
\r
268 val->arr.dimensions[2]);
\r
271 //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",
\r
277 /*OC_LOG_V(ERROR, TAG
\r
278 , "\t\t%s <-- Unknown type!", val->name);*/
\r
290 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
291 DEVICE_PROVISIONED);
\r
294 return OC_STACK_KEEP_TRANSACTION;
\r
297 "ProvisionEnrolleeResponse received NULL clientResponse. \
\r
298 Invoking Provisioing Status Callback");
\r
299 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
300 DEVICE_NOT_PROVISIONED);
\r
302 return OC_STACK_DELETE_TRANSACTION;
\r
308 OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,
\r
309 OCDevAddr *destination) {
\r
310 OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
\r
313 OCRepPayload* payload = OCRepPayloadCreate();
\r
315 OCRepPayloadSetUri(payload,resUri);
\r
316 OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN,netProvInfo->netAddressInfo.WIFI.ssid);
\r
317 OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD,netProvInfo->netAddressInfo.WIFI.pwd);
\r
319 OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");
\r
321 OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, destination, OC_HIGH_QOS,
\r
322 ProvisionEnrolleeResponse, payload, NULL, 0);
\r
328 OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
\r
329 OCDoHandle handle, OCClientResponse * clientResponse) {
\r
330 ProvisioningInfo *provInfo;
\r
332 if (clientResponse == NULL) {
\r
334 "getReqCB received NULL clientResponse. \
\r
335 Invoking Provisioing Status Callback");
\r
336 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
337 DEVICE_NOT_PROVISIONED);
\r
339 return OC_STACK_DELETE_TRANSACTION;
\r
342 if (clientResponse->rcvdVendorSpecificHeaderOptions
\r
343 && clientResponse->numRcvdVendorSpecificHeaderOptions) {
\r
344 OIC_LOG(INFO, TAG, "Received vendor specific options");
\r
346 OCHeaderOption * rcvdOptions =
\r
347 clientResponse->rcvdVendorSpecificHeaderOptions;
\r
348 for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
\r
350 if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
\r
351 OIC_LOG_V(INFO, TAG,
\r
352 "Received option with OC_COAP_ID and ID %u with",
\r
353 ((OCHeaderOption) rcvdOptions[i]).optionID);
\r
355 OIC_LOG_BUFFER(INFO, TAG,
\r
356 ((OCHeaderOption) rcvdOptions[i]).optionData,
\r
357 MAX_HEADER_OPTION_DATA_LENGTH);
\r
362 char query[OIC_STRING_MAX_VALUE] = { '\0' };
\r
364 if(NULL == clientResponse->payload)
\r
367 OIC_LOG_V(DEBUG, TAG, "OCClientResponse is NULL");
\r
369 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
370 DEVICE_NOT_PROVISIONED);
\r
373 return OC_STACK_DELETE_TRANSACTION;
\r
376 OCRepPayload* repPayload = (OCRepPayload*)clientResponse->payload;
\r
378 OIC_LOG_V(DEBUG, TAG, "repPayload URI = %s",repPayload->uri);
\r
380 snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
\r
381 clientResponse->addr->addr,
\r
382 IP_PORT, repPayload->uri);
\r
384 //OCPayloadLogRep(DEBUG,TAG,input);
\r
386 if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV,
\r
387 clientResponse->addr) != OC_STACK_OK) {
\r
389 "GetProvisioningStatusResponse received NULL clientResponse. \
\r
390 Invoking Provisioing Status Callback");
\r
391 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
392 DEVICE_NOT_PROVISIONED);
\r
395 return OC_STACK_DELETE_TRANSACTION;
\r
398 return OC_STACK_DELETE_TRANSACTION;
\r
401 OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,
\r
402 OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* payload,
\r
403 OCHeaderOption * options, uint8_t numOptions) {
\r
405 OCCallbackData cbData;
\r
408 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
411 ret = OCDoResource(NULL, method, query, dest, (OCPayload*)payload, OC_CONNTYPE, qos,
\r
412 &cbData, options, numOptions);
\r
414 if (ret != OC_STACK_OK) {
\r
415 OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
\r
422 OCStackResult GetProvisioningStatus(OCQualityOfService qos,
\r
424 const OCDevAddr *destination) {
\r
425 OCStackResult ret = OC_STACK_ERROR;
\r
426 OCHeaderOption options[MAX_HEADER_OPTIONS];
\r
428 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
\r
430 uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
\r
431 uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
\r
432 memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
\r
433 options[0].protocolID = OC_COAP_ID;
\r
434 options[0].optionID = 2048;
\r
435 memcpy(options[0].optionData, option0, sizeof(option0));
\r
436 options[0].optionLength = 10;
\r
437 options[1].protocolID = OC_COAP_ID;
\r
438 options[1].optionID = 3000;
\r
439 memcpy(options[1].optionData, option1, sizeof(option1));
\r
440 options[1].optionLength = 10;
\r
442 ret = InvokeOCDoResource(query, OC_REST_GET, destination, OC_HIGH_QOS,
\r
443 GetProvisioningStatusResponse, NULL, options, 2);
\r
447 OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
\r
448 OCProvisioningStatusCB provisioningStatusCallback) {
\r
449 OCStackResult result = OC_STACK_ERROR;
\r
451 if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
\r
452 OIC_LOG(ERROR, TAG, "Request URI is NULL");
\r
456 if (provisioningStatusCallback == NULL) {
\r
457 OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
\r
461 cbData = provisioningStatusCallback;
\r
463 //Copy Network Provisioning Information
\r
464 netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
\r
466 if (NULL == netProvInfo)
\r
468 OIC_LOG(ERROR, TAG, "Invalid input..");
\r
469 return OC_STACK_ERROR;
\r
471 memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
\r
473 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
\r
474 netProvInfo->netAddressInfo.WIFI.ssid);
\r
476 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
\r
477 netProvInfo->netAddressInfo.WIFI.pwd);
\r
481 != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
\r
483 OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");
\r
484 ca_thread_pool_free(g_threadPoolHandle);
\r
485 ca_mutex_unlock(g_provisioningMutex);
\r
486 ca_mutex_free(g_provisioningMutex);
\r
487 ca_cond_free(g_provisioningCond);
\r
488 return OC_STACK_ERROR;
\r
490 return OC_STACK_OK;
\r
493 void StopProvisioningProcess() {
\r
498 // This is a function called back when a device is discovered
\r
499 OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
\r
500 OCDoHandle handle, OCClientResponse * clientResponse) {
\r
501 OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
\r
503 ProvisioningInfo *provInfo = NULL;
\r
504 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
\r
506 if(clientResponse == NULL)
\r
508 OIC_LOG(ERROR, TAG,
\r
509 "OCClientResponse is NULL");
\r
511 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
512 DEVICE_NOT_PROVISIONED);
\r
518 if (clientResponse->result != OC_STACK_OK || NULL == clientResponse->payload) {
\r
519 OIC_LOG(ERROR, TAG,
\r
520 "OCStack stop error. Calling Provisioing Status Callback");
\r
522 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
523 DEVICE_NOT_PROVISIONED);
\r
529 OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*)clientResponse->payload;
\r
531 OIC_LOG_V(DEBUG, TAG, "discoveryPayload->resources->uri = %s",
\r
532 discoveryPayload->resources->uri);
\r
533 char szQueryUri[64] = { 0 };
\r
535 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
\r
536 clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);
\r
537 OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
\r
539 if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != OC_STACK_OK) {
\r
541 "GetProvisioningStatus returned error. \
\r
542 Invoking Provisioing Status Callback");
\r
543 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
544 DEVICE_NOT_PROVISIONED);
\r
547 return OC_STACK_DELETE_TRANSACTION;
\r
550 return OC_STACK_KEEP_TRANSACTION;
\r
554 void FindProvisioningResource(void *data)
\r
556 OCStackResult ret = OC_STACK_ERROR;
\r
558 /* Start a discovery query*/
\r
559 char szQueryUri[64] = { 0 };
\r
561 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
\r
562 netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
\r
564 OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
\r
566 OCCallbackData ocCBData;
\r
568 ocCBData.cb = FindProvisioningResourceResponse;
\r
569 ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
570 ocCBData.cd = NULL;
\r
572 ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, NULL, OC_CONNTYPE,
\r
573 OC_LOW_QOS, &ocCBData, NULL, 0);
\r
575 if (ret != OC_STACK_OK) {
\r
576 OIC_LOG(ERROR, TAG, "OCStack resource error");
\r
578 OIC_LOG(ERROR, TAG,
\r
579 "FindProvisioningResource failed. \
\r
580 Invoking Provisioing Status Callback");
\r
582 ProvisioningInfo *provInfo;
\r
583 provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
\r
585 if(provInfo == NULL)
\r
587 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
591 OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
\r
593 if(devAddr == NULL)
\r
595 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
599 strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));
\r
600 devAddr->port= IP_PORT;
\r
601 provInfo->provDeviceInfo.addr = devAddr;
\r
602 provInfo->provStatus = DEVICE_NOT_PROVISIONED;
\r
609 OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
\r
610 OCClientResponse* clientResponse) {
\r
611 OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
\r
613 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
\r
615 if (clientResponse->result != OC_STACK_OK) {
\r
616 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
620 if (clientResponse) {
\r
621 OIC_LOG(INFO, TAG, PCF("Client Response exists"));
\r
623 if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
\r
625 OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
\r
629 OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);
\r
630 if(!discoveryPayload)
\r
632 OIC_LOG_V(DEBUG, TAG, "invalid payload");
\r
636 char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
\r
637 snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
\r
639 OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
\r
640 discoveryPayload->uri, sourceIPAddr);
\r
642 /* Start a discovery query*/
\r
643 char szQueryUri[64] = { 0 };
\r
645 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
\r
646 sourceIPAddr, IP_PORT);
\r
648 /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
\r
649 OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
\r
650 return OC_STACK_KEEP_TRANSACTION;
\r
653 // clientResponse is invalid
\r
654 OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
\r
656 return OC_STACK_KEEP_TRANSACTION;
\r
660 OCStackResult SubscribeProvPresence(OCQualityOfService qos,
\r
661 const char* requestURI) {
\r
662 OCStackResult ret = OC_STACK_ERROR;
\r
664 OCCallbackData cbData;
\r
666 cbData.cb = &SubscribeProvPresenceCallback;
\r
667 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
670 ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
\r
671 OC_LOW_QOS, &cbData, NULL, 0);
\r
673 if (ret != OC_STACK_OK) {
\r
674 OIC_LOG(ERROR, TAG, "OCStack resource error");
\r
680 OCStackResult FindNetworkResource() {
\r
681 OCStackResult ret = OC_STACK_ERROR;
\r
682 if (OCStop() != OC_STACK_OK) {
\r
683 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
689 ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
\r
691 ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
\r
693 if(provInfo == NULL)
\r
695 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
699 OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
\r
701 if(devAddr == NULL)
\r
703 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
707 strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));
\r
708 devAddr->port= clientResponse->addr->port;
\r
710 provInfo->provDeviceInfo.addr = devAddr;
\r
712 provInfo->provStatus = provStatus;
\r