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 ESEnrolleeResourceEventCallback gNetworkInfoProvEventCb = NULL;
63 void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback 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, MAXSSIDLEN, gProvResource.tnn);
81 OICStrcpy(pass, MAXNETCREDLEN, 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 (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
172 OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn);
173 OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn);
175 gProvResource.ps = ES_PS_PROVISIONING_COMPLETED;
179 if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
181 OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd);
182 OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd);
185 OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps);
188 if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_TR, &tr))
191 gProvResource.tr = tr;
194 //ES_PS_PROVISIONING_COMPLETED state indicates that already provisioning is completed.
195 // A new request for provisioning means overriding existing network provisioning information.
196 if (gProvResource.ps == ES_PS_PROVISIONING_COMPLETED && tr == ES_PS_TRIGGER_CONNECTION)
198 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning already completed."
199 "Tiggering the network connection");
201 if (gNetworkInfoProvEventCb)
203 gNetworkInfoProvEventCb(ES_RECVTRIGGEROFPROVRES);
208 gProvResource.tr = ES_PS_TRIGGER_INIT_VALUE;
209 OIC_LOG(ERROR, ES_RH_TAG, "gNetworkInfoProvEventCb is NULL."
210 "Network handler not registered. Failed to connect to the network");
211 ehResult = OC_EH_ERROR;
216 else if (gProvResource.ps == ES_PS_PROVISIONING_COMPLETED)
218 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning already completed. "
219 "This a request to override the existing the network provisioning information");
223 OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning the network information to the Enrollee.");
226 OCRepPayload *getResp = constructResponse(ehRequest);
229 OIC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
239 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest * ehRequest,
240 OCRepPayload** payload)
242 OCEntityHandlerResult ehResult = OC_EH_ERROR;
247 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
249 OCRepPayload* payload = OCRepPayloadCreate();
252 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
256 if (ehRequest->resource == gProvResource.handle)
258 OIC_LOG(INFO, ES_RH_TAG, "constructResponse prov res");
259 OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
260 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS, gProvResource.ps);
261 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, gProvResource.tnt);
263 else if (ehRequest->requestHandle == gNetResource.handle)
266 OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
267 OCRepPayloadSetPropInt(payload, "ant", gNetResource.ant[0]);
273 * This is the entity handler for the registered resource.
274 * This is invoked by OCStack whenever it recevies a request for this resource.
276 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
277 OCEntityHandlerRequest* entityHandlerRequest, void *callback)
280 OCEntityHandlerResult ehRet = OC_EH_OK;
281 OCEntityHandlerResponse response =
282 { 0, 0, OC_EH_ERROR, 0, 0,
285 OCRepPayload* payload = NULL;
287 if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
289 if (OC_REST_GET == entityHandlerRequest->method)
291 OIC_LOG(INFO, ES_RH_TAG, "Received GET request");
292 ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
294 else if (OC_REST_PUT == entityHandlerRequest->method)
296 OIC_LOG(INFO, ES_RH_TAG, "Received PUT request");
298 //PUT request will be handled in the internal implementation
299 if (gProvResource.handle != NULL
300 && entityHandlerRequest->resource == gProvResource.handle)
302 ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
306 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
310 else if (OC_REST_POST == entityHandlerRequest->method)
312 OIC_LOG(INFO, ES_RH_TAG, "Received OC_REST_POST from client");
313 if (gProvResource.handle != NULL
314 && entityHandlerRequest->resource == gProvResource.handle)
316 ehRet = ProcessPostRequest(entityHandlerRequest, &payload);
320 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
325 if (ehRet == OC_EH_OK)
327 // Format the response. Note this requires some info about the request
328 response.requestHandle = entityHandlerRequest->requestHandle;
329 response.resourceHandle = entityHandlerRequest->resource;
330 response.ehResult = ehRet;
331 //response uses OCPaylod while all get,put methodes use OCRepPayload
332 response.payload = (OCPayload*) (payload);
333 response.numSendVendorSpecificHeaderOptions = 0;
334 memset(response.sendVendorSpecificHeaderOptions, 0,
335 sizeof(response.sendVendorSpecificHeaderOptions));
336 memset(response.resourceUri, 0, sizeof(response.resourceUri));
337 // Indicate that response is NOT in a persistent buffer
338 response.persistentBufferFlag = 0;
341 if (OCDoResponse(&response) != OC_STACK_OK)
343 OIC_LOG(ERROR, ES_RH_TAG, "Error sending response");
352 const char *getResult(OCStackResult result)
357 return "OC_STACK_OK";
358 case OC_STACK_INVALID_URI:
359 return "OC_STACK_INVALID_URI";
360 case OC_STACK_INVALID_QUERY:
361 return "OC_STACK_INVALID_QUERY";
362 case OC_STACK_INVALID_IP:
363 return "OC_STACK_INVALID_IP";
364 case OC_STACK_INVALID_PORT:
365 return "OC_STACK_INVALID_PORT";
366 case OC_STACK_INVALID_CALLBACK:
367 return "OC_STACK_INVALID_CALLBACK";
368 case OC_STACK_INVALID_METHOD:
369 return "OC_STACK_INVALID_METHOD";
370 case OC_STACK_NO_MEMORY:
371 return "OC_STACK_NO_MEMORY";
372 case OC_STACK_COMM_ERROR:
373 return "OC_STACK_COMM_ERROR";
374 case OC_STACK_INVALID_PARAM:
375 return "OC_STACK_INVALID_PARAM";
376 case OC_STACK_NOTIMPL:
377 return "OC_STACK_NOTIMPL";
378 case OC_STACK_NO_RESOURCE:
379 return "OC_STACK_NO_RESOURCE";
380 case OC_STACK_RESOURCE_ERROR:
381 return "OC_STACK_RESOURCE_ERROR";
382 case OC_STACK_SLOW_RESOURCE:
383 return "OC_STACK_SLOW_RESOURCE";
384 case OC_STACK_NO_OBSERVERS:
385 return "OC_STACK_NO_OBSERVERS";
387 return "OC_STACK_ERROR";