--- /dev/null
- #include "cJSON.h"
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "resourceHandler.h"
- OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *);
++#include "ocpayload.h"
+
+PROGMEM const char TAG[] = "resourceHandler";
+
+ProvResource g_prov;
+NetResource g_net;
+
- OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- char* constructJsonResponse(OCEntityHandlerRequest *ehRequest);
-
++OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *, void *callback);
+const char *getResult(OCStackResult result);
+
- g_cbForResEvent = cb;
++OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
+int g_flag = 0;
+
+ResourceEventCallback g_cbForResEvent = NULL;
+
+void RegisterResourceEventCallBack(ResourceEventCallback cb)
+{
- if (name != NULL && pass != NULL)
- {
- sprintf(name, "%s", g_prov.tnn);
- sprintf(pass, "%s", g_prov.cd);
- }
++ g_cbForResEvent = cb;
+}
+
+void GetTargetNetworkInfoFromProvResource(char *name, char *pass)
+{
- g_prov.ps = 1; // need to provisioning
- g_prov.tnt = ES_WIFI;
- sprintf(g_prov.tnn, "Unknown");
- sprintf(g_prov.cd, "Unknown");
++ if (name != NULL && pass != NULL)
++ {
++ sprintf(name, "%s", g_prov.tnn);
++ sprintf(pass, "%s", g_prov.cd);
++ }
+}
+
+OCStackResult CreateProvisioningResource()
+{
- OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
- "/oic/prov", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
++ g_prov.ps = 1; // need to provisioning
++ g_prov.tnt = ES_WIFI;
++ sprintf(g_prov.tnn, "Unknown");
++ sprintf(g_prov.cd, "Unknown");
+
- OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
++ OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
++ OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+
- return res;
++ OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
+
- NetworkInfo netInfo;
++ return res;
+}
+
+OCStackResult CreateNetworkResource()
+{
- if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
- {
- return OC_STACK_ERROR;
- }
++ NetworkInfo netInfo;
+
- if (netInfo.type != ES_WIFI)
- {
- return OC_STACK_ERROR;
- }
++ if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
++ {
++ return OC_STACK_ERROR;
++ }
+
- g_net.cnt = (int) netInfo.type;
- g_net.ant[0] = (int) ES_WIFI;
- sprintf(g_net.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1], netInfo.ipaddr[2],
- netInfo.ipaddr[3]);
- sprintf(g_net.cnn, "%s", netInfo.ssid);
++ if (netInfo.type != ES_WIFI)
++ {
++ return OC_STACK_ERROR;
++ }
+
- OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
- OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
++ g_net.cnt = (int) netInfo.type;
++ g_net.ant[0] = (int) ES_WIFI;
++ sprintf(g_net.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1], netInfo.ipaddr[2],
++ netInfo.ipaddr[3]);
++ sprintf(g_net.cnn, "%s", netInfo.ssid);
+
- OCStackResult res = OCCreateResource(&g_net.handle, "oic.net", OC_RSRVD_INTERFACE_DEFAULT,
- "/oic/net", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
- OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
++ OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
++ OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
+
- return res;
++ OCStackResult res = OCCreateResource(&g_net.handle, "oic.net", OC_RSRVD_INTERFACE_DEFAULT,
++ OC_RSRVD_ES_URI_NET, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
++ OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
+
- OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++ return res;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
-
- char *getResp = constructJsonResponse(ehRequest);
-
- if (!getResp)
- {
- OC_LOG(ERROR, TAG, "constructJsonResponse failed");
- return OC_EH_ERROR;
- }
-
- if (MAX_RESPONSE_LENGTH > strlen(getResp))
- {
- strncpy(payload, getResp, strlen(getResp));
- ehResult = OC_EH_OK;
- }
- else
- {
- OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
- ehResult = OC_EH_ERROR;
- }
-
- free(getResp);
-
- return ehResult;
++OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
+{
- OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++ OCEntityHandlerResult ehResult = OC_EH_ERROR;
++ OCRepPayload *getResp = constructResponse(ehRequest);
++ if(!getResp)
++ {
++ OC_LOG(ERROR, TAG, "constructResponse failed");
++ return OC_EH_ERROR;
++ }
++
++ *payload = getResp;
++ ehResult = OC_EH_OK;
++
++ return ehResult;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
-
- OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
-
- // Get cJSON pointer to query
- cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
- if (!putJson)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- // Get root of JSON payload, then the 1st resource.
- cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
- carrier = cJSON_GetArrayItem(carrier, 0);
- carrier = cJSON_GetObjectItem(carrier, "rep");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- cJSON* prop = cJSON_GetObjectItem(carrier, "tnn");
- if (prop)
- {
- sprintf(g_prov.tnn, "%s", prop->valuestring);
- }
-
- prop = cJSON_GetObjectItem(carrier, "cd");
- if (prop)
- {
- sprintf(g_prov.cd, "%s", prop->valuestring);
- }
-
- cJSON_Delete(putJson);
-
- // TODO: Now once receiving PUT request, the enrollee start to connect to enroller.
- g_flag = 1;
-
- char *getResp = constructJsonResponse(ehRequest);
-
- if (!getResp)
- {
- OC_LOG(ERROR, TAG, "constructJsonResponse failed");
- return OC_EH_ERROR;
- }
-
- if (MAX_RESPONSE_LENGTH > strlen(getResp))
- {
- strncpy(payload, getResp, strlen(getResp));
- ehResult = OC_EH_OK;
- }
- else
- {
- OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
- ehResult = OC_EH_ERROR;
- }
-
- free(getResp);
- return ehResult;
++OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
++ OCRepPayload** payload)
+{
- OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++
++ OCEntityHandlerResult ehResult=OC_EH_ERROR;
++ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++ OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
++ return ehResult;
++ }
++
++ OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
++ if(!input)
++ {
++ OC_LOG_V(ERROR, TAG, "Failed to parse");
++ return ehResult;
++ }
++
++ const char* tnn;
++ if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN, &tnn))
++ {
++ sprintf(g_prov.tnn, "%s", tnn);
++ }
++
++ const char* cd;
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
++ {
++ sprintf(g_prov.cd, "%s", cd);
++ }
++
++ g_flag = 1;
++
++ OCRepPayload *getResp = constructResponse(ehRequest);
++ if(!getResp)
++ {
++ OC_LOG(ERROR, TAG, "constructResponse failed");
++ return OC_EH_ERROR;
++ }
++
++ *payload = getResp;
++ ehResult = OC_EH_OK;
++
++
++
++ return ehResult;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
- OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
-
- // Get cJSON pointer to query
- cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-
- if (!putJson)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- // Get root of JSON payload, then the 1st resource.
- cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
- carrier = cJSON_GetArrayItem(carrier, 0);
- carrier = cJSON_GetObjectItem(carrier, "rep");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- cJSON* prop = cJSON_GetObjectItem(carrier, "tr");
- if (prop)
- {
- // Triggering
- ehResult = OC_EH_OK;
- }
-
- cJSON_Delete(putJson);
-
- g_flag = 1;
-
- return ehResult;
++
++OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
+{
- char* constructJsonResponse(OCEntityHandlerRequest *ehRequest)
++ OCEntityHandlerResult ehResult = OC_EH_ERROR;
++ if(!ehRequest)
++ {
++ OC_LOG(ERROR, TAG, PCF("Request is Null"));
++ return ehResult;
++ }
++ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++ OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
++ return ehResult;
++ }
++
++ OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
++ if(!input)
++ {
++ OC_LOG_V(ERROR, TAG, "Failed to parse" );
++ return ehResult;
++ }
++ const char* tr;
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_TR, &tr))
++ {
++
++ // Triggering
++ ehResult = OC_EH_OK;
++ }
++
++ g_flag = 1;
++
++ return ehResult;
+}
+
- cJSON *json = cJSON_CreateObject();
- cJSON *format;
- char *jsonResponse;
- char *JsonResp;
- char temp_resp[256];
-
- if (g_prov.handle != NULL && ehRequest->resource == g_prov.handle)
- {
- char *uri = (char *) "/oic/prov";
-
- cJSON_AddStringToObject(json, "href", uri);
- cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
- cJSON_AddNumberToObject(format, "ps", g_prov.ps);
- cJSON_AddNumberToObject(format, "tnt", g_prov.tnt);
- cJSON_AddStringToObject(format, "tnn", g_prov.tnn);
- cJSON_AddStringToObject(format, "cd", g_prov.cd);
-
- jsonResponse = cJSON_Print(json);
- cJSON_Delete(json);
- }
- else if (g_net.handle != NULL && ehRequest->requestHandle == g_net.handle)
- {
- char *uri = (char *) "/oic/net";
-
- cJSON_AddStringToObject(json, "href", uri);
- cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
- cJSON_AddNumberToObject(format, "ant", g_net.ant[0]);
-
- jsonResponse = cJSON_Print(json);
- cJSON_Delete(json);
- }
- else
- {
- return jsonResponse;
- }
-
- OC_LOG_V(INFO, TAG, "Constructed Response: %s", jsonResponse);
-
- return jsonResponse;
++OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
+{
- OCEntityHandlerRequest* entityHandlerRequest)
++
++ OCRepPayload* payload = OCRepPayloadCreate();
++ if(!payload)
++ {
++ OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
++ return NULL;
++ }
++
++ if (g_prov.handle != NULL && ehRequest->resource == g_prov.handle)
++ {
++
++
++ OCRepPayloadSetUri(payload,OC_RSRVD_ES_URI_PROV);
++
++ OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS,g_prov.ps);
++ OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, g_prov.tnt);
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN, g_prov.tnn);
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD, g_prov.cd);
++ }
++ else if (g_net.handle != NULL && ehRequest->requestHandle == g_net.handle)
++ {
++
++ OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
++ OCRepPayloadSetPropInt(payload, "ant", g_net.ant[0]);
++ }
++ return payload;
+}
+
+// This is the entity handler for the registered resource.
+// This is invoked by OCStack whenever it recevies a request for this resource.
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
- OCEntityHandlerResult ehRet = OC_EH_OK;
- OCEntityHandlerResponse response =
- { 0 };
- char payload[MAX_RESPONSE_LENGTH] =
- { 0 };
-
- if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
- {
- if (OC_REST_GET == entityHandlerRequest->method)
- {
- OC_LOG_V(INFO, TAG, "Received GET request");
- ehRet = ProcessGetRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
- }
- else if (OC_REST_PUT == entityHandlerRequest->method)
- {
- OC_LOG_V(INFO, TAG, "Received PUT request");
-
- if (g_prov.handle != NULL && entityHandlerRequest->resource == g_prov.handle)
- {
- ehRet = ProcessPutRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
- }
- else
- {
- ehRet = OC_EH_ERROR;
- }
- }
- else if (OC_REST_POST == entityHandlerRequest->method)
- {
- // TODO: As of now, POST request will be not received.
- OC_LOG(INFO, TAG, "Received OC_REST_POST from client");
- //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
- }
-
- if (ehRet == OC_EH_OK)
- {
- // Format the response. Note this requires some info about the request
- response.requestHandle = entityHandlerRequest->requestHandle;
- response.resourceHandle = entityHandlerRequest->resource;
- response.ehResult = ehRet;
- response.payload = payload;
- response.payloadSize = strlen(payload);
- response.numSendVendorSpecificHeaderOptions = 0;
- memset(response.sendVendorSpecificHeaderOptions, 0,
- sizeof response.sendVendorSpecificHeaderOptions);
- memset(response.resourceUri, 0, sizeof response.resourceUri);
- // Indicate that response is NOT in a persistent buffer
- response.persistentBufferFlag = 0;
-
- // Send the response
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, "Error sending response");
- ehRet = OC_EH_ERROR;
- }
- }
- }
-
- if (g_flag == 1)
- {
- g_cbForResEvent(ES_RECVTRIGGEROFPROVRES);
- g_flag = 0;
- }
-
- return ehRet;
++ OCEntityHandlerRequest* entityHandlerRequest,void *callback)
+{
- switch (result)
- {
- case OC_STACK_OK:
- return "OC_STACK_OK";
- case OC_STACK_INVALID_URI:
- return "OC_STACK_INVALID_URI";
- case OC_STACK_INVALID_QUERY:
- return "OC_STACK_INVALID_QUERY";
- case OC_STACK_INVALID_IP:
- return "OC_STACK_INVALID_IP";
- case OC_STACK_INVALID_PORT:
- return "OC_STACK_INVALID_PORT";
- case OC_STACK_INVALID_CALLBACK:
- return "OC_STACK_INVALID_CALLBACK";
- case OC_STACK_INVALID_METHOD:
- return "OC_STACK_INVALID_METHOD";
- case OC_STACK_NO_MEMORY:
- return "OC_STACK_NO_MEMORY";
- case OC_STACK_COMM_ERROR:
- return "OC_STACK_COMM_ERROR";
- case OC_STACK_INVALID_PARAM:
- return "OC_STACK_INVALID_PARAM";
- case OC_STACK_NOTIMPL:
- return "OC_STACK_NOTIMPL";
- case OC_STACK_NO_RESOURCE:
- return "OC_STACK_NO_RESOURCE";
- case OC_STACK_RESOURCE_ERROR:
- return "OC_STACK_RESOURCE_ERROR";
- case OC_STACK_SLOW_RESOURCE:
- return "OC_STACK_SLOW_RESOURCE";
- case OC_STACK_NO_OBSERVERS:
- return "OC_STACK_NO_OBSERVERS";
- case OC_STACK_ERROR:
- return "OC_STACK_ERROR";
- default:
- return "UNKNOWN";
- }
++ (void)callback;
++ OCEntityHandlerResult ehRet = OC_EH_OK;
++ OCEntityHandlerResponse response =
++ { 0 };
++ OCRepPayload* payload = NULL;
++ if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
++ {
++ if (OC_REST_GET == entityHandlerRequest->method)
++ {
++ OC_LOG_V(INFO, TAG, "Received GET request");
++ ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
++ }
++ else if (OC_REST_PUT == entityHandlerRequest->method)
++ {
++ OC_LOG_V(INFO, TAG, "Received PUT request");
++
++ if (g_prov.handle != NULL && entityHandlerRequest->resource == g_prov.handle)
++ {
++ ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
++ }
++ else
++ {
++ ehRet = OC_EH_ERROR;
++ }
++ }
++ else if (OC_REST_POST == entityHandlerRequest->method)
++ {
++ // TODO: As of now, POST request will be not received.
++ OC_LOG(INFO, TAG, "Received OC_REST_POST from client");
++ //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
++ }
++
++ if (ehRet == OC_EH_OK)
++ {
++ // Format the response. Note this requires some info about the request
++ response.requestHandle = entityHandlerRequest->requestHandle;
++ response.resourceHandle = entityHandlerRequest->resource;
++ response.ehResult = ehRet;
++ response.payload = (OCPayload*)(&payload); //response uses OCPaylod while all get,put methodes use OCRepPayload
++ response.numSendVendorSpecificHeaderOptions = 0;
++ memset(response.sendVendorSpecificHeaderOptions, 0,
++ sizeof response.sendVendorSpecificHeaderOptions);
++ memset(response.resourceUri, 0, sizeof response.resourceUri);
++ // Indicate that response is NOT in a persistent buffer
++ response.persistentBufferFlag = 0;
++
++ // Send the response
++ if (OCDoResponse(&response) != OC_STACK_OK)
++ {
++ OC_LOG(ERROR, TAG, "Error sending response");
++ ehRet = OC_EH_ERROR;
++ }
++ }
++ }
++
++ if (g_flag == 1)
++ {
++ g_cbForResEvent(ES_RECVTRIGGEROFPROVRES);
++ g_flag = 0;
++ }
++
++ return ehRet;
+}
+
+const char *getResult(OCStackResult result)
+{
++ switch (result)
++ {
++ case OC_STACK_OK:
++ return "OC_STACK_OK";
++ case OC_STACK_INVALID_URI:
++ return "OC_STACK_INVALID_URI";
++ case OC_STACK_INVALID_QUERY:
++ return "OC_STACK_INVALID_QUERY";
++ case OC_STACK_INVALID_IP:
++ return "OC_STACK_INVALID_IP";
++ case OC_STACK_INVALID_PORT:
++ return "OC_STACK_INVALID_PORT";
++ case OC_STACK_INVALID_CALLBACK:
++ return "OC_STACK_INVALID_CALLBACK";
++ case OC_STACK_INVALID_METHOD:
++ return "OC_STACK_INVALID_METHOD";
++ case OC_STACK_NO_MEMORY:
++ return "OC_STACK_NO_MEMORY";
++ case OC_STACK_COMM_ERROR:
++ return "OC_STACK_COMM_ERROR";
++ case OC_STACK_INVALID_PARAM:
++ return "OC_STACK_INVALID_PARAM";
++ case OC_STACK_NOTIMPL:
++ return "OC_STACK_NOTIMPL";
++ case OC_STACK_NO_RESOURCE:
++ return "OC_STACK_NO_RESOURCE";
++ case OC_STACK_RESOURCE_ERROR:
++ return "OC_STACK_RESOURCE_ERROR";
++ case OC_STACK_SLOW_RESOURCE:
++ return "OC_STACK_SLOW_RESOURCE";
++ case OC_STACK_NO_OBSERVERS:
++ return "OC_STACK_NO_OBSERVERS";
++ case OC_STACK_ERROR:
++ return "OC_STACK_ERROR";
++ default:
++ return "UNKNOWN";
++ }
+}
+
--- /dev/null
- //******************************************************************
- //
- // Copyright 2015 Samsung Electronics All Rights Reserved.
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <unistd.h>
-
- #include "provisioninghandler.h"
-
- // External includes
- #include "cJSON.h"
- #include "camutex.h"
- #include "cathreadpool.h"
- #include "logger.h"
- #include "oic_malloc.h"
-
-
- /**
- * @var g_provisioningMutex
- * @brief Mutex to synchronize access to g_caDtlsContext.
- */
- static ca_mutex g_provisioningMutex = NULL;
- static ca_cond g_provisioningCond = NULL;
- bool g_provisioningCondFlag = false;
-
- static EnrolleeNWProvInfo_t* netProvInfo;
-
- /**
- * @var cbData
- * @brief Callback for providing provisioning status callback to application
- */
- static OCProvisioningStatusCB cbData = NULL;
- static ca_thread_pool_t g_threadPoolHandle = NULL;
-
- OCStackResult InitProvisioningHandler() {
- OCStackResult ret = OC_STACK_ERROR;
- /* Initialize OCStack*/
- if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack init error");
- return ret;
- }
-
- g_provisioningMutex = ca_mutex_new();
-
- OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
-
- if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
- OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
- return OC_STACK_ERROR;
- }
-
- g_provisioningCond = ca_cond_new();
- if (NULL == g_provisioningCond) {
- OIC_LOG(DEBUG, TAG, "Failed to create condition");
- ca_mutex_free(g_provisioningMutex);
- ca_thread_pool_free(g_threadPoolHandle);
- return OC_STACK_ERROR;
- }
-
- char *string = "listeningFunc invoked in a thread";
- if (CA_STATUS_OK
- != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
- (void *) string)) {
- OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
- ca_thread_pool_free(g_threadPoolHandle);
- ca_mutex_unlock(g_provisioningMutex);
- ca_mutex_free(g_provisioningMutex);
- ca_cond_free(g_provisioningCond);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
- }
-
- OCStackResult TerminateProvisioningHandler() {
- OCStackResult ret = OC_STACK_ERROR;
- if (OCStop() != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- ca_mutex_lock(g_provisioningMutex);
- g_provisioningCondFlag = true;
- //ca_cond_signal(g_provisioningCond);
- ca_mutex_unlock(g_provisioningMutex);
-
- ca_mutex_free(g_provisioningMutex);
- g_provisioningMutex = NULL;
-
- ca_thread_pool_free(g_threadPoolHandle);
- g_threadPoolHandle = NULL;
-
- ret = OC_STACK_OK;
- return ret;
- }
-
- void listeningFunc(void *data) {
- while (!g_provisioningCondFlag) {
- OCStackResult result;
-
- ca_mutex_lock(g_provisioningMutex);
- result = OCProcess();
- ca_mutex_unlock(g_provisioningMutex);
-
- if (result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- // To minimize CPU utilization we may wish to do this with sleep
- sleep(1);
- }
- }
-
- OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
- OCClientResponse * clientResponse) {
- ProvisioningInfo *provInfo;
-
- if (clientResponse) {
- OIC_LOG_V(INFO, TAG, "Put Response JSON = %s",
- clientResponse->resJSONPayload);
- } else {
- OIC_LOG_V(INFO, TAG,
- "ProvisionEnrolleeResponse received Null clientResponse");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s ",
- clientResponse->resJSONPayload);
-
- if (clientResponse->resJSONPayload) {
- cJSON *observeJson = cJSON_CreateObject();
- observeJson = cJSON_Parse(clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
- cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
- char *ocArray_str = cJSON_PrintUnformatted(representationArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(observeJson);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- int countofrep = cJSON_GetArraySize(representationArray);
-
- for (int i = 0; i < countofrep; ++i) {
- cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
- OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_PS))
- {
- if(arrayJSON->valueint == 1)
- {
- OIC_LOG_V(DEBUG, TAG, "PS is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_TNN))
- {
- if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.ssid))
- {
- OIC_LOG_V(DEBUG, TAG, "SSID is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_CD))
- {
- if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.pwd))
- {
- OIC_LOG_V(DEBUG, TAG, "Password is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- switch (arrayJSON->type) {
- case cJSON_False:
- case cJSON_True:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's int value : %d", i,
- arrayJSON->valueint);
- break;
- case cJSON_Number:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's double value : %f", i,
- arrayJSON->valuedouble);
- break;
- case cJSON_String:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
- arrayJSON->valuestring);
- break;
- case cJSON_NULL:
- default:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
- break;
- }
- }
-
- cJSON_Delete(observeJson);
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_PROVISIONED);
- cbData(provInfo);
-
- return OC_STACK_KEEP_TRANSACTION;
- } else {
- OIC_LOG(INFO, TAG,
- "ProvisionEnrolleeResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
-
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {
- OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
-
- cJSON *jsonFinal = cJSON_CreateObject();
- cJSON *json = cJSON_CreateObject();
- cJSON *jsonArray;
- cJSON *format;
- char* payload = NULL;
-
- cJSON_AddStringToObject(json, OC_RSRVD_HREF, resUri);
- cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, format = cJSON_CreateObject());
- cJSON_AddStringToObject(format, OC_RSRVD_ES_TNN, netProvInfo->netAddressInfo.WIFI.ssid);
- cJSON_AddStringToObject(format, OC_RSRVD_ES_CD, netProvInfo->netAddressInfo.WIFI.pwd);
- cJSON_AddItemToObject(jsonFinal, OC_RSRVD_OC, jsonArray = cJSON_CreateArray());
- cJSON_AddItemToArray(jsonArray, json);
-
- OIC_LOG_V(DEBUG, TAG, "ProvisionEnrollee : %s",
- cJSON_PrintUnformatted(jsonFinal));
- payload = cJSON_Print(jsonFinal);
- OIC_LOG_V(DEBUG, TAG, "Payload : %s", payload);
-
- OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,
- ProvisionEnrolleeResponse, payload, NULL, 0);
-
- cJSON_Delete(json);
- return ret;
- }
-
- OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
- OCDoHandle handle, OCClientResponse * clientResponse) {
- ProvisioningInfo *provInfo;
-
- if (clientResponse == NULL) {
- OIC_LOG(INFO, TAG,
- "getReqCB received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- if (clientResponse->rcvdVendorSpecificHeaderOptions
- && clientResponse->numRcvdVendorSpecificHeaderOptions) {
- OIC_LOG(INFO, TAG, "Received vendor specific options");
- uint8_t i = 0;
- OCHeaderOption * rcvdOptions =
- clientResponse->rcvdVendorSpecificHeaderOptions;
- for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
- i++) {
- if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
- OIC_LOG_V(INFO, TAG,
- "Received option with OC_COAP_ID and ID %u with",
- ((OCHeaderOption) rcvdOptions[i]).optionID);
-
- OIC_LOG_BUFFER(INFO, TAG,
- ((OCHeaderOption) rcvdOptions[i]).optionData,
- MAX_HEADER_OPTION_DATA_LENGTH);
- }
- }
- }
-
- char query[OIC_STRING_MAX_VALUE] = { '\0' };
-
-
- if (clientResponse->resJSONPayload) {
- cJSON *observeJson = cJSON_CreateObject();
- observeJson = cJSON_Parse(clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
- cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
-
- OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
- resUriObj->string, resUriObj->valuestring);
-
- char resURI[MAX_URI_LENGTH]={'\0'};
-
- strncpy(resURI, resUriObj->valuestring, sizeof(resURI));
-
- snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
- clientResponse->addr->addr,
- IP_PORT, resURI);
-
- cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
- char *ocArray_str = cJSON_PrintUnformatted(representationArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(observeJson);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- int countofrep = cJSON_GetArraySize(representationArray);
-
- for (int i = 0; i < countofrep; ++i) {
- cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
- OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
-
- switch (arrayJSON->type) {
- case cJSON_False:
- case cJSON_True:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
- arrayJSON->valueint);
- break;
- case cJSON_Number:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
- arrayJSON->valuedouble);
- break;
- case cJSON_String:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
- arrayJSON->valuestring);
- break;
- case cJSON_NULL:
- default:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
- break;
- }
- }
- cJSON_Delete(observeJson);
-
- if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatusResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
-
- return OC_STACK_DELETE_TRANSACTION;
- }
- } else {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatusResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
- OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
- OCHeaderOption * options, uint8_t numOptions) {
- OCStackResult ret;
- OCCallbackData cbData;
-
- cbData.cb = cb;
- cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
- cbData.cd = NULL;
-
- ret = OCDoResource(NULL, method, query, 0, request, OC_CONNTYPE, qos,
- &cbData, options, numOptions);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
- ret, method);
- }
-
- return ret;
- }
-
- OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
- OCStackResult ret = OC_STACK_ERROR;
- OCHeaderOption options[MAX_HEADER_OPTIONS];
-
- OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
-
- uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
- memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
- options[0].protocolID = OC_COAP_ID;
- options[0].optionID = 2048;
- memcpy(options[0].optionData, option0, sizeof(option0));
- options[0].optionLength = 10;
- options[1].protocolID = OC_COAP_ID;
- options[1].optionID = 3000;
- memcpy(options[1].optionData, option1, sizeof(option1));
- options[1].optionLength = 10;
-
- ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
- GetProvisioningStatusResponse, NULL, options, 2);
- return ret;
- }
-
- OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
- OCProvisioningStatusCB provisioningStatusCallback) {
- OCStackResult result = OC_STACK_ERROR;
-
- if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
- OIC_LOG(ERROR, TAG, "Request URI is NULL");
- return result;
- }
-
- if (provisioningStatusCallback == NULL) {
- OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
- return result;
- }
-
- cbData = provisioningStatusCallback;
-
- //Copy Network Provisioning Information
- netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
-
- if (NULL == netProvInfo)
- {
- OIC_LOG(ERROR, TAG, "Invalid input..");
- return OC_STACK_ERROR;
- }
- memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
-
- OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
- netProvInfo->netAddressInfo.WIFI.ssid);
-
- OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
- netProvInfo->netAddressInfo.WIFI.pwd);
-
-
- if (CA_STATUS_OK
- != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
- (void *) "")) {
- OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");
- ca_thread_pool_free(g_threadPoolHandle);
- ca_mutex_unlock(g_provisioningMutex);
- ca_mutex_free(g_provisioningMutex);
- ca_cond_free(g_provisioningCond);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
- }
-
- void StopProvisioningProcess() {
- cbData = NULL;
- }
-
- // This is a function called back when a device is discovered
- OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
- OCDoHandle handle, OCClientResponse * clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
-
- OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
-
- ProvisioningInfo *provInfo;
-
- if (clientResponse->result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG,
- "OCStack stop error. Calling Provisioing Status Callback");
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
-
- cbData(provInfo);
- return response;
- }
-
- if (clientResponse) {
- cJSON *discoveryJson = cJSON_CreateObject();
- discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
- char *ocArray_str = cJSON_PrintUnformatted(ocArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(discoveryJson);
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return response;
- }
-
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
- cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
-
- OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
- resUriObj->string, resUriObj->valuestring);
-
-
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
- clientResponse->devAddr.addr, IP_PORT, resUriObj->valuestring);
- OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
-
- if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatus returned error. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
-
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- } else {
- // clientResponse is invalid
- OIC_LOG(ERROR, TAG,
- "Invalid response for Provisioning Discovery request. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return response;
- }
- return OC_STACK_KEEP_TRANSACTION;
- }
-
- void FindProvisioningResource(void *data)
- {
- OCStackResult ret = OC_STACK_ERROR;
-
- /* Start a discovery query*/
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
- netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
-
- OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
-
- OCCallbackData ocCBData;
-
- ocCBData.cb = FindProvisioningResourceResponse;
- ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
- ocCBData.cd = NULL;
-
- ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
- OC_LOW_QOS, &ocCBData, NULL, 0);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack resource error");
-
- OIC_LOG(ERROR, TAG,
- "FindProvisioningResource failed. \
- Invoking Provisioing Status Callback");
-
- ProvisioningInfo *provInfo;
- provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
-
- if(provInfo == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return;
- }
-
- OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
-
- if(devAddr == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return;
- }
-
- strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));
- devAddr->port= IP_PORT;
- provInfo->provDeviceInfo.addr = devAddr;
- provInfo->provStatus = DEVICE_NOT_PROVISIONED;
-
-
- cbData(provInfo);
- }
- }
-
- OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
- OCClientResponse* clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
-
- OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
-
- if (clientResponse->result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- return response;
- }
-
- if (clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Client Response exists"));
-
- cJSON *discoveryJson = cJSON_CreateObject();
- discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
- char *ocArray_str = cJSON_PrintUnformatted(ocArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(discoveryJson);
- return response;
- }
-
- char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
- snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
-
- OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
- clientResponse->resJSONPayload, sourceIPAddr);
-
- /* Start a discovery query*/
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
- sourceIPAddr, IP_PORT);
-
- /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
- return OC_STACK_KEEP_TRANSACTION;
- }*/
- } else {
- // clientResponse is invalid
- OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
- }
- return OC_STACK_KEEP_TRANSACTION;
- }
-
- OCStackResult SubscribeProvPresence(OCQualityOfService qos,
- const char* requestURI) {
- OCStackResult ret = OC_STACK_ERROR;
-
- OCCallbackData cbData;
-
- cbData.cb = &SubscribeProvPresenceCallback;
- cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
- cbData.cd = NULL;
-
- ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
- OC_LOW_QOS, &cbData, NULL, 0);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack resource error");
- }
-
- return ret;
- }
-
- OCStackResult FindNetworkResource() {
- OCStackResult ret = OC_STACK_ERROR;
- if (OCStop() != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- return ret;
- }
-
- ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
-
- ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
-
- if(provInfo == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return NULL;
- }
-
- OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
-
- if(devAddr == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return NULL;
- }
-
- strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));
- devAddr->port= clientResponse->addr->port;
-
- provInfo->provDeviceInfo.addr = devAddr;
-
- provInfo->provStatus = provStatus;
-
- return provInfo;
- }
-
++//******************************************************************\r
++//\r
++// Copyright 2015 Samsung Electronics All Rights Reserved.\r
++//\r
++//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
++//\r
++// Licensed under the Apache License, Version 2.0 (the "License");\r
++// you may not use this file except in compliance with the License.\r
++// You may obtain a copy of the License at\r
++//\r
++// http://www.apache.org/licenses/LICENSE-2.0\r
++//\r
++// Unless required by applicable law or agreed to in writing, software\r
++// distributed under the License is distributed on an "AS IS" BASIS,\r
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
++// See the License for the specific language governing permissions and\r
++// limitations under the License.\r
++//\r
++//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
++\r
++#include <stdio.h>\r
++#include <stdlib.h>\r
++#include <string.h>\r
++#include <signal.h>\r
++#include <unistd.h>\r
++#include "ocpayload.h"\r
++#include "provisioninghandler.h"\r
++\r
++// External includes\r
++\r
++#include "camutex.h"\r
++#include "cathreadpool.h"\r
++#include "logger.h"\r
++#include "oic_malloc.h"\r
++\r
++\r
++/**\r
++ * @var g_provisioningMutex\r
++ * @brief Mutex to synchronize access to g_caDtlsContext.\r
++ */\r
++static ca_mutex g_provisioningMutex = NULL;\r
++static ca_cond g_provisioningCond = NULL;\r
++bool g_provisioningCondFlag = false;\r
++\r
++static EnrolleeNWProvInfo_t* netProvInfo;\r
++\r
++/**\r
++ * @var cbData\r
++ * @brief Callback for providing provisioning status callback to application\r
++ */\r
++static OCProvisioningStatusCB cbData = NULL;\r
++static ca_thread_pool_t g_threadPoolHandle = NULL;\r
++\r
++OCStackResult InitProvisioningHandler() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ /* Initialize OCStack*/\r
++ if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack init error");\r
++ return ret;\r
++ }\r
++\r
++ g_provisioningMutex = ca_mutex_new();\r
++\r
++ OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");\r
++\r
++ if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_init failed");\r
++ return OC_STACK_ERROR;\r
++ }\r
++\r
++ g_provisioningCond = ca_cond_new();\r
++ if (NULL == g_provisioningCond) {\r
++ OIC_LOG(DEBUG, TAG, "Failed to create condition");\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ return OC_STACK_ERROR;\r
++ }\r
++\r
++ char *string = "listeningFunc invoked in a thread";\r
++ if (CA_STATUS_OK\r
++ != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,\r
++ (void *) string)) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_cond_free(g_provisioningCond);\r
++ return OC_STACK_ERROR;\r
++ }\r
++ return OC_STACK_OK;\r
++}\r
++\r
++OCStackResult TerminateProvisioningHandler() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ if (OCStop() != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ ca_mutex_lock(g_provisioningMutex);\r
++ g_provisioningCondFlag = true;\r
++ //ca_cond_signal(g_provisioningCond);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++\r
++ ca_mutex_free(g_provisioningMutex);\r
++ g_provisioningMutex = NULL;\r
++\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ g_threadPoolHandle = NULL;\r
++\r
++ ret = OC_STACK_OK;\r
++ return ret;\r
++}\r
++\r
++void listeningFunc(void *data) {\r
++ while (!g_provisioningCondFlag) {\r
++ OCStackResult result;\r
++\r
++ ca_mutex_lock(g_provisioningMutex);\r
++ result = OCProcess();\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++\r
++ if (result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ // To minimize CPU utilization we may wish to do this with sleep\r
++ sleep(1);\r
++ }\r
++}\r
++\r
++OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,\r
++ OCClientResponse * clientResponse) {\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse) {\r
++ OIC_LOG_V(INFO, TAG, "Put Response");\r
++ } else {\r
++ OIC_LOG_V(INFO, TAG,\r
++ "ProvisionEnrolleeResponse received Null clientResponse");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ if (clientResponse->payload) {\r
++\r
++ if(clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);\r
++ if(!input)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ while(input){\r
++\r
++ int64_t ps;\r
++ if(OCRepPayloadGetPropInt(input,OC_RSRVD_ES_PS,&ps)) {\r
++ if(ps == 1)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "PS is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ }\r
++ }\r
++\r
++ const char* tnn;\r
++ if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN,&tnn)){\r
++ if(!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "SSID is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ }\r
++ }\r
++ const char* cd;\r
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD,&cd)){\r
++ if(!strcmp(cd,netProvInfo->netAddressInfo.WIFI.pwd))\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Password is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ }\r
++ }\r
++\r
++ OCRepPayloadValue* val = input->values;\r
++\r
++ switch(val->type)\r
++ {\r
++ case OCREP_PROP_NULL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);\r
++ break;\r
++ case OCREP_PROP_INT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);\r
++ break;\r
++ case OCREP_PROP_DOUBLE:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);\r
++ break;\r
++ case OCREP_PROP_BOOL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");\r
++ break;\r
++ case OCREP_PROP_STRING:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);\r
++ break;\r
++ case OCREP_PROP_OBJECT:\r
++ // Note: Only prints the URI (if available), to print further, you'll\r
++ // need to dig into the object better!\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);\r
++ break;\r
++ case OCREP_PROP_ARRAY:\r
++ switch(val->arr.type)\r
++ {\r
++ case OCREP_PROP_INT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_DOUBLE:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_BOOL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_STRING:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_OBJECT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ default:\r
++ //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",\r
++ // val->name);\r
++ break;\r
++ }\r
++ break;\r
++ default:\r
++ /*OC_LOG_V(ERROR, TAG\r
++ , "\t\t%s <-- Unknown type!", val->name);*/\r
++ break;\r
++ }\r
++ input=input->next;\r
++ }\r
++\r
++\r
++\r
++\r
++\r
++\r
++\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++ } else {\r
++ OIC_LOG(INFO, TAG,\r
++ "ProvisionEnrolleeResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++}\r
++\r
++\r
++\r
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {\r
++ OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);\r
++\r
++\r
++ OCRepPayload* payload = OCRepPayloadCreate();\r
++\r
++ OCRepPayloadSetUri(payload,resUri);\r
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN,netProvInfo->netAddressInfo.WIFI.ssid);\r
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD,netProvInfo->netAddressInfo.WIFI.pwd);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");\r
++\r
++ OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,\r
++ ProvisionEnrolleeResponse, payload, NULL, 0);\r
++\r
++ return ret;\r
++}\r
++\r
++\r
++OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,\r
++ OCDoHandle handle, OCClientResponse * clientResponse) {\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse == NULL) {\r
++ OIC_LOG(INFO, TAG,\r
++ "getReqCB received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ if (clientResponse->rcvdVendorSpecificHeaderOptions\r
++ && clientResponse->numRcvdVendorSpecificHeaderOptions) {\r
++ OIC_LOG(INFO, TAG, "Received vendor specific options");\r
++ uint8_t i = 0;\r
++ OCHeaderOption * rcvdOptions =\r
++ clientResponse->rcvdVendorSpecificHeaderOptions;\r
++ for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;\r
++ i++) {\r
++ if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {\r
++ OIC_LOG_V(INFO, TAG,\r
++ "Received option with OC_COAP_ID and ID %u with",\r
++ ((OCHeaderOption) rcvdOptions[i]).optionID);\r
++\r
++ OIC_LOG_BUFFER(INFO, TAG,\r
++ ((OCHeaderOption) rcvdOptions[i]).optionData,\r
++ MAX_HEADER_OPTION_DATA_LENGTH);\r
++ }\r
++ }\r
++ }\r
++\r
++ char query[OIC_STRING_MAX_VALUE] = { '\0' };\r
++\r
++\r
++ if (clientResponse->payload) {\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);\r
++ if(!input)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s",input->uri);\r
++\r
++ char resURI[MAX_URI_LENGTH]={'\0'};\r
++\r
++ strncpy(resURI, input->uri, sizeof(resURI));\r
++\r
++ snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,\r
++ clientResponse->addr->addr,\r
++ IP_PORT, resURI);\r
++\r
++ //OCPayloadLogRep(DEBUG,TAG,input);\r
++\r
++ if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatusResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ } else {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatusResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++}\r
++\r
++OCStackResult InvokeOCDoResource(const char* query, OCMethod method,\r
++ OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* request,\r
++ OCHeaderOption * options, uint8_t numOptions) {\r
++ OCStackResult ret;\r
++ OCCallbackData cbData;\r
++\r
++ cbData.cb = cb;\r
++ cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ cbData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, method, query, 0, &request->base, OC_CONNTYPE, qos,\r
++ &cbData, options, numOptions);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",\r
++ ret, method);\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ OCHeaderOption options[MAX_HEADER_OPTIONS];\r
++\r
++ OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);\r
++\r
++ uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r
++ uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };\r
++ memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);\r
++ options[0].protocolID = OC_COAP_ID;\r
++ options[0].optionID = 2048;\r
++ memcpy(options[0].optionData, option0, sizeof(option0));\r
++ options[0].optionLength = 10;\r
++ options[1].protocolID = OC_COAP_ID;\r
++ options[1].optionID = 3000;\r
++ memcpy(options[1].optionData, option1, sizeof(option1));\r
++ options[1].optionLength = 10;\r
++\r
++ ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,\r
++ GetProvisioningStatusResponse, NULL, options, 2);\r
++ return ret;\r
++}\r
++\r
++OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,\r
++ OCProvisioningStatusCB provisioningStatusCallback) {\r
++ OCStackResult result = OC_STACK_ERROR;\r
++\r
++ if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {\r
++ OIC_LOG(ERROR, TAG, "Request URI is NULL");\r
++ return result;\r
++ }\r
++\r
++ if (provisioningStatusCallback == NULL) {\r
++ OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");\r
++ return result;\r
++ }\r
++\r
++ cbData = provisioningStatusCallback;\r
++\r
++ //Copy Network Provisioning Information\r
++ netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));\r
++\r
++ if (NULL == netProvInfo)\r
++ {\r
++ OIC_LOG(ERROR, TAG, "Invalid input..");\r
++ return OC_STACK_ERROR;\r
++ }\r
++ memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",\r
++ netProvInfo->netAddressInfo.WIFI.ssid);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",\r
++ netProvInfo->netAddressInfo.WIFI.pwd);\r
++\r
++\r
++ if (CA_STATUS_OK\r
++ != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,\r
++ (void *) "")) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_cond_free(g_provisioningCond);\r
++ return OC_STACK_ERROR;\r
++ }\r
++ return OC_STACK_OK;\r
++}\r
++\r
++void StopProvisioningProcess() {\r
++ cbData = NULL;\r
++}\r
++\r
++\r
++// This is a function called back when a device is discovered\r
++OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,\r
++ OCDoHandle handle, OCClientResponse * clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));\r
++\r
++ OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
++\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse->result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG,\r
++ "OCStack stop error. Calling Provisioing Status Callback");\r
++\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++\r
++ if (clientResponse) {\r
++\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);\r
++ if(!discoveryPayload)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s",discoveryPayload->uri);\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,\r
++ clientResponse->devAddr.addr, IP_PORT, discoveryPayload->uri);\r
++ OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);\r
++\r
++ if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatus returned error. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ } else {\r
++ // clientResponse is invalid\r
++ OIC_LOG(ERROR, TAG,\r
++ "Invalid response for Provisioning Discovery request. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++}\r
++\r
++\r
++void FindProvisioningResource(void *data)\r
++{\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++\r
++ /* Start a discovery query*/\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
++ netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);\r
++\r
++ OCCallbackData ocCBData;\r
++\r
++ ocCBData.cb = FindProvisioningResourceResponse;\r
++ ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ ocCBData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,\r
++ OC_LOW_QOS, &ocCBData, NULL, 0);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack resource error");\r
++\r
++ OIC_LOG(ERROR, TAG,\r
++ "FindProvisioningResource failed. \\r
++ Invoking Provisioing Status Callback");\r
++\r
++ ProvisioningInfo *provInfo;\r
++ provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
++\r
++ if(provInfo == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return;\r
++ }\r
++\r
++ OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
++\r
++ if(devAddr == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return;\r
++ }\r
++\r
++ strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));\r
++ devAddr->port= IP_PORT;\r
++ provInfo->provDeviceInfo.addr = devAddr;\r
++ provInfo->provStatus = DEVICE_NOT_PROVISIONED;\r
++\r
++\r
++ cbData(provInfo);\r
++ }\r
++}\r
++\r
++OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,\r
++ OCClientResponse* clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));\r
++\r
++ OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
++\r
++ if (clientResponse->result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ return response;\r
++ }\r
++\r
++ if (clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Client Response exists"));\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return response;\r
++ }\r
++\r
++ OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);\r
++ if(!discoveryPayload)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "invalid payload");\r
++ return response;\r
++ }\r
++\r
++ char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };\r
++ snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",\r
++ discoveryPayload->uri, sourceIPAddr);\r
++\r
++ /* Start a discovery query*/\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
++ sourceIPAddr, IP_PORT);\r
++\r
++ /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++ }*/\r
++ } else {\r
++ // clientResponse is invalid\r
++ OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));\r
++ }\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++}\r
++\r
++\r
++OCStackResult SubscribeProvPresence(OCQualityOfService qos,\r
++ const char* requestURI) {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++\r
++ OCCallbackData cbData;\r
++\r
++ cbData.cb = &SubscribeProvPresenceCallback;\r
++ cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ cbData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,\r
++ OC_LOW_QOS, &cbData, NULL, 0);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack resource error");\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++OCStackResult FindNetworkResource() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ if (OCStop() != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {\r
++\r
++ ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
++\r
++ if(provInfo == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return NULL;\r
++ }\r
++\r
++ OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
++\r
++ if(devAddr == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return NULL;\r
++ }\r
++\r
++ strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));\r
++ devAddr->port= clientResponse->addr->port;\r
++\r
++ provInfo->provDeviceInfo.addr = devAddr;\r
++\r
++ provInfo->provStatus = provStatus;\r
++\r
++ return provInfo;\r
++}\r
++\r
++\r
++\r
++\r