1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
27 #include "provisioninghandler.h"
32 #include "cathreadpool.h"
34 #include "oic_malloc.h"
38 * @var g_provisioningMutex
39 * @brief Mutex to synchronize access to g_caDtlsContext.
41 static ca_mutex g_provisioningMutex = NULL;
42 static ca_cond g_provisioningCond = NULL;
43 bool g_provisioningCondFlag = false;
45 static EnrolleeNWProvInfo_t* netProvInfo;
49 * @brief Callback for providing provisioning status callback to application
51 static OCProvisioningStatusCB cbData = NULL;
52 static ca_thread_pool_t g_threadPoolHandle = NULL;
54 OCStackResult InitProvisioningHandler() {
55 OCStackResult ret = OC_STACK_ERROR;
56 /* Initialize OCStack*/
57 if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
58 OIC_LOG(ERROR, TAG, "OCStack init error");
62 g_provisioningMutex = ca_mutex_new();
64 OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
66 if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
67 OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
68 return OC_STACK_ERROR;
71 g_provisioningCond = ca_cond_new();
72 if (NULL == g_provisioningCond) {
73 OIC_LOG(DEBUG, TAG, "Failed to create condition");
74 ca_mutex_free(g_provisioningMutex);
75 ca_thread_pool_free(g_threadPoolHandle);
76 return OC_STACK_ERROR;
79 char *string = "listeningFunc invoked in a thread";
81 != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
83 OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
84 ca_thread_pool_free(g_threadPoolHandle);
85 ca_mutex_unlock(g_provisioningMutex);
86 ca_mutex_free(g_provisioningMutex);
87 ca_cond_free(g_provisioningCond);
88 return OC_STACK_ERROR;
93 OCStackResult TerminateProvisioningHandler() {
94 OCStackResult ret = OC_STACK_ERROR;
95 if (OCStop() != OC_STACK_OK) {
96 OIC_LOG(ERROR, TAG, "OCStack stop error");
99 ca_mutex_lock(g_provisioningMutex);
100 g_provisioningCondFlag = true;
101 //ca_cond_signal(g_provisioningCond);
102 ca_mutex_unlock(g_provisioningMutex);
104 ca_mutex_free(g_provisioningMutex);
105 g_provisioningMutex = NULL;
107 ca_thread_pool_free(g_threadPoolHandle);
108 g_threadPoolHandle = NULL;
114 void listeningFunc(void *data) {
115 while (!g_provisioningCondFlag) {
116 OCStackResult result;
118 ca_mutex_lock(g_provisioningMutex);
119 result = OCProcess();
120 ca_mutex_unlock(g_provisioningMutex);
122 if (result != OC_STACK_OK) {
123 OIC_LOG(ERROR, TAG, "OCStack stop error");
126 // To minimize CPU utilization we may wish to do this with sleep
131 OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
132 OCClientResponse * clientResponse) {
133 ProvisioningInfo provInfo;
135 if (clientResponse) {
136 OIC_LOG_V(INFO, TAG, "Put Response JSON = %s",
137 clientResponse->resJSONPayload);
140 "ProvisionEnrolleeResponse received Null clientResponse");
141 PrepareProvisioingStatusCB(&provInfo, clientResponse,
142 DEVICE_NOT_PROVISIONED);
144 return OC_STACK_DELETE_TRANSACTION;
147 uint16_t remotePortNum;
149 OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
151 char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
152 snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
153 clientResponse->addr->addr[0], clientResponse->addr->addr[1],
154 clientResponse->addr->addr[2], clientResponse->addr->addr[3],
155 remotePortNum, OIC_PROVISIONING_URI);
157 OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s @ %s",
158 clientResponse->resJSONPayload, sourceaddr);
160 if (clientResponse->resJSONPayload) {
161 cJSON *observeJson = cJSON_CreateObject();
162 observeJson = cJSON_Parse(clientResponse->resJSONPayload);
164 cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
165 cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
167 cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
168 char *ocArray_str = cJSON_PrintUnformatted(representationArray);
170 if (strstr(ocArray_str, "[{}") == ocArray_str) {
171 OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
172 cJSON_Delete(observeJson);
173 return OC_STACK_DELETE_TRANSACTION;
176 int countofrep = cJSON_GetArraySize(representationArray);
178 for (int i = 0; i < countofrep; ++i) {
179 cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
180 OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
182 switch (arrayJSON->type) {
185 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
186 arrayJSON->valueint);
189 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
190 arrayJSON->valuedouble);
193 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
194 arrayJSON->valuestring);
198 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
203 cJSON_Delete(observeJson);
205 PrepareProvisioingStatusCB(&provInfo, clientResponse,
209 return OC_STACK_KEEP_TRANSACTION;
212 "ProvisionEnrolleeResponse received NULL clientResponse. \
213 Invoking Provisioing Status Callback");
214 PrepareProvisioingStatusCB(&provInfo, clientResponse,
215 DEVICE_NOT_PROVISIONED);
217 return OC_STACK_DELETE_TRANSACTION;
221 OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query) {
222 OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
224 cJSON *jsonFinal = cJSON_CreateObject();
225 cJSON *json = cJSON_CreateObject();
228 char* payload = NULL;
230 char nodeData[OIC_STRING_MAX_VALUE] = { '\0' };
231 snprintf(nodeData, sizeof(nodeData), "%s", OIC_PROVISIONING_URI);
233 cJSON_AddStringToObject(json, "href", nodeData);
234 cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
235 cJSON_AddStringToObject(format, "tnn", netProvInfo->netAddressInfo.WIFI.ssid);
236 cJSON_AddStringToObject(format, "cd", netProvInfo->netAddressInfo.WIFI.pwd);
237 cJSON_AddItemToObject(jsonFinal, "oic", jsonArray = cJSON_CreateArray());
238 cJSON_AddItemToArray(jsonArray, json);
240 OIC_LOG_V(DEBUG, TAG, "ProvisionEnrollee : %s",
241 cJSON_PrintUnformatted(jsonFinal));
242 payload = cJSON_Print(jsonFinal);
243 OIC_LOG_V(DEBUG, TAG, "Payload : %s", payload);
245 OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,
246 ProvisionEnrolleeResponse, payload, NULL, 0);
252 OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
253 OCDoHandle handle, OCClientResponse * clientResponse) {
254 ProvisioningInfo provInfo;
256 if (clientResponse == NULL) {
258 "getReqCB received NULL clientResponse. \
259 Invoking Provisioing Status Callback");
260 PrepareProvisioingStatusCB(&provInfo, clientResponse,
261 DEVICE_NOT_PROVISIONED);
263 return OC_STACK_DELETE_TRANSACTION;
266 if (clientResponse->rcvdVendorSpecificHeaderOptions
267 && clientResponse->numRcvdVendorSpecificHeaderOptions) {
268 OIC_LOG(INFO, TAG, "Received vendor specific options");
270 OCHeaderOption * rcvdOptions =
271 clientResponse->rcvdVendorSpecificHeaderOptions;
272 for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
274 if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
276 "Received option with OC_COAP_ID and ID %u with",
277 ((OCHeaderOption) rcvdOptions[i]).optionID);
279 OIC_LOG_BUFFER(INFO, TAG,
280 ((OCHeaderOption) rcvdOptions[i]).optionData,
281 MAX_HEADER_OPTION_DATA_LENGTH);
286 char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
287 snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
288 clientResponse->addr->addr[0], clientResponse->addr->addr[1],
289 clientResponse->addr->addr[2], clientResponse->addr->addr[3],
290 6298, OIC_PROVISIONING_URI);
292 if (clientResponse->resJSONPayload) {
293 cJSON *observeJson = cJSON_CreateObject();
294 observeJson = cJSON_Parse(clientResponse->resJSONPayload);
296 cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
297 cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
299 cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
300 char *ocArray_str = cJSON_PrintUnformatted(representationArray);
302 if (strstr(ocArray_str, "[{}") == ocArray_str) {
303 OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
304 cJSON_Delete(observeJson);
305 return OC_STACK_DELETE_TRANSACTION;
308 int countofrep = cJSON_GetArraySize(representationArray);
310 for (int i = 0; i < countofrep; ++i) {
311 cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
312 OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
314 switch (arrayJSON->type) {
317 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
318 arrayJSON->valueint);
321 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
322 arrayJSON->valuedouble);
325 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
326 arrayJSON->valuestring);
330 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
334 cJSON_Delete(observeJson);
336 if (ProvisionEnrollee(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
338 "GetProvisioningStatusResponse received NULL clientResponse. \
339 Invoking Provisioing Status Callback");
340 PrepareProvisioingStatusCB(&provInfo, clientResponse,
341 DEVICE_NOT_PROVISIONED);
344 return OC_STACK_DELETE_TRANSACTION;
348 "GetProvisioningStatusResponse received NULL clientResponse. \
349 Invoking Provisioing Status Callback");
350 PrepareProvisioingStatusCB(&provInfo, clientResponse,
351 DEVICE_NOT_PROVISIONED);
353 return OC_STACK_DELETE_TRANSACTION;
355 return OC_STACK_DELETE_TRANSACTION;
358 OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
359 OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
360 OCHeaderOption * options, uint8_t numOptions) {
362 OCCallbackData cbData;
365 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
368 ret = OCDoResource(NULL, method, query, 0, request, OC_CONNTYPE, qos,
369 &cbData, options, numOptions);
371 if (ret != OC_STACK_OK) {
372 OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
379 OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
380 OCStackResult ret = OC_STACK_ERROR;
381 OCHeaderOption options[MAX_HEADER_OPTIONS];
383 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
385 uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
386 uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
387 memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
388 options[0].protocolID = OC_COAP_ID;
389 options[0].optionID = 2048;
390 memcpy(options[0].optionData, option0, sizeof(option0));
391 options[0].optionLength = 10;
392 options[1].protocolID = OC_COAP_ID;
393 options[1].optionID = 3000;
394 memcpy(options[1].optionData, option1, sizeof(option1));
395 options[1].optionLength = 10;
397 ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
398 GetProvisioningStatusResponse, NULL, options, 2);
402 OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
403 OCProvisioningStatusCB provisioningStatusCallback) {
404 OCStackResult result = OC_STACK_ERROR;
405 ProvisioningInfo provInfo;
407 if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
408 OIC_LOG(ERROR, TAG, "Request URI is NULL");
412 if (provisioningStatusCallback == NULL) {
413 OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
417 cbData = provisioningStatusCallback;
419 //Copy Network Provisioning Information
420 netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
422 if (NULL == netProvInfo)
424 OIC_LOG(ERROR, TAG, "Invalid input..");
425 return OC_STACK_ERROR;
427 memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
429 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
430 netProvInfo->netAddressInfo.WIFI.ssid);
432 OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
433 netProvInfo->netAddressInfo.WIFI.pwd);
435 /* Start a discovery query*/
436 char szQueryUri[64] = { 0 };
438 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
439 netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
441 OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
443 if (FindProvisioningResource(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
445 "FindProvisioningResource failed. \
446 Invoking Provisioing Status Callback");
448 ProvDeviceInfo provDeviceIndo;
451 dst.addr[0] = netProvInfo->netAddressInfo.WIFI.ipAddress[0];
452 dst.addr[1] = netProvInfo->netAddressInfo.WIFI.ipAddress[1];
453 dst.addr[2] = netProvInfo->netAddressInfo.WIFI.ipAddress[2];
454 dst.addr[3] = netProvInfo->netAddressInfo.WIFI.ipAddress[3];
455 dst.addr[4] = (uint8_t) IP_PORT;
456 dst.addr[5] = (uint8_t)(IP_PORT >> 8);
458 provInfo.provStatus = DEVICE_NOT_PROVISIONED;
459 provDeviceIndo.addr = &dst;
460 provDeviceIndo.connType = OC_IPV4;
461 provInfo.provDeviceInfo = provDeviceIndo;
466 result = OC_STACK_OK;
471 void StopProvisioningProcess() {
475 // This is a function called back when a device is discovered
476 OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
477 OCDoHandle handle, OCClientResponse * clientResponse) {
478 OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
480 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
482 ProvisioningInfo provInfo;
484 if (clientResponse->result != OC_STACK_OK) {
486 "OCStack stop error. Calling Provisioing Status Callback");
488 PrepareProvisioingStatusCB(&provInfo, clientResponse,
489 DEVICE_NOT_PROVISIONED);
495 if (clientResponse) {
496 // Parse header options from server
501 for (int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
504 clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
506 clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData;
507 payload = clientResponse->resJSONPayload;
510 cJSON *discoveryJson = cJSON_CreateObject();
511 discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
513 cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
514 char *ocArray_str = cJSON_PrintUnformatted(ocArray);
516 if (strstr(ocArray_str, "[{}") == ocArray_str) {
517 OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
518 cJSON_Delete(discoveryJson);
520 PrepareProvisioingStatusCB(&provInfo, clientResponse,
521 DEVICE_NOT_PROVISIONED);
526 char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
527 snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
528 clientResponse->addr->addr[0], clientResponse->addr->addr[1],
529 clientResponse->addr->addr[2], clientResponse->addr->addr[3],
530 IP_PORT, OIC_PROVISIONING_URI);
532 OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
533 clientResponse->resJSONPayload, sourceaddr);
535 if (GetProvisioningStatus(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
537 "GetProvisioningStatus returned error. \
538 Invoking Provisioing Status Callback");
539 PrepareProvisioingStatusCB(&provInfo, clientResponse,
540 DEVICE_NOT_PROVISIONED);
543 return OC_STACK_DELETE_TRANSACTION;
546 // clientResponse is invalid
548 "Invalid response for Provisioning Discovery request. \
549 Invoking Provisioing Status Callback");
550 PrepareProvisioingStatusCB(&provInfo, clientResponse,
551 DEVICE_NOT_PROVISIONED);
555 return OC_STACK_KEEP_TRANSACTION;
558 OCStackResult FindProvisioningResource(OCQualityOfService qos,
559 const char* requestURI) {
560 OCStackResult ret = OC_STACK_ERROR;
562 OCCallbackData cbData;
564 cbData.cb = FindProvisioningResourceResponse;
565 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
568 ret = OCDoResource(NULL, OC_REST_GET, requestURI, 0, 0, OC_CONNTYPE,
569 OC_LOW_QOS, &cbData, NULL, 0);
571 if (ret != OC_STACK_OK) {
572 OIC_LOG(ERROR, TAG, "OCStack resource error");
578 OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
579 OCClientResponse* clientResponse) {
580 OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
582 OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
584 if (clientResponse->result != OC_STACK_OK) {
585 OIC_LOG(ERROR, TAG, "OCStack stop error");
589 if (clientResponse) {
590 OIC_LOG(INFO, TAG, PCF("Client Response exists"));
591 // Parse header options from server
596 for (int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
599 clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
601 clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData;
602 payload = clientResponse->resJSONPayload;
605 cJSON *discoveryJson = cJSON_CreateObject();
606 discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
608 cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
609 char *ocArray_str = cJSON_PrintUnformatted(ocArray);
611 if (strstr(ocArray_str, "[{}") == ocArray_str) {
612 OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
613 cJSON_Delete(discoveryJson);
617 char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
618 snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%d.%d.%d.%d",
619 clientResponse->addr->addr[0], clientResponse->addr->addr[1],
620 clientResponse->addr->addr[2], clientResponse->addr->addr[3]);
622 OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
623 clientResponse->resJSONPayload, sourceIPAddr);
625 /* Start a discovery query*/
626 char szQueryUri[64] = { 0 };
627 OCQualityOfService qos = OC_NA_QOS;
629 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
630 sourceIPAddr, IP_PORT);
632 if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
633 OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
634 return OC_STACK_KEEP_TRANSACTION;
637 // clientResponse is invalid
638 OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
640 return OC_STACK_KEEP_TRANSACTION;
643 OCStackResult SubscribeProvPresence(OCQualityOfService qos,
644 const char* requestURI) {
645 OCStackResult ret = OC_STACK_ERROR;
647 OCCallbackData cbData;
649 cbData.cb = &SubscribeProvPresenceCallback;
650 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
653 ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
654 OC_LOW_QOS, &cbData, NULL, 0);
656 if (ret != OC_STACK_OK) {
657 OIC_LOG(ERROR, TAG, "OCStack resource error");
663 OCStackResult FindNetworkResource() {
664 OCStackResult ret = OC_STACK_ERROR;
665 if (OCStop() != OC_STACK_OK) {
666 OIC_LOG(ERROR, TAG, "OCStack stop error");
672 void PrepareProvisioingStatusCB(ProvisioningInfo *provInfo,
673 OCClientResponse * clientResponse, ProvStatus provStatus) {
674 ProvDeviceInfo provDeviceIndo;
677 uint16_t remotePortNum;
678 OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
680 dst.addr[0] = clientResponse->addr->addr[0];
681 dst.addr[1] = clientResponse->addr->addr[1];
682 dst.addr[2] = clientResponse->addr->addr[2];
683 dst.addr[3] = clientResponse->addr->addr[3];
684 dst.addr[4] = (uint8_t) remotePortNum;
685 dst.addr[5] = (uint8_t)(remotePortNum >> 8);
687 provInfo->provStatus = provStatus;
689 provDeviceIndo.addr = &dst;
690 provDeviceIndo.connType = OC_IPV4;
692 provInfo->provDeviceInfo = provDeviceIndo;