Merge branch 'master' into resource-manipulation
[platform/upstream/iotivity.git] / resource / csdk / stack / samples / linux / SimpleClientServer / occlientbasicops.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 //      http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
18 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <stdint.h>
26 #include <sstream>
27
28 #include "ocstack.h"
29 #include "logger.h"
30 #include "occlientbasicops.h"
31 #include "cJSON.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34
35 #define MAX_IP_ADDR_ST_SZ  16 //string size of "155.255.255.255" (15 + 1)
36 #define MAX_PORT_ST_SZ  6     //string size of "65535" (5 + 1)
37
38 static int IPV4_ADDR_SIZE = 24;
39 static int UNICAST_DISCOVERY = 0;
40 static int TEST_CASE = 0;
41 static int CONNECTIVITY = 0;
42
43 static const char UNICAST_DISCOVERY_QUERY[] = "coap://%s/oic/res";
44 static std::string putPayload = "{\"oic\":[{\"rep\":{\"power\":15,\"state\":true}}]}";
45
46 //The following variable determines the interface protocol (IP, etc)
47 //to be used for sending unicast messages. Default set to IP.
48 static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
49 static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
50
51 int gQuitFlag = 0;
52
53 struct ResourceNode *resourceList;
54 /*
55  * SIGINT handler: set gQuitFlag to 1 for graceful termination
56  * */
57 void handleSigInt(int signum)
58 {
59     if (signum == SIGINT)
60     {
61         gQuitFlag = 1;
62     }
63 }
64
65 static void PrintUsage()
66 {
67     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3> -c <0|1>");
68     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
69     OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
70     OC_LOG(INFO, TAG, "-t 2 : Discover Resources and"
71             " Initiate Nonconfirmable Get/Put/Post Requests");
72     OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate "
73             "Confirmable Get/Put/Post Requests");
74     OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
75     OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
76 }
77
78 /*
79  * Returns the first resource in the list
80  */
81 const ResourceNode * getResource()
82 {
83     return resourceList;
84 }
85
86 OCStackResult InvokeOCDoResource(std::ostringstream &query, OCMethod method,
87                                  OCConnectivityType connType, OCQualityOfService qos,
88         OCClientResponseHandler cb, OCHeaderOption * options, uint8_t numOptions)
89 {
90     OCStackResult ret;
91     OCCallbackData cbData;
92
93     cbData.cb = cb;
94     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
95     cbData.cd = NULL;
96
97     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
98         (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload.c_str() : NULL,
99          connType, qos, &cbData, options, numOptions);
100
101     if (ret != OC_STACK_OK)
102     {
103         OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
104                  ret, method);
105     }
106
107     return ret;
108 }
109
110 OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle,
111                                 OCClientResponse * clientResponse)
112 {
113     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
114     {
115         OC_LOG(INFO, TAG, "<====Callback Context for PUT received successfully====>");
116     }
117     else
118     {
119         OC_LOG(ERROR, TAG, "<====Callback Context for PUT fail====>");
120     }
121
122     if(clientResponse)
123     {
124         OC_LOG_V(INFO, TAG,"PUT Response: %s \nFrom %s:%d\n",
125                  clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
126     }
127     else
128     {
129         OC_LOG(ERROR, TAG, "<====PUT Callback fail to receive clientResponse====>\n");
130     }
131     return OC_STACK_DELETE_TRANSACTION;
132 }
133
134 OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle,
135                           OCClientResponse *clientResponse)
136 {
137     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
138     {
139         OC_LOG(INFO, TAG, "<====Callback Context for POST received successfully====>");
140     }
141     else
142     {
143         OC_LOG(ERROR, TAG, "<====Callback Context for POST fail====>");
144     }
145
146     if(clientResponse)
147     {
148         OC_LOG_V(INFO, TAG,"POST Response: %s \nFrom %s:%d\n",
149                     clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
150     }
151     else
152     {
153         OC_LOG(ERROR, TAG, "<====POST Callback fail to receive clientResponse====>\n");
154     }
155
156     return OC_STACK_DELETE_TRANSACTION;
157 }
158
159 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
160                            OCClientResponse * clientResponse)
161 {
162     if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
163     {
164         OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>");
165     }
166     else
167     {
168         OC_LOG(ERROR, TAG, "<====Callback Context for GET fail====>");
169     }
170
171     if (clientResponse)
172     {
173         OC_LOG_V(INFO, TAG,"Get Response: %s \nFrom %s:%d\n",
174                 clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
175
176         if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0 )
177         {
178             OC_LOG (INFO, TAG, "Received vendor specific options");
179             uint8_t i = 0;
180             OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
181             for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
182             {
183                 if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)
184                 {
185                     OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
186                             ((OCHeaderOption)rcvdOptions[i]).optionID );
187
188                     OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
189                         MAX_HEADER_OPTION_DATA_LENGTH);
190                 }
191             }
192         }
193     }
194     else
195     {
196         OC_LOG(ERROR, TAG, "<====GET Callback fail to receive clientResponse====>\n");
197     }
198     return OC_STACK_DELETE_TRANSACTION;
199 }
200
201 /*
202  * This is a function called back when a device is discovered
203  */
204 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
205         OCClientResponse * clientResponse)
206 {
207     if (ctx == (void*)DEFAULT_CONTEXT_VALUE)
208     {
209         OC_LOG(INFO, TAG, "\n<====Callback Context for DISCOVERY query "
210                "received successfully====>");
211     }
212     else
213     {
214         OC_LOG(ERROR, TAG, "\n<====Callback Context for DISCOVERY fail====>");
215     }
216
217     if (clientResponse)
218     {
219         OC_LOG_V(INFO, TAG,
220                 "Device Discovered %s \n @ %s:%d\n",
221                 clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
222
223         collectUniqueResource(clientResponse);
224     }
225     else
226     {
227         OC_LOG(ERROR, TAG, "<====DISCOVERY Callback fail to receive clientResponse====>\n");
228     }
229     return (UNICAST_DISCOVERY) ?
230            OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION ;
231 }
232
233 int InitPutRequest(OCQualityOfService qos)
234 {
235     std::ostringstream query;
236     //Get most recently inserted resource
237     const ResourceNode * resource  = getResource();
238
239     if(!resource)
240     {
241         OC_LOG_V(ERROR, TAG, "Resource null, can't do PUT request\n");
242         return -1;
243     }
244     query << "coap://" << resource->ip << ":" << resource->port << resource->uri ;
245     OC_LOG_V(INFO, TAG,"Executing InitPutRequest, Query: %s", query.str().c_str());
246
247     return (InvokeOCDoResource(query, OC_REST_PUT, resource->connType,
248            ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
249             putReqCB, NULL, 0));
250 }
251
252 int InitPostRequest(OCQualityOfService qos)
253 {
254     OCStackResult result;
255     std::ostringstream query;
256     //Get most recently inserted resource
257     const ResourceNode * resource  = getResource();
258
259     if(!resource)
260     {
261         OC_LOG_V(ERROR, TAG, "Resource null, can't do POST request\n");
262         return -1;
263     }
264
265     query << "coap://" << resource->ip << ":" << resource->port << resource->uri ;
266     OC_LOG_V(INFO, TAG,"Executing InitPostRequest, Query: %s", query.str().c_str());
267
268     // First POST operation (to create an LED instance)
269     result = InvokeOCDoResource(query, OC_REST_POST, resource->connType,
270             ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
271             postReqCB, NULL, 0);
272     if (OC_STACK_OK != result)
273     {
274         // Error can happen if for example, network connectivity is down
275         OC_LOG(ERROR, TAG, "First POST call did not succeed");
276     }
277
278     // Second POST operation (to create an LED instance)
279     result = InvokeOCDoResource(query, OC_REST_POST, resource->connType,
280             ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
281             postReqCB, NULL, 0);
282     if (OC_STACK_OK != result)
283     {
284         OC_LOG(ERROR, TAG, "Second POST call did not succeed");
285     }
286
287     // This POST operation will update the original resourced /a/led
288     return (InvokeOCDoResource(query, OC_REST_POST,resource->connType,
289                 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
290                 postReqCB, NULL, 0));
291 }
292
293 int InitGetRequest(OCQualityOfService qos)
294 {
295     std::ostringstream query;
296     //Get most recently inserted resource
297     const ResourceNode * resource  = getResource();
298
299     if(!resource)
300     {
301         OC_LOG_V(ERROR, TAG, "Resource null, can't do GET request\n");
302         return -1;
303     }
304     query << "coap://" << resource->ip << ":" << resource->port << resource->uri ;
305     OC_LOG_V(INFO, TAG,"Executing InitGetRequest, Query: %s", query.str().c_str());
306
307     return (InvokeOCDoResource(query, OC_REST_GET, resource->connType,
308             (qos == OC_HIGH_QOS)?OC_HIGH_QOS:OC_LOW_QOS, getReqCB, NULL, 0));
309 }
310
311 int InitDiscovery()
312 {
313     OCStackResult ret;
314     OCCallbackData cbData;
315     /* Start a discovery query*/
316     char szQueryUri[64] = {};
317     if (UNICAST_DISCOVERY)
318     {
319         char ipv4addr[IPV4_ADDR_SIZE];
320         OC_LOG(INFO, TAG, "Enter IP address with port of the Server hosting resource"\
321                     "(Ex: 192.168.0.15:1234) ");
322
323         if (fgets(ipv4addr, IPV4_ADDR_SIZE, stdin))
324         {
325             //Strip newline char from ipv4addr
326             StripNewLineChar(ipv4addr);
327             snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_DISCOVERY_QUERY, ipv4addr);
328         }
329         else
330         {
331             OC_LOG(ERROR, TAG, "!! Bad input for IPV4 address. !!");
332             return OC_STACK_INVALID_PARAM;
333         }
334     }
335     else
336     {
337         strcpy(szQueryUri, MULTICAST_RESOURCE_DISCOVERY_QUERY);
338     }
339     cbData.cb = discoveryReqCB;
340     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
341     cbData.cd = NULL;
342     if (UNICAST_DISCOVERY)
343     {
344         ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
345                 OC_LOW_QOS, &cbData, NULL, 0);
346     }
347     else
348     {
349         ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, CT_DEFAULT,
350                 OC_LOW_QOS, &cbData, NULL, 0);
351     }
352
353     if (ret != OC_STACK_OK)
354     {
355         OC_LOG(ERROR, TAG, "OCStack resource error");
356     }
357     return ret;
358 }
359
360 const char *getIPAddr(const OCClientResponse *clientResponse)
361 {
362     if (!clientResponse)
363     {
364         return "";
365     }
366
367     const OCDevAddr *devAddr = &clientResponse->devAddr;
368     char *ipaddr = (char *) OICCalloc(1, strlen(devAddr->addr) +1);
369     if (ipaddr)
370     {
371         snprintf(ipaddr, MAX_IP_ADDR_ST_SZ, "%s", devAddr->addr);
372     }
373     else
374     {
375         OC_LOG(ERROR, TAG, "Memory not allocated to ipaddr");
376     }
377     return ipaddr;
378 }
379
380 const char *getPort(const OCClientResponse *clientResponse)
381 {
382     if(!clientResponse)
383     {
384         return "";
385     }
386
387     char *port = NULL;
388     if((port = (char *)OICCalloc(1, MAX_PORT_ST_SZ)))
389     {
390         snprintf(port, MAX_PORT_ST_SZ, "%d", clientResponse->devAddr.port);
391     }
392     else
393     {
394         OC_LOG(ERROR, TAG, "Memory not allocated to port");
395     }
396     return port;
397 }
398
399 int parseJSON(const char * resJSONPayload, char ** sid_c,
400               char *** uri_c, int * totalRes)
401 {
402     cJSON * root = NULL;
403     cJSON * oc = NULL;
404
405     root = cJSON_Parse((char *)(resJSONPayload));
406
407     if (!root)
408     {
409         OC_LOG(ERROR, TAG, "JSON Parsing Error");
410         return OC_STACK_INVALID_JSON;
411     }
412
413     oc = cJSON_GetObjectItem(root,"oic");
414     if (!oc)
415     {
416         OC_LOG(ERROR, TAG, "Invalid JSON : Missing oc object");
417         return OC_STACK_INVALID_JSON;
418     }
419
420     * totalRes = cJSON_GetArraySize(oc);
421
422     if(oc->type == cJSON_Array)
423     {
424         cJSON * resource = cJSON_GetArrayItem(oc, 0);
425
426         if(!resource)
427         {
428             return OC_STACK_INVALID_JSON;
429         }
430
431         if (cJSON_GetObjectItem(resource, "sid"))
432         {
433             char * sid = cJSON_GetObjectItem(resource, "sid")->valuestring;
434             if((* sid_c = (char *)OICCalloc(1, strlen (sid) + 1)))
435             {
436                 memcpy(* sid_c, sid, strlen(sid) + 1);
437             }
438             else
439             {
440                 OC_LOG(ERROR, TAG, "Memory not allocated to sid");
441                 return OC_STACK_NO_MEMORY;
442             }
443         }
444         else
445         {
446             OC_LOG(ERROR, TAG, "Invalid JSON : Missing sid object");
447             return OC_STACK_INVALID_JSON;
448         }
449
450         if(!(* uri_c =  (char ** )OICMalloc ((* totalRes) * sizeof(char *))))
451         {
452             OC_LOG(ERROR, TAG, "Memory not allocated to uri_c array");
453             return OC_STACK_NO_MEMORY;
454         }
455
456         int i = 0;
457
458         while(true)
459         {
460             if (cJSON_GetObjectItem(resource, "href"))
461             {
462                 char *uri= cJSON_GetObjectItem(resource, "href")->valuestring;
463                 if(((*uri_c)[i] = (char *)OICCalloc(1, strlen (uri) + 1)))
464                 {
465                     memcpy((*uri_c)[i], uri, strlen(uri) + 1);
466                 }
467                 else
468                 {
469                     OC_LOG(ERROR, TAG, "Memory not allocated to uri");
470                     return OC_STACK_NO_MEMORY;
471                 }
472                 i++;
473                 if(i >= (* totalRes))
474                     break;
475                 resource = cJSON_GetArrayItem(oc, i);
476             }
477             else
478             {
479                OC_LOG(ERROR, TAG, "Invalid JSON : Missing uri object");
480                return OC_STACK_INVALID_JSON;
481            }
482         }
483     }
484     else
485     {
486         return OC_STACK_INVALID_JSON;
487         OC_LOG(ERROR, TAG, "Invalid JSON : oc object type is not an array");
488     }
489     return OC_STACK_OK;
490 }
491
492 void queryResource()
493 {
494     switch(TEST_CASE)
495     {
496         case TEST_DISCOVER_REQ:
497             break;
498         case TEST_NON_CON_OP:
499             InitGetRequest(OC_LOW_QOS);
500             InitPutRequest(OC_LOW_QOS);
501             InitPostRequest(OC_LOW_QOS);
502             break;
503         case TEST_CON_OP:
504             InitGetRequest(OC_HIGH_QOS);
505             InitPutRequest(OC_HIGH_QOS);
506             InitPostRequest(OC_HIGH_QOS);
507             break;
508         default:
509             PrintUsage();
510             break;
511     }
512 }
513
514
515 void collectUniqueResource(const OCClientResponse * clientResponse)
516 {
517     char * sid = NULL;
518     char ** uri = NULL;
519     int totalRes = 0;
520     int i;
521
522     if(parseJSON(clientResponse->resJSONPayload, & sid, & uri, &totalRes)
523             != OC_STACK_OK)
524     {
525         OC_LOG(ERROR, TAG, "Error while parsing JSON payload in OCClientResponse");
526
527         OICFree(sid);
528         for (i = 0; i < totalRes; i++)
529         {
530             OICFree(uri[i]);
531         }
532         OICFree(uri);
533
534        return;
535     }
536
537     for(i = 0; i < totalRes; i++)
538     {
539         if(insertResource(sid, uri[i], clientResponse) == 1)
540         {
541             printf("%s%s%s%s\n",sid, ":", uri[i], " is new");
542             printResourceList();
543             queryResource();
544         }
545         else
546         {
547             printf("%s%s%s%s\n\n",sid, ":", uri[i], " has been seen before");
548         }
549     }
550
551     OICFree(sid);
552     for (i = 0; i < totalRes; i++)
553     {
554         OICFree(uri[i]);
555     }
556     OICFree(uri);
557 }
558
559 /* This function searches for the resource(sid:uri) in the ResourceList.
560  * If the Resource is found in the list then it returns 0 else insert
561  * the resource to front of the list and returns 1.
562  */
563 int insertResource(const char * sid, char const * uri,
564             const OCClientResponse * clientResponse)
565 {
566     ResourceNode * iter = resourceList;
567     char * sid_cpy =  OICStrdup(sid);
568     char * uri_cpy = OICStrdup(uri);
569
570     //Checking if the resource(sid:uri) is new
571     while(iter)
572     {
573         if((strcmp(iter->sid, sid) == 0) && (strcmp(iter->uri, uri) == 0))
574         {
575             OICFree(sid_cpy);
576             OICFree(uri_cpy);
577             return 0;
578         }
579         else
580         {
581             iter = iter->next;
582         }
583     }
584
585     //Creating new ResourceNode
586     if((iter = (ResourceNode *) OICMalloc(sizeof(ResourceNode))))
587     {
588         iter->sid = sid_cpy;
589         iter->uri = uri_cpy;
590         iter->ip = getIPAddr(clientResponse);
591         iter->port = getPort(clientResponse);
592         iter->connType = clientResponse->connType;
593         iter->next = NULL;
594     }
595     else
596     {
597         OC_LOG(ERROR, TAG, "Memory not allocated to ResourceNode");
598         OICFree(sid_cpy);
599         OICFree(uri_cpy);
600         return -1;
601     }
602
603     //Adding new ResourceNode to front of the ResourceList
604     if(!resourceList)
605     {
606         resourceList = iter;
607     }
608     else
609     {
610         iter->next = resourceList;
611         resourceList = iter;
612     }
613     return 1;
614 }
615
616 void printResourceList()
617 {
618     ResourceNode * iter;
619     iter = resourceList;
620     OC_LOG(INFO, TAG, "Resource List: ");
621     while(iter)
622     {
623         OC_LOG(INFO, TAG, "*****************************************************");
624         OC_LOG_V(INFO, TAG, "sid = %s",iter->sid);
625         OC_LOG_V(INFO, TAG, "uri = %s", iter->uri);
626         OC_LOG_V(INFO, TAG, "ip = %s", iter->ip);
627         OC_LOG_V(INFO, TAG, "port = %s", iter->port);
628         switch (iter->connType & CT_MASK_ADAPTER)
629         {
630             case CT_ADAPTER_IP:
631                 OC_LOG(INFO, TAG, "connType = Default (IPv4)");
632                 break;
633             case OC_ADAPTER_GATT_BTLE:
634                 OC_LOG(INFO, TAG, "connType = BLE");
635                 break;
636             case OC_ADAPTER_RFCOMM_BTEDR:
637                 OC_LOG(INFO, TAG, "connType = BT");
638                 break;
639             default:
640                 OC_LOG(INFO, TAG, "connType = Invalid connType");
641                 break;
642         }
643         OC_LOG(INFO, TAG, "*****************************************************");
644         iter = iter->next;
645     }
646 }
647
648 void freeResourceList()
649 {
650     OC_LOG(INFO, TAG, "Freeing ResourceNode List");
651     ResourceNode * temp;
652     while(resourceList)
653     {
654
655         temp = resourceList;
656         resourceList = resourceList->next;
657         OICFree((void *)temp->sid);
658         OICFree((void *)temp->uri);
659         OICFree((void *)temp->ip);
660         OICFree((void *)temp->port);
661         OICFree(temp);
662     }
663     resourceList = NULL;
664 }
665
666 int main(int argc, char* argv[])
667 {
668     int opt;
669     resourceList = NULL;
670     while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
671     {
672         switch(opt)
673         {
674             case 'u':
675                 UNICAST_DISCOVERY = atoi(optarg);
676                 break;
677             case 't':
678                 TEST_CASE = atoi(optarg);
679                 break;
680             case 'c':
681
682                 CONNECTIVITY = atoi(optarg);
683                 break;
684             default:
685                 PrintUsage();
686                 return -1;
687         }
688     }
689
690     if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
691         (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
692         (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
693     {
694         PrintUsage();
695         return -1;
696     }
697
698     /* Initialize OCStack*/
699     if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
700     {
701         OC_LOG(ERROR, TAG, "OCStack init error");
702         return 0;
703     }
704
705     if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY ==  CT_IP)
706     {
707         OC_CONNTYPE =  CT_ADAPTER_IP;//CT_DEFAULT;
708     }
709     else
710     {
711         OC_LOG(INFO, TAG, "Default Connectivity type selected");
712         PrintUsage();
713     }
714
715     InitDiscovery();
716
717     // Break from loop with Ctrl+C
718     signal(SIGINT, handleSigInt);
719
720     while (!gQuitFlag)
721     {
722         if (OCProcess() != OC_STACK_OK)
723         {
724             OC_LOG(ERROR, TAG, "OCStack process error");
725             return 0;
726         }
727         sleep(2);
728     }
729
730     freeResourceList();
731     OC_LOG(INFO, TAG, "Exiting occlient main loop...");
732     if (OCStop() != OC_STACK_OK)
733     {
734         OC_LOG(ERROR, TAG, "OCStack stop error");
735     }
736     return 0;
737 }
738
739