resourcehandler.c 71.4 KB
Newer Older
1 2
//******************************************************************
//
3
// Copyright 2015 Samsung Electronics All Rights Reserved.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

21
#include "resourcehandler.h"
22
#include "internal/es_util.h"
23

24 25
#include "ocpayload.h"
#include "oic_string.h"
26
#include "oic_malloc.h"
27
#include "cautilinterface.h"
28
#include "payload_logging.h"
29

30 31 32 33 34 35 36
// TODO: Remove this flag and enable the code it guards.
// This is a temporary workaround to ignore the failure of OCLinksPayloadArrayCreate
// in some cases. This allows the response to still be made, even though links property will be
// missing.
// Bug: IOT-2762
#define ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE

37 38 39 40 41
/**
 * @var ES_RH_TAG
 * @brief Logging tag for module name.
 */
#define ES_RH_TAG "ES_RH"
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

#define EASY_SETUP_RES  0
#define WIFI_CONF_RES   1
#define CLOUD_CONF_RES  2
#define DEV_CONF_RES    3

/**
 * @brief  To determine the inclusion/exclusion of resources in batch response.
 */
typedef enum
{
    RES_EXCLUDE = 0,        /**< Indicates the exclusion of the resource **/
    RES_INCLUDE = 1,        /**< Indicates the inclusion of the resource with its representation**/
    RES_INCLUDE_EMPTY_REP = 2   /**< Indicates the inclusion of the resource with empty representation **/
} ES_BATCH_UPDATE_RESPONSE;

58 59 60 61 62
//-----------------------------------------------------------------------------
// Private variables
//-----------------------------------------------------------------------------

/**
63
 * @var g_ESEasySetupResource
64
 * @brief Structure for holding the Provisioning status
65
 */
66 67 68
EasySetupResource g_ESEasySetupResource;
WiFiConfResource g_ESWiFiConfResource;
CoapCloudConfResource g_ESCoapCloudConfResource;
69
DevConfResource g_ESDevConfResource;
70 71 72 73

//-----------------------------------------------------------------------------
// Private internal function prototypes
//-----------------------------------------------------------------------------
74 75 76 77 78
OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest *ehRequest,
        void *callback);
OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
79 80
OCEntityHandlerResult updateEasySetupResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input,
        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 86
bool isAuthTypeSupported(WIFI_AUTHTYPE authType);
bool isEncTypeSupported(WIFI_ENCTYPE encType);
Jihun Ha's avatar
Jihun Ha committed
87
const char *getResult(OCStackResult result);
88

89
ESConnectRequestCB gConnectRequestEvtCb = NULL;
90 91
ESWiFiConfCB gWifiConfRsrcEvtCb = NULL;
ESCoapCloudConfCB gCoapCloudConfRsrcEvtCb = NULL;
92
ESDevConfCB gDevConfRsrcEvtCb = NULL;
93

94 95 96
ESReadUserdataCb gReadUserdataCb = NULL;
ESWriteUserdataCb gWriteUserdataCb = NULL;

97
void GetInterfaceNameFromQuery(const char *query, char **iface)
98
{
99
    if (!iface)
100
    {
101
        return;
102
    }
103 104 105
    *iface = NULL;
    char *str = OICStrdup(query);
    char *ptr = strtok(str, ";");
106

107
    while (ptr)
108
    {
109
        if (strstr(ptr, ".if."))
110 111 112 113 114
        {
            char *if_ptr = NULL;
            if_ptr = strtok(ptr, "=");
            if_ptr = strtok(NULL, "=");

115 116
            *iface = OICStrdup(if_ptr);
            break;
117
        }
118 119
        ptr = strtok(NULL, ";");
    }
120

121
    OICFree(str);
122 123 124 125
}

bool CompareResourceInterface(const char *from, const char *iface)
{
126
    char *if_ptr = NULL;
127 128 129 130 131 132 133 134 135 136 137 138
    GetInterfaceNameFromQuery(from, &if_ptr);
    if (!if_ptr)
    {
        return false;
    }
    if (!strcmp(if_ptr, iface))
    {
        OICFree(if_ptr);
        return true;
    }
    OICFree(if_ptr);

139 140 141
    return false;
}

142 143
ESResult SetCallbackForUserData(ESReadUserdataCb readCb, ESWriteUserdataCb writeCb)
{
144
    if (!readCb && !writeCb)
145
    {
146
        OIC_LOG(DEBUG, ES_RH_TAG, "Both of callbacks for user data are null");
147 148 149 150 151 152 153
        return ES_ERROR;
    }
    gReadUserdataCb = readCb;
    gWriteUserdataCb = writeCb;
    return ES_OK;
}

154
void RegisterWifiRsrcEventCallBack(ESWiFiConfCB cb)
155
{
156
    gWifiConfRsrcEvtCb = cb;
157 158
}

159
void RegisterCloudRsrcEventCallBack(ESCoapCloudConfCB cb)
160
{
161
    gCoapCloudConfRsrcEvtCb = cb;
162 163 164 165 166
}

void RegisterDevConfRsrcEventCallBack(ESDevConfCB cb)
{
    gDevConfRsrcEvtCb = cb;
167 168
}

169 170 171 172 173
void RegisterConnectRequestEventCallBack(ESConnectRequestCB cb)
{
    gConnectRequestEvtCb = cb;
}

174 175
void UnRegisterResourceEventCallBack()
{
176
    if (gWifiConfRsrcEvtCb)
177
    {
178
        gWifiConfRsrcEvtCb = NULL;
179
    }
180
    if (gCoapCloudConfRsrcEvtCb)
181
    {
182
        gCoapCloudConfRsrcEvtCb = NULL;
183 184 185 186
    }
    if (gDevConfRsrcEvtCb)
    {
        gDevConfRsrcEvtCb = NULL;
187
    }
188 189 190 191
    if (gConnectRequestEvtCb)
    {
        gConnectRequestEvtCb = NULL;
    }
192 193
}

194
OCStackResult initEasySetupResource(bool isSecured)
195
{
196 197
    g_ESEasySetupResource.status = ES_STATE_INIT;
    g_ESEasySetupResource.lastErrCode = ES_ERRCODE_NO_ERROR;
198
    for (int i = 0; i < NUM_CONNECT_TYPE; ++i)
199 200 201 202
    {
        g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
    }
    g_ESEasySetupResource.numRequest = 0;
203

204 205 206
    OCStackResult res = OC_STACK_ERROR;
    if (isSecured)
    {
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 223 224
        return res;
    }

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 230 231
        return res;
    }

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 237
        return res;
    }
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 243
        return res;
    }
244

245
    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created EasySetup resource with result: %s", getResult(res));
246 247
    return res;
}
248

249
OCStackResult initWiFiConfResource(bool isSecured)
250 251 252
{
    OCStackResult res = OC_STACK_ERROR;

253 254 255
    g_ESWiFiConfResource.supportedFreq[0] = WIFI_24G;
    g_ESWiFiConfResource.supportedFreq[1] = WIFI_5G;
    g_ESWiFiConfResource.numSupportedFreq=2;
256 257 258 259 260 261 262 263 264
    g_ESWiFiConfResource.supportedMode[0] = WIFI_11A;
    g_ESWiFiConfResource.supportedMode[1] = WIFI_11B;
    g_ESWiFiConfResource.supportedMode[2] = WIFI_11G;
    g_ESWiFiConfResource.supportedMode[3] = WIFI_11N;
    g_ESWiFiConfResource.numMode = 4;
    g_ESWiFiConfResource.authType = NONE_AUTH;
    g_ESWiFiConfResource.encType = NONE_ENC;
    OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), "");
    OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), "");
265 266 267

    if (isSecured)
    {
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 279 280
        NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
    }

281 282 283 284 285 286 287
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create WiFiConf resource with result: %s",
            getResult(res));
        return res;
    }

288 289 290 291 292 293 294 295
    res = OCBindResourceInterfaceToResource(g_ESWiFiConfResource.handle,
    OC_RSRVD_INTERFACE_READ_WRITE);
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
        return res;
    }

296
    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created WiFiConf resource with result: %s", getResult(res));
297 298 299 300
    return res;

}

301
OCStackResult initCoapCloudConfResource(bool isSecured)
302 303 304
{
    OCStackResult res = OC_STACK_ERROR;

305
    OICStrcpy(g_ESCoapCloudConfResource.authCode, sizeof(g_ESCoapCloudConfResource.authCode), "");
306 307
    OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken),
            "");
308
    g_ESCoapCloudConfResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
309 310
    OICStrcpy(g_ESCoapCloudConfResource.authProvider,
            sizeof(g_ESCoapCloudConfResource.authProvider), "");
311
    OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), "");
312 313 314

    if (isSecured)
    {
315 316 317 318 319 320 321
        res = OCCreateResource(&g_ESCoapCloudConfResource.handle,
                OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
                OC_RSRVD_INTERFACE_DEFAULT,
                OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
                NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
    }
    else
322
    {
323 324 325 326 327 328 329
        res = OCCreateResource(&g_ESCoapCloudConfResource.handle,
                OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
                OC_RSRVD_INTERFACE_DEFAULT,
                OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
                NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
    }

330 331 332 333 334 335 336
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create CoapCloudConf resource with result: %s",
            getResult(res));
        return res;
    }

337 338 339 340 341 342
    res = OCBindResourceInterfaceToResource(g_ESCoapCloudConfResource.handle,
            OC_RSRVD_INTERFACE_READ_WRITE);
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
        return res;
343 344
    }

345
    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created CoapCloudConf resource with result: %s", getResult(res));
346 347 348 349 350 351 352
    return res;
}

OCStackResult initDevConfResource(bool isSecured)
{
    OCStackResult res = OC_STACK_ERROR;

353
    OICStrcpy(g_ESDevConfResource.devName, sizeof(g_ESDevConfResource.devName), "");
354 355 356

    if (isSecured)
    {
357
        res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
358 359
        OC_RSRVD_INTERFACE_DEFAULT,
        OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
360
        NULL, OC_DISCOVERABLE | OC_SECURE);
361 362
    }
    else
363
    {
364
        res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
365 366
        OC_RSRVD_INTERFACE_DEFAULT,
        OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
367
        NULL, OC_DISCOVERABLE);
368 369
    }

370 371 372 373 374 375 376
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Failed to create DevConf resource with result: %s",
            getResult(res));
        return res;
    }

377 378 379 380 381 382 383
    res = OCBindResourceInterfaceToResource(g_ESDevConfResource.handle, OC_RSRVD_INTERFACE_READ);
    if (res != OC_STACK_OK)
    {
        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
        return res;
    }

384
    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created DevConf resource with result: %s", getResult(res));
385 386 387 388
    return res;

}

389
OCEntityHandlerResult updateEasySetupResource(OCEntityHandlerRequest* ehRequest,
390
    OCRepPayload* input, ES_BATCH_UPDATE_RESPONSE batch_update_rsrc_arr[4])
391
{
392
    OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.status %d", g_ESEasySetupResource.status);
393

394
    OCEntityHandlerResult ehResult = OC_EH_OK;
395 396 397 398
    if (ehRequest->query)
    {
        if (CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_BATCH))
        {
399 400 401 402 403
            batch_update_rsrc_arr[EASY_SETUP_RES] = RES_EXCLUDE;
            batch_update_rsrc_arr[WIFI_CONF_RES] = RES_EXCLUDE;
            batch_update_rsrc_arr[CLOUD_CONF_RES] = RES_EXCLUDE;
            batch_update_rsrc_arr[DEV_CONF_RES] = RES_EXCLUDE;

404
            bool hasError = false;
405 406 407 408 409
            // When Provisioning resource has a POST with BatchInterface
            // Parsing POST request on Batch Interface cosidering same format as GET using batch.
            OCRepPayload *children = input;
            while(children)
            {
410
                char* uri = children->uri;
411
                if (NULL == uri)
412
                {
413 414 415 416 417
                    OIC_LOG(DEBUG, ES_RH_TAG, "No URI found in request");
                }
                else
                {
                    OIC_LOG_V(DEBUG, ES_RH_TAG, "Request URI [%s]", uri);
418
                }
419

420 421
                OCRepPayload *repPayload = NULL;
                OCRepPayloadGetPropObject(children, OC_RSRVD_REPRESENTATION, &repPayload);
422
                if (NULL == repPayload)
423
                {
424
                    OIC_LOG(ERROR, ES_RH_TAG, "repPayload is null!");
425 426 427 428
                    children = children->next;
                    continue;
                }

429 430 431
                // If uri is NULL, rep is applied to all resources in collection;
                // otherwise its applied to specific target resources.
                if (NULL == uri || 0 == strlen(uri) || 0 == strcmp(uri, OC_RSRVD_ES_URI_EASYSETUP))
432
                {
433 434 435 436 437
                    // If payload has read-only properties, then the request is considered as a bad request.
                    if (!OCRepPayloadIsNull(children, OC_RSRVD_ES_PROVSTATUS) ||
                        !OCRepPayloadIsNull(children, OC_RSRVD_ES_LAST_ERRORCODE))
                    {
                        OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
438 439
                        // "rep" field of EasySetup resource in the response will be empty.
                        batch_update_rsrc_arr[EASY_SETUP_RES] = RES_INCLUDE_EMPTY_REP;
440 441 442 443 444
                        hasError = true;
                    }
                    else
                    {
                        updateEasySetupConnectProperty(repPayload);
445
                        batch_update_rsrc_arr[EASY_SETUP_RES] = RES_INCLUDE;
446
                    }
447
                }
448 449 450

                if (NULL == uri || 0 == strlen(uri)
                    || 0 == strcmp(uri, OC_RSRVD_ES_URI_WIFICONF))
451
                {
452 453 454 455
                    if (updateWiFiConfResource(repPayload) != OC_EH_OK)
                    {
                        OIC_LOG(ERROR, ES_RH_TAG, "Failed to update WiFiConf resource.");
                        hasError = true;
456 457 458 459 460 461 462
                        // As there is a problem in updating the WiFiConf resource,
                        // corresponding "rep" field in the response will be empty.
                        batch_update_rsrc_arr[WIFI_CONF_RES] = RES_INCLUDE_EMPTY_REP;
                    }
                    else
                    {
                        batch_update_rsrc_arr[WIFI_CONF_RES] = RES_INCLUDE;
463
                    }
464
                }
465 466 467

                if (NULL == uri ||  0 == strlen(uri)
                    || 0 == strcmp(uri, OC_RSRVD_ES_URI_COAPCLOUDCONF))
468 469
                {
                    updateCoapCloudConfResource(repPayload);
470
                    batch_update_rsrc_arr[CLOUD_CONF_RES] = RES_INCLUDE;
471
                }
472 473 474

                if (NULL == uri ||  0 == strlen(uri)
                    || 0 == strcmp(uri, OC_RSRVD_ES_URI_DEVCONF))
475
                {
476 477 478 479
                    if (updateDevConfResource(repPayload) != OC_EH_OK)
                    {
                        OIC_LOG(ERROR, ES_RH_TAG, "Failed to update DevConf resource.");
                        hasError = true;
480 481 482 483 484 485 486
                        // As there is a problem in updating the DevConf resource,
                        // corresponding "rep" field in the response will be empty.
                        batch_update_rsrc_arr[DEV_CONF_RES] = RES_INCLUDE_EMPTY_REP;
                    }
                    else
                    {
                        batch_update_rsrc_arr[DEV_CONF_RES] = RES_INCLUDE;
487
                    }
488 489 490 491
                }

                children = children->next;
                OCRepPayloadDestroy(repPayload);
492
            }
493

494 495 496 497
            if (hasError)
            {
               ehResult = OC_EH_BAD_REQ;
            }
498
        }
499 500 501
        else if (CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_DEFAULT))
        {
            OIC_LOG(DEBUG, ES_RH_TAG, "Handling POST request on default interface");
502 503 504 505 506 507 508 509 510 511 512
            // If payload has read-only properties, then the request is considered as a bad request.
            if (!OCRepPayloadIsNull(input, OC_RSRVD_ES_PROVSTATUS) ||
                !OCRepPayloadIsNull(input, OC_RSRVD_ES_LAST_ERRORCODE))
            {
                OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
                ehResult = OC_EH_BAD_REQ;
            }
            else
            {
                updateEasySetupConnectProperty(input);
            }
513
        }
514
    }
515

516
    OIC_LOG(DEBUG, ES_RH_TAG, "updateEasySetupResource exit");
George Nash's avatar
George Nash committed
517
    return ehResult;
518 519 520 521
}

void updateEasySetupConnectProperty(OCRepPayload* input)
{
522 523 524 525 526
    int64_t *connect_req = NULL;
    size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
    if (OCRepPayloadGetIntArray(input, OC_RSRVD_ES_CONNECT, &connect_req, dimensions))
    {
        ESConnectRequest* connectRequest = (ESConnectRequest*)OICMalloc(sizeof(ESConnectRequest));
527 528 529
        if (!connectRequest)
        {
            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
530
            return;
531 532
        }

533
        int cntRequest = 0;
534
        for (unsigned int i = 0 ; i < NUM_CONNECT_TYPE ; ++i)
535 536 537 538
        {
            g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
            connectRequest->connect[i] = ES_CONNECT_NONE;

539
            if (i < dimensions[0] && connect_req[i] >= ES_CONNECT_NONE)
540 541 542 543 544 545 546 547 548 549 550
            {
                g_ESEasySetupResource.connectRequest[cntRequest] = connect_req[i];
                connectRequest->connect[cntRequest] = connect_req[i];
                OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.connectType[%d] : %d",
                                                    cntRequest, g_ESEasySetupResource.connectRequest[cntRequest]);
                cntRequest++;
            }
        }
        connectRequest->numRequest = cntRequest;
        g_ESEasySetupResource.numRequest = cntRequest;

551
        if (g_ESEasySetupResource.connectRequest[0] != ES_CONNECT_NONE)
552 553 554
        {
            OIC_LOG(DEBUG, ES_RH_TAG, "Send ConnectRequest Callback To ES");

555 556
            //@todo Need to check appropriateness of gWiFiData
            if (gConnectRequestEvtCb != NULL)
557 558 559 560 561 562 563 564 565
            {
                gConnectRequestEvtCb(ES_OK, connectRequest);
            }
            else
            {
                OIC_LOG(ERROR, ES_RH_TAG, "gConnectRequestEvtCb is NULL");
            }
        }
    }
566 567
}

568
OCEntityHandlerResult updateWiFiConfResource(OCRepPayload* input)
569
{
570 571 572 573 574 575 576 577 578 579
    // If payload has read-only properties, then the request is considered as a bad request.
    if (!OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIMODE) ||
        !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIFREQ) ||
        !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIAUTHTYPE) ||
        !OCRepPayloadIsNull(input, OC_RSRVD_ES_SUPPORTEDWIFIENCTYPE))
    {
        OIC_LOG(ERROR, ES_RH_TAG, "Read-only property cannot be updated.");
        return OC_EH_BAD_REQ;
    }

580
    OCEntityHandlerResult ehResult = OC_EH_ERROR;
581
    ESWiFiConfData* wiFiData = (ESWiFiConfData*) OICMalloc(sizeof(ESWiFiConfData));
582
    if (wiFiData == NULL)
583 584
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
585
        return ehResult;
586
    }
587

588 589 590 591
    char* ssid = NULL;
    char* cred = NULL;
    char *authType = NULL;
    char *encType = NULL;
592 593
    memset(wiFiData->ssid, 0, OIC_STRING_MAX_VALUE);
    memset(wiFiData->pwd, 0, OIC_STRING_MAX_VALUE);
594 595
    wiFiData->authtype = NONE_AUTH;
    wiFiData->enctype = NONE_AUTH;
596 597
    wiFiData->userdata = NULL;

598 599
    bool validAuthType = false;
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHTYPE, &authType))
600
    {
601 602
        WIFI_AUTHTYPE tmp;
        validAuthType = WiFiAuthTypeStringToEnum(authType, &tmp);
603
        if (validAuthType && isAuthTypeSupported(tmp))
604
        {
605
            wiFiData->authtype = tmp;
606
            OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.authType %u",
607 608 609 610 611 612 613
                    wiFiData->authtype);
        }
        else
        {
            OIC_LOG(ERROR, ES_RH_TAG, "AuthType is not supported.");
            ehResult = OC_EH_BAD_REQ;
            goto EXIT;
614
        }
615 616
    }

617 618
    bool validEncType = false;
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ENCTYPE, &encType))
619
    {
620 621
        WIFI_ENCTYPE tmp;
        validEncType = WiFiEncTypeStringToEnum(encType, &tmp);
622
        if (validEncType && isEncTypeSupported(tmp))
623
        {
624
            wiFiData->enctype = tmp;
625
            OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.encType %u",
626 627 628 629 630 631 632
                    wiFiData->enctype);
        }
        else
        {
            OIC_LOG(ERROR, ES_RH_TAG, "EncType is not supported.");
            ehResult = OC_EH_BAD_REQ;
            goto EXIT;
633
        }
634
    }
635

636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
    if (validAuthType)
    {
        g_ESWiFiConfResource.authType = wiFiData->authtype;
    }

    if (validEncType)
    {
        g_ESWiFiConfResource.encType = wiFiData->enctype;
    }

    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_SSID, &ssid))
    {
        OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), ssid);
        OICStrcpy(wiFiData->ssid, sizeof(wiFiData->ssid), ssid);
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.ssid : %s",
                g_ESWiFiConfResource.ssid);
    }

    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CRED, &cred))
    {
        OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), cred);
        OICStrcpy(wiFiData->pwd, sizeof(wiFiData->pwd), cred);
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.cred %s",
                g_ESWiFiConfResource.cred);
    }

662
    if (gReadUserdataCb)
Jihun Ha's avatar
Jihun Ha committed
663
    {
664
        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_WIFICONF, &wiFiData->userdata);
Jihun Ha's avatar
Jihun Ha committed
665
    }
666

667
    if (ssid || cred || validAuthType || validEncType)
668
    {
669
        OIC_LOG(DEBUG, ES_RH_TAG, "Send WiFiConfRsrc Callback To ES");
670

671 672
        //@todo Need to check appropriateness of gWiFiData
        if (gWifiConfRsrcEvtCb != NULL)
673
        {
674
            gWifiConfRsrcEvtCb(ES_OK, wiFiData);
675 676 677
        }
        else
        {
678
            OIC_LOG(ERROR, ES_RH_TAG, "gWifiConfRsrcEvtCb is NULL");
679 680 681
        }
    }

682
    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESWiFiConfResource.handle, OC_HIGH_QOS))
683
    {
684 685 686 687 688 689
        OIC_LOG(DEBUG, ES_RH_TAG, "WiFiConf resource doesn't have any observer.");
    }

    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "EasySetup resource doesn't have any observer.");
690 691
    }

692 693 694
    ehResult = OC_EH_OK;

EXIT:
695 696 697 698
    OICFree(encType);
    OICFree(authType);
    OICFree(cred);
    OICFree(ssid);
699
    OICFree(wiFiData);
700
    return ehResult;
701
}
702

703
void updateCoapCloudConfResource(OCRepPayload* input)
704
{
705
    ESCoapCloudConfData* cloudData = (ESCoapCloudConfData*)OICMalloc(sizeof(ESCoapCloudConfData));
706

707
    if (cloudData == NULL)
708 709
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
710
        return;
711
    }
712 713

    memset(cloudData->authCode, 0, OIC_STRING_MAX_VALUE);
714
    memset(cloudData->accessToken, 0, OIC_STRING_MAX_VALUE);
715
    g_ESCoapCloudConfResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
716
    memset(cloudData->authProvider, 0, OIC_STRING_MAX_VALUE);
717
    memset(cloudData->ciServer, 0, OIC_URI_STRING_MAX_VALUE);
718 719
    cloudData->userdata = NULL;

720
    char *authCode = NULL;
721 722
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHCODE, &authCode))
    {
723
        OICStrcpy(g_ESCoapCloudConfResource.authCode, sizeof(g_ESCoapCloudConfResource.authCode), authCode);
724
        OICStrcpy(cloudData->authCode, sizeof(cloudData->authCode), authCode);
725
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.authCode %s", g_ESCoapCloudConfResource.authCode);
726 727
    }

728 729 730
    char *accessToken = NULL;
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ACCESSTOKEN, &accessToken))
    {
731
        OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken), accessToken);
732
        OICStrcpy(cloudData->accessToken, sizeof(cloudData->accessToken), accessToken);
733
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.accessToken %s", g_ESCoapCloudConfResource.accessToken);
734 735 736 737 738
    }

    int64_t accessTokenType = -1;
    if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_ACCESSTOKEN_TYPE, &accessTokenType))
    {
739 740
        g_ESCoapCloudConfResource.accessTokenType = accessTokenType;
        cloudData->accessTokenType = g_ESCoapCloudConfResource.accessTokenType;
741
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.accessTokenType %d", g_ESCoapCloudConfResource.accessTokenType);
742 743
    }

744
    char *authProvider = NULL;
745 746
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHPROVIDER, &authProvider))
    {
747
        OICStrcpy(g_ESCoapCloudConfResource.authProvider, sizeof(g_ESCoapCloudConfResource.authProvider), authProvider);
748
        OICStrcpy(cloudData->authProvider, sizeof(cloudData->authProvider), authProvider);
749
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.authServerUrl %s", g_ESCoapCloudConfResource.authProvider);
750 751
    }

752
    char *ciServer = NULL;
753 754
    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CISERVER, &ciServer))
    {
755
        OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), ciServer);
756
        OICStrcpy(cloudData->ciServer, sizeof(cloudData->ciServer), ciServer);
757
        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.ciServer %s", g_ESCoapCloudConfResource.ciServer);
758
    }
759

760
    if (gReadUserdataCb)
Jihun Ha's avatar
Jihun Ha committed
761
    {
762
        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF, &cloudData->userdata);
Jihun Ha's avatar
Jihun Ha committed
763
    }
764

765
    if (authCode || accessToken || authProvider || ciServer)
766
    {
767
        OIC_LOG(DEBUG, ES_RH_TAG, "Send CoapCloudConfRsrc Callback To ES");
768

769 770
        //@todo Need to check appropriateness of gCloudData
        if (gCoapCloudConfRsrcEvtCb != NULL)
771
        {
772
            gCoapCloudConfRsrcEvtCb(ES_OK, cloudData);
773 774 775
        }
        else
        {
776
            OIC_LOG(DEBUG, ES_RH_TAG, "gCoapCloudConfRsrcEvtCb is NULL");
777 778
        }
    }
779

780
    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESCoapCloudConfResource.handle, OC_HIGH_QOS))
781
    {
782
        OIC_LOG(DEBUG, ES_RH_TAG, "CoapCloudConf resource doesn't have any observer.");
783 784
    }

785 786 787 788 789
    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "EasySetup resource doesn't have any observer.");
    }

790
    OICFree(cloudData);
791 792
}

793
OCEntityHandlerResult updateDevConfResource(OCRepPayload* input)
794
{
795
    ESDevConfData* devConfData = (ESDevConfData*)OICMalloc(sizeof(ESDevConfData));
796

797
    if (devConfData == NULL)
798 799
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
800
        return OC_EH_ERROR;
801 802 803
    }
    devConfData->userdata = NULL;

804
    if (gReadUserdataCb)
Jihun Ha's avatar
Jihun Ha committed
805
    {
806
        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_DEVCONF, &devConfData->userdata);
Jihun Ha's avatar
Jihun Ha committed
807
    }
808

809 810
    // If a writable property in oic.r.devconf is added later,
    // a condition for calling a resistered callback should be implemented also.
811
    if (devConfData->userdata != NULL)
812
    {
813
        OIC_LOG(DEBUG, ES_RH_TAG, "Send DevConfRsrc Callback To ES");
814

815 816
        //@todo : Need to check appropriateness of gDevConfData
        if (gDevConfRsrcEvtCb != NULL)
817
        {
818
            gDevConfRsrcEvtCb(ES_OK, devConfData);
819 820 821
        }
        else
        {
822
            OIC_LOG(DEBUG, ES_RH_TAG, "gDevConfRsrcEvtCb is NULL");
823 824
        }
    }
825

826
    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESDevConfResource.handle, OC_HIGH_QOS))
827
    {
828
        OIC_LOG(DEBUG, ES_RH_TAG, "devConfResource doesn't have any observer.");
829 830
    }

831
    OICFree(devConfData);
832
    return OC_EH_OK;
833 834
}

835
OCRepPayload* constructResponseOfWiFiConf(char *interface, ES_BATCH_UPDATE_RESPONSE resp)
836
{
837 838 839 840 841 842
    if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH) && RES_EXCLUDE == resp)
    {
        OIC_LOG(DEBUG, ES_RH_TAG, "Excluding WiFiConf resource from the batch response.");
        return NULL;
    }

843 844 845 846 847 848 849
    OCRepPayload* payload = OCRepPayloadCreate();
    if (!payload)
    {
        OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
        return NULL;
    }

850
    if (g_ESWiFiConfResource.handle == NULL)
851
    {
852
        OIC_LOG(ERROR, ES_RH_TAG, "WiFiConf resource is not created");
853 854 855
        return NULL;
    }

856
    OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse WiFiConf res");
857 858 859

    OCRepPayload* repPayload = NULL;
    OCRepPayload* tempPayload = NULL;
860
    if (!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
861
    {
862 863
        OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_WIFICONF);

864 865 866 867 868 869 870 871 872 873
        repPayload = OCRepPayloadCreate();
        if (!repPayload)
        {
            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
            return NULL;
        }

        tempPayload = payload;
        payload = repPayload;

874
        if (RES_INCLUDE == resp)
Jihun Ha's avatar