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