Deprecate OCSetDeviceInfo and registerDeviceInfo
[platform/upstream/iotivity.git] / cloud / samples / client / thin_light / thin_room_light.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 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 ///
22 /// This sample provides the way to create cloud sample
23 ///
24 #include <memory>
25 #include <iostream>
26 #include <stdexcept>
27 #include <condition_variable>
28 #include <map>
29 #include <vector>
30 #include <string>
31 #include <pthread.h>
32 #include <unistd.h>
33
34 #include "ocstack.h"
35 #include "ocpayload.h"
36 #include "rd_client.h"
37 #include "OCPlatform.h"
38
39 using namespace std;
40
41 #define VERIFY_SUCCESS(op)                          \
42 {                                                   \
43     if (op != OC_STACK_OK)                          \
44     {                                               \
45         cout << #op << " failed!!" << endl;         \
46         goto exit;                                  \
47     }                                               \
48 }
49
50 #define DEFAULT_CONTEXT_VALUE 0x99
51 #define DEFAULT_AUTH_SIGNUP "/oic/account"
52 #define DEFAULT_AUTH_SESSION "/oic/account/session"
53 #define DEFAULT_AUTH_REFRESH "/oic/account/tokenrefresh"
54
55 OCStackResult OCCloudSignup(const char *host, const char *deviceId, const char *authprovider,
56                             const char *authcode, OCClientResponseHandler response)
57 {
58     char targetUri[MAX_URI_LENGTH * 2] =
59     { 0, };
60     snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_SIGNUP);
61
62     OCCallbackData cbData;
63     memset(&cbData, 0, sizeof(OCCallbackData));
64     cbData.cb = response;
65     cbData.cd = NULL;
66     cbData.context = (void *) DEFAULT_CONTEXT_VALUE;
67
68     OCRepPayload *registerPayload = OCRepPayloadCreate();
69     if (!registerPayload)
70     {
71         goto no_memory;
72     }
73
74     OCRepPayloadSetPropString(registerPayload, "di", deviceId);
75     OCRepPayloadSetPropString(registerPayload, "authprovider", authprovider);
76     OCRepPayloadSetPropString(registerPayload, "authcode", authcode);
77
78     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) registerPayload,
79                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
80
81 no_memory:
82     OCRepPayloadDestroy(registerPayload);
83     return OC_STACK_NO_MEMORY;
84 }
85
86 OCStackResult OCCloudSession(const char *host, const char *query, const char *uId,
87                              const char *deviceId, const char *accesstoken, bool isLogin,
88                              OCClientResponseHandler response)
89 {
90     char targetUri[MAX_URI_LENGTH * 2] =
91     { 0, };
92     snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
93
94     OCCallbackData cbData;
95     memset(&cbData, 0, sizeof(OCCallbackData));
96     cbData.cb = response;
97     cbData.cd = NULL;
98     cbData.context = (void *) DEFAULT_CONTEXT_VALUE;
99
100     OCRepPayload *loginoutPayload = OCRepPayloadCreate();
101     if (!loginoutPayload)
102     {
103         goto no_memory;
104     }
105
106     if (uId != NULL)
107     {
108         OCRepPayloadSetPropString(loginoutPayload, "uid", uId);
109     }
110
111     if (deviceId != NULL)
112     {
113         OCRepPayloadSetPropString(loginoutPayload, "di", deviceId);
114     }
115
116     if (accesstoken != NULL)
117     {
118         OCRepPayloadSetPropString(loginoutPayload, "accesstoken", accesstoken);
119     }
120     OCRepPayloadSetPropBool(loginoutPayload, "login", isLogin);
121
122     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) loginoutPayload,
123                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
124
125 no_memory:
126     OCRepPayloadDestroy(loginoutPayload);
127     return OC_STACK_NO_MEMORY;
128 }
129
130 //Client should call refresh before expiresin or when receive 4.01 during sign-in
131 OCStackResult OCCloudRefresh(const char *host, const char *query, const char *uId,
132                              const char *deviceId, const char *refreshtoken, OCClientResponseHandler response)
133 {
134     char targetUri[MAX_URI_LENGTH * 2] =
135     { 0, };
136     snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
137
138     OCCallbackData cbData;
139     memset(&cbData, 0, sizeof(OCCallbackData));
140     cbData.cb = response;
141     cbData.cd = NULL;
142     cbData.context = (void *) DEFAULT_CONTEXT_VALUE;
143
144     OCRepPayload *refreshPayload = OCRepPayloadCreate();
145     if (!refreshPayload)
146     {
147         goto no_memory;
148     }
149
150     OCRepPayloadSetPropString(refreshPayload, "uid", uId);
151     OCRepPayloadSetPropString(refreshPayload, "di", deviceId);
152     OCRepPayloadSetPropString(refreshPayload, "granttype", "refresh_token");
153     OCRepPayloadSetPropString(refreshPayload, "refreshtoken", refreshtoken);
154
155     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *) refreshPayload,
156                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
157
158 no_memory:
159     OCRepPayloadDestroy(refreshPayload);
160     return OC_STACK_NO_MEMORY;
161 }
162
163 OCStackResult OCCloudLogin(const char *host, const char *uId, const char *deviceId,
164                            const char *accesstoken, OCClientResponseHandler response)
165 {
166     return OCCloudSession(host, DEFAULT_AUTH_SESSION, uId, deviceId, accesstoken, true, response);
167 }
168
169 OCStackResult OCCloudLogout(const char *host, OCClientResponseHandler response)
170 {
171     return OCCloudSession(host, DEFAULT_AUTH_SESSION, NULL, NULL, NULL, false, response);
172 }
173
174 ////////////////////////////////////////Device Sample
175
176 #define SAMPLE_MAX_NUM_POST_INSTANCE  1
177 typedef struct LIGHTRESOURCE
178 {
179     OCResourceHandle handle;
180     bool state;
181     int power;
182 } LightResource;
183 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
184
185 OCRepPayload *responsePayload(int64_t power, bool state)
186 {
187     OCRepPayload *payload = OCRepPayloadCreate();
188     if (!payload)
189     {
190         cout << "Failed to allocate Payload" << endl;
191         return nullptr;
192     }
193
194     OCRepPayloadSetPropBool(payload, "state", state);
195     OCRepPayloadSetPropInt(payload, "power", power);
196
197     return payload;
198 }
199
200 OCRepPayload *constructResponse(OCEntityHandlerRequest *ehRequest)
201 {
202     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
203     {
204         cout << "Incoming payload not a representation" << endl;
205         return nullptr;
206     }
207
208     LightResource *currLightResource = NULL;
209
210     if (ehRequest->resource == gLightInstance[0].handle)
211     {
212         currLightResource = &gLightInstance[0];
213     }
214
215     if (OC_REST_PUT == ehRequest->method)
216     {
217         // Get pointer to query
218         int64_t pow;
219         OCRepPayload *input = reinterpret_cast< OCRepPayload * >(ehRequest->payload);
220
221         if (OCRepPayloadGetPropInt(input, "power", &pow))
222         {
223             currLightResource->power = pow;
224         }
225
226         bool state;
227         if (OCRepPayloadGetPropBool(input, "state", &state))
228         {
229             currLightResource->state = state;
230         }
231     }
232
233     return responsePayload(currLightResource->power, currLightResource->state);
234 }
235
236 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
237 {
238     OCRepPayload *getResp = constructResponse(ehRequest);
239     if (!getResp)
240     {
241         cout << "constructResponse failed" << endl;
242         return OC_EH_ERROR;
243     }
244
245     *payload = getResp;
246
247     return OC_EH_OK;
248 }
249
250 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
251 {
252     OCEntityHandlerResult ehResult;
253     OCRepPayload *putResp = constructResponse(ehRequest);
254
255     if (!putResp)
256     {
257         cout << "Failed to construct Json response" << endl;
258         return OC_EH_ERROR;
259     }
260
261     *payload = putResp;
262     ehResult = OC_EH_OK;
263
264     return ehResult;
265 }
266
267 #define SAMPLE_MAX_NUM_OBSERVATIONS  2
268 static bool observeThreadStarted = false;
269 int gLightUnderObservation = 0;
270 pthread_t threadId_observe;
271 typedef struct
272 {
273     OCObservationId observationId;
274     bool valid;
275     OCResourceHandle resourceHandle;
276 } Observers;
277 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
278
279 void *ChangeLightRepresentation(void *param)
280 {
281     (void) param;
282     OCStackResult result = OC_STACK_ERROR;
283
284     while (true)
285     {
286         sleep(3);
287         gLightInstance[0].power += 1;
288
289         if (gLightUnderObservation)
290         {
291             cout << " =====> Notifying stack of new power level " << gLightInstance[0].power
292                  << endl;
293             // Notifying all observers
294             result = OCNotifyAllObservers(gLightInstance[0].handle, OC_NA_QOS);
295
296             cout << " =====> Notifying result " << result << endl;
297         }
298     }
299     return NULL;
300 }
301
302 void ProcessObserveRegister(OCEntityHandlerRequest *ehRequest)
303 {
304     cout << "Received observation registration request with observation Id "
305          << ehRequest->obsInfo.obsId << endl;
306
307     if (!observeThreadStarted)
308     {
309         pthread_create(&threadId_observe, NULL, ChangeLightRepresentation, (void *) NULL);
310         observeThreadStarted = 1;
311     }
312     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
313     {
314         if (interestedObservers[i].valid == false)
315         {
316             interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
317             interestedObservers[i].valid = true;
318             gLightUnderObservation = 1;
319             break;
320         }
321     }
322 }
323
324 void ProcessObserveDeregister(OCEntityHandlerRequest *ehRequest)
325 {
326     bool clientStillObserving = false;
327
328     cout << "Received observation deregistration request for observation Id "
329          << ehRequest->obsInfo.obsId << endl;
330     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
331     {
332         if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
333         {
334             interestedObservers[i].valid = false;
335         }
336         if (interestedObservers[i].valid == true)
337         {
338             // Even if there is one single client observing we continue notifying entity handler
339             clientStillObserving = true;
340         }
341     }
342     if (clientStillObserving == false)
343         gLightUnderObservation = 0;
344 }
345
346 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
347                                         OCEntityHandlerRequest *entityHandlerRequest, void * /*callback*/)
348 {
349     OCEntityHandlerResult ehResult = OC_EH_OK;
350     OCEntityHandlerResponse response =
351     {
352         0, 0, OC_EH_ERROR, 0, 0,
353         { },
354         { 0 }, false
355     };
356
357     // Validate pointer
358     if (!entityHandlerRequest)
359     {
360         cout << "Invalid request pointer" << endl;
361         return OC_EH_ERROR;
362     }
363
364     // Initialize certain response fields
365     response.numSendVendorSpecificHeaderOptions = 0;
366     memset(response.sendVendorSpecificHeaderOptions, 0,
367            sizeof response.sendVendorSpecificHeaderOptions);
368     memset(response.resourceUri, 0, sizeof response.resourceUri);
369     OCRepPayload *payload = nullptr;
370
371     if (flag & OC_REQUEST_FLAG)
372     {
373         cout << "Flag includes OC_REQUEST_FLAG" << endl;
374
375         if (OC_REST_GET == entityHandlerRequest->method)
376         {
377             cout << "Received OC_REST_GET from client" << endl;
378             ehResult = ProcessGetRequest(entityHandlerRequest, &payload);
379         }
380         else if (OC_REST_PUT == entityHandlerRequest->method)
381         {
382             cout << "Received OC_REST_PUT from client" << endl;
383             ehResult = ProcessPutRequest(entityHandlerRequest, &payload);
384         }
385         else
386         {
387             cout << "Received unsupported method %d from client " << entityHandlerRequest->method
388                  << endl;
389             ehResult = OC_EH_ERROR;
390         }
391         // If the result isn't an error or forbidden, send response
392         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
393         {
394             // Format the response.  Note this requires some info about the request
395             response.requestHandle = entityHandlerRequest->requestHandle;
396             response.resourceHandle = entityHandlerRequest->resource;
397             response.ehResult = ehResult;
398             response.payload = reinterpret_cast< OCPayload * >(payload);
399             // Indicate that response is NOT in a persistent buffer
400             response.persistentBufferFlag = 0;
401
402             // Send the response
403             if (OCDoResponse(&response) != OC_STACK_OK)
404             {
405                 cout << "Error sending response" << endl;
406                 ehResult = OC_EH_ERROR;
407             }
408         }
409     }
410
411     if (flag & OC_OBSERVE_FLAG)
412     {
413         cout << "Flag includes OC_OBSERVE_FLAG" << endl;
414         if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
415         {
416             cout << "Received OC_OBSERVE_REGISTER from client" << endl;
417             ProcessObserveRegister(entityHandlerRequest);
418         }
419         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
420         {
421             cout << "Received OC_OBSERVE_DEREGISTER from client" << endl;
422             ProcessObserveDeregister(entityHandlerRequest);
423         }
424     }
425
426     OCPayloadDestroy(response.payload);
427     return ehResult;
428 }
429
430 int createLightResource(char *uri, LightResource *lightResource)
431 {
432     if (!uri)
433     {
434         cout << "Resource URI cannot be NULL" << endl;
435         return -1;
436     }
437
438     lightResource->state = false;
439     lightResource->power = 0;
440     OCStackResult res = OCCreateResource(&(lightResource->handle), "core.light", "oc.mi.def", uri,
441                                          OCEntityHandlerCb, NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
442     cout << "Created Light resource with result:" << res << endl;
443
444     return res;
445 }
446
447 OCStackApplicationResult handlePublishCB(void *ctx, OCDoHandle /*handle*/,
448         OCClientResponse *clientResponse)
449 {
450     if (ctx != (void *) DEFAULT_CONTEXT_VALUE)
451     {
452         cout << "Invalid Publish callback received" << endl;
453     }
454
455     cout << "Publish resource response received, code: " << clientResponse->result << endl;
456
457     return OC_STACK_KEEP_TRANSACTION;
458 }
459
460 OCStackResult SetDeviceInfo()
461 {
462     OCResourceHandle resourceHandle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
463     if (resourceHandle == NULL)
464     {
465         cout << "Device Resource does not exist." << endl;
466         goto exit;
467     }
468
469     VERIFY_SUCCESS(OCBindResourceTypeToResource(resourceHandle, "oic.d.light"));
470
471     if (OCGetServerInstanceIDString() == NULL)
472     {
473         cout << "Device ID generation failed"  << endl;
474         goto exit;
475     }
476
477     VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, "Living Room Light"));
478
479     cout << "Device information published successfully." << endl;
480     return OC_STACK_OK;
481
482 exit:
483     return OC_STACK_ERROR;
484 }
485
486 void PublishResources(string host)
487 {
488     cout << "Publishing resources..." << endl;
489
490     if (createLightResource((char *) "/a/light/0", &gLightInstance[0]) != 0)
491     {
492         cout << "Unable to create sample resource" << endl;
493     }
494
495     OCResourceHandle resourceHandles[1] =
496     { gLightInstance[0].handle, };
497     OCCallbackData cbData;
498     cbData.cb = handlePublishCB;
499     cbData.context = (void *) DEFAULT_CONTEXT_VALUE;
500     cbData.cd = NULL;
501
502     cout << "Publishing default resources" << endl;
503
504     OCStackResult res = SetDeviceInfo();
505
506     if (res != OC_STACK_OK)
507     {
508         cout << "Publishing device info failed" << endl;
509     }
510
511     res = OCRDPublish(host.c_str(), CT_ADAPTER_TCP, NULL, 0, &cbData, OC_LOW_QOS);
512     if (res != OC_STACK_OK)
513     {
514         cout << "Unable to publish default resources to cloud" << endl;
515     }
516
517     cout << "Publishing user resources" << endl;
518
519     res = OCRDPublish(host.c_str(), CT_ADAPTER_TCP, resourceHandles, 1, &cbData, OC_LOW_QOS);
520     if (res != OC_STACK_OK)
521     {
522         cout << "Unable to publish user resources to cloud" << endl;
523     }
524 }
525
526 /////////////////////////////////////////////Common sample
527 void printRepresentation(OCRepPayloadValue *value)
528 {
529     while (value)
530     {
531         cout << "Key: " << value->name;
532         switch (value->type)
533         {
534             case OCREP_PROP_NULL:
535                 cout << " Value: None" << endl;
536                 break;
537             case OCREP_PROP_INT:
538                 cout << " Value: " << value->i << endl;
539                 break;
540             case OCREP_PROP_DOUBLE:
541                 cout << " Value: " << value->d << endl;
542                 break;
543             case OCREP_PROP_BOOL:
544                 cout << " Value: " << value->b << endl;
545                 break;
546             case OCREP_PROP_STRING:
547                 cout << " Value: " << value->str << endl;
548                 break;
549             case OCREP_PROP_BYTE_STRING:
550                 cout << " Value: Byte String" << endl;
551                 break;
552             case OCREP_PROP_OBJECT:
553                 cout << " Value: Object" << endl;
554                 break;
555             case OCREP_PROP_ARRAY:
556                 cout << " Value: Array" << endl;
557                 break;
558         }
559         value = value->next;
560     }
561 }
562
563 string g_host = "coap+tcp://";
564
565 OCStackApplicationResult handleLoginoutCB(void *ctx, OCDoHandle /*handle*/,
566         OCClientResponse *clientResponse)
567 {
568     if (ctx != (void *) DEFAULT_CONTEXT_VALUE)
569     {
570         cout << "Invalid Login/out callback received" << endl;
571     }
572
573     cout << "Login/out response received code: " << clientResponse->result << endl;
574
575     if (clientResponse->payload != NULL
576         && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
577     {
578         cout << "PAYLOAD_TYPE_REPRESENTATION received" << endl;
579
580         OCRepPayloadValue *val = ((OCRepPayload *) clientResponse->payload)->values;
581
582         printRepresentation(val);
583     }
584
585     if (clientResponse->result < 5)
586     {
587         PublishResources(g_host);
588     }
589
590     return OC_STACK_KEEP_TRANSACTION;
591 }
592
593 OCStackApplicationResult handleRegisterCB(void *ctx, OCDoHandle /*handle*/,
594         OCClientResponse *clientResponse)
595 {
596     if (ctx != (void *) DEFAULT_CONTEXT_VALUE)
597     {
598         cout << "Invalid Register callback received" << endl;
599     }
600
601     cout << "Register response received code: " << clientResponse->result << endl;
602
603     if (clientResponse->payload != NULL
604         && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
605     {
606         cout << "PAYLOAD_TYPE_REPRESENTATION received" << endl;
607         cout << "You can Sign-In using retrieved accesstoken when disconnected or reboot" << endl;
608
609         OCRepPayloadValue *val = ((OCRepPayload *) clientResponse->payload)->values;
610
611         printRepresentation(val);
612     }
613
614     return OC_STACK_KEEP_TRANSACTION;
615 }
616
617 void PrintUsage()
618 {
619     cout << endl;
620     cout << "Usage : thin_room_light <addr:port> <uid> <accesstoken>\n";
621     cout << "<addr:port>: Cloud Address, \"127.0.0.1:5683\"\n";
622     cout
623             << "<accesstoken>: String value, Provided by response of onboarding scenario\n\tor kind of registration portal\n\n";
624     cout << "sample: \"thin_room_light 127.0.0.1:5683\"\n\t-Sign-Up mode\n\n";
625     cout
626             << "sample: \"thin_room_light 127.0.0.1:5683 abcdefg 1234567890123456\"\n\t-Sign-in and Publish resource to registered account\n\n";
627
628     cout << endl;
629     cout << "Usage : thin_room_light <addr:port> <uid> <refreshtoken> 1\n";
630     cout
631             << "<refreshtoken>: String value, Provided by response of onboarding scenario\n\tor kind of registration portal\n\n";
632     cout
633             << "sample: \"thin_room_light 127.0.0.1:5683 abcdefg 6543210987654321 1\"\n\t-token refresh and get renewed access token\n\n";
634
635 }
636
637 static FILE *client_open(const char * /*path*/, const char *mode)
638 {
639     return fopen("./thin_resource_server.dat", mode);
640 }
641
642 int main(int argc, char *argv[])
643 {
644     string uId;
645     string accessToken;
646     string refreshToken;
647     string authProvider;
648     string authCode;
649
650     OCMode stackMode = OC_CLIENT_SERVER;
651
652     switch (argc)
653     {
654         case 2:
655             cout << "Put auth provider name(ex: github)" << endl;
656             cin >> authProvider;
657             cout << "Put auth code(provided by auth provider)" << endl;
658             cin >> authCode;
659             break;
660
661         case 4:
662             uId = argv[2];
663             accessToken = argv[3];
664             break;
665
666         case 5:
667             uId = argv[2];
668             refreshToken = argv[3];
669             break;
670
671         default:
672             PrintUsage();
673             return 0;
674     }
675
676     g_host += argv[1];
677
678     cout << "Host " << g_host.c_str() << endl;
679
680     OCPersistentStorage ps
681     { client_open, fread, fwrite, fclose, unlink };
682     if (OCRegisterPersistentStorageHandler(&ps) != OC_STACK_OK)
683     {
684         cout << "OCStack init persistent storage error" << endl;
685         return 0;
686     }
687
688     if (OCInit(NULL, 0, stackMode) != OC_STACK_OK)
689     {
690         cout << "OCStack init error" << endl;
691         return 0;
692     }
693
694     OCStackResult res = OC_STACK_ERROR;
695
696     switch (argc)
697     {
698         case 2:
699             cout << "Sign-Up to cloud using " << authProvider << " " << authCode << endl;
700             res = OCCloudSignup(g_host.c_str(), OCGetServerInstanceIDString(), authProvider.c_str(),
701                                 authCode.c_str(), handleRegisterCB);
702             cout << "OCCloudSignup return " << res << endl;
703             break;
704
705         case 4:
706             cout << "Sign-In to cloud using " << accessToken << endl;
707             res = OCCloudLogin(g_host.c_str(), uId.c_str(), OCGetServerInstanceIDString(),
708                                accessToken.c_str(), handleLoginoutCB);
709             cout << "OCCloudLogin return " << res << endl;
710             break;
711
712         case 5:
713             cout << "Token refresh to cloud using the refresh token " << refreshToken << endl;
714             res = OCCloudRefresh(g_host.c_str(), DEFAULT_AUTH_REFRESH, uId.c_str(),
715                                  OCGetServerInstanceIDString(), refreshToken.c_str(), handleRegisterCB);
716             cout << "OCCloudRefresh return " << res << endl;
717             break;
718
719         default:
720             PrintUsage();
721             return 0;
722     }
723
724     cout << "Waiting response.." << endl;
725
726     while (true)
727     {
728         if (OCProcess() != OC_STACK_OK)
729         {
730             cout << "OCProcess process error" << endl;
731         }
732
733         sleep(1);
734     }
735
736     if (OCStop() != OC_STACK_OK)
737     {
738         cout << "OCStop process error" << endl;
739     }
740
741     return 0;
742 }