--- /dev/null
- const char* tnn;
+//******************************************************************
+//
+// 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"
+#include "ocpayload.h"
+
+PROGMEM const char TAG[] = "resourceHandler";
+
+ProvResource g_prov;
+NetResource g_net;
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *, void *callback);
+const char *getResult(OCStackResult result);
+
+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)
+{
+ g_cbForResEvent = cb;
+}
+
+void GetTargetNetworkInfoFromProvResource(char *name, char *pass)
+{
+ if (name != NULL && pass != NULL)
+ {
+ sprintf(name, "%s", g_prov.tnn);
+ sprintf(pass, "%s", g_prov.cd);
+ }
+}
+
+OCStackResult CreateProvisioningResource()
+{
+ g_prov.ps = 1; // need to provisioning
+ g_prov.tnt = ES_WIFI;
+ sprintf(g_prov.tnn, "Unknown");
+ sprintf(g_prov.cd, "Unknown");
+
+ OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
+ OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+ OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
+
+ return res;
+}
+
+OCStackResult CreateNetworkResource()
+{
+ NetworkInfo netInfo;
+
+ if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ if (netInfo.type != ES_WIFI)
+ {
+ 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);
+
+ OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
+ OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
+
+ 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));
+
+ return res;
+}
+
+OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
+{
+ 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 *getResp = constructResponse(ehRequest);
+ if(!getResp)
+ {
+ OC_LOG(ERROR, TAG, "constructResponse failed");
+ return OC_EH_ERROR;
+ }
+
+ *payload = getResp;
+ ehResult = OC_EH_OK;
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload** payload)
+{
+
+ 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* cd;
++ char* tnn;
+ if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN, &tnn))
+ {
+ sprintf(g_prov.tnn, "%s", tnn);
+ }
+
- const char* tr;
++ 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 ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
+{
+ 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;
+ }
++ char* tr;
+ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_TR, &tr))
+ {
+
+ // Triggering
+ ehResult = OC_EH_OK;
+ }
+
+ g_flag = 1;
+
+ return ehResult;
+}
+
+OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
+{
+ OCRepPayload* payload = OCRepPayloadCreate();
+ if(!payload)
+ {
+ OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+ return NULL;
+ }
+
+ if (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 (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,
+ OCEntityHandlerRequest* entityHandlerRequest,void *callback)
+{
+ (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
- //******************************************************************\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
- input = input->next;\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
- return OC_STACK_DELETE_TRANSACTION;\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
- input = input->next;\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
- return OC_STACK_DELETE_TRANSACTION;\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
- input = input->next;\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
- return OC_STACK_DELETE_TRANSACTION;\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
- OCDevAddr *destination) {\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, destination, 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
- if(NULL == clientResponse->payload)\r
- \r
- {\r
- OIC_LOG_V(DEBUG, TAG, "OCClientResponse is NULL");\r
- \r
- provInfo = PrepareProvisioingStatusCB(clientResponse,\r
- DEVICE_NOT_PROVISIONED);\r
- cbData(provInfo);\r
- \r
- return OC_STACK_DELETE_TRANSACTION;\r
- }\r
- \r
- OCRepPayload* repPayload = (OCRepPayload*)clientResponse->payload;\r
- \r
- OIC_LOG_V(DEBUG, TAG, "repPayload URI = %s",repPayload->uri);\r
- \r
- snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,\r
- clientResponse->addr->addr,\r
- IP_PORT, repPayload->uri);\r
- \r
- //OCPayloadLogRep(DEBUG,TAG,input);\r
- \r
- if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV,\r
- clientResponse->addr) != 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
- \r
- return OC_STACK_DELETE_TRANSACTION;\r
- }\r
- \r
- OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,\r
- OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* payload,\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, dest, (OCPayload*)payload, 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,\r
- const char* query,\r
- const OCDevAddr *destination) {\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, destination, 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
- ProvisioningInfo *provInfo = NULL;\r
- OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
- \r
- if(clientResponse == NULL)\r
- {\r
- OIC_LOG(ERROR, TAG,\r
- "OCClientResponse is NULL");\r
- \r
- provInfo = PrepareProvisioingStatusCB(clientResponse,\r
- DEVICE_NOT_PROVISIONED);\r
- \r
- cbData(provInfo);\r
- return response;\r
- }\r
- \r
- if (clientResponse->result != OC_STACK_OK || NULL == clientResponse->payload) {\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
- OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*)clientResponse->payload;\r
- \r
- OIC_LOG_V(DEBUG, TAG, "discoveryPayload->resources->uri = %s",\r
- discoveryPayload->resources->uri);\r
- char szQueryUri[64] = { 0 };\r
- \r
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,\r
- clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);\r
- OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);\r
- \r
- if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != 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
- \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_DISCOVER, szQueryUri, NULL, NULL, 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
++//******************************************************************
++//
++// 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 "ocpayload.h"
++#include "provisioninghandler.h"
++#include "common.h"
++// External includes
++
++#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;
++
++void ErrorCallback(ProvStatus status)
++{
++ ProvisioningInfo *provInfo = GetCallbackObjectOnError(status);
++ cbData(provInfo);
++}
++
++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 (!ValidateEnrolleResponse(clientResponse))
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ char* tnn;
++ char* cd;
++
++ OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
++
++ while (input)
++ {
++
++ int64_t ps;
++ if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_PS, &ps))
++ {
++
++ if (ps == 1)
++ {
++ OIC_LOG_V(DEBUG, TAG, "PS is proper");
++ input = input->next;
++ continue;
++ }
++ else
++ {
++ OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
++ goto Error;
++
++ }
++ }
++
++ if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
++ {
++ if (!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))
++ {
++ OIC_LOG_V(DEBUG, TAG, "SSID is proper");
++ input = input->next;
++ continue;
++ }
++ else
++ {
++ OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
++ goto Error;
++ }
++ }
++
++ if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
++ {
++ if (!strcmp(cd, netProvInfo->netAddressInfo.WIFI.pwd))
++ {
++ OIC_LOG_V(DEBUG, TAG, "Password is proper");
++ input = input->next;
++ continue;
++ }
++ else
++ {
++ OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
++ goto Error;
++ }
++ }
++
++ LogProvisioningResponse(input->values);
++
++ input = input->next;
++
++ }
++
++ SuccessCallback(clientResponse);
++
++ return OC_STACK_KEEP_TRANSACTION;
++
++ Error:
++ {
++
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++}
++
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,
++ OCDevAddr *destination)
++{
++ OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
++
++ OCRepPayload* payload = OCRepPayloadCreate();
++
++ OCRepPayloadSetUri(payload, resUri);
++ OCRepPayloadSetPropString(payload, OC_RSRVD_ES_TNN, netProvInfo->netAddressInfo.WIFI.ssid);
++ OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CD, netProvInfo->netAddressInfo.WIFI.pwd);
++
++ OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");
++
++ OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, destination, OC_HIGH_QOS,
++ ProvisionEnrolleeResponse, payload, NULL, 0);
++
++ return ret;
++}
++
++OCStackApplicationResult GetProvisioningStatusResponse(void* ctx, OCDoHandle handle,
++ OCClientResponse * clientResponse)
++{
++
++ ProvisioningInfo *provInfo;
++
++ if (!ValidateEnrolleResponse(clientResponse))
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ ClearMemory();
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
++
++ char query[OIC_STRING_MAX_VALUE] =
++ { '\0' };
++ char resURI[MAX_URI_LENGTH] =
++ { '\0' };
++
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s", input->uri);
++
++ strncpy(resURI, input->uri, sizeof(resURI));
++
++ snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY, clientResponse->addr->addr, IP_PORT,
++ resURI);
++
++ //OCPayloadLogRep(DEBUG,TAG,input);
++
++ if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV, clientResponse->addr)
++ != OC_STACK_OK)
++ {
++ OIC_LOG(INFO, TAG,
++ "GetProvisioningStatusResponse received NULL clientResponse.Invoking Provisioing Status Callback");
++
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ ClearMemory();
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ return OC_STACK_KEEP_TRANSACTION;
++
++}
++
++OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,
++ OCQualityOfService qos, OCClientResponseHandler cb, OCRepPayload* payload,
++ 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, dest, (OCPayload*) payload, 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,
++ const OCDevAddr *destination)
++{
++ 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, destination, OC_HIGH_QOS,
++ GetProvisioningStatusResponse, NULL, options, 2);
++ return ret;
++}
++
++OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
++ OCProvisioningStatusCB provisioningStatusCallback)
++{
++
++ OCStackResult result = OC_STACK_ERROR;
++
++ if (!ValidateEasySetupParams(netInfo, provisioningStatusCallback))
++ {
++ goto Error;
++ }
++
++ //Only basis test is done for below API
++ if (!SetProgress(provisioningStatusCallback))
++ {
++ // Device provisioning session is running already.
++ OIC_LOG(INFO, TAG, PCF("Device provisioning session is running already"));
++ goto Error;
++ }
++
++ if (!ConfigEnrolleeObject(netInfo))
++ {
++ goto Error;
++ }
++
++ if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
++ (void *) ""))
++ {
++ goto Error;
++ }
++
++ return OC_STACK_OK;
++
++ Error:
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ ClearMemory();
++ return OC_STACK_ERROR;
++ }
++
++}
++
++void StopProvisioningProcess()
++{
++ //Only basis test is done for below API
++ ResetProgress();
++}
++
++// 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"));
++
++ if (!ValidateFinddResourceResponse(clientResponse))
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
++
++ ProvisioningInfo *provInfo;
++ char szQueryUri[64] =
++ { 0 };
++
++ OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*) (clientResponse->payload);
++
++ // Need to conform if below check is required or not. As Null check of clientResponse->payload is already performed above
++ if (!discoveryPayload)
++ {
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s", discoveryPayload->resources->uri);
++
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
++ clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);
++
++ OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
++
++ if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != OC_STACK_OK)
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ return OC_STACK_DELETE_TRANSACTION;
++ }
++
++ 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_DISCOVER, szQueryUri, NULL, NULL, OC_CONNTYPE, OC_LOW_QOS,
++ &ocCBData, NULL, 0);
++
++ if (ret != OC_STACK_OK)
++ {
++ ErrorCallback( DEVICE_NOT_PROVISIONED);
++ ClearMemory();
++ }
++}
++
++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"));
++
++ if (clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
++ return response;
++ }
++
++ OCRepPayload* discoveryPayload = (OCRepPayload*) (clientResponse->payload);
++ if (!discoveryPayload)
++ {
++ OIC_LOG_V(DEBUG, TAG, "invalid payload");
++ 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", discoveryPayload->uri, 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;
++}
++
++bool ValidateEasySetupParams(const EnrolleeNWProvInfo_t *netInfo,
++ OCProvisioningStatusCB provisioningStatusCallback)
++{
++
++ if (netInfo == NULL || netInfo->netAddressInfo.WIFI.ipAddress == NULL)
++ {
++ OIC_LOG(ERROR, TAG, "Request URI is NULL");
++ return false;
++ }
++
++ if (provisioningStatusCallback == NULL)
++ {
++ OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
++ return false;
++ }
++
++ return true;
++
++}
++
++bool InProgress()
++{
++
++ // It means already Easy Setup provisioning session is going on.
++ if (NULL != cbData)
++ {
++ OIC_LOG(ERROR, TAG, "Easy setup session is already in progress");
++ return true;
++ }
++
++ return false;
++}
++
++bool SetProgress(OCProvisioningStatusCB provisioningStatusCallback)
++{
++ ca_mutex_lock(g_provisioningMutex);
++
++ if (InProgress())
++ return false;
++
++ cbData = provisioningStatusCallback;
++
++ ca_mutex_unlock(g_provisioningMutex);
++
++ return true;
++}
++
++bool ResetProgress()
++{
++ ca_mutex_lock(g_provisioningMutex);
++
++ cbData = NULL;
++
++ ca_mutex_unlock(g_provisioningMutex);
++}
++
++ProvisioningInfo* CreateCallBackObject()
++{
++
++ 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;
++ }
++
++ provInfo->provDeviceInfo.addr = devAddr;
++
++ return provInfo;
++
++}
++
++ProvisioningInfo* GetCallbackObjectOnError(ProvStatus status)
++{
++
++ ProvisioningInfo *provInfo = CreateCallBackObject();
++ strncpy(provInfo->provDeviceInfo.addr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress,
++ sizeof(provInfo->provDeviceInfo.addr->addr));
++ provInfo->provDeviceInfo.addr->port = IP_PORT;
++ provInfo->provStatus = status;
++ return provInfo;
++}
++
++ProvisioningInfo* GetCallbackObjectOnSuccess(OCClientResponse * clientResponse,
++ ProvStatus provStatus)
++{
++ ProvisioningInfo *provInfo = CreateCallBackObject();
++ strncpy(provInfo->provDeviceInfo.addr->addr, clientResponse->addr->addr,
++ sizeof(provInfo->provDeviceInfo.addr->addr));
++ provInfo->provDeviceInfo.addr->port = clientResponse->addr->port;
++ provInfo->provStatus = provStatus;
++ return provInfo;
++}
++
++bool ValidateFinddResourceResponse(OCClientResponse * clientResponse)
++{
++
++ if (!(clientResponse) || !(clientResponse->payload))
++ {
++
++ OIC_LOG_V(INFO, TAG, "ProvisionEnrolleeResponse received Null clientResponse");
++
++ return false;
++
++ }
++return true;
++}
++
++bool ValidateEnrolleResponse(OCClientResponse * clientResponse)
++{
++
++ if (!(clientResponse) || !(clientResponse->payload))
++ {
++
++ OIC_LOG_V(INFO, TAG, "ProvisionEnrolleeResponse received Null clientResponse");
++
++ return false;
++
++ }
++
++ if (clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
++ return false;
++
++ }
++
++ // If flow reachese here means no error condition hit.
++ return true;
++
++}
++
++
++void SuccessCallback(OCClientResponse * clientResponse)
++{
++ ProvisioningInfo *provInfo = GetCallbackObjectOnSuccess(clientResponse, DEVICE_PROVISIONED);
++ cbData(provInfo);
++}
++
++bool ClearMemory()
++{
++
++ 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 true;
++
++}
++
++bool ConfigEnrolleeObject(const EnrolleeNWProvInfo_t *netInfo)
++{
++
++ //Copy Network Provisioning Information
++ netProvInfo = (EnrolleeNWProvInfo_t *) OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
++
++ if (netProvInfo == NULL)
++ {
++ OIC_LOG(ERROR, TAG, "Invalid input..");
++ return false;
++ }
++
++ 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);
++
++ return true;
++
++}
++
++void LogProvisioningResponse(OCRepPayloadValue* val)
++{
++
++ switch (val->type)
++ {
++ case OCREP_PROP_NULL:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);
++ break;
++ case OCREP_PROP_INT:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);
++ break;
++ case OCREP_PROP_DOUBLE:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);
++ break;
++ case OCREP_PROP_BOOL:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
++ break;
++ case OCREP_PROP_STRING:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);
++ break;
++ case OCREP_PROP_OBJECT:
++ // Note: Only prints the URI (if available), to print further, you'll
++ // need to dig into the object better!
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
++ break;
++ case OCREP_PROP_ARRAY:
++ switch (val->arr.type)
++ {
++ case OCREP_PROP_INT:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld", val->name,
++ val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++ break;
++ case OCREP_PROP_DOUBLE:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld", val->name,
++ val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++ break;
++ case OCREP_PROP_BOOL:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld", val->name,
++ val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++ break;
++ case OCREP_PROP_STRING:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld", val->name,
++ val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++ break;
++ case OCREP_PROP_OBJECT:
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld", val->name,
++ val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++ break;
++ default:
++ //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",
++ // val->name);
++ break;
++ }
++ break;
++ default:
++ /*OC_LOG_V(ERROR, TAG
++ , "\t\t%s <-- Unknown type!", val->name);*/
++ break;
++ }
++}
++