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
171 OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
\r
172 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
173 DEVICE_NOT_PROVISIONED);
\r
180 if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN,&tnn)){
\r
181 if(!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))
\r
183 OIC_LOG_V(DEBUG, TAG, "SSID is proper");
\r
187 OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
\r
188 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
189 DEVICE_NOT_PROVISIONED);
\r
194 if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD,&cd)){
\r
195 if(!strcmp(cd,netProvInfo->netAddressInfo.WIFI.pwd))
\r
197 OIC_LOG_V(DEBUG, TAG, "Password is proper");
\r
201 OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
\r
202 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
203 DEVICE_NOT_PROVISIONED);
\r
208 OCRepPayloadValue* val = input->values;
\r
212 case OCREP_PROP_NULL:
\r
213 OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);
\r
215 case OCREP_PROP_INT:
\r
216 OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);
\r
218 case OCREP_PROP_DOUBLE:
\r
219 OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);
\r
221 case OCREP_PROP_BOOL:
\r
222 OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
\r
224 case OCREP_PROP_STRING:
\r
225 OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);
\r
227 case OCREP_PROP_OBJECT:
\r
228 // Note: Only prints the URI (if available), to print further, you'll
\r
229 // need to dig into the object better!
\r
230 OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
\r
232 case OCREP_PROP_ARRAY:
\r
233 switch(val->arr.type)
\r
235 case OCREP_PROP_INT:
\r
236 OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld",
\r
238 val->arr.dimensions[0], val->arr.dimensions[1],
\r
239 val->arr.dimensions[2]);
\r
241 case OCREP_PROP_DOUBLE:
\r
242 OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld",
\r
244 val->arr.dimensions[0], val->arr.dimensions[1],
\r
245 val->arr.dimensions[2]);
\r
247 case OCREP_PROP_BOOL:
\r
248 OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld",
\r
250 val->arr.dimensions[0], val->arr.dimensions[1],
\r
251 val->arr.dimensions[2]);
\r
253 case OCREP_PROP_STRING:
\r
254 OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld",
\r
256 val->arr.dimensions[0], val->arr.dimensions[1],
\r
257 val->arr.dimensions[2]);
\r
259 case OCREP_PROP_OBJECT:
\r
260 OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",
\r
262 val->arr.dimensions[0], val->arr.dimensions[1],
\r
263 val->arr.dimensions[2]);
\r
266 //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",
\r
272 /*OC_LOG_V(ERROR, TAG
\r
273 , "\t\t%s <-- Unknown type!", val->name);*/
\r
285 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
286 DEVICE_PROVISIONED);
\r
289 return OC_STACK_KEEP_TRANSACTION;
\r
292 "ProvisionEnrolleeResponse received NULL clientResponse. \
\r
293 Invoking Provisioing Status Callback");
\r
294 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
295 DEVICE_NOT_PROVISIONED);
\r
297 return OC_STACK_DELETE_TRANSACTION;
\r
303 OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {
\r
304 OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
\r
307 OCRepPayload* payload = OCRepPayloadCreate();
\r
309 OCRepPayloadSetUri(payload,resUri);
\r
310 OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN,netProvInfo->netAddressInfo.WIFI.ssid);
\r
311 OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD,netProvInfo->netAddressInfo.WIFI.pwd);
\r
313 OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");
\r
315 OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,
\r
316 ProvisionEnrolleeResponse, payload, NULL, 0);
\r
322 OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
\r
323 OCDoHandle handle, OCClientResponse * clientResponse) {
\r
324 ProvisioningInfo *provInfo;
\r
326 if (clientResponse == NULL) {
\r
328 "getReqCB received NULL clientResponse. \
\r
329 Invoking Provisioing Status Callback");
\r
330 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
331 DEVICE_NOT_PROVISIONED);
\r
333 return OC_STACK_DELETE_TRANSACTION;
\r
336 if (clientResponse->rcvdVendorSpecificHeaderOptions
\r
337 && clientResponse->numRcvdVendorSpecificHeaderOptions) {
\r
338 OIC_LOG(INFO, TAG, "Received vendor specific options");
\r
340 OCHeaderOption * rcvdOptions =
\r
341 clientResponse->rcvdVendorSpecificHeaderOptions;
\r
342 for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
\r
344 if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
\r
345 OIC_LOG_V(INFO, TAG,
\r
346 "Received option with OC_COAP_ID and ID %u with",
\r
347 ((OCHeaderOption) rcvdOptions[i]).optionID);
\r
349 OIC_LOG_BUFFER(INFO, TAG,
\r
350 ((OCHeaderOption) rcvdOptions[i]).optionData,
\r
351 MAX_HEADER_OPTION_DATA_LENGTH);
\r
356 char query[OIC_STRING_MAX_VALUE] = { '\0' };
\r
359 if (clientResponse->payload) {
\r
361 if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
\r
364 OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
\r
365 return OC_STACK_DELETE_TRANSACTION;
\r
368 OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);
\r
371 OIC_LOG_V(DEBUG, TAG, "Failed To parse");
\r
372 return OC_STACK_DELETE_TRANSACTION;
\r
374 OIC_LOG_V(DEBUG, TAG, "resUri = %s",input->uri);
\r
376 char resURI[MAX_URI_LENGTH]={'\0'};
\r
378 strncpy(resURI, input->uri, sizeof(resURI));
\r
380 snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
\r
381 clientResponse->addr->addr,
\r
384 //OCPayloadLogRep(DEBUG,TAG,input);
\r
386 if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {
\r
388 "GetProvisioningStatusResponse received NULL clientResponse. \
\r
389 Invoking Provisioing Status Callback");
\r
390 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
391 DEVICE_NOT_PROVISIONED);
\r
394 return OC_STACK_DELETE_TRANSACTION;
\r
398 "GetProvisioningStatusResponse received NULL clientResponse. \
\r
399 Invoking Provisioing Status Callback");
\r
400 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
401 DEVICE_NOT_PROVISIONED);
\r
403 return OC_STACK_DELETE_TRANSACTION;
\r
405 return OC_STACK_DELETE_TRANSACTION;
\r
408 OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
\r
409 OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* request,
\r
410 OCHeaderOption * options, uint8_t numOptions) {
\r
412 OCCallbackData cbData;
\r
415 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
418 ret = OCDoResource(NULL, method, query, 0, &request->base, OC_CONNTYPE, qos,
\r
419 &cbData, options, numOptions);
\r
421 if (ret != OC_STACK_OK) {
\r
422 OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
\r
429 OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
\r
430 OCStackResult ret = OC_STACK_ERROR;
\r
431 OCHeaderOption options[MAX_HEADER_OPTIONS];
\r
433 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
\r
435 uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
\r
436 uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
\r
437 memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
\r
438 options[0].protocolID = OC_COAP_ID;
\r
439 options[0].optionID = 2048;
\r
440 memcpy(options[0].optionData, option0, sizeof(option0));
\r
441 options[0].optionLength = 10;
\r
442 options[1].protocolID = OC_COAP_ID;
\r
443 options[1].optionID = 3000;
\r
444 memcpy(options[1].optionData, option1, sizeof(option1));
\r
445 options[1].optionLength = 10;
\r
447 ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
\r
448 GetProvisioningStatusResponse, NULL, options, 2);
\r
452 OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
\r
453 OCProvisioningStatusCB provisioningStatusCallback) {
\r
454 OCStackResult result = OC_STACK_ERROR;
\r
456 if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
\r
457 OIC_LOG(ERROR, TAG, "Request URI is NULL");
\r
461 if (provisioningStatusCallback == NULL) {
\r
462 OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
\r
466 cbData = provisioningStatusCallback;
\r
468 //Copy Network Provisioning Information
\r
469 netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
\r
471 if (NULL == netProvInfo)
\r
473 OIC_LOG(ERROR, TAG, "Invalid input..");
\r
474 return OC_STACK_ERROR;
\r
476 memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
\r
478 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
\r
479 netProvInfo->netAddressInfo.WIFI.ssid);
\r
481 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
\r
482 netProvInfo->netAddressInfo.WIFI.pwd);
\r
486 != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
\r
488 OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");
\r
489 ca_thread_pool_free(g_threadPoolHandle);
\r
490 ca_mutex_unlock(g_provisioningMutex);
\r
491 ca_mutex_free(g_provisioningMutex);
\r
492 ca_cond_free(g_provisioningCond);
\r
493 return OC_STACK_ERROR;
\r
495 return OC_STACK_OK;
\r
498 void StopProvisioningProcess() {
\r
503 // This is a function called back when a device is discovered
\r
504 OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
\r
505 OCDoHandle handle, OCClientResponse * clientResponse) {
\r
506 OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
\r
508 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
\r
510 ProvisioningInfo *provInfo;
\r
512 if (clientResponse->result != OC_STACK_OK) {
\r
513 OIC_LOG(ERROR, TAG,
\r
514 "OCStack stop error. Calling Provisioing Status Callback");
\r
516 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
517 DEVICE_NOT_PROVISIONED);
\r
523 if (clientResponse) {
\r
526 if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
\r
528 OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
\r
529 return OC_STACK_DELETE_TRANSACTION;
\r
532 OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);
\r
533 if(!discoveryPayload)
\r
535 OIC_LOG_V(DEBUG, TAG, "Failed To parse");
\r
536 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
537 DEVICE_NOT_PROVISIONED);
\r
541 OIC_LOG_V(DEBUG, TAG, "resUri = %s",discoveryPayload->uri);
\r
542 char szQueryUri[64] = { 0 };
\r
544 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
\r
545 clientResponse->devAddr.addr, IP_PORT, discoveryPayload->uri);
\r
546 OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
\r
548 if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
\r
550 "GetProvisioningStatus returned error. \
\r
551 Invoking Provisioing Status Callback");
\r
552 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
553 DEVICE_NOT_PROVISIONED);
\r
556 return OC_STACK_DELETE_TRANSACTION;
\r
559 // clientResponse is invalid
\r
560 OIC_LOG(ERROR, TAG,
\r
561 "Invalid response for Provisioning Discovery request. \
\r
562 Invoking Provisioing Status Callback");
\r
563 provInfo = PrepareProvisioingStatusCB(clientResponse,
\r
564 DEVICE_NOT_PROVISIONED);
\r
568 return OC_STACK_KEEP_TRANSACTION;
\r
572 void FindProvisioningResource(void *data)
\r
574 OCStackResult ret = OC_STACK_ERROR;
\r
576 /* Start a discovery query*/
\r
577 char szQueryUri[64] = { 0 };
\r
579 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
\r
580 netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
\r
582 OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
\r
584 OCCallbackData ocCBData;
\r
586 ocCBData.cb = FindProvisioningResourceResponse;
\r
587 ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
588 ocCBData.cd = NULL;
\r
590 ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
\r
591 OC_LOW_QOS, &ocCBData, NULL, 0);
\r
593 if (ret != OC_STACK_OK) {
\r
594 OIC_LOG(ERROR, TAG, "OCStack resource error");
\r
596 OIC_LOG(ERROR, TAG,
\r
597 "FindProvisioningResource failed. \
\r
598 Invoking Provisioing Status Callback");
\r
600 ProvisioningInfo *provInfo;
\r
601 provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
\r
603 if(provInfo == NULL)
\r
605 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
609 OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
\r
611 if(devAddr == NULL)
\r
613 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
617 strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));
\r
618 devAddr->port= IP_PORT;
\r
619 provInfo->provDeviceInfo.addr = devAddr;
\r
620 provInfo->provStatus = DEVICE_NOT_PROVISIONED;
\r
627 OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
\r
628 OCClientResponse* clientResponse) {
\r
629 OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
\r
631 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
\r
633 if (clientResponse->result != OC_STACK_OK) {
\r
634 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
638 if (clientResponse) {
\r
639 OIC_LOG(INFO, TAG, PCF("Client Response exists"));
\r
641 if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
\r
643 OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
\r
647 OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);
\r
648 if(!discoveryPayload)
\r
650 OIC_LOG_V(DEBUG, TAG, "invalid payload");
\r
654 char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
\r
655 snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
\r
657 OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
\r
658 discoveryPayload->uri, sourceIPAddr);
\r
660 /* Start a discovery query*/
\r
661 char szQueryUri[64] = { 0 };
\r
663 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
\r
664 sourceIPAddr, IP_PORT);
\r
666 /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
\r
667 OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
\r
668 return OC_STACK_KEEP_TRANSACTION;
\r
671 // clientResponse is invalid
\r
672 OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
\r
674 return OC_STACK_KEEP_TRANSACTION;
\r
678 OCStackResult SubscribeProvPresence(OCQualityOfService qos,
\r
679 const char* requestURI) {
\r
680 OCStackResult ret = OC_STACK_ERROR;
\r
682 OCCallbackData cbData;
\r
684 cbData.cb = &SubscribeProvPresenceCallback;
\r
685 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
\r
688 ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
\r
689 OC_LOW_QOS, &cbData, NULL, 0);
\r
691 if (ret != OC_STACK_OK) {
\r
692 OIC_LOG(ERROR, TAG, "OCStack resource error");
\r
698 OCStackResult FindNetworkResource() {
\r
699 OCStackResult ret = OC_STACK_ERROR;
\r
700 if (OCStop() != OC_STACK_OK) {
\r
701 OIC_LOG(ERROR, TAG, "OCStack stop error");
\r
707 ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
\r
709 ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
\r
711 if(provInfo == NULL)
\r
713 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
717 OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
\r
719 if(devAddr == NULL)
\r
721 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
\r
725 strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));
\r
726 devAddr->port= clientResponse->addr->port;
\r
728 provInfo->provDeviceInfo.addr = devAddr;
\r
730 provInfo->provStatus = provStatus;
\r