1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "resourcehandler.h"
25 #include "ocpayload.h"
26 #include "oic_string.h"
30 * @brief Logging tag for module name.
32 #define ES_RH_TAG "ES_RH"
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
39 * @brief Structure for holding the Provisioning status and target information required to
40 * connect to the target network
42 static ProvResource gProvResource;
46 * @brief Structure forr holding the Provisioning status of network information
48 static NetResource gNetResource;
50 //-----------------------------------------------------------------------------
51 // Private internal function prototypes
52 //-----------------------------------------------------------------------------
53 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest *ehRequest,
55 const char *getResult(OCStackResult result);
56 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
57 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
58 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
59 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
61 ResourceEventCallback gNetworkInfoProvEventCb = NULL;
63 void RegisterResourceEventCallBack(ResourceEventCallback cb)
65 gNetworkInfoProvEventCb = cb;
68 void UnRegisterResourceEventCallBack()
70 if (gNetworkInfoProvEventCb)
72 gNetworkInfoProvEventCb = NULL;
76 void GetTargetNetworkInfoFromProvResource(char *name, char *pass)
78 if (name != NULL && pass != NULL)
80 OICStrcpy(name, sizeof(name), gProvResource.tnn);
81 OICStrcpy(pass, sizeof(pass), gProvResource.cd);
85 OCStackResult CreateProvisioningResource(bool isSecured)
87 gProvResource.ps = ES_PS_NEED_PROVISIONING;
88 gProvResource.tr = ES_PS_TRIGGER_INIT_VALUE;
90 gProvResource.tnt = CT_ADAPTER_IP;
91 OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), "Unknown");
92 OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), "Unknown");
94 OCStackResult res = OC_STACK_ERROR;
97 res = OCCreateResource(&gProvResource.handle, OC_RSRVD_ES_PROV_RES_TYPE,
98 OC_RSRVD_INTERFACE_DEFAULT,
99 OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,
100 NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
104 res = OCCreateResource(&gProvResource.handle, OC_RSRVD_ES_PROV_RES_TYPE,
105 OC_RSRVD_INTERFACE_DEFAULT,
106 OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,
107 NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
110 OIC_LOG_V(INFO, ES_RH_TAG, "Created Prov resource with result: %s", getResult(res));
114 OCStackResult DeleteProvisioningResource()
116 OCStackResult res = OCDeleteResource(gProvResource.handle);
117 if (res != OC_STACK_OK)
119 OIC_LOG_V(INFO, ES_RH_TAG, "Deleting Prov resource error with result: %s", getResult(res));
125 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
127 OCEntityHandlerResult ehResult = OC_EH_ERROR;
130 OIC_LOG(ERROR, ES_RH_TAG, "Request is Null");
133 if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
135 OIC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
139 OCRepPayload *getResp = constructResponse(ehRequest);
142 OIC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
152 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
154 OIC_LOG(INFO, ES_RH_TAG, "ProcessPostRequest enter");
155 OCEntityHandlerResult ehResult = OC_EH_ERROR;
156 if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
158 OIC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
162 OCRepPayload* input = (OCRepPayload*) (ehRequest->payload);
165 OIC_LOG(ERROR, ES_RH_TAG, "Failed to parse");
170 if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_TR, &tr))
173 gProvResource.tr = tr;
176 //ES_PS_PROVISIONING_COMPLETED state indicates that already provisioning is completed.
177 // A new request for provisioning means overriding existing network provisioning information.
178 if (gProvResource.ps == ES_PS_PROVISIONING_COMPLETED && tr == ES_PS_TRIGGER_CONNECTION)
180 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning already completed."
181 "Tiggering the network connection");
183 if (gNetworkInfoProvEventCb)
185 gNetworkInfoProvEventCb(ES_RECVTRIGGEROFPROVRES);
190 OIC_LOG(ERROR, ES_RH_TAG, "gNetworkInfoProvEventCb is NULL."
191 "Network handler not registered. Failed to connect to the network");
192 ehResult = OC_EH_ERROR;
197 else if (gProvResource.ps == ES_PS_PROVISIONING_COMPLETED)
199 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning already completed. "
200 "This a request to override the existing the network provisioning information");
204 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning the network information to the Enrollee.");
207 OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), "");
208 OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), "");
211 if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
213 OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn);
214 OIC_LOG(INFO, ES_RH_TAG, "got ssid");
217 OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn);
220 if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
222 OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd);
223 OIC_LOG(INFO, ES_RH_TAG, "got password");
224 }OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd);
226 gProvResource.ps = ES_PS_PROVISIONING_COMPLETED;
228 OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps);
230 OCRepPayload *getResp = constructResponse(ehRequest);
233 OIC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
243 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest * /*ehRequest*/,
244 OCRepPayload** /*payload*/)
246 OCEntityHandlerResult ehResult = OC_EH_ERROR;
251 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
253 OCRepPayload* payload = OCRepPayloadCreate();
256 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
260 if (ehRequest->resource == gProvResource.handle)
262 OIC_LOG(INFO, ES_RH_TAG, "constructResponse prov res");
263 OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
264 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS, gProvResource.ps);
265 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, gProvResource.tnt);
267 else if (ehRequest->requestHandle == gNetResource.handle)
270 OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
271 OCRepPayloadSetPropInt(payload, "ant", gNetResource.ant[0]);
277 * This is the entity handler for the registered resource.
278 * This is invoked by OCStack whenever it recevies a request for this resource.
280 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
281 OCEntityHandlerRequest* entityHandlerRequest, void *callback)
284 OCEntityHandlerResult ehRet = OC_EH_OK;
285 OCEntityHandlerResponse response =
286 { 0, 0, OC_EH_ERROR, 0, 0,
289 OCRepPayload* payload = NULL;
291 if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
293 if (OC_REST_GET == entityHandlerRequest->method)
295 OIC_LOG(INFO, ES_RH_TAG, "Received GET request");
296 ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
298 else if (OC_REST_PUT == entityHandlerRequest->method)
300 OIC_LOG(INFO, ES_RH_TAG, "Received PUT request");
302 //PUT request will be handled in the internal implementation
303 if (gProvResource.handle != NULL
304 && entityHandlerRequest->resource == gProvResource.handle)
306 ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
310 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
314 else if (OC_REST_POST == entityHandlerRequest->method)
316 OIC_LOG(INFO, ES_RH_TAG, "Received OC_REST_POST from client");
317 if (gProvResource.handle != NULL
318 && entityHandlerRequest->resource == gProvResource.handle)
320 ehRet = ProcessPostRequest(entityHandlerRequest, &payload);
324 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
329 if (ehRet == OC_EH_OK)
331 // Format the response. Note this requires some info about the request
332 response.requestHandle = entityHandlerRequest->requestHandle;
333 response.resourceHandle = entityHandlerRequest->resource;
334 response.ehResult = ehRet;
335 //response uses OCPaylod while all get,put methodes use OCRepPayload
336 response.payload = (OCPayload*) (payload);
337 response.numSendVendorSpecificHeaderOptions = 0;
338 memset(response.sendVendorSpecificHeaderOptions, 0,
339 sizeof(response.sendVendorSpecificHeaderOptions));
340 memset(response.resourceUri, 0, sizeof(response.resourceUri));
341 // Indicate that response is NOT in a persistent buffer
342 response.persistentBufferFlag = 0;
345 if (OCDoResponse(&response) != OC_STACK_OK)
347 OIC_LOG(ERROR, ES_RH_TAG, "Error sending response");
356 const char *getResult(OCStackResult result)
361 return "OC_STACK_OK";
362 case OC_STACK_INVALID_URI:
363 return "OC_STACK_INVALID_URI";
364 case OC_STACK_INVALID_QUERY:
365 return "OC_STACK_INVALID_QUERY";
366 case OC_STACK_INVALID_IP:
367 return "OC_STACK_INVALID_IP";
368 case OC_STACK_INVALID_PORT:
369 return "OC_STACK_INVALID_PORT";
370 case OC_STACK_INVALID_CALLBACK:
371 return "OC_STACK_INVALID_CALLBACK";
372 case OC_STACK_INVALID_METHOD:
373 return "OC_STACK_INVALID_METHOD";
374 case OC_STACK_NO_MEMORY:
375 return "OC_STACK_NO_MEMORY";
376 case OC_STACK_COMM_ERROR:
377 return "OC_STACK_COMM_ERROR";
378 case OC_STACK_INVALID_PARAM:
379 return "OC_STACK_INVALID_PARAM";
380 case OC_STACK_NOTIMPL:
381 return "OC_STACK_NOTIMPL";
382 case OC_STACK_NO_RESOURCE:
383 return "OC_STACK_NO_RESOURCE";
384 case OC_STACK_RESOURCE_ERROR:
385 return "OC_STACK_RESOURCE_ERROR";
386 case OC_STACK_SLOW_RESOURCE:
387 return "OC_STACK_SLOW_RESOURCE";
388 case OC_STACK_NO_OBSERVERS:
389 return "OC_STACK_NO_OBSERVERS";
391 return "OC_STACK_ERROR";