replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / stack / samples / linux / secure / occlientdirectpairing.cpp
1 //******************************************************************\r
2 //\r
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.\r
4 //\r
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
6 //\r
7 // Licensed under the Apache License, Version 2.0 (the "License");\r
8 // you may not use this file except in compliance with the License.\r
9 // You may obtain a copy of the License at\r
10 //\r
11 //      http://www.apache.org/licenses/LICENSE-2.0\r
12 //\r
13 // Unless required by applicable law or agreed to in writing, software\r
14 // distributed under the License is distributed on an "AS IS" BASIS,\r
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16 // See the License for the specific language governing permissions and\r
17 // limitations under the License.\r
18 //\r
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
20 \r
21 #include "iotivity_config.h"\r
22 #include <stdio.h>\r
23 #include <stdlib.h>\r
24 #include <string.h>\r
25 #include <signal.h>\r
26 #ifdef HAVE_UNISTD_H\r
27 #include <unistd.h>\r
28 #endif\r
29 #ifdef HAVE_PTHREAD_H\r
30 #include <pthread.h>\r
31 #endif\r
32 #include <iostream>\r
33 #include <sstream>\r
34 #if defined(HAVE_WINDOWS_H)\r
35 #include <windows.h>\r
36 /** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */\r
37 #ifdef ERROR\r
38 #undef ERROR\r
39 #endif\r
40 #endif // defined(HAVE_WINDOWS_H)\r
41 #include "ocstack.h"\r
42 #include "logger.h"\r
43 #include "ocpayload.h"\r
44 #include "payload_logging.h"\r
45 #include "oic_malloc.h"\r
46 #include "oic_string.h"\r
47 #include "utlist.h"\r
48 \r
49 #define TAG "occlient-directpairing"\r
50 \r
51 #define BOLD_BEGIN    "\033[1m"\r
52 #define RED_BEGIN      "\033[1;31m"\r
53 #define GREEN_BEGIN  "\033[1;92m"\r
54 #define COLOR_END      "\033[0m"\r
55 #define MAX_LINE (1024)\r
56 #define DP_DISCOVERY_TIMEOUT   3  // 3 sec\r
57 #define DP_PIN_LENGTH 8 // 8 digit\r
58 \r
59 static char DISCOVERY_QUERY[] = "%s/oic/res";\r
60 \r
61 //Secure Virtual Resource database for Iotivity Client application\r
62 //It contains Client's Identity and the PSK credentials\r
63 //of other devices which the client trusts\r
64 static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat";\r
65 \r
66 static const OCDPDev_t *discoveredDevs = NULL;\r
67 static const OCDPDev_t *pairedDevs = NULL;\r
68 \r
69 int gQuitFlag = 0;\r
70 \r
71 //-----------------------------------------------------------------------------\r
72 // Function prototype\r
73 //-----------------------------------------------------------------------------\r
74 \r
75 \r
76 \r
77 \r
78 //-----------------------------------------------------------------------------\r
79 // Function body\r
80 //-----------------------------------------------------------------------------\r
81 \r
82 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */\r
83 void handleSigInt(int signum)\r
84 {\r
85     if (signum == SIGINT)\r
86     {\r
87         gQuitFlag = 1;\r
88     }\r
89 }\r
90 \r
91 const char *readline(const char *in, const char *defaultStr)\r
92 {\r
93     static char rbuffer[MAX_LINE] = {0,};\r
94     char *cptr, *p;\r
95 \r
96     size_t in_len = strlen(in);\r
97     for (size_t i=0; i<in_len; i++)\r
98     {\r
99         fprintf(stdout, "%c", in[i]);\r
100     }\r
101 \r
102     if (NULL != (cptr = fgets(rbuffer, MAX_LINE, stdin)))\r
103     {\r
104         /* kill preceding whitespace but leave \n so we're guaranteed to have something */\r
105         /*while(*cptr == ' ' || *cptr == '\t')\r
106         {\r
107             cptr++;\r
108         }*/\r
109 \r
110         if ( (p = strchr(cptr, '\n')) != NULL )\r
111         {\r
112             *p = '\0';\r
113         }\r
114 \r
115         if (strlen(cptr)==0 && defaultStr)\r
116         {\r
117             return defaultStr;\r
118         }\r
119         return cptr;\r
120     }\r
121     else\r
122     {\r
123         return 0;\r
124     }\r
125 }\r
126 \r
127 const char *getResult(OCStackResult result) {\r
128     switch (result) {\r
129     case OC_STACK_OK:\r
130         return "OC_STACK_OK";\r
131     case OC_STACK_RESOURCE_CREATED:\r
132         return "OC_STACK_RESOURCE_CREATED";\r
133     case OC_STACK_RESOURCE_DELETED:\r
134         return "OC_STACK_RESOURCE_DELETED";\r
135     case OC_STACK_INVALID_URI:\r
136         return "OC_STACK_INVALID_URI";\r
137     case OC_STACK_INVALID_QUERY:\r
138         return "OC_STACK_INVALID_QUERY";\r
139     case OC_STACK_INVALID_IP:\r
140         return "OC_STACK_INVALID_IP";\r
141     case OC_STACK_INVALID_PORT:\r
142         return "OC_STACK_INVALID_PORT";\r
143     case OC_STACK_INVALID_CALLBACK:\r
144         return "OC_STACK_INVALID_CALLBACK";\r
145     case OC_STACK_INVALID_METHOD:\r
146         return "OC_STACK_INVALID_METHOD";\r
147     case OC_STACK_NO_MEMORY:\r
148         return "OC_STACK_NO_MEMORY";\r
149     case OC_STACK_COMM_ERROR:\r
150         return "OC_STACK_COMM_ERROR";\r
151     case OC_STACK_INVALID_PARAM:\r
152         return "OC_STACK_INVALID_PARAM";\r
153     case OC_STACK_NOTIMPL:\r
154         return "OC_STACK_NOTIMPL";\r
155     case OC_STACK_NO_RESOURCE:\r
156         return "OC_STACK_NO_RESOURCE";\r
157     case OC_STACK_RESOURCE_ERROR:\r
158         return "OC_STACK_RESOURCE_ERROR";\r
159     case OC_STACK_SLOW_RESOURCE:\r
160         return "OC_STACK_SLOW_RESOURCE";\r
161     case OC_STACK_NO_OBSERVERS:\r
162         return "OC_STACK_NO_OBSERVERS";\r
163     #ifdef WITH_PRESENCE\r
164     case OC_STACK_PRESENCE_STOPPED:\r
165         return "OC_STACK_PRESENCE_STOPPED";\r
166     #endif\r
167     case OC_STACK_ERROR:\r
168         return "OC_STACK_ERROR";\r
169     default:\r
170         return "UNKNOWN";\r
171     }\r
172 }\r
173 \r
174 OCDPDev_t* getDev(const OCDPDev_t* pList, const uint32_t dev_num)\r
175 {\r
176     if(NULL == pList)\r
177     {\r
178         printf("     Device List is Empty..\n");\r
179         return NULL;\r
180     }\r
181 \r
182     OCDPDev_t* lst =  (OCDPDev_t*)pList;\r
183     for(size_t i=0; lst; )\r
184     {\r
185         if(dev_num == ++i)\r
186         {\r
187             return lst;\r
188         }\r
189         lst = lst->next;\r
190     }\r
191 \r
192     return NULL;  // in here |lst| is always |NULL|\r
193 }\r
194 \r
195 int printList(const OCDPDev_t* pList)\r
196 {\r
197     if(!pList)\r
198     {\r
199         printf("     Device List is Empty..\n\n");\r
200         return 0;\r
201     }\r
202 \r
203     const OCDPDev_t* lst = pList;\r
204     int lst_cnt = 0;\r
205     for( ; lst; )\r
206     {\r
207         printf("     [%d] ", ++lst_cnt);\r
208         for(int i=0; i<UUID_IDENTITY_SIZE; i++)\r
209         {\r
210             fprintf(stdout, "%c", (char)lst->deviceID.id[i]);\r
211         }\r
212         printf("\n");\r
213         lst = lst->next;\r
214     }\r
215     printf("\n");\r
216 \r
217     return lst_cnt;\r
218 }\r
219 \r
220 bool printPairingMethod(const OCDPDev_t* pDev)\r
221 {\r
222     printf("\n   * List of supported pairing method\n");\r
223 \r
224     if(!pDev || false == pDev->edp)\r
225     {\r
226         printf("     Invalid device or Not support direct-pairing..\n\n");\r
227         return false;\r
228     }\r
229 \r
230     if(!pDev->prm || 0 == pDev->prmLen)\r
231     {\r
232         printf("     Not exist any support method..\n\n");\r
233         return false;\r
234     }\r
235 \r
236     bool bAvailable = true;\r
237     for(size_t i=0; i<pDev->prmLen; i++)\r
238     {\r
239         printf("     [%ld] ", i+1);\r
240         switch (pDev->prm[i])\r
241         {\r
242             case DP_PRE_CONFIGURED:\r
243                 printf("Pre-Configured PIN");\r
244                 break;\r
245             case DP_RANDOM_PIN:\r
246                 printf("Random PIN");\r
247                 break;\r
248             default:\r
249                 printf("NOT Allowed (%d)", pDev->prm[i]);\r
250                 bAvailable = false;\r
251                 break;\r
252         }\r
253         printf("\n");\r
254     }\r
255     printf("\n");\r
256 \r
257     return bAvailable;\r
258 }\r
259 \r
260 // This is a function called back when a device is discovered\r
261 OCStackApplicationResult discoveryReqCB(void*, OCDoHandle,\r
262         OCClientResponse * clientResponse)\r
263 {\r
264     OIC_LOG(INFO, TAG, "Callback Context for DISCOVER query recvd successfully");\r
265 \r
266     if (clientResponse)\r
267     {\r
268         OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));\r
269         OIC_LOG_V(INFO, TAG,\r
270                 "Device =============> Discovered @ %s:%d",\r
271                 clientResponse->devAddr.addr,\r
272                 clientResponse->devAddr.port);\r
273 \r
274         if (clientResponse->result == OC_STACK_OK)\r
275         {\r
276             OIC_LOG_PAYLOAD(INFO, clientResponse->payload);\r
277         }\r
278     }\r
279 \r
280     return OC_STACK_DELETE_TRANSACTION;\r
281 \r
282 }\r
283 \r
284 // This is a function called back when direct-pairing status is changed\r
285 void pairingReqCB(void *ctx, OCDPDev_t* peer, OCStackResult result)\r
286 {\r
287     OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing establishment\n");\r
288 \r
289     (void) ctx;\r
290     if (OC_STACK_OK == result)\r
291     {\r
292         OIC_LOG_V(INFO, TAG,\r
293                 "Direct-Pairing SUCCESS =============> Target @ %s:%d\n",\r
294                 peer->endpoint.addr,\r
295                 peer->endpoint.port);\r
296     }\r
297     else\r
298     {\r
299         OIC_LOG(ERROR, TAG, "Direct-Pairing FAILED..\n");\r
300     }\r
301 }\r
302 \r
303 OCStackApplicationResult getReqCB(void * ctx, OCDoHandle handle, OCClientResponse *clientResponse)\r
304 {\r
305     OIC_LOG(INFO, TAG, "Callback Context for GET query recvd successfully");\r
306 \r
307     (void)ctx;\r
308     (void)handle;\r
309     if (clientResponse)\r
310     {\r
311         OIC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));\r
312         OIC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);\r
313         OIC_LOG_PAYLOAD(INFO, clientResponse->payload);\r
314         if ((OCSecurityPayload*)clientResponse->payload)\r
315         {\r
316             OIC_LOG(INFO, TAG, PCF("=============> Get Response"));\r
317         }\r
318     }\r
319     return OC_STACK_DELETE_TRANSACTION;\r
320 }\r
321 \r
322 int DeviceDiscovery()\r
323 {\r
324     OCStackResult ret;\r
325     OCCallbackData cbData;\r
326     char queryUri[200];\r
327     char ipaddr[100] = { '\0' };\r
328 \r
329     snprintf(queryUri, sizeof (queryUri), DISCOVERY_QUERY, ipaddr);\r
330 \r
331     cbData.cb = discoveryReqCB;\r
332     cbData.context = NULL;\r
333     cbData.cd = NULL;\r
334 \r
335     /* Start a discovery query*/\r
336     OIC_LOG_V(INFO, TAG, "Resource Discovery : %s\n", queryUri);\r
337 \r
338     ret = OCDoRequest(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,\r
339                       OC_LOW_QOS, &cbData, NULL, 0);\r
340     if (ret != OC_STACK_OK)\r
341     {\r
342         OIC_LOG(ERROR, TAG, "OCStack resource error");\r
343     }\r
344     return ret;\r
345 }\r
346 \r
347 OCStackResult DirectPairingDiscovery()\r
348 {\r
349     // initiate direct pairing discovery\r
350     OIC_LOG(INFO, TAG, "   Discovering Only Owned Devices on Network..");\r
351     discoveredDevs = OCDiscoverDirectPairingDevices(DP_DISCOVERY_TIMEOUT);\r
352     if(NULL == discoveredDevs)\r
353     {\r
354         OIC_LOG(ERROR, TAG, "OCDiscoverDirectPairingDevices API error");\r
355         return OC_STACK_ERROR;\r
356     }\r
357 \r
358     // display the discovered unowned list\r
359     printf("   > Discovered Direct-Pairing Support Devices\n");\r
360     printList(discoveredDevs);\r
361 \r
362     return OC_STACK_OK;\r
363 }\r
364 \r
365 OCStackResult DoDirectPairing(OCDPDev_t* peer, OCPrm_t pmSel, char *pinNumber)\r
366 {\r
367     if (NULL == peer || NULL == pinNumber)\r
368     {\r
369         OIC_LOG(ERROR, TAG, "invalid parameter");\r
370         return OC_STACK_INVALID_PARAM;\r
371     }\r
372 \r
373     // start direct pairing\r
374     OIC_LOG(INFO, TAG, "   Start Direct Pairing..");\r
375     if(OC_STACK_OK != OCDoDirectPairing(NULL, peer, pmSel, pinNumber, pairingReqCB))\r
376     {\r
377         OIC_LOG(ERROR, TAG, "OCDoDirectPairing API error");\r
378         return OC_STACK_ERROR;\r
379     }\r
380 \r
381     return OC_STACK_OK;\r
382 }\r
383 \r
384 OCStackResult SendGetRequest(OCDPDev_t* peer)\r
385 {\r
386     OIC_LOG(INFO, TAG, "Send Get REQ to Led server");\r
387 \r
388     char szQueryUri[] = "/a/led";\r
389     OCDoHandle handle;\r
390     OCCallbackData cbData;\r
391     OCDevAddr endpoint;\r
392     OCStackResult ret;\r
393 \r
394     memcpy(&endpoint, &peer->endpoint, sizeof(OCDevAddr));\r
395     endpoint.port = peer->securePort;\r
396     endpoint.flags = (OCTransportFlags)(endpoint.flags | OC_SECURE);\r
397 \r
398     cbData.cb = getReqCB;\r
399     cbData.context = NULL;\r
400     cbData.cd = NULL;\r
401 \r
402     OIC_LOG(INFO, TAG, "Request to /a/light ");\r
403     ret = OCDoRequest(&handle, OC_REST_GET, szQueryUri,\r
404                       &endpoint, NULL, peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
405     if (ret != OC_STACK_OK)\r
406     {\r
407         OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, OC_REST_GET);\r
408     }\r
409 \r
410     return ret;\r
411 }\r
412 \r
413 FILE* client_fopen(const char *path, const char *mode)\r
414 {\r
415     (void)path;\r
416     return fopen(CRED_FILE, mode);\r
417 }\r
418 \r
419 void *CLInterface(void *data)\r
420 {\r
421     printf(RED_BEGIN "#Ready to operation ('h' for help)#\n" COLOR_END);\r
422 \r
423     (void)data;\r
424     OCStackResult ret;\r
425     char query[MAX_LINE] = {0};\r
426     const char prompt[] = BOLD_BEGIN "IoTivity-DP#" COLOR_END" ";\r
427     const char* helpmsg[6] = {\r
428             GREEN_BEGIN "# h  (or help) : show help message" COLOR_END,\r
429             GREEN_BEGIN "# dd (DP device discovery) : discover Direct-Pairing devices" COLOR_END,\r
430             GREEN_BEGIN "# dp (start Direct-Pairing) : negotiate DP method & start Direct-Pairing" COLOR_END,\r
431             GREEN_BEGIN "# sd (send data) : send data to device" COLOR_END,\r
432             GREEN_BEGIN "# ll (list all device) : list all discovered/paired devices" COLOR_END,\r
433             GREEN_BEGIN "# q  (quit) : quit test" COLOR_END,\r
434         };\r
435 \r
436     for (size_t i=0; i<(sizeof(helpmsg)/sizeof(char*)); i++)\r
437     {\r
438         fprintf(stderr, "%s\n", helpmsg[i]);\r
439     }\r
440     printf("\n");\r
441 \r
442     // cli\r
443     for (;;)\r
444     {\r
445         const char *input = readline(prompt, NULL);\r
446         if (!input) {\r
447             continue;\r
448         }\r
449 \r
450         strncpy(query, input, MAX_LINE);\r
451         if (!strlen(query))\r
452         {\r
453             continue;\r
454         }\r
455         else if (!strcmp(query, "h") || !strcmp(query, "help"))\r
456         {\r
457             for (size_t i=0; i<(sizeof(helpmsg)/sizeof(char*)); i++)\r
458             {\r
459                 fprintf(stderr, "%s\n", helpmsg[i]);\r
460             }\r
461             continue;\r
462         }\r
463         else\r
464         {\r
465             if (!strcmp(query, "dd"))\r
466             {\r
467                 OIC_LOG(INFO, TAG, "- Direct-Pairing device discovery -");\r
468 \r
469                 ret = DirectPairingDiscovery();\r
470                 if (OC_STACK_OK != ret)\r
471                 {\r
472                     OIC_LOG(ERROR, TAG, "Error in DirectPairingDiscovery()");\r
473                 }\r
474             }\r
475             else if (!strcmp(query, "dp"))\r
476             {\r
477                 OIC_LOG(INFO, TAG, "- Negotiate DP method & Start Direct-Pairing -");\r
478 \r
479                 printf("\n   * List of  discovered device\n");\r
480                 printList(discoveredDevs);\r
481 \r
482                 // target peer\r
483                 OCDPDev_t *peer = NULL;\r
484                 long peerIdx;\r
485                 input = readline("   > Enter Peer Device Number to initiate Direct-Pairing: ", NULL);\r
486                 if (!input || !strlen(input))\r
487                 {\r
488                     continue;\r
489                 }\r
490                 char *ptr;\r
491                 peerIdx = strtol(input, &ptr, 10);\r
492 \r
493                 peer = getDev(discoveredDevs, (uint32_t)peerIdx);\r
494                 if (NULL == peer)\r
495                 {\r
496                     OIC_LOG(ERROR, TAG, "Not found the peer in discovered list");\r
497                     continue;\r
498                 }\r
499 \r
500                 // get pairing method\r
501                 long pmIdx;\r
502                 OCPrm_t pmSel = DP_NOT_ALLOWED;\r
503                 if (false == printPairingMethod(peer))\r
504                 {\r
505                     OIC_LOG(ERROR, TAG, "Target does not support the Direct-Pairing");\r
506                     continue;\r
507                 }\r
508                 input = readline("   > Enter pairing method: ", NULL);\r
509                 if (!input || !strlen(input))\r
510                 {\r
511                     continue;\r
512                 }\r
513                 pmIdx = strtol(input, &ptr, 10);\r
514                 printf("\n");\r
515                 if (0 >= pmIdx || peer->prmLen+1 < (size_t)pmIdx)\r
516                 {\r
517                     OIC_LOG(ERROR, TAG, "Invalid mode selection");\r
518                     continue;\r
519                 }\r
520                 pmSel = peer->prm[pmIdx-1];\r
521 \r
522                 // get PIN\r
523                 char pinNumber[DP_PIN_LENGTH+1];\r
524                 input = readline("   > Enter PIN Number for authentication (ex - '00000000' [8 digit] ): ", NULL);\r
525                 if (!input || DP_PIN_LENGTH != strlen(input))\r
526                 {\r
527                     OIC_LOG(ERROR, TAG, "Invalid PIN");\r
528                     continue;\r
529                 }\r
530                 sscanf(input, "%8s", pinNumber);\r
531                 printf("\n");\r
532 \r
533                 ret = DoDirectPairing(peer, pmSel, pinNumber);\r
534                 if (OC_STACK_OK != ret)\r
535                 {\r
536                     OIC_LOG(ERROR, TAG, "Error in DoDirectPairing()");\r
537                 }\r
538             }\r
539             else if (!strcmp(query, "sd"))\r
540             {\r
541                 OIC_LOG(INFO, TAG, "- Send data(GET Request) to device(led server) -");\r
542 \r
543                 //pairedDevs = OCGetDirectPairedDevices();\r
544                 //printList(pairedDevs);\r
545                 printList(discoveredDevs);\r
546 \r
547                 // target peer\r
548                 OCDPDev_t *peer = NULL;\r
549                 long peerIdx;\r
550                 input = readline("   > Enter Peer Device Number to initiate Direct-Pairing: ", NULL);\r
551                 if (!input || !strlen(input))\r
552                 {\r
553                     continue;\r
554                 }\r
555                 char *ptr;\r
556                 peerIdx = strtol(input, &ptr, 10);\r
557 \r
558                 //peer = getDev(pairedDevs, peerIdx);\r
559                 peer = getDev(discoveredDevs, (uint32_t)peerIdx);\r
560                 if (NULL == peer)\r
561                 {\r
562                     OIC_LOG(ERROR, TAG, "Not found the peer in discovered list");\r
563                     continue;\r
564                 }\r
565 \r
566                 // send Get Req\r
567                 ret = SendGetRequest(peer);\r
568                 if (OC_STACK_OK != ret)\r
569                 {\r
570                     OIC_LOG(ERROR, TAG, "Error in SendGetRequest()");\r
571                 }\r
572             }\r
573             else if (!strcmp(query, "ll"))\r
574             {\r
575                 OIC_LOG(INFO, TAG, "- List all discovered and paired devices) -");\r
576 \r
577                 printf("  > List of discovered devices\n");\r
578                 printList(discoveredDevs);\r
579                 printf("\n");\r
580 \r
581                 printf("  > List of paired devices\n");\r
582                 pairedDevs = OCGetDirectPairedDevices();\r
583                 printList(pairedDevs);\r
584                 printf("\n");\r
585             }\r
586             else if (!strcmp(query, "q"))\r
587             {\r
588                 printf("QUIT\n");\r
589                 gQuitFlag = 1;\r
590                 break;\r
591             }\r
592         }\r
593     }\r
594 \r
595     return 0;\r
596 }\r
597 \r
598 int main(void)\r
599 {\r
600     struct timespec timeout;\r
601 \r
602     // Initialize Persistent Storage for SVR database\r
603     OCPersistentStorage ps = { client_fopen, fread, fwrite, fclose, unlink };\r
604     OCRegisterPersistentStorageHandler(&ps);\r
605 \r
606     /* Initialize OCStack*/\r
607     if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)\r
608     {\r
609         OIC_LOG(ERROR, TAG, "OCStack init error");\r
610         return 0;\r
611     }\r
612 \r
613 //    DeviceDiscovery();\r
614 \r
615     timeout.tv_sec  = 0;\r
616     timeout.tv_nsec = 100000000L;\r
617 \r
618     // Break from loop with Ctrl+C\r
619     OIC_LOG(INFO, TAG, "Entering occlient main loop...");\r
620     signal(SIGINT, handleSigInt);\r
621 \r
622     // CLI\r
623     int thr_id;\r
624     pthread_t p_thread;\r
625     thr_id = pthread_create(&p_thread, NULL, CLInterface, (void *)NULL);\r
626     if (thr_id < 0)\r
627     {\r
628         OIC_LOG(ERROR, TAG, "create CLI Thread error");\r
629         return 0;\r
630     }\r
631 \r
632     // loop\r
633     while (!gQuitFlag)\r
634     {\r
635         if (OCProcess() != OC_STACK_OK)\r
636         {\r
637             OIC_LOG(ERROR, TAG, "OCStack process error");\r
638             return 0;\r
639         }\r
640 \r
641 #if defined(_WIN32)\r
642         Sleep(100);\r
643 #else\r
644         nanosleep(&timeout, NULL);\r
645 #endif // defined(_WIN32)\r
646 \r
647     }\r
648     OIC_LOG(INFO, TAG, "Exiting occlient main loop...");\r
649 \r
650     if (OCStop() != OC_STACK_OK)\r
651     {\r
652         OIC_LOG(ERROR, TAG, "OCStack stop error");\r
653     }\r
654 \r
655     return 0;\r
656 }\r