[Easy Setup] Check required properties for UPDATE
[iotivity.git] / service / easy-setup / enrollee / src / resourcehandler.c
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "resourcehandler.h"
22 #include "internal/es_util.h"
23
24 #include "ocpayload.h"
25 #include "oic_string.h"
26 #include "oic_malloc.h"
27 #include "cautilinterface.h"
28 #include "experimental/payload_logging.h"
29
30 // TODO: Remove this flag and enable the code it guards.
31 // This is a temporary workaround to ignore the failure of OCLinksPayloadArrayCreate
32 // in some cases. This allows the response to still be made, even though links property will be
33 // missing.
34 // Bug: IOT-2762
35 #define ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
36
37 /**
38  * @var ES_RH_TAG
39  * @brief Logging tag for module name.
40  */
41 #define ES_RH_TAG "ES_RH"
42
43 #define EASY_SETUP_RES  0
44 #define WIFI_CONF_RES   1
45 #define CLOUD_CONF_RES  2
46 #define DEV_CONF_RES    3
47
48 /**
49  * @brief  To determine the inclusion/exclusion of resources in batch response.
50  */
51 typedef enum
52 {
53     RES_EXCLUDE = 0,        /**< Indicates the exclusion of the resource **/
54     RES_INCLUDE = 1,        /**< Indicates the inclusion of the resource with its representation**/
55     RES_INCLUDE_EMPTY_REP = 2   /**< Indicates the inclusion of the resource with empty representation **/
56 } ES_BATCH_UPDATE_RESPONSE;
57
58 //-----------------------------------------------------------------------------
59 // Private variables
60 //-----------------------------------------------------------------------------
61
62 /**
63  * @var g_ESEasySetupResource
64  * @brief Structure for holding the Provisioning status
65  */
66 EasySetupResource g_ESEasySetupResource;
67 WiFiConfResource g_ESWiFiConfResource;
68 CoapCloudConfResource g_ESCoapCloudConfResource;
69 DevConfResource g_ESDevConfResource;
70
71 //-----------------------------------------------------------------------------
72 // Private internal function prototypes
73 //-----------------------------------------------------------------------------
74 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest *ehRequest,
75         void *callback);
76 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
77 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
78 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
79 OCEntityHandlerResult updateEasySetupResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input,
80         ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4]);
81 void updateEasySetupConnectProperty(OCRepPayload* input);
82 OCEntityHandlerResult updateWiFiConfResource(OCRepPayload* input);
83 void updateCoapCloudConfResource(OCRepPayload* input);
84 OCEntityHandlerResult updateDevConfResource(OCRepPayload* input);
85 bool isAuthTypeSupported(WIFI_AUTHTYPE authType);
86 bool isEncTypeSupported(WIFI_ENCTYPE encType);
87 const char *getResult(OCStackResult result);
88
89 ESConnectRequestCB gConnectRequestEvtCb = NULL;
90 ESWiFiConfCB gWifiConfRsrcEvtCb = NULL;
91 ESCoapCloudConfCB gCoapCloudConfRsrcEvtCb = NULL;
92 ESDevConfCB gDevConfRsrcEvtCb = NULL;
93
94 ESReadUserdataCb gReadUserdataCb = NULL;
95 ESWriteUserdataCb gWriteUserdataCb = NULL;
96
97 void GetInterfaceNameFromQuery(const char *query, char **iface)
98 {
99     if (!iface)
100     {
101         return;
102     }
103     *iface = NULL;
104     char *str = OICStrdup(query);
105     char *ptr = strtok(str, ";");
106
107     while (ptr)
108     {
109         if (strstr(ptr, ".if."))
110         {
111             char *if_ptr = NULL;
112             if_ptr = strtok(ptr, "=");
113             if_ptr = strtok(NULL, "=");
114
115             *iface = OICStrdup(if_ptr);
116             break;
117         }
118         ptr = strtok(NULL, ";");
119     }
120
121     OICFree(str);
122 }
123
124 bool CompareResourceInterface(const char *from, const char *iface)
125 {
126     char *if_ptr = NULL;
127     GetInterfaceNameFromQuery(from, &if_ptr);
128     if (!if_ptr)
129     {
130         return false;
131     }
132     if (!strcmp(if_ptr, iface))
133     {
134         OICFree(if_ptr);
135         return true;
136     }
137     OICFree(if_ptr);
138
139     return false;
140 }
141
142 ESResult SetCallbackForUserData(ESReadUserdataCb readCb, ESWriteUserdataCb writeCb)
143 {
144     if (!readCb && !writeCb)
145     {
146         OIC_LOG(DEBUG, ES_RH_TAG, "Both of callbacks for user data are null");
147         return ES_ERROR;
148     }
149     gReadUserdataCb = readCb;
150     gWriteUserdataCb = writeCb;
151     return ES_OK;
152 }
153
154 void RegisterWifiRsrcEventCallBack(ESWiFiConfCB cb)
155 {
156     gWifiConfRsrcEvtCb = cb;
157 }
158
159 void RegisterCloudRsrcEventCallBack(ESCoapCloudConfCB cb)
160 {
161     gCoapCloudConfRsrcEvtCb = cb;
162 }
163
164 void RegisterDevConfRsrcEventCallBack(ESDevConfCB cb)
165 {
166     gDevConfRsrcEvtCb = cb;
167 }
168
169 void RegisterConnectRequestEventCallBack(ESConnectRequestCB cb)
170 {
171     gConnectRequestEvtCb = cb;
172 }
173
174 void UnRegisterResourceEventCallBack(void)
175 {
176     if (gWifiConfRsrcEvtCb)
177     {
178         gWifiConfRsrcEvtCb = NULL;
179     }
180     if (gCoapCloudConfRsrcEvtCb)
181     {
182         gCoapCloudConfRsrcEvtCb = NULL;
183     }
184     if (gDevConfRsrcEvtCb)
185     {
186         gDevConfRsrcEvtCb = NULL;
187     }
188     if (gConnectRequestEvtCb)
189     {
190         gConnectRequestEvtCb = NULL;
191     }
192 }
193
194 OCStackResult initEasySetupResource(bool isSecured)
195 {
196     g_ESEasySetupResource.status = ES_STATE_INIT;
197     g_ESEasySetupResource.lastErrCode = ES_ERRCODE_NO_ERROR;
198     for (int i = 0; i < NUM_CONNECT_TYPE; ++i)
199     {
200         g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
201     }
202     g_ESEasySetupResource.numRequest = 0;
203
204     OCStackResult res = OC_STACK_ERROR;
205     if (isSecured)
206     {
207         res = OCCreateResource(&g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_EASYSETUP,
208         OC_RSRVD_INTERFACE_DEFAULT,
209         OC_RSRVD_ES_URI_EASYSETUP, OCEntityHandlerCb,
210         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
211     }
212     else
213     {
214         res = OCCreateResource(&g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_EASYSETUP,
215         OC_RSRVD_INTERFACE_DEFAULT,
216         OC_RSRVD_ES_URI_EASYSETUP, OCEntityHandlerCb,
217         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
218     }
219     if (res != OC_STACK_OK)
220     {
221         OIC_LOG_V(ERROR, ES_RH_TAG, "Created EasySetup resource with result: %s", getResult(res));
222         return res;
223     }
224
225     res = OCBindResourceTypeToResource(g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_COL);
226     if (res != OC_STACK_OK)
227     {
228         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource type with result: %s", getResult(res));
229         return res;
230     }
231
232     res = OCBindResourceInterfaceToResource(g_ESEasySetupResource.handle, OC_RSRVD_INTERFACE_LL);
233     if (res != OC_STACK_OK)
234     {
235         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
236         return res;
237     }
238     res = OCBindResourceInterfaceToResource(g_ESEasySetupResource.handle, OC_RSRVD_INTERFACE_BATCH);
239     if (res != OC_STACK_OK)
240     {
241         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
242         return res;
243     }
244
245     OIC_LOG_V(DEBUG, ES_RH_TAG, "Created EasySetup resource with result: %s", getResult(res));
246     return res;
247 }
248
249 OCStackResult initWiFiConfResource(bool isSecured)
250 {
251     OCStackResult res = OC_STACK_ERROR;
252
253     g_ESWiFiConfResource.supportedFreq[0] = WIFI_24G;
254     g_ESWiFiConfResource.supportedFreq[1] = WIFI_5G;
255     g_ESWiFiConfResource.numSupportedFreq=2;
256     g_ESWiFiConfResource.supportedMode[0] = WIFI_11A;
257     g_ESWiFiConfResource.supportedMode[1] = WIFI_11B;
258     g_ESWiFiConfResource.supportedMode[2] = WIFI_11G;
259     g_ESWiFiConfResource.supportedMode[3] = WIFI_11N;
260     g_ESWiFiConfResource.numMode = 4;
261     g_ESWiFiConfResource.authType = NONE_AUTH;
262     g_ESWiFiConfResource.encType = NONE_ENC;
263     OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), "");
264     OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), "");
265
266     if (isSecured)
267     {
268         res = OCCreateResource(&g_ESWiFiConfResource.handle, OC_RSRVD_ES_RES_TYPE_WIFICONF,
269         OC_RSRVD_INTERFACE_DEFAULT,
270         OC_RSRVD_ES_URI_WIFICONF, OCEntityHandlerCb,
271         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
272     }
273     else
274     {
275         res = OCCreateResource(&g_ESWiFiConfResource.handle, OC_RSRVD_ES_RES_TYPE_WIFICONF,
276         OC_RSRVD_INTERFACE_DEFAULT,
277         OC_RSRVD_ES_URI_WIFICONF, OCEntityHandlerCb,
278         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
279     }
280
281     if (res != OC_STACK_OK)
282     {
283         OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create WiFiConf resource with result: %s",
284             getResult(res));
285         return res;
286     }
287
288     res = OCBindResourceInterfaceToResource(g_ESWiFiConfResource.handle,
289     OC_RSRVD_INTERFACE_READ_WRITE);
290     if (res != OC_STACK_OK)
291     {
292         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
293         return res;
294     }
295
296     OIC_LOG_V(DEBUG, ES_RH_TAG, "Created WiFiConf resource with result: %s", getResult(res));
297     return res;
298
299 }
300
301 OCStackResult initCoapCloudConfResource(bool isSecured)
302 {
303     OCStackResult res = OC_STACK_ERROR;
304
305     OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken),
306             "");
307     OICStrcpy(g_ESCoapCloudConfResource.authProvider,
308             sizeof(g_ESCoapCloudConfResource.authProvider), "");
309     OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), "");
310
311     if (isSecured)
312     {
313         res = OCCreateResource(&g_ESCoapCloudConfResource.handle,
314                 OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
315                 OC_RSRVD_INTERFACE_DEFAULT,
316                 OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
317                 NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
318     }
319     else
320     {
321         res = OCCreateResource(&g_ESCoapCloudConfResource.handle,
322                 OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
323                 OC_RSRVD_INTERFACE_DEFAULT,
324                 OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
325                 NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
326     }
327
328     if (res != OC_STACK_OK)
329     {
330         OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create CoapCloudConf resource with result: %s",
331             getResult(res));
332         return res;
333     }
334
335     res = OCBindResourceInterfaceToResource(g_ESCoapCloudConfResource.handle,
336             OC_RSRVD_INTERFACE_READ_WRITE);
337     if (res != OC_STACK_OK)
338     {
339         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
340         return res;
341     }
342
343     OIC_LOG_V(DEBUG, ES_RH_TAG, "Created CoapCloudConf resource with result: %s", getResult(res));
344     return res;
345 }
346
347 OCStackResult initDevConfResource(bool isSecured)
348 {
349     OCStackResult res = OC_STACK_ERROR;
350
351     OICStrcpy(g_ESDevConfResource.devName, sizeof(g_ESDevConfResource.devName), "");
352
353     if (isSecured)
354     {
355         res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
356         OC_RSRVD_INTERFACE_DEFAULT,
357         OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
358         NULL, OC_DISCOVERABLE | OC_SECURE);
359     }
360     else
361     {
362         res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
363         OC_RSRVD_INTERFACE_DEFAULT,
364         OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
365         NULL, OC_DISCOVERABLE);
366     }
367
368     if (res != OC_STACK_OK)
369     {
370         OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create DevConf resource with result: %s",
371             getResult(res));
372         return res;
373     }
374
375     res = OCBindResourceInterfaceToResource(g_ESDevConfResource.handle, OC_RSRVD_INTERFACE_READ);
376     if (res != OC_STACK_OK)
377     {
378         OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
379         return res;
380     }
381
382     OIC_LOG_V(DEBUG, ES_RH_TAG, "Created DevConf resource with result: %s", getResult(res));
383     return res;
384
385 }
386
387 OCEntityHandlerResult updateEasySetupResource(OCEntityHandlerRequest* ehRequest,
388     OCRepPayload* input, ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4])
389 {
390     OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.status %d", g_ESEasySetupResource.status);
391
392     char *iface_name = NULL;
393     GetInterfaceNameFromQuery(ehRequest->query, &iface_name);
394     if (!iface_name)
395     {
396         iface_name = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
397         if(NULL == iface_name)
398         {
399             OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to duplicate string.");
400             return OC_EH_INTERNAL_SERVER_ERROR;
401         }
402     }
403
404     OCEntityHandlerResult ehResult = OC_EH_OK;
405
406     if (!strcmp(iface_name, OC_RSRVD_INTERFACE_BATCH))
407     {
408         batch_update_rsrc_arr[EASY_SETUP_RES] = RES_EXCLUDE;
409         batch_update_rsrc_arr[WIFI_CONF_RES] = RES_EXCLUDE;
410         batch_update_rsrc_arr[CLOUD_CONF_RES] = RES_EXCLUDE;
411         batch_update_rsrc_arr[DEV_CONF_RES] = RES_EXCLUDE;
412
413         bool hasError = false;
414         // When Provisioning resource has a POST with BatchInterface
415         // Parsing POST request on Batch Interface cosidering same format as GET using batch.
416         OCRepPayload *children = input;
417         while(children)
418         {
419             char* uri = children->uri;
420             if (NULL == uri)
421             {
422                 OIC_LOG(DEBUG, ES_RH_TAG, "No URI found in request");
423             }
424             else
425             {
426                 OIC_LOG_V(DEBUG, ES_RH_TAG, "Request URI [%s]", uri);
427             }
428
429             OCRepPayload *repPayload = NULL;
430             OCRepPayloadGetPropObject(children, OC_RSRVD_REPRESENTATION, &repPayload);
431             if (NULL == repPayload)
432             {
433                 OIC_LOG(ERROR, ES_RH_TAG, "repPayload is null!");
434                 children = children->next;
435                 continue;
436             }
437
438             // If uri is NULL, rep is applied to all resources in collection;
439             // otherwise its applied to specific target resources.
440             if (NULL == uri || 0 == strlen(uri) || 0 == strcmp(uri, OC_RSRVD_ES_URI_EASYSETUP))
441             {
442                 // If payload has read-only properties, then the request is considered as a bad request.
443                 if (!OCRepPayloadIsNull(children, OC_RSRVD_ES_PROVSTATUS) ||
444                     !OCRepPayloadIsNull(children, OC_RSRVD_ES_LAST_ERRORCODE))
445                 {
446                     OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
447                     // "rep" field of EasySetup resource in the response will be empty.
448                     batch_update_rsrc_arr[EASY_SETUP_RES] = RES_INCLUDE_EMPTY_REP;
449                     hasError = true;
450                 }
451                 else
452                 {
453                     updateEasySetupConnectProperty(repPayload);
454                     batch_update_rsrc_arr[EASY_SETUP_RES] = RES_INCLUDE;
455                 }
456             }
457
458             if (NULL == uri || 0 == strlen(uri)
459                 || 0 == strcmp(uri, OC_RSRVD_ES_URI_WIFICONF))
460             {
461                 if (updateWiFiConfResource(repPayload) != OC_EH_OK)
462                 {
463                     OIC_LOG(ERROR, ES_RH_TAG, "Failed to update WiFiConf resource.");
464                     hasError = true;
465                     // As there is a problem in updating the WiFiConf resource,
466                     // corresponding "rep" field in the response will be empty.
467                     batch_update_rsrc_arr[WIFI_CONF_RES] = RES_INCLUDE_EMPTY_REP;
468                 }
469                 else
470                 {
471                     batch_update_rsrc_arr[WIFI_CONF_RES] = RES_INCLUDE;
472                 }
473             }
474
475             if (NULL == uri ||  0 == strlen(uri)
476                 || 0 == strcmp(uri, OC_RSRVD_ES_URI_COAPCLOUDCONF))
477             {
478                 updateCoapCloudConfResource(repPayload);
479                 batch_update_rsrc_arr[CLOUD_CONF_RES] = RES_INCLUDE;
480             }
481
482             if (NULL == uri ||  0 == strlen(uri)
483                 || 0 == strcmp(uri, OC_RSRVD_ES_URI_DEVCONF))
484             {
485                 if (updateDevConfResource(repPayload) != OC_EH_OK)
486                 {
487                     OIC_LOG(ERROR, ES_RH_TAG, "Failed to update DevConf resource.");
488                     hasError = true;
489                     // As there is a problem in updating the DevConf resource,
490                     // corresponding "rep" field in the response will be empty.
491                     batch_update_rsrc_arr[DEV_CONF_RES] = RES_INCLUDE_EMPTY_REP;
492                 }
493                 else
494                 {
495                     batch_update_rsrc_arr[DEV_CONF_RES] = RES_INCLUDE;
496                 }
497             }
498
499             children = children->next;
500             OCRepPayloadDestroy(repPayload);
501         }
502
503         if (hasError)
504         {
505            ehResult = OC_EH_BAD_REQ;
506         }
507     }
508     else if (!strcmp(iface_name, OC_RSRVD_INTERFACE_DEFAULT))
509     {
510         OIC_LOG(DEBUG, ES_RH_TAG, "Handling POST request on default interface");
511         // If payload has read-only properties, then the request is considered as a bad request.
512         if (!OCRepPayloadIsNull(input, OC_RSRVD_ES_PROVSTATUS) ||
513             !OCRepPayloadIsNull(input, OC_RSRVD_ES_LAST_ERRORCODE))
514         {
515             OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
516             ehResult = OC_EH_BAD_REQ;
517         }
518         else
519         {
520             updateEasySetupConnectProperty(input);
521         }
522     }
523
524     OICFree(iface_name);
525
526     OIC_LOG(DEBUG, ES_RH_TAG, "updateEasySetupResource exit");
527     return ehResult;
528 }
529
530 void updateEasySetupConnectProperty(OCRepPayload* input)
531 {
532     int64_t *connect_req = NULL;
533     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
534     if (OCRepPayloadGetIntArray(input, OC_RSRVD_ES_CONNECT, &connect_req, dimensions))
535     {
536         ESConnectRequest* connectRequest = (ESConnectRequest*)OICMalloc(sizeof(ESConnectRequest));
537         if (!connectRequest)
538         {
539             OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
540             return;
541         }
542
543         int cntRequest = 0;
544         for (unsigned int i = 0 ; i < NUM_CONNECT_TYPE ; ++i)
545         {
546             g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
547             connectRequest->connect[i] = ES_CONNECT_NONE;
548
549             if (i < dimensions[0] && connect_req[i] >= ES_CONNECT_NONE)
550             {
551                 g_ESEasySetupResource.connectRequest[cntRequest] = connect_req[i];
552                 connectRequest->connect[cntRequest] = connect_req[i];
553                 OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.connectType[%d] : %d",
554                                                     cntRequest, g_ESEasySetupResource.connectRequest[cntRequest]);
555                 cntRequest++;
556             }
557         }
558         connectRequest->numRequest = cntRequest;
559         g_ESEasySetupResource.numRequest = cntRequest;
560
561         if (g_ESEasySetupResource.connectRequest[0] != ES_CONNECT_NONE)
562         {
563             OIC_LOG(DEBUG, ES_RH_TAG, "Send ConnectRequest Callback To ES");
564
565             //@todo Need to check appropriateness of gWiFiData
566             if (gConnectRequestEvtCb != NULL)
567             {
568                 gConnectRequestEvtCb(ES_OK, connectRequest);
569             }
570             else
571             {
572                 OIC_LOG(ERROR, ES_RH_TAG, "gConnectRequestEvtCb is NULL");
573             }
574         }
575     }
576 }
577
578 OCEntityHandlerResult updateWiFiConfResource(OCRepPayload* input)
579 {
580     // If payload has read-only properties, then the request is considered as a bad request.
581     if (!OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIMODE) ||
582         !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIFREQ) ||
583         !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE) ||
584         !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE))
585     {
586         OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
587         return OC_EH_BAD_REQ;
588     }
589
590     // If payload does not contain all required properties, then the request is
591     // considered as a bad request.
592     if (OCRepPayloadIsNull(input, OC_RSRVD_ES_SSID) ||
593         OCRepPayloadIsNull(input, OC_RSRVD_ES_AUTHTYPE) ||
594         OCRepPayloadIsNull(input, OC_RSRVD_ES_ENCTYPE))
595     {
596         OIC_LOG(ERROR, ES_RH_TAG, "Required property for Update is missing!");
597         return OC_EH_BAD_REQ;
598     }
599
600     OCEntityHandlerResult ehResult = OC_EH_ERROR;
601     ESWiFiConfData* wiFiData = (ESWiFiConfData*) OICMalloc(sizeof(ESWiFiConfData));
602     if (wiFiData == NULL)
603     {
604         OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
605         return ehResult;
606     }
607
608     char* ssid = NULL;
609     char* cred = NULL;
610     char *authType = NULL;
611     char *encType = NULL;
612     memset(wiFiData->ssid, 0, OIC_STRING_MAX_VALUE);
613     memset(wiFiData->pwd, 0, OIC_STRING_MAX_VALUE);
614     wiFiData->authtype = NONE_AUTH;
615     wiFiData->enctype = NONE_AUTH;
616     wiFiData->userdata = NULL;
617
618     bool validAuthType = false;
619     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHTYPE, &authType))
620     {
621         WIFI_AUTHTYPE tmp;
622         validAuthType = WiFiAuthTypeStringToEnum(authType, &tmp);
623         if (validAuthType && isAuthTypeSupported(tmp))
624         {
625             wiFiData->authtype = tmp;
626             OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.authType %u",
627                     wiFiData->authtype);
628         }
629         else
630         {
631             OIC_LOG(ERROR, ES_RH_TAG, "AuthType is not supported.");
632             ehResult = OC_EH_BAD_REQ;
633             goto EXIT;
634         }
635     }
636
637     bool validEncType = false;
638     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ENCTYPE, &encType))
639     {
640         WIFI_ENCTYPE tmp;
641         validEncType = WiFiEncTypeStringToEnum(encType, &tmp);
642         if (validEncType && isEncTypeSupported(tmp))
643         {
644             wiFiData->enctype = tmp;
645             OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.encType %u",
646                     wiFiData->enctype);
647         }
648         else
649         {
650             OIC_LOG(ERROR, ES_RH_TAG, "EncType is not supported.");
651             ehResult = OC_EH_BAD_REQ;
652             goto EXIT;
653         }
654     }
655
656     if (validAuthType)
657     {
658         g_ESWiFiConfResource.authType = wiFiData->authtype;
659     }
660
661     if (validEncType)
662     {
663         g_ESWiFiConfResource.encType = wiFiData->enctype;
664     }
665
666     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_SSID, &ssid))
667     {
668         OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), ssid);
669         OICStrcpy(wiFiData->ssid, sizeof(wiFiData->ssid), ssid);
670         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.ssid : %s",
671                 g_ESWiFiConfResource.ssid);
672     }
673
674     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CRED, &cred))
675     {
676         OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), cred);
677         OICStrcpy(wiFiData->pwd, sizeof(wiFiData->pwd), cred);
678         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.cred %s",
679                 g_ESWiFiConfResource.cred);
680     }
681
682     if (gReadUserdataCb)
683     {
684         gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_WIFICONF, &wiFiData->userdata);
685     }
686
687     if (ssid || cred || validAuthType || validEncType)
688     {
689         OIC_LOG(DEBUG, ES_RH_TAG, "Send WiFiConfRsrc Callback To ES");
690
691         //@todo Need to check appropriateness of gWiFiData
692         if (gWifiConfRsrcEvtCb != NULL)
693         {
694             gWifiConfRsrcEvtCb(ES_OK, wiFiData);
695         }
696         else
697         {
698             OIC_LOG(ERROR, ES_RH_TAG, "gWifiConfRsrcEvtCb is NULL");
699         }
700     }
701
702     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESWiFiConfResource.handle, OC_HIGH_QOS))
703     {
704         OIC_LOG(DEBUG, ES_RH_TAG, "WiFiConf resource doesn't have any observer.");
705     }
706
707     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
708     {
709         OIC_LOG(DEBUG, ES_RH_TAG, "EasySetup resource doesn't have any observer.");
710     }
711
712     ehResult = OC_EH_OK;
713
714 EXIT:
715     OICFree(encType);
716     OICFree(authType);
717     OICFree(cred);
718     OICFree(ssid);
719     OICFree(wiFiData);
720     return ehResult;
721 }
722
723 void updateCoapCloudConfResource(OCRepPayload* input)
724 {
725     ESCoapCloudConfData* cloudData = (ESCoapCloudConfData*)OICMalloc(sizeof(ESCoapCloudConfData));
726
727     if (cloudData == NULL)
728     {
729         OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
730         return;
731     }
732
733     memset(cloudData->accessToken, 0, OIC_STRING_MAX_VALUE);
734     cloudData->accessTokenType = NONE_OAUTH_TOKENTYPE;
735     memset(cloudData->authProvider, 0, OIC_STRING_MAX_VALUE);
736     memset(cloudData->ciServer, 0, OIC_URI_STRING_MAX_VALUE);
737     cloudData->userdata = NULL;
738
739
740     // As per OCF 1.4 Spec, Access Token Type property in not supported in CoAPCloudConf Resource.
741     // Hence, setting Token Type as "Bearer" by default.
742     g_ESCoapCloudConfResource.accessTokenType = OAUTH_TOKENTYPE_BEARER;
743
744     char *accessToken = NULL;
745     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ACCESSTOKEN, &accessToken))
746     {
747         OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken), accessToken);
748         OICStrcpy(cloudData->accessToken, sizeof(cloudData->accessToken), accessToken);
749         cloudData->accessTokenType = g_ESCoapCloudConfResource.accessTokenType;
750         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.accessToken %s", g_ESCoapCloudConfResource.accessToken);
751     }
752
753     char *authProvider = NULL;
754     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHPROVIDER, &authProvider))
755     {
756         OICStrcpy(g_ESCoapCloudConfResource.authProvider, sizeof(g_ESCoapCloudConfResource.authProvider), authProvider);
757         OICStrcpy(cloudData->authProvider, sizeof(cloudData->authProvider), authProvider);
758         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.authServerUrl %s", g_ESCoapCloudConfResource.authProvider);
759     }
760
761     char *ciServer = NULL;
762     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CISERVER, &ciServer))
763     {
764         OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), ciServer);
765         OICStrcpy(cloudData->ciServer, sizeof(cloudData->ciServer), ciServer);
766         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.ciServer %s", g_ESCoapCloudConfResource.ciServer);
767     }
768
769     if (gReadUserdataCb)
770     {
771         gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF, &cloudData->userdata);
772     }
773
774     if (accessToken || authProvider || ciServer)
775     {
776         OIC_LOG(DEBUG, ES_RH_TAG, "Send CoapCloudConfRsrc Callback To ES");
777
778         //@todo Need to check appropriateness of gCloudData
779         if (gCoapCloudConfRsrcEvtCb != NULL)
780         {
781             gCoapCloudConfRsrcEvtCb(ES_OK, cloudData);
782         }
783         else
784         {
785             OIC_LOG(DEBUG, ES_RH_TAG, "gCoapCloudConfRsrcEvtCb is NULL");
786         }
787     }
788
789     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESCoapCloudConfResource.handle, OC_HIGH_QOS))
790     {
791         OIC_LOG(DEBUG, ES_RH_TAG, "CoapCloudConf resource doesn't have any observer.");
792     }
793
794     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
795     {
796         OIC_LOG(DEBUG, ES_RH_TAG, "EasySetup resource doesn't have any observer.");
797     }
798
799     OICFree(cloudData);
800 }
801
802 OCEntityHandlerResult updateDevConfResource(OCRepPayload* input)
803 {
804     ESDevConfData* devConfData = (ESDevConfData*)OICMalloc(sizeof(ESDevConfData));
805
806     if (devConfData == NULL)
807     {
808         OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
809         return OC_EH_ERROR;
810     }
811     devConfData->userdata = NULL;
812
813     if (gReadUserdataCb)
814     {
815         gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_DEVCONF, &devConfData->userdata);
816     }
817
818     // If a writable property in oic.r.devconf is added later,
819     // a condition for calling a resistered callback should be implemented also.
820     if (devConfData->userdata != NULL)
821     {
822         OIC_LOG(DEBUG, ES_RH_TAG, "Send DevConfRsrc Callback To ES");
823
824         //@todo : Need to check appropriateness of gDevConfData
825         if (gDevConfRsrcEvtCb != NULL)
826         {
827             gDevConfRsrcEvtCb(ES_OK, devConfData);
828         }
829         else
830         {
831             OIC_LOG(DEBUG, ES_RH_TAG, "gDevConfRsrcEvtCb is NULL");
832         }
833     }
834
835     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESDevConfResource.handle, OC_HIGH_QOS))
836     {
837         OIC_LOG(DEBUG, ES_RH_TAG, "devConfResource doesn't have any observer.");
838     }
839
840     OICFree(devConfData);
841     return OC_EH_OK;
842 }
843
844 OCRepPayload* constructResponseOfWiFiConf(char *interface, ES_BATCH_UPDATE_RESPONSE resp)
845 {
846     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH) && RES_EXCLUDE == resp)
847     {
848         OIC_LOG(DEBUG, ES_RH_TAG, "Excluding WiFiConf resource from the batch response.");
849         return NULL;
850     }
851
852     OCRepPayload* payload = OCRepPayloadCreate();
853     if (!payload)
854     {
855         OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
856         return NULL;
857     }
858
859     if (g_ESWiFiConfResource.handle == NULL)
860     {
861         OIC_LOG(ERROR, ES_RH_TAG, "WiFiConf resource is not created");
862         return NULL;
863     }
864
865     OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse WiFiConf res");
866
867     OCRepPayload* repPayload = NULL;
868     OCRepPayload* tempPayload = NULL;
869     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
870     {
871         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_WIFICONF);
872
873         repPayload = OCRepPayloadCreate();
874         if (!repPayload)
875         {
876             OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
877             return NULL;
878         }
879
880         tempPayload = payload;
881         payload = repPayload;
882
883         if (RES_INCLUDE == resp)
884         {
885             size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {2, 0, 0};
886             char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
887             if (!interfaces)
888             {
889                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
890                 return NULL;
891             }
892
893             interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
894             interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ_WRITE);
895
896             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
897
898             size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
899             char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
900             if (!resourceTypes)
901             {
902                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
903                 return NULL;
904             }
905
906             resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFICONF);
907
908             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
909         }
910     }
911     else
912     {
913         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
914         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_READ_WRITE);
915         OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_WIFICONF);
916     }
917
918     if (RES_INCLUDE == resp)
919     {
920         // Do not add Read Only Properties when using OC_RSRVD_INTERFACE_READ_WRITE
921         if (strcmp(interface, OC_RSRVD_INTERFACE_READ_WRITE) != 0)
922         {
923             size_t dimensionsModes[MAX_REP_ARRAY_DEPTH] = { g_ESWiFiConfResource.numMode, 0, 0 };
924             const char *modes[NUM_WIFIMODE] = { 0, };
925             for (int i = 0; i < g_ESWiFiConfResource.numMode; ++i)
926             {
927                 modes[i] = WiFiModeEnumToString(g_ESWiFiConfResource.supportedMode[i]);
928             }
929             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIMODE, &modes[0],
930                     dimensionsModes);
931
932             size_t dimensionsFreq[MAX_REP_ARRAY_DEPTH] = { g_ESWiFiConfResource.numSupportedFreq, 0, 0 };
933             const char *freq[NUM_WIFIFREQ] = { 0, };
934             for (int i = 0; i < g_ESWiFiConfResource.numSupportedFreq; ++i)
935             {
936                 freq[i] = WiFiFreqEnumToString(g_ESWiFiConfResource.supportedFreq[i]);
937             }
938             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIFREQ, freq, dimensionsFreq);
939
940             size_t dimensionsAuthType[MAX_REP_ARRAY_DEPTH] = { g_ESWiFiConfResource.numSupportedAuthType, 0,
941                     0 };
942             const char *authType[NUM_WIFIAUTHTYPE] = { 0, };
943             for (int i = 0; i < g_ESWiFiConfResource.numSupportedAuthType; ++i)
944             {
945                 authType[i] = WiFiAuthTypeEnumToString(g_ESWiFiConfResource.supportedAuthType[i]);
946             }
947             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE, authType,
948                     dimensionsAuthType);
949
950             size_t dimensionsEncType[MAX_REP_ARRAY_DEPTH] =
951                     { g_ESWiFiConfResource.numSupportedEncType, 0, 0 };
952             const char *encType[NUM_WIFIENCTYPE] = { 0, };
953             for (int i = 0; i < g_ESWiFiConfResource.numSupportedEncType; ++i)
954             {
955                 encType[i] = WiFiEncTypeEnumToString(g_ESWiFiConfResource.supportedEncType[i]);
956             }
957             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE, encType,
958                     dimensionsEncType);
959         }
960
961         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_SSID, g_ESWiFiConfResource.ssid);
962         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CRED, g_ESWiFiConfResource.cred);
963         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHTYPE,
964                 WiFiAuthTypeEnumToString(g_ESWiFiConfResource.authType));
965         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_ENCTYPE,
966                 WiFiEncTypeEnumToString(g_ESWiFiConfResource.encType));
967
968         if (gWriteUserdataCb)
969         {
970             gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_WIFICONF);
971         }
972     }
973     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
974     {
975         payload = tempPayload;
976         OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
977     }
978
979     return payload;
980 }
981
982 OCRepPayload* constructResponseOfCoapCloudConf(char *interface, ES_BATCH_UPDATE_RESPONSE resp)
983 {
984     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH) && RES_EXCLUDE == resp)
985     {
986         OIC_LOG(DEBUG, ES_RH_TAG, "Excluding CoapCloudConf resource from the batch response.");
987         return NULL;
988     }
989
990     OCRepPayload* payload = OCRepPayloadCreate();
991     if (!payload)
992     {
993         OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
994         return NULL;
995     }
996
997     if (g_ESCoapCloudConfResource.handle == NULL)
998     {
999         OIC_LOG(ERROR, ES_RH_TAG, "CoapCloudConf resource is not created");
1000         return NULL;
1001     }
1002
1003     OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse CoapCloudConf res");
1004
1005     OCRepPayload* repPayload = NULL;
1006     OCRepPayload* tempPayload = NULL;
1007     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
1008     {
1009         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_COAPCLOUDCONF);
1010
1011         repPayload = OCRepPayloadCreate();
1012         if (!repPayload)
1013         {
1014             OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1015             return NULL;
1016         }
1017
1018         tempPayload = payload;
1019         payload = repPayload;
1020
1021         if (RES_INCLUDE == resp)
1022         {
1023             size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {2, 0, 0};
1024             char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
1025             if (!interfaces)
1026             {
1027                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1028                 return NULL;
1029             }
1030
1031             interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1032             interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ_WRITE);
1033
1034             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
1035
1036             size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
1037             char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
1038             if (!resourceTypes)
1039             {
1040                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1041                 return NULL;
1042             }
1043
1044             resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
1045
1046             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
1047         }
1048     }
1049     else
1050     {
1051         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
1052         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_READ_WRITE);
1053         OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
1054     }
1055
1056     if (RES_INCLUDE == resp)
1057     {
1058         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_ACCESSTOKEN, g_ESCoapCloudConfResource.accessToken);
1059         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, g_ESCoapCloudConfResource.authProvider);
1060         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, g_ESCoapCloudConfResource.ciServer);
1061
1062         if (gWriteUserdataCb)
1063         {
1064             gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
1065         }
1066     }
1067
1068     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
1069     {
1070         payload = tempPayload;
1071         OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
1072     }
1073
1074     return payload;
1075 }
1076
1077 OCRepPayload* constructResponseOfDevConf(char *interface, ES_BATCH_UPDATE_RESPONSE resp)
1078 {
1079     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH) && RES_EXCLUDE == resp)
1080     {
1081         OIC_LOG(DEBUG, ES_RH_TAG, "Excluding DevConf resource from the batch response.");
1082         return NULL;
1083     }
1084
1085     OCRepPayload* payload = OCRepPayloadCreate();
1086     if (!payload)
1087     {
1088         OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1089         return NULL;
1090     }
1091
1092     if (g_ESDevConfResource.handle == NULL)
1093     {
1094         OIC_LOG(ERROR, ES_RH_TAG, "DevConf resource is not created");
1095         return NULL;
1096     }
1097
1098     OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse DevConf res");
1099
1100     OCRepPayload* repPayload = NULL;
1101     OCRepPayload* tempPayload = NULL;
1102     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
1103     {
1104         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_DEVCONF);
1105
1106         repPayload = OCRepPayloadCreate();
1107         if (!repPayload)
1108         {
1109             OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1110             return NULL;
1111         }
1112
1113         tempPayload = payload;
1114         payload = repPayload;
1115
1116         if (RES_INCLUDE == resp)
1117         {
1118             size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {2, 0, 0};
1119             char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
1120             if (!interfaces)
1121             {
1122                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1123                 return NULL;
1124             }
1125
1126             interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1127             interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1128
1129             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
1130
1131             size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
1132             char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
1133             if (!resourceTypes)
1134             {
1135                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1136                 return NULL;
1137             }
1138
1139             resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_DEVCONF);
1140
1141             OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
1142         }
1143     }
1144     else
1145     {
1146         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
1147         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_READ);
1148         OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_DEVCONF);
1149     }
1150
1151     if (RES_INCLUDE == resp)
1152     {
1153         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_DEVNAME, g_ESDevConfResource.devName);
1154
1155         if (gWriteUserdataCb)
1156         {
1157             gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_DEVCONF);
1158         }
1159     }
1160
1161     if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
1162     {
1163         payload = tempPayload;
1164         OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
1165     }
1166
1167     return payload;
1168 }
1169
1170 OCRepPayload* constructResponseOfEasySetup(OCEntityHandlerRequest *ehRequest,
1171         ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4])
1172 {
1173     OCRepPayload* payload = OCRepPayloadCreate();
1174     if (!payload)
1175     {
1176         OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1177         return NULL;
1178     }
1179
1180     OIC_LOG_V(DEBUG, ES_RH_TAG, "constructResponseOfEasySetup: qry = %s",
1181             (ehRequest->query) ? (ehRequest->query) : "null");
1182
1183     // Requested interface is Link list or baseline interface
1184      if (!ehRequest->query ||
1185          (ehRequest->query && !strcmp(ehRequest->query, "")) ||
1186          (ehRequest->query && CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_LL)) ||
1187          (ehRequest->query && CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_DEFAULT)))
1188      {
1189         size_t arraySize;
1190         OCRepPayload **linkArr = OCLinksPayloadArrayCreate(OC_RSRVD_ES_URI_EASYSETUP, ehRequest,
1191             true, &arraySize);
1192
1193 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1194         bool linkArrConstructed = true; // TODO: Remove this when
1195                                         // ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE is removed.
1196 #endif
1197
1198         if (!linkArr || (arraySize == 0))
1199         {
1200             OIC_LOG(ERROR, ES_RH_TAG, "Failed to create Easy Setup collections ll response.");
1201
1202 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1203             linkArrConstructed = false;
1204 #else
1205             OICFree(linkArr);
1206             OCRepPayloadDestroy(payload);
1207             return NULL;
1208 #endif
1209         }
1210 #ifndef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1211         else
1212         {
1213 #endif
1214             OIC_LOG(DEBUG, ES_RH_TAG, "Constructed links payload.");
1215
1216             if (!ehRequest->query || (ehRequest->query && !strcmp(ehRequest->query, ""))
1217                     || (ehRequest->query
1218                             && CompareResourceInterface(ehRequest->query,
1219                                     OC_RSRVD_INTERFACE_DEFAULT)))
1220             {
1221                 OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse EasySetup res (Default interface)");
1222                 OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
1223                 OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_LL);
1224                 OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_BATCH);
1225                 OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
1226                 OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_COL);
1227
1228                 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PROVSTATUS,
1229                         g_ESEasySetupResource.status);
1230                 OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_LAST_ERRORCODE,
1231                         g_ESEasySetupResource.lastErrCode);
1232
1233                 if (g_ESEasySetupResource.numRequest > 0)
1234                 {
1235                     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { g_ESEasySetupResource.numRequest, 0,
1236                             0 };
1237                     int64_t *connectRequest = (int64_t *) OICMalloc(
1238                             g_ESEasySetupResource.numRequest * sizeof(int64_t));
1239                     if (!connectRequest)
1240                     {
1241                         OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1242                         return NULL;
1243                     }
1244
1245                     for (int i = 0; i < g_ESEasySetupResource.numRequest; ++i)
1246                     {
1247                         connectRequest[i] = g_ESEasySetupResource.connectRequest[i];
1248                     }
1249
1250                     bool b = OCRepPayloadSetIntArrayAsOwner(payload, OC_RSRVD_ES_CONNECT,
1251                             (int64_t *) connectRequest, dimensions);
1252                     if (!b)
1253                     {
1254                         OIC_LOG(ERROR, ES_RH_TAG, "Failed to set array value for Connect property");
1255                         OICFree(connectRequest);
1256                     }
1257                 }
1258                 else
1259                 {
1260                     OIC_LOG(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.numRequest is 0");
1261                     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
1262                     OCRepPayloadSetIntArrayAsOwner(payload, OC_RSRVD_ES_CONNECT, NULL, dimensions);
1263                 }
1264
1265                 if (gWriteUserdataCb)
1266                 {
1267                     gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
1268                 }
1269
1270 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1271                 if (linkArrConstructed)
1272                 {
1273 #endif
1274                     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { arraySize, 0, 0 };
1275                     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_LINKS,
1276                             (const OCRepPayload **) linkArr, dimensions);
1277                     for (size_t i = 0; i < arraySize; ++i)
1278                     {
1279                         OCRepPayloadDestroy(linkArr[i]);
1280                     }
1281 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1282                 }
1283 #endif
1284             }
1285             else // link list interface
1286             {
1287 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1288                 if (linkArrConstructed)
1289                 {
1290 #endif
1291                     uint16_t acceptVersion = 0;
1292                     OCPayloadFormat contentFormat; // not used
1293                     OCGetRequestPayloadVersion(ehRequest, &contentFormat, &acceptVersion);
1294                     // acceptVersion("OCF-Accept-Content-Format-Version") is present for OCF Request
1295                     if (acceptVersion != 0)
1296                     {
1297                         for (size_t i = 0; i < arraySize - 1; ++i)
1298                         {
1299                             linkArr[i]->next = linkArr[i + 1];
1300                         }
1301                         // payload is directly the linkArr array, free earlier allocated memory.
1302                         OCRepPayloadDestroy(payload);
1303                         payload = linkArr[0];
1304                     }
1305                     else // for backward compatibility with OIC
1306                     {
1307                         size_t dimensions[MAX_REP_ARRAY_DEPTH] = { arraySize, 0, 0 };
1308                         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_LINKS,
1309                                 (const OCRepPayload **) linkArr, dimensions);
1310                         for (size_t i = 0; i < arraySize; ++i)
1311                         {
1312                             OCRepPayloadDestroy(linkArr[i]);
1313                         }
1314                     }
1315 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1316                 }
1317 #endif
1318             }
1319 #ifndef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
1320         }
1321 #endif
1322         OICFree(linkArr);
1323     }
1324     else if (ehRequest->query
1325             && CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_BATCH))
1326     {
1327         OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse EasySetup res (Batch Interface)");
1328         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_EASYSETUP);
1329
1330         OCRepPayload* repPayload = OCRepPayloadCreate();
1331         if (!repPayload)
1332         {
1333             OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1334             return NULL;
1335         }
1336
1337         if (batch_update_rsrc_arr[EASY_SETUP_RES] == RES_INCLUDE)
1338         {
1339             size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0 };
1340             char **interfaces = (char **) OICMalloc(3 * sizeof(char*));
1341             if (!interfaces)
1342             {
1343                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1344                 return NULL;
1345             }
1346
1347             interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1348             interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_LL);
1349             interfaces[2] = OICStrdup(OC_RSRVD_INTERFACE_BATCH);
1350
1351             OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_INTERFACE, (const char **) interfaces,
1352                     interfacesDimensions);
1353
1354             size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = { 2, 0, 0 };
1355             char **resourceTypes = (char **) OICMalloc(2 * sizeof(char*));
1356             if (!resourceTypes)
1357             {
1358                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1359                 return NULL;
1360             }
1361
1362             resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_EASYSETUP);
1363             resourceTypes[1] = OICStrdup(OC_RSRVD_ES_RES_TYPE_COL);
1364
1365             OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_RES_TYPE, (const char **) resourceTypes,
1366                     resourceTypesDimensions);
1367
1368             OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_PROVSTATUS, g_ESEasySetupResource.status);
1369             OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_LAST_ERRORCODE,
1370                     g_ESEasySetupResource.lastErrCode);
1371             if (g_ESEasySetupResource.numRequest > 0)
1372             {
1373                 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { g_ESEasySetupResource.numRequest, 0, 0 };
1374                 int64_t *connectRequest = (int64_t *) OICMalloc(
1375                         g_ESEasySetupResource.numRequest * sizeof(int64_t));
1376                 if (!connectRequest)
1377                 {
1378                     OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
1379                     return NULL;
1380                 }
1381
1382                 for (int i = 0; i < g_ESEasySetupResource.numRequest; ++i)
1383                 {
1384                     connectRequest[i] = g_ESEasySetupResource.connectRequest[i];
1385                 }
1386
1387                 bool b = OCRepPayloadSetIntArrayAsOwner(repPayload, OC_RSRVD_ES_CONNECT,
1388                         (int64_t *) connectRequest, dimensions);
1389                 if (!b)
1390                 {
1391                     OIC_LOG(ERROR, ES_RH_TAG, "Failed to set array value for Connect property");
1392                     OICFree(connectRequest);
1393                 }
1394             }
1395             else
1396             {
1397                 OIC_LOG(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.numRequest is 0");
1398                 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0, 0, 0 };
1399                 OCRepPayloadSetIntArrayAsOwner(repPayload, OC_RSRVD_ES_CONNECT, NULL, dimensions);
1400             }
1401
1402             if (gWriteUserdataCb)
1403             {
1404                 gWriteUserdataCb(repPayload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
1405             }
1406         }
1407
1408         OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
1409
1410         OCRepPayload* head = payload;
1411         OCRepPayload* nextPayload = NULL;
1412
1413         nextPayload = constructResponseOfWiFiConf(OC_RSRVD_INTERFACE_BATCH,
1414                 batch_update_rsrc_arr[WIFI_CONF_RES]);
1415         if (nextPayload != NULL)
1416         {
1417             payload->next = nextPayload;
1418             payload = payload->next;
1419         }
1420
1421         nextPayload = constructResponseOfCoapCloudConf(OC_RSRVD_INTERFACE_BATCH,
1422                 batch_update_rsrc_arr[CLOUD_CONF_RES]);
1423         if (nextPayload != NULL)
1424         {
1425             payload->next = nextPayload;
1426             payload = payload->next;
1427         }
1428
1429         nextPayload = constructResponseOfDevConf(OC_RSRVD_INTERFACE_BATCH,
1430                 batch_update_rsrc_arr[DEV_CONF_RES]);
1431         if (nextPayload != NULL)
1432         {
1433             payload->next = nextPayload;
1434         }
1435
1436         payload = head;
1437
1438     }
1439
1440     return payload;
1441 }
1442
1443
1444 OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMask)
1445 {
1446     OCStackResult res = OC_STACK_ERROR;
1447     bool maskFlag = false;
1448
1449     res = initEasySetupResource(isSecured);
1450     if (res != OC_STACK_OK)
1451     {
1452         // TODO: destroy logic will be added
1453         OIC_LOG_V(ERROR, ES_RH_TAG, "initEasySetupResource result: %s", getResult(res));
1454
1455         return res;
1456     }
1457
1458     if ((resourceMask & ES_WIFICONF_RESOURCE) == ES_WIFICONF_RESOURCE)
1459     {
1460         maskFlag = true;
1461         res = initWiFiConfResource(isSecured);
1462         if (res != OC_STACK_OK)
1463         {
1464             OIC_LOG_V(ERROR, ES_RH_TAG, "initWiFiConfResource result: %s", getResult(res));
1465             return res;
1466         }
1467
1468         res = OCBindResource(g_ESEasySetupResource.handle, g_ESWiFiConfResource.handle);
1469         if (res != OC_STACK_OK)
1470         {
1471             OIC_LOG_V(ERROR, ES_RH_TAG, "Bind WiFiConfResource result: %s", getResult(res));
1472             return res;
1473         }
1474     }
1475
1476     if ((resourceMask & ES_COAPCLOUDCONF_RESOURCE) == ES_COAPCLOUDCONF_RESOURCE)
1477     {
1478         maskFlag = true;
1479         res = initCoapCloudConfResource(isSecured);
1480         if (res != OC_STACK_OK)
1481         {
1482             OIC_LOG_V(ERROR, ES_RH_TAG, "initCoapCloudConfResource result: %s", getResult(res));
1483             return res;
1484         }
1485
1486         res = OCBindResource(g_ESEasySetupResource.handle, g_ESCoapCloudConfResource.handle);
1487         if (res != OC_STACK_OK)
1488         {
1489             OIC_LOG_V(ERROR, ES_RH_TAG, "Bind CoapCloudConfResource result: %s", getResult(res));
1490             return res;
1491         }
1492     }
1493
1494     if ((resourceMask & ES_DEVCONF_RESOURCE) == ES_DEVCONF_RESOURCE)
1495     {
1496         maskFlag = true;
1497         res = initDevConfResource(isSecured);
1498         if (res != OC_STACK_OK)
1499         {
1500             OIC_LOG_V(ERROR, ES_RH_TAG, "initDevConf result: %s", getResult(res));
1501             return res;
1502         }
1503
1504         res = OCBindResource(g_ESEasySetupResource.handle, g_ESDevConfResource.handle);
1505         if (res != OC_STACK_OK)
1506         {
1507             OIC_LOG_V(ERROR, ES_RH_TAG, "Bind DevConfResource result: %s", getResult(res));
1508             return res;
1509         }
1510     }
1511
1512     if (maskFlag == false)
1513     {
1514         OIC_LOG_V(ERROR, ES_RH_TAG, "Invalid ResourceMask");
1515         return OC_STACK_ERROR;
1516
1517     }
1518
1519     OIC_LOG_V(DEBUG, ES_RH_TAG, "Created all resources with result: %s", getResult(res));
1520
1521     return res;
1522 }
1523
1524 OCStackResult DeleteEasySetupResources(void)
1525 {
1526     OCStackResult res = OC_STACK_ERROR;
1527     if (g_ESWiFiConfResource.handle != NULL)
1528     {
1529         res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESWiFiConfResource.handle);
1530         if (res != OC_STACK_OK)
1531         {
1532             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind WiFi resource error with result: %s", getResult(res));
1533         }
1534     }
1535     if (g_ESCoapCloudConfResource.handle != NULL)
1536     {
1537         res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESCoapCloudConfResource.handle);
1538         if (res != OC_STACK_OK)
1539         {
1540             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind CloudServer resource error with result: %s", getResult(res));
1541         }
1542     }
1543     if (g_ESDevConfResource.handle != NULL)
1544     {
1545         res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESDevConfResource.handle);
1546         if (res != OC_STACK_OK)
1547         {
1548             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind DevConf resource error with result: %s", getResult(res));
1549         }
1550     }
1551
1552     if (g_ESWiFiConfResource.handle != NULL)
1553     {
1554         res = OCDeleteResource(g_ESWiFiConfResource.handle);
1555         if (res != OC_STACK_OK)
1556         {
1557             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting WiFi resource error with result: %s", getResult(res));
1558         }
1559     }
1560
1561     if (g_ESCoapCloudConfResource.handle != NULL)
1562     {
1563         res = OCDeleteResource(g_ESCoapCloudConfResource.handle);
1564         if (res != OC_STACK_OK)
1565         {
1566             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting CloudServer resource error with result: %s", getResult(res));
1567         }
1568     }
1569
1570     if (g_ESDevConfResource.handle != NULL)
1571     {
1572         res = OCDeleteResource(g_ESDevConfResource.handle);
1573         if (res != OC_STACK_OK)
1574         {
1575             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting DevConf resource error with result: %s", getResult(res));
1576         }
1577     }
1578
1579     if (g_ESEasySetupResource.handle != NULL)
1580     {
1581         res = OCDeleteResource(g_ESEasySetupResource.handle);
1582         if (res != OC_STACK_OK)
1583         {
1584             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting Prov resource error with result: %s", getResult(res));
1585         }
1586     }
1587
1588     return res;
1589 }
1590
1591 static bool isValidESResourceHandle(OCResourceHandle handle)
1592 {
1593     return ((handle == g_ESEasySetupResource.handle) || (handle == g_ESWiFiConfResource.handle)
1594             || (handle == g_ESCoapCloudConfResource.handle)
1595             || (handle == g_ESDevConfResource.handle));
1596 }
1597
1598 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
1599 {
1600     OCEntityHandlerResult ehResult = OC_EH_ERROR;
1601     if (!ehRequest)
1602     {
1603         OIC_LOG(ERROR, ES_RH_TAG, "Request is Null");
1604         return ehResult;
1605     }
1606     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
1607     {
1608         OIC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
1609         return ehResult;
1610     }
1611     if (!isValidESResourceHandle(ehRequest->resource))
1612     {
1613         OIC_LOG(ERROR, ES_RH_TAG, "Request does not have a valid Easy Setup Resource handle");
1614         return ehResult;
1615     }
1616     if (CheckEhRequestPayload(ehRequest) != OC_EH_OK)
1617     {
1618         OIC_LOG(ERROR, ES_RH_TAG, "Not supported Interface");
1619         return OC_EH_BAD_REQ;
1620     }
1621
1622     OCRepPayload *getResp = NULL;
1623     *payload = NULL;
1624
1625     char *iface_name = NULL;
1626     GetInterfaceNameFromQuery(ehRequest->query, &iface_name);
1627     if (!iface_name)
1628     {
1629         iface_name = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1630     }
1631
1632     ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4] = { RES_INCLUDE, RES_INCLUDE, RES_INCLUDE, RES_INCLUDE };
1633
1634     if (ehRequest->resource == g_ESEasySetupResource.handle)
1635     {
1636             getResp = constructResponseOfEasySetup(ehRequest, batch_update_rsrc_arr);
1637     }
1638     else if (ehRequest->resource == g_ESWiFiConfResource.handle)
1639     {
1640             getResp = constructResponseOfWiFiConf(iface_name, RES_INCLUDE);
1641     }
1642     else if (ehRequest->resource == g_ESCoapCloudConfResource.handle)
1643     {
1644             getResp = constructResponseOfCoapCloudConf(iface_name, RES_INCLUDE);
1645     }
1646     else if (ehRequest->resource == g_ESDevConfResource.handle)
1647     {
1648             getResp = constructResponseOfDevConf(iface_name, RES_INCLUDE);
1649     }
1650
1651     OICFree(iface_name);
1652
1653     if (!getResp)
1654     {
1655         OIC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
1656         return OC_EH_ERROR;
1657     }
1658
1659     *payload = getResp;
1660     ehResult = OC_EH_OK;
1661
1662     return ehResult;
1663 }
1664
1665 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
1666 {
1667     OIC_LOG(DEBUG, ES_RH_TAG, "ProcessPostRequest enter");
1668
1669     OCEntityHandlerResult ehResult = OC_EH_ERROR;
1670     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
1671     {
1672         OIC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
1673         return ehResult;
1674     }
1675
1676     OCRepPayload* input = (OCRepPayload*) (ehRequest->payload);
1677     if (!input)
1678     {
1679         OIC_LOG(ERROR, ES_RH_TAG, "Failed to parse");
1680         return ehResult;
1681     }
1682
1683     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)input);
1684
1685     ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4] = { 0 };
1686
1687     if (ehRequest->resource == g_ESEasySetupResource.handle)
1688     {
1689         if (ehRequest->query &&
1690             strcmp(ehRequest->query, "") &&
1691             !CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_BATCH) &&
1692             !CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_DEFAULT))
1693         {
1694             OIC_LOG(ERROR, ES_RH_TAG, "Not supported Interface");
1695             return OC_EH_BAD_REQ;
1696         }
1697         else
1698         {
1699             ehResult = updateEasySetupResource(ehRequest, input, batch_update_rsrc_arr);
1700             if (ehResult != OC_EH_OK)
1701             {
1702                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to update EasySetup resource.");
1703             }
1704         }
1705     }
1706     else if (ehRequest->resource == g_ESWiFiConfResource.handle)
1707     {
1708         if (CheckEhRequestPayload(ehRequest) != OC_EH_OK)
1709         {
1710             OIC_LOG(ERROR, ES_RH_TAG, "Not supported Interface");
1711             return OC_EH_BAD_REQ;
1712         }
1713         else
1714         {
1715             if (updateWiFiConfResource(input) != OC_EH_OK)
1716             {
1717                 OIC_LOG(ERROR, ES_RH_TAG, "Failed to update WifiConf resource.");
1718                 return OC_EH_BAD_REQ;
1719             }
1720         }
1721     }
1722     else if (ehRequest->resource == g_ESCoapCloudConfResource.handle)
1723     {
1724         if (CheckEhRequestPayload(ehRequest) != OC_EH_OK)
1725         {
1726             OIC_LOG(ERROR, ES_RH_TAG, "Not supported Interface");
1727             return OC_EH_BAD_REQ;
1728         }
1729         else
1730         {
1731             updateCoapCloudConfResource(input);
1732         }
1733     }
1734     else if (ehRequest->resource == g_ESDevConfResource.handle)
1735     {
1736         // Reject POST request for DevConf resource as it has only a single read-only property.
1737         // TODO As DevConf also supports user-defined properties, we need to find another way
1738         // to reject the POST requests based on the presence of read-only properties in the payload.
1739         OIC_LOG(ERROR, ES_RH_TAG, "Failed to update DevConf resource.");
1740         return OC_EH_BAD_REQ;
1741     }
1742
1743     OCRepPayload *getResp = NULL;
1744     if (ehRequest->resource == g_ESEasySetupResource.handle)
1745     {
1746         getResp = constructResponseOfEasySetup(ehRequest, batch_update_rsrc_arr);
1747     }
1748     else if (ehRequest->resource == g_ESWiFiConfResource.handle)
1749     {
1750         getResp = constructResponseOfWiFiConf(OC_RSRVD_INTERFACE_DEFAULT, RES_INCLUDE);
1751     }
1752     else if (ehRequest->resource == g_ESCoapCloudConfResource.handle)
1753     {
1754         getResp = constructResponseOfCoapCloudConf(OC_RSRVD_INTERFACE_DEFAULT, RES_INCLUDE);
1755     }
1756     else if (ehRequest->resource == g_ESDevConfResource.handle)
1757     {
1758         getResp = constructResponseOfDevConf(OC_RSRVD_INTERFACE_DEFAULT, RES_INCLUDE);
1759     }
1760
1761     if (!getResp)
1762     {
1763         OIC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
1764         return OC_EH_ERROR;
1765     }
1766
1767     *payload = getResp;
1768     if (ehRequest->resource != g_ESEasySetupResource.handle)
1769     {
1770         ehResult = OC_EH_OK;
1771     }
1772
1773     return ehResult;
1774 }
1775
1776 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest * ehRequest,
1777         OCRepPayload** payload)
1778 {
1779     (void) ehRequest;
1780     (void) payload;
1781     OCEntityHandlerResult ehResult = OC_EH_BAD_REQ;
1782
1783     return ehResult;
1784 }
1785
1786 /**
1787  * This is the entity handler for the registered resource.
1788  * This is invoked by OCStack whenever it recevies a request for this resource.
1789  */
1790 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
1791         OCEntityHandlerRequest* entityHandlerRequest, void *callback)
1792 {
1793     (void) callback;
1794     OCEntityHandlerResult ehRet = OC_EH_OK;
1795     OCEntityHandlerResponse response =
1796     { 0, 0, OC_EH_ERROR, 0, 0,
1797     { },
1798     { 0 }, false };
1799     OCRepPayload* payload = NULL;
1800
1801     if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
1802     {
1803         if (OC_REST_GET == entityHandlerRequest->method)
1804         {
1805             OIC_LOG(DEBUG, ES_RH_TAG, "Received GET request");
1806             ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
1807         }
1808         else if (OC_REST_PUT == entityHandlerRequest->method)
1809         {
1810             OIC_LOG(DEBUG, ES_RH_TAG, "Received PUT request");
1811
1812             //PUT request will be handled in the internal implementation
1813             if (g_ESEasySetupResource.handle != NULL)
1814             {
1815                 ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
1816             }
1817             else
1818             {
1819                 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
1820                 ehRet = OC_EH_ERROR;
1821             }
1822         }
1823         else if (OC_REST_POST == entityHandlerRequest->method)
1824         {
1825             OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_REST_POST from client");
1826             if (g_ESEasySetupResource.handle != NULL)
1827             {
1828                 ehRet = ProcessPostRequest(entityHandlerRequest, &payload);
1829             }
1830             else
1831             {
1832                 OIC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
1833                 ehRet = OC_EH_ERROR;
1834             }
1835         }
1836
1837         // Format the response.  Note this requires some info about the request
1838         response.requestHandle = entityHandlerRequest->requestHandle;
1839         response.ehResult = ehRet;
1840         //response uses OCPaylod while all get,put methodes use OCRepPayload
1841         response.payload = (OCPayload*) (payload);
1842         response.numSendVendorSpecificHeaderOptions = 0;
1843         memset(response.sendVendorSpecificHeaderOptions, 0,
1844                 sizeof(response.sendVendorSpecificHeaderOptions));
1845         memset(response.resourceUri, 0, sizeof(response.resourceUri));
1846         // Indicate that response is NOT in a persistent buffer
1847         response.persistentBufferFlag = 0;
1848
1849         // Send the response
1850         if (OCDoResponse(&response) != OC_STACK_OK)
1851         {
1852             OIC_LOG(ERROR, ES_RH_TAG, "Error sending response");
1853             ehRet = OC_EH_ERROR;
1854         }
1855     }
1856     if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
1857     {
1858         OIC_LOG(DEBUG, ES_RH_TAG, "Flag includes OC_OBSERVE_FLAG");
1859
1860         if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
1861         {
1862             OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_OBSERVE_REGISTER from Mediator");
1863         }
1864         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
1865         {
1866             OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_OBSERVE_DEREGISTER from Mediator");
1867         }
1868     }
1869     return ehRet;
1870 }
1871
1872 OCStackResult SetDeviceProperty(ESDeviceProperty *deviceProperty)
1873 {
1874     OIC_LOG(DEBUG, ES_RH_TAG, "SetDeviceProperty IN");
1875
1876     if (deviceProperty->WiFi.numSupportedMode > NUM_WIFIMODE
1877             || deviceProperty->WiFi.numSupportedFreq > NUM_WIFIFREQ
1878             || deviceProperty->WiFi.numSupportedAuthType > NUM_WIFIAUTHTYPE
1879             || deviceProperty->WiFi.numSupportedEncType > NUM_WIFIENCTYPE)
1880     {
1881         OIC_LOG(ERROR, ES_RH_TAG, "SetDeviceProperty: Invalid Input Param");
1882         return OC_STACK_INVALID_PARAM;
1883     }
1884
1885     g_ESWiFiConfResource.numSupportedFreq = deviceProperty->WiFi.numSupportedFreq;
1886     for (uint8_t i = 0; i < g_ESWiFiConfResource.numSupportedFreq; ++i)
1887     {
1888         g_ESWiFiConfResource.supportedFreq[i] = (deviceProperty->WiFi).supportedFreq[i];
1889         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Freq : %d", g_ESWiFiConfResource.supportedFreq[i]);
1890     }
1891
1892     g_ESWiFiConfResource.numMode = deviceProperty->WiFi.numSupportedMode;
1893     for (uint8_t i = 0; i < g_ESWiFiConfResource.numMode; ++i)
1894     {
1895         g_ESWiFiConfResource.supportedMode[i] = (deviceProperty->WiFi).supportedMode[i];
1896         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Mode : %d", g_ESWiFiConfResource.supportedMode[i]);
1897     }
1898
1899     g_ESWiFiConfResource.numSupportedAuthType = deviceProperty->WiFi.numSupportedAuthType;
1900     for (uint8_t i = 0; i < g_ESWiFiConfResource.numSupportedAuthType; ++i)
1901     {
1902         g_ESWiFiConfResource.supportedAuthType[i] = (deviceProperty->WiFi).supportedAuthType[i];
1903         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Auth Type : %d",
1904                 g_ESWiFiConfResource.supportedAuthType[i]);
1905     }
1906
1907     g_ESWiFiConfResource.numSupportedEncType = deviceProperty->WiFi.numSupportedEncType;
1908     for (uint8_t i = 0; i < g_ESWiFiConfResource.numSupportedEncType; ++i)
1909     {
1910         g_ESWiFiConfResource.supportedEncType[i] = (deviceProperty->WiFi).supportedEncType[i];
1911         OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Enc Type : %d",
1912                 g_ESWiFiConfResource.supportedEncType[i]);
1913     }
1914
1915     OICStrcpy(g_ESDevConfResource.devName, OIC_STRING_MAX_VALUE,
1916             (deviceProperty->DevConf).deviceName);
1917     OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Device Name : %s", g_ESDevConfResource.devName);
1918
1919     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESWiFiConfResource.handle, OC_HIGH_QOS))
1920     {
1921         OIC_LOG(DEBUG, ES_RH_TAG, "wifiResource doesn't have any observers.");
1922     }
1923
1924     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESDevConfResource.handle, OC_HIGH_QOS))
1925     {
1926         OIC_LOG(DEBUG, ES_RH_TAG, "devConfResource doesn't have any observers.");
1927     }
1928
1929     OIC_LOG(DEBUG, ES_RH_TAG, "SetDeviceProperty OUT");
1930     return OC_STACK_OK;
1931 }
1932
1933 OCStackResult SetEnrolleeState(ESEnrolleeState esState)
1934 {
1935     OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeState IN");
1936
1937     g_ESEasySetupResource.status = esState;
1938     OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Enrollee Status : %d", g_ESEasySetupResource.status);
1939
1940     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
1941     {
1942         OIC_LOG(DEBUG, ES_RH_TAG, "provResource doesn't have any observers.");
1943     }
1944
1945     OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeState OUT");
1946     return OC_STACK_OK;
1947 }
1948
1949 OCStackResult SetEnrolleeErrCode(ESErrorCode esErrCode)
1950 {
1951     OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeErrCode IN");
1952
1953     g_ESEasySetupResource.lastErrCode = esErrCode;
1954     OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Enrollee ErrorCode : %d", g_ESEasySetupResource.lastErrCode);
1955
1956     if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
1957     {
1958         OIC_LOG(DEBUG, ES_RH_TAG, "provResource doesn't have any observers.");
1959     }
1960
1961     OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeErrCode OUT");
1962     return OC_STACK_OK;
1963 }
1964
1965 OCEntityHandlerResult CheckEhRequestPayload(OCEntityHandlerRequest *ehRequest)
1966 {
1967     if (ehRequest->query && strcmp(ehRequest->query, ""))
1968     {
1969         uint8_t numResourceInterfaces = 0;
1970         OCStackResult res = OCGetNumberOfResourceInterfaces(ehRequest->resource,
1971                 &numResourceInterfaces);
1972         if (res != OC_STACK_OK)
1973         {
1974             OIC_LOG_V(ERROR, ES_RH_TAG, "Unable to get Number of Interfaces: %s", getResult(res));
1975             return OC_EH_ERROR;
1976         }
1977         for (uint8_t i = 0; i < numResourceInterfaces; ++i)
1978         {
1979             const char *interfaceName = OCGetResourceInterfaceName(ehRequest->resource, i);
1980             if (CompareResourceInterface(ehRequest->query, interfaceName))
1981             {
1982                 return OC_EH_OK;
1983             }
1984         }
1985         OIC_LOG(ERROR, ES_RH_TAG, "Not supported Interface");
1986         return OC_EH_BAD_REQ;
1987     }
1988     return OC_EH_OK;
1989 }
1990
1991 bool isAuthTypeSupported(WIFI_AUTHTYPE authType)
1992 {
1993     bool supported = false;
1994     for (uint8_t i = 0; i < g_ESWiFiConfResource.numSupportedAuthType; ++i)
1995     {
1996         if (g_ESWiFiConfResource.supportedAuthType[i] == authType)
1997         {
1998             supported = true;
1999             break;
2000         }
2001     }
2002     return supported;
2003 }
2004
2005 bool isEncTypeSupported(WIFI_ENCTYPE encType)
2006 {
2007     bool supported = false;
2008     for (uint8_t i = 0; i < g_ESWiFiConfResource.numSupportedEncType; ++i)
2009     {
2010         if (g_ESWiFiConfResource.supportedEncType[i] == encType)
2011         {
2012             supported = true;
2013             break;
2014         }
2015     }
2016     return supported;
2017 }
2018
2019 const char *getResult(OCStackResult result)
2020 {
2021     switch (result)
2022     {
2023         case OC_STACK_OK:
2024             return "OC_STACK_OK";
2025         case OC_STACK_INVALID_URI:
2026             return "OC_STACK_INVALID_URI";
2027         case OC_STACK_INVALID_QUERY:
2028             return "OC_STACK_INVALID_QUERY";
2029         case OC_STACK_INVALID_IP:
2030             return "OC_STACK_INVALID_IP";
2031         case OC_STACK_INVALID_PORT:
2032             return "OC_STACK_INVALID_PORT";
2033         case OC_STACK_INVALID_CALLBACK:
2034             return "OC_STACK_INVALID_CALLBACK";
2035         case OC_STACK_INVALID_METHOD:
2036             return "OC_STACK_INVALID_METHOD";
2037         case OC_STACK_NO_MEMORY:
2038             return "OC_STACK_NO_MEMORY";
2039         case OC_STACK_COMM_ERROR:
2040             return "OC_STACK_COMM_ERROR";
2041         case OC_STACK_INVALID_PARAM:
2042             return "OC_STACK_INVALID_PARAM";
2043         case OC_STACK_NOTIMPL:
2044             return "OC_STACK_NOTIMPL";
2045         case OC_STACK_NO_RESOURCE:
2046             return "OC_STACK_NO_RESOURCE";
2047         case OC_STACK_RESOURCE_ERROR:
2048             return "OC_STACK_RESOURCE_ERROR";
2049         case OC_STACK_SLOW_RESOURCE:
2050             return "OC_STACK_SLOW_RESOURCE";
2051         case OC_STACK_NO_OBSERVERS:
2052             return "OC_STACK_NO_OBSERVERS";
2053         case OC_STACK_ERROR:
2054             return "OC_STACK_ERROR";
2055         default:
2056             return "UNKNOWN";
2057     }
2058 }