[IOT-3022] CNC fixes for CTT
[iotivity.git] / resource / csdk / security / provisioning / src / cloud / cloudresource.c
1 /* *****************************************************************
2  *
3  * Copyright 2018 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 "iotivity_config.h"
22 #include "iotivity_debug.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26 #include <unistd.h>
27
28 #include "octypes.h"
29 #include "oic_malloc.h"
30 #include "utlist.h"
31 #include "experimental/logger.h"
32 #include "ocpayload.h"
33 #include "ocpayloadcbor.h"
34 #include "srmutility.h"
35 #include "psinterface.h"
36 #include "deviceonboardingstate.h"
37 #include "srmresourcestrings.h"
38 #include "resourcemanager.h"
39 #include "cloud/cloudresource.h"
40 #include "cloud/auth.h"
41
42 #define TAG  "OIC_CLOUD_RESOURCE"
43
44 static OicCloud_t           *gCloud = NULL;
45 static OCResourceHandle     gCloudHandle = NULL;
46
47 static oc_mutex     gCloudMutex;
48
49 #define OC_CLOUD_PROVISIONING_APN   "apn"
50 #define OC_CLOUD_PROVISIONING_CIS   "cis"
51 #define OC_CLOUD_PROVISIONING_AT    "at"
52 #define OC_CLOUD_PROVISIONING_SID   "sid"
53 #define OC_CLOUD_PROVISIONING_CLEC  "clec"
54
55 static OicCloud_t gDefaultCloud =
56 {
57     NULL,
58     NULL,
59     NULL,
60     NULL,
61     NULL,
62     OC_CLOUD_OK,
63     NULL,
64     NULL,
65     NULL,
66     NULL
67 };
68
69 static void DeleteCloudList(OicCloud_t *clouds)
70 {
71     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
72
73     if (!clouds)
74     {
75         OIC_LOG_V(WARNING, TAG, "%s: cloud is NULL", __func__);
76         return;
77     }
78
79     OicCloud_t *p1 = NULL, *p2 = NULL;
80     oc_mutex_lock(gCloudMutex);
81     LL_FOREACH_SAFE(clouds, p1, p2)
82     {
83         OCCloudSignOut(p1);
84         LL_DELETE(clouds, p1);
85         p1 = NULL;
86     }
87     oc_mutex_unlock(gCloudMutex);
88
89     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
90 }
91
92 void StopClouds()
93 {
94     DeleteCloudList(gCloud);
95 }
96
97 void DeleteCloudAccount()
98 {
99     if ( OC_STACK_OK != OCCloudDelete(gCloud))
100     {
101         OIC_LOG_V(ERROR, TAG, "%s: cannot delete cloud", __func__);
102     }
103     else
104     {
105         OIC_LOG_V(ERROR, TAG, "%s: cloud is deleted", __func__);
106     }
107 }
108
109 static void *CloudWaitForRFNOP(void *data)
110 {
111     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
112     OicSecDostype_t dos;
113
114     OicCloud_t *cloud = (OicCloud_t *)data;
115     VERIFY_NOT_NULL(TAG, cloud, ERROR);
116
117     VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
118
119     while (DOS_RFNOP != dos.state && OC_CLOUD_EXIT != cloud->stat)
120     {
121         VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
122         sleep(1);
123     }
124
125     if (OC_STACK_OK != OCCloudSignUp(cloud))
126     {
127         OIC_LOG_V(ERROR, TAG, "%s: cloud sign up", __func__);
128     }
129 exit:
130     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
131     return NULL;
132 }
133
134 static OCEntityHandlerResult HandleCloudPostRequest(OCEntityHandlerRequest *ehRequest)
135 {
136     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
137     OCEntityHandlerResult ehRet = OC_EH_INTERNAL_SERVER_ERROR;
138     OicSecDostype_t dos;
139     OicCloud_t *newCloud = NULL;
140     OCRepPayload *payload = NULL;
141     bool isDeviceOwned = false;
142     OicCloud_t *xcloud = NULL;
143
144     VERIFY_NOT_NULL(TAG, ehRequest, ERROR);
145     VERIFY_NOT_NULL(TAG, ehRequest->payload, ERROR);
146
147     VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&dos), ERROR);
148
149     if (DOS_RFNOP != dos.state && DOS_RFPRO != dos.state)
150     {
151         OIC_LOG_V(ERROR, TAG, "%s %s resource is read-only in not RFNOP or DOS_RFPRO", __func__,
152                   OIC_RSRC_TYPE_SEC_CLOUDCONF);
153         ehRet = OC_EH_NOT_ACCEPTABLE;
154         goto exit;
155     }
156
157     OCGetDeviceOwnedState(&isDeviceOwned);
158
159     if (!isDeviceOwned)
160     {
161         OIC_LOG_V(ERROR, TAG, "%s: device is not owned", __func__);
162         ehRet = OC_EH_NOT_ACCEPTABLE;
163         goto exit;
164     }
165
166     newCloud = (OicCloud_t *) OICCalloc(1, sizeof(OicCloud_t));
167     VERIFY_NOT_NULL(TAG, newCloud, ERROR);
168
169     payload = (OCRepPayload *)ehRequest->payload;
170
171     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_APN, &newCloud->apn))
172     {
173         OIC_LOG_V(WARNING, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_APN);
174     }
175     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_CIS, &newCloud->cis))
176     {
177         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_CIS);
178         goto exit;
179     }
180     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_AT, &newCloud->at))
181     {
182         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_AT);
183         goto exit;
184     }
185     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_SID, &newCloud->sid))
186     {
187         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_SID);
188         goto exit;
189     }
190
191     if (!ValidCloud(newCloud))
192     {
193         OIC_LOG_V(ERROR, TAG, "%s: Error validate the new cloud", __func__);
194         goto exit;
195     }
196
197     xcloud = CloudFind(gCloud, newCloud);
198     if (xcloud)
199     {
200         OIC_LOG_V(WARNING, TAG, "%s: cloud: %s exist", __func__, newCloud->cis);
201         if (OC_CLOUD_TOKEN_REFRESH0 < xcloud->stat)
202         {
203             if (!CloudCopy(newCloud, xcloud))
204             {
205                 OIC_LOG_V(WARNING, TAG, "%s: cloud: cannot update: %s", __func__, xcloud->cis);
206             }
207         }
208         else
209         {
210             OIC_LOG_V(WARNING, TAG, "%s: cloud: cannot update: %s status: %s", __func__, xcloud->cis,
211                       GetCloudStatus(xcloud));
212
213             FreeCloud(newCloud);
214             goto exit;
215         }
216     }
217
218     oc_mutex_lock(gCloudMutex);
219 #ifdef _MULTIPLE_CNC_
220     LL_APPEND(gCloud, newCloud);
221 #else
222     FreeCloud(gCloud);
223     gCloud = newCloud;
224 #endif
225     oc_mutex_unlock(gCloudMutex);
226
227     newCloud->stat = OC_CLOUD_PROV;
228
229
230     if (DOS_RFNOP == dos.state)
231     {
232         if (OC_STACK_OK != OCCloudSignUp(newCloud))
233         {
234             OIC_LOG_V(ERROR, TAG, "%s: cloud sign up", __func__);
235         }
236     }
237     else
238     {
239         OCThreadResult_t res = OC_THREAD_SUCCESS;
240         res = oc_thread_new(&newCloud->pid, CloudWaitForRFNOP, newCloud);
241         if (OC_THREAD_SUCCESS != res)
242         {
243             OIC_LOG_V(ERROR, TAG, "%s: create thread: %d", __func__, res);
244         }
245     }
246
247     ehRet = OC_EH_OK;
248 exit:
249     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
250             OC_EH_OK : OC_EH_ERROR;
251
252     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
253
254     return ehRet;
255 }
256
257 static int64_t  GetClec(const OicCloud_t *cloud)
258 {
259     OIC_LOG_V(DEBUG, TAG, "%s: %d", __func__, cloud->stat);
260
261     switch (cloud->stat)
262     {
263         case OC_CLOUD_OK:
264         case OC_CLOUD_PROV:
265         case OC_CLOUD_SIGNUP:
266         case OC_CLOUD_SIGNIN:
267         case OC_CLOUD_SIGNOUT:
268         case OC_CLOUD_TOKEN_REFRESH0:
269         case OC_CLOUD_TOKEN_REFRESH1:
270         case OC_CLOUD_TOKEN_REFRESH2:
271         case OC_CLOUD_TOKEN_REFRESH3:
272         case OC_CLOUD_TOKEN_REFRESH4:
273             return 0;
274         case OC_CLOUD_ERROR_INVALID_ACCESS_TOKEN:
275             return 3;
276         case OC_CLOUD_ERROR_UNREACHABLE:
277         case OC_CLOUD_ERROR_TLS:
278         case OC_CLOUD_ERROR_REDIRECT:
279             return 2;
280         case OC_CLOUD_ERROR_REFRESHTOKEN:
281             return 3;
282         case OC_CLOUD_ERROR_SIGNOUT:
283         case OC_CLOUD_ERROR_SIGNIN:
284         case OC_CLOUD_ERROR_CREATE_SESSION:
285         case OC_CLOUD_ERROR_CHECK_SESSION:
286         case OC_CLOUD_ERROR_SIGNUP:
287         case OC_CLOUD_ERROR:
288         case OC_CLOUD_EXIT:
289             return 1;
290     }
291     return 0;
292 }
293
294 OCRepPayload *CreateCloudGetPayload(const OicCloud_t *cloud)
295 {
296     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
297
298     OCRepPayload *payload = NULL;
299     payload = OCRepPayloadCreate();
300     VERIFY_NOT_NULL(TAG, payload, ERROR);
301
302     OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
303     OCRepPayloadAddResourceType(payload, OIC_RSRC_TYPE_SEC_CLOUDCONF);
304
305     if (NULL == cloud)
306     {
307         OIC_LOG_V(DEBUG, TAG, "%s: Create empty filled payload", __func__);
308
309         if (OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_APN, ""))
310         {
311                 OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_APN);
312         }
313         if (OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_CIS, ""))
314         {
315             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_CIS);
316         }
317         if (!OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_SID, "00000000-0000-0000-0000-000000000000"))
318         {
319             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_SID);
320         }
321         if (!OCRepPayloadSetPropInt(payload, OIC_JSON_CLOUD_CLEC, (int64_t)0))
322         {
323             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_CLEC);
324         }
325     }
326     else
327     {
328         if (cloud->apn)
329         {
330             if (OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_APN, cloud->apn))
331             {
332                 OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_APN);
333             }
334         }
335         if (OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_CIS, cloud->cis))
336         {
337             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_CIS);
338         }
339         if (!OCRepPayloadSetPropString(payload, OIC_JSON_CLOUD_SID, cloud->sid))
340         {
341             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_SID);
342         }
343         if (!OCRepPayloadSetPropInt(payload, OIC_JSON_CLOUD_CLEC, GetClec(cloud)))
344         {
345             OIC_LOG_V(ERROR, TAG, "%s: Can't set: %s", __func__, OC_CLOUD_PROVISIONING_CLEC);
346         }
347     }
348 exit:
349     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
350     return payload;
351 }
352
353 static OCEntityHandlerResult HandleCloudGetRequest(OCEntityHandlerRequest *ehRequest)
354 {
355     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
356     OCEntityHandlerResult ehRet = OC_EH_INTERNAL_SERVER_ERROR;
357     OicCloud_t *cloud = NULL;
358     OCRepPayload *payload = NULL;
359     bool isDeviceOwned = false;
360     OicCloud_t *p1 = NULL, *p2 = NULL;
361     OCEntityHandlerResponse response;
362
363     VERIFY_NOT_NULL(TAG, ehRequest, ERROR);
364
365     OCGetDeviceOwnedState(&isDeviceOwned);
366
367     if (!isDeviceOwned)
368     {
369         OIC_LOG_V(ERROR, TAG, "%s: device is not owned", __func__);
370         ehRet = OC_EH_NOT_ACCEPTABLE;
371         goto exit;
372     }
373
374     if (NULL == gCloud)
375     {
376         ehRet = OC_EH_OK;
377         goto exit;
378     }
379
380     cloud = (OicCloud_t *) OICCalloc(1, sizeof(OicCloud_t));
381     VERIFY_NOT_NULL(TAG, cloud, ERROR);
382
383     payload = (OCRepPayload *)ehRequest->payload;
384
385     if (!payload || !OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_CIS, &cloud->cis))
386     {
387         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_CIS);
388         p1 = gCloud;
389         ehRet = OC_EH_OK;
390         goto exit;
391     }
392     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_APN, &cloud->apn))
393     {
394         OIC_LOG_V(WARNING, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_APN);
395     }
396     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_AT, &cloud->at))
397     {
398         OIC_LOG_V(WARNING, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_AT);
399     }
400
401     LL_FOREACH_SAFE(gCloud, p1, p2)
402     {
403         if (p1 && p1->cis && 0 == strcmp(p1->cis, cloud->cis))
404         {
405             ehRet = OC_EH_OK;
406             break;
407         }
408     }
409 exit:
410     response.requestHandle = ehRequest ? ehRequest->requestHandle : NULL;
411     response.payload = (OCPayload *)CreateCloudGetPayload(p1);
412     response.payload->type = PAYLOAD_TYPE_REPRESENTATION;
413     response.persistentBufferFlag = 0;
414
415     if (OC_STACK_OK != OCDoResponse(&response))
416     {
417         OIC_LOG_V(ERROR, TAG, "%s: send response", __func__);
418         ehRet = OC_EH_ERROR;
419     }
420
421     FreeCloud(cloud);
422
423     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
424
425     return ehRet;
426 }
427
428 static OCEntityHandlerResult HandleCloudDeleteRequest(OCEntityHandlerRequest *ehRequest)
429 {
430     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
431     OCEntityHandlerResult ehRet = OC_EH_INTERNAL_SERVER_ERROR;
432     OicCloud_t *cloud = NULL;
433     OCRepPayload *payload = NULL;
434     bool isDeviceOwned = false;
435     OicCloud_t *p1 = NULL, *p2 = NULL;
436     OCEntityHandlerResponse response;
437
438     VERIFY_NOT_NULL(TAG, ehRequest, ERROR);
439     VERIFY_NOT_NULL(TAG, ehRequest->payload, ERROR);
440
441     OCGetDeviceOwnedState(&isDeviceOwned);
442
443     if (!isDeviceOwned)
444     {
445         OIC_LOG_V(ERROR, TAG, "%s: device is not owned", __func__);
446         ehRet = OC_EH_NOT_ACCEPTABLE;
447         goto exit;
448     }
449
450     cloud = (OicCloud_t *) OICCalloc(1, sizeof(OicCloud_t));
451     VERIFY_NOT_NULL(TAG, cloud, ERROR);
452
453     payload = (OCRepPayload *)ehRequest->payload;
454
455     if (!cloud->cis || !OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_CIS, &cloud->cis))
456     {
457         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_CIS);
458         goto exit;
459     }
460     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_APN, &cloud->apn))
461     {
462         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_APN);
463     }
464     if (!OCRepPayloadGetPropString(payload, OC_CLOUD_PROVISIONING_AT, &cloud->at))
465     {
466         OIC_LOG_V(ERROR, TAG, "%s: Can't get: %s", __func__, OC_CLOUD_PROVISIONING_AT);
467     }
468
469     LL_FOREACH_SAFE(gCloud, p1, p2)
470     {
471         if (p1 && p1->cis && 0 == strcmp(p1->cis, cloud->cis))
472         {
473             OIC_LOG_V(INFO, TAG, "%s: delete cloud: %s", __func__, p1->cis);
474             p1->stat = OC_CLOUD_EXIT;
475             OCCloudSignOut(p1);
476             LL_DELETE(gCloud, p1);
477             ehRet = OC_EH_OK;
478             break;
479         }
480     }
481 exit:
482     response.requestHandle = ehRequest ? ehRequest->requestHandle : NULL;
483     response.ehResult = ehRet;
484     response.payload = (OCPayload *)OCRepPayloadCreate();
485     response.payload->type = PAYLOAD_TYPE_REPRESENTATION;
486     response.persistentBufferFlag = 0;
487
488     if (OC_STACK_OK != OCDoResponse(&response))
489     {
490         OIC_LOG_V(ERROR, TAG, "%s: send response", __func__);
491         ehRet = OC_EH_ERROR;
492     }
493
494     if (cloud)
495     {
496         FreeCloud(cloud);
497     }
498
499     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
500
501     return ehRet;
502 }
503
504
505 OCEntityHandlerResult CloudEntityHandler(OCEntityHandlerFlag flag,
506         OCEntityHandlerRequest *ehRequest, void *callbackParam)
507 {
508     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
509
510     OC_UNUSED(callbackParam);
511
512     VERIFY_NOT_NULL_RETURN(TAG, ehRequest, ERROR, OC_EH_ERROR);
513
514     OCEntityHandlerResult ehRet = OC_EH_ERROR;
515
516     if (flag & OC_REQUEST_FLAG)
517     {
518         switch (ehRequest->method)
519         {
520             case OC_REST_POST:
521                 ehRet = HandleCloudPostRequest(ehRequest);
522                 break;
523             case OC_REST_GET:
524                 ehRet = HandleCloudGetRequest(ehRequest);
525                 break;
526             case OC_REST_DELETE:
527                 ehRet = HandleCloudDeleteRequest(ehRequest);
528                 break;
529             default:
530                 OIC_LOG_V(WARNING, TAG, "%s: Unknow request: %d", __func__, ehRequest->method);
531                 usleep(300000);
532                 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
533                         OC_EH_OK : OC_EH_ERROR;
534                 break;
535         }
536     }
537     else
538     {
539         OIC_LOG_V(WARNING, TAG, "%s: Flag  does not includes OC_REQUEST_FLAG", __func__);
540     }
541
542     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
543     return ehRet;
544 }
545
546 OCStackResult CreateCloudResource()
547 {
548     OCStackResult ret = OCCreateResource(&gCloudHandle,
549                                          OIC_RSRC_TYPE_SEC_CLOUDCONF,
550                                          OC_RSRVD_INTERFACE_DEFAULT,
551                                          OIC_RSRC_CLOUDCONF_URI,
552                                          CloudEntityHandler,
553                                          NULL,
554                                          OC_SECURE | OC_NONSECURE |
555                                          OC_DISCOVERABLE);
556
557     if (OC_STACK_OK != ret)
558     {
559         OIC_LOG (FATAL, TAG, "Unable to create cloud config resource");
560         DeInitCloudResource();
561     }
562     return ret;
563 }
564
565 OCStackResult DeInitCloudResource()
566 {
567     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
568
569     OCStackResult ret = OCDeleteResource(gCloudHandle);
570     if (gCloud  != &gDefaultCloud)
571     {
572         DeleteCloudList(gCloud);
573     }
574
575     oc_mutex_free(gCloudMutex);
576
577     gCloud = NULL;
578
579     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
580
581     if (OC_STACK_OK == ret)
582     {
583         return OC_STACK_OK;
584     }
585     else
586     {
587         return OC_STACK_ERROR;
588     }
589 }
590
591 static void StartClouds()
592 {
593     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
594     bool isDeviceOwned = false;
595
596     OCGetDeviceOwnedState(&isDeviceOwned);
597
598     if (!isDeviceOwned)
599     {
600         OIC_LOG_V(ERROR, TAG, "%s: device is not owned", __func__);
601         return;
602     }
603
604     OicCloud_t *p1 = NULL, *p2 = NULL;
605     LL_FOREACH_SAFE(gCloud, p1, p2)
606     {
607         if (OC_CLOUD_PROV == p1->stat)
608         {
609             if (OC_STACK_OK != OCCloudSignUp(p1))
610             {
611                 OIC_LOG_V(ERROR, TAG, "%s: cloud sign up", __func__);
612             }
613         }
614     }
615
616     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
617 }
618
619 OCStackResult InitCloudResource()
620 {
621     uint8_t *data = NULL;
622     size_t size = 0;
623
624     gCloudMutex = oc_mutex_new();
625
626     if (OC_STACK_OK != GetSecureVirtualDatabaseFromPS(OIC_JSON_CLOUDS_NAME, &data, &size))
627     {
628         OIC_LOG (WARNING, TAG, "There is no cloud data in database");
629     }
630     else
631     {
632         if (data)
633         {
634             oc_mutex_lock(gCloudMutex);
635             if (OC_STACK_OK != CBORPayloadToCloud(data, size, &gCloud))
636             {
637                 OIC_LOG (WARNING, TAG, "There is no cloud data in database");
638             }
639             else
640             {
641                 StartClouds();
642             }
643             oc_mutex_unlock(gCloudMutex);
644         }
645     }
646
647     return CreateCloudResource();
648 }
649
650 bool UpdateCloudPersistentStorage()
651 {
652     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
653
654     VERIFY_NOT_NULL_RETURN(TAG, gCloud, ERROR, false);
655
656     bool ret = false;
657     uint8_t *payload = NULL;
658     size_t size = 0;
659     oc_mutex_lock(gCloudMutex);
660     if (OC_STACK_OK != CloudToCBORPayload(gCloud, &payload, &size))
661     {
662         OIC_LOG_V(ERROR, TAG, "%s: cloud to cbor", __func__);
663         goto exit;
664     }
665
666     VERIFY_NOT_NULL(TAG, payload, ERROR);
667
668     if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CLOUDS_NAME, payload, size))
669     {
670         ret = true;
671     }
672
673     OICFree(payload);
674 exit:
675     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
676     oc_mutex_unlock(gCloudMutex);
677     return ret;
678 }