Changed C Samples to use correct adapter type
[platform/upstream/iotivity.git] / resource / csdk / stack / samples / linux / SimpleClientServer / occlientcoll.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 //
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 <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <ocstack.h>
27 #include <iostream>
28 #include <sstream>
29 #include "logger.h"
30 const char *getResult(OCStackResult result);
31 std::string getIPAddrTBServer(OCClientResponse * clientResponse);
32 std::string getPortTBServer(OCClientResponse * clientResponse);
33 std::string getQueryStrForGetPut(const char * responsePayload);
34
35 #define TAG PCF("occlient")
36 #define DEFAULT_CONTEXT_VALUE 0x99
37 #ifndef MAX_LENGTH_IPv4_ADDR
38 #define MAX_LENGTH_IPv4_ADDR 16
39 #endif
40
41 typedef enum
42 {
43     TEST_INVALID = 0,
44     TEST_GET_DEFAULT,
45     TEST_GET_BATCH,
46     TEST_GET_LINK_LIST,
47     TEST_PUT_DEFAULT,
48     TEST_PUT_BATCH,
49     TEST_PUT_LINK_LIST,
50     TEST_UNKNOWN_RESOURCE_GET_DEFAULT,
51     TEST_UNKNOWN_RESOURCE_GET_BATCH,
52     TEST_UNKNOWN_RESOURCE_GET_LINK_LIST,
53     MAX_TESTS
54 } CLIENT_TEST;
55
56 /**
57  * List of connectivity types that can be initiated from the client
58  * Required for user input validation
59  */
60 typedef enum {
61     CT_ADAPTER_DEFAULT = 0,
62     CT_IP,
63     MAX_CT
64 } CLIENT_CONNECTIVITY_TYPE;
65
66 unsigned static int TEST = TEST_INVALID;
67 unsigned static int CONNECTIVITY = 0;
68
69 typedef struct
70 {
71     char text[30];
72     CLIENT_TEST test;
73 } testToTextMap;
74
75 testToTextMap queryInterface[] = {
76         {"invalid", TEST_INVALID},
77         {"?if=oic.if.baseline", TEST_GET_DEFAULT},
78         {"?if=oic.if.b", TEST_GET_BATCH},
79         {"?if=oic.if.ll", TEST_GET_LINK_LIST},
80         {"?if=oic.if.baseline", TEST_UNKNOWN_RESOURCE_GET_DEFAULT},
81         {"?if=oic.if.b", TEST_UNKNOWN_RESOURCE_GET_BATCH},
82         {"?if=oic.if.ll", TEST_UNKNOWN_RESOURCE_GET_LINK_LIST},
83         {"?if=oic.if.baseline", TEST_PUT_DEFAULT},
84         {"?if=oic.if.b", TEST_PUT_BATCH},
85         {"?if=oic.if.ll", TEST_PUT_LINK_LIST},
86 };
87
88 static std::string putPayload = "{\"state\":\"off\",\"power\":\"0\"}";
89
90 //The following variable determines the interface protocol (IP, etc)
91 //to be used for sending unicast messages. Default set to IP.
92 static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
93 static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
94
95 // The handle for the observe registration
96 OCDoHandle gObserveDoHandle;
97 // After this crosses a threshold client deregisters for further observations
98 int gNumObserveNotifies = 1;
99
100 int gQuitFlag = 0;
101 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
102 void handleSigInt(int signum)
103 {
104     if (signum == SIGINT)
105     {
106         gQuitFlag = 1;
107     }
108 }
109
110 // Forward Declaration
111 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse);
112 int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse);
113 int InitObserveRequest(OCClientResponse * clientResponse);
114 int InitPutRequest(OCClientResponse * clientResponse);
115 int InitGetRequest(OCClientResponse * clientResponse);
116 int InitDiscovery();
117
118 void PrintUsage()
119 {
120     OC_LOG(INFO, TAG, "Usage : occlientcoll -t <Test Case> -c <CA connectivity Type>");
121     OC_LOG(INFO, TAG, "-c 0 : Default auto-selection");
122     OC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
123     OC_LOG(INFO, TAG, "Test Case 1 : Discover Resources && Initiate GET Request on an "\
124             "available resource using default interface.");
125     OC_LOG(INFO, TAG, "Test Case 2 : Discover Resources && Initiate GET Request on an "\
126                  "available resource using batch interface.");
127     OC_LOG(INFO, TAG, "Test Case 3 : Discover Resources && Initiate GET Request on an "\
128                  "available resource using link list interface.");
129     OC_LOG(INFO, TAG, "Test Case 4 : Discover Resources && Initiate GET & PUT Request on an "\
130                  "available resource using default interface.");
131     OC_LOG(INFO, TAG, "Test Case 5 : Discover Resources && Initiate GET & PUT Request on an "\
132                  "available resource using batch interface.");
133     OC_LOG(INFO, TAG, "Test Case 6 : Discover Resources && Initiate GET & PUT Request on an "\
134                  "available resource using link list interface.");
135     OC_LOG(INFO, TAG, "Test Case 7 : Discover Resources && Initiate GET Request on an "\
136                  "unavailable resource using default interface.");
137     OC_LOG(INFO, TAG, "Test Case 8 : Discover Resources && Initiate GET Request on an "\
138                  "unavailable resource using batch interface.");
139     OC_LOG(INFO, TAG, "Test Case 9 : Discover Resources && Initiate GET Request on an "\
140                  "unavailable resource using link list interface.");
141 }
142
143 OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
144 {
145     if(clientResponse == NULL)
146     {
147         OC_LOG(INFO, TAG, "The clientResponse is NULL");
148         return   OC_STACK_DELETE_TRANSACTION;
149     }
150     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
151     {
152         OC_LOG_V(INFO, TAG, "Callback Context for PUT query recvd successfully");
153         OC_LOG_V(INFO, TAG, "JSON = %s =============> Discovered", clientResponse->resJSONPayload);
154     }
155
156     return OC_STACK_KEEP_TRANSACTION;
157 }
158
159 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
160 {
161     OC_LOG_V(INFO, TAG, "StackResult: %s",
162             getResult(clientResponse->result));
163     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
164     {
165         OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
166         if(clientResponse->sequenceNumber == 0)
167         {
168             OC_LOG_V(INFO, TAG, "Callback Context for GET query recvd successfully");
169             OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
170         }
171         else
172         {
173             OC_LOG_V(INFO, TAG, "Callback Context for Get recvd successfully %d",
174                     gNumObserveNotifies);
175             OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
176             gNumObserveNotifies++;
177             if (gNumObserveNotifies == 3)
178             {
179                 if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
180                 {
181                     OC_LOG(ERROR, TAG, "Observe cancel error");
182                 }
183             }
184         }
185     }
186     if(TEST == TEST_PUT_DEFAULT || TEST == TEST_PUT_BATCH || TEST == TEST_PUT_LINK_LIST)
187     {
188         InitPutRequest(clientResponse);
189     }
190     return OC_STACK_KEEP_TRANSACTION;
191 }
192
193
194 // This is a function called back when a device is discovered
195 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
196         OCClientResponse * clientResponse)
197 {
198     OC_LOG(INFO, TAG,
199             "Entering discoveryReqCB (Application Layer CB)");
200     OC_LOG_V(INFO, TAG, "StackResult: %s",
201             getResult(clientResponse->result));
202
203     if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
204     {
205         OC_LOG_V(INFO, TAG, "Callback Context recvd successfully");
206     }
207
208     OC_LOG_V(INFO, TAG,
209             "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
210             clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
211
212     if(TEST == TEST_UNKNOWN_RESOURCE_GET_DEFAULT || TEST == TEST_UNKNOWN_RESOURCE_GET_BATCH ||\
213             TEST == TEST_UNKNOWN_RESOURCE_GET_LINK_LIST)
214     {
215         InitGetRequestToUnavailableResource(clientResponse);
216     }
217     else
218     {
219         InitGetRequest(clientResponse);
220     }
221     return OC_STACK_KEEP_TRANSACTION;
222 }
223
224
225 int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse)
226 {
227     OCStackResult ret;
228     OCCallbackData cbData;
229     std::ostringstream getQuery;
230     getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
231             clientResponse->devAddr.port << "/SomeUnknownResource";
232     cbData.cb = getReqCB;
233     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
234     cbData.cd = NULL;
235
236     ret = OCDoResource(NULL, OC_REST_GET, getQuery.str().c_str(), 0, 0, OC_CONNTYPE, OC_LOW_QOS,
237             &cbData, NULL, 0);
238     if (ret != OC_STACK_OK)
239     {
240         OC_LOG(ERROR, TAG, "OCStack resource error");
241     }
242     return ret;
243 }
244
245
246 int InitObserveRequest(OCClientResponse * clientResponse)
247 {
248     OCStackResult ret;
249     OCCallbackData cbData;
250     OCDoHandle handle;
251     std::ostringstream obsReg;
252     obsReg << "coap://" << clientResponse->devAddr.addr << ":" <<
253             clientResponse->devAddr.addr <<
254             getQueryStrForGetPut(clientResponse->resJSONPayload);
255     cbData.cb = getReqCB;
256     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
257     cbData.cd = NULL;
258     OC_LOG_V(INFO, TAG, "OBSERVE payload from client = %s ", putPayload.c_str());
259
260     ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(), 0, 0, OC_CONNTYPE,
261             OC_LOW_QOS, &cbData, NULL, 0);
262     if (ret != OC_STACK_OK)
263     {
264         OC_LOG(ERROR, TAG, "OCStack resource error");
265     }
266     else
267     {
268         gObserveDoHandle = handle;
269     }
270     return ret;
271 }
272
273
274 int InitPutRequest(OCClientResponse * clientResponse)
275 {
276     OCStackResult ret;
277     OCCallbackData cbData;
278     //* Make a PUT query*/
279     std::ostringstream getQuery;
280     getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
281             clientResponse->devAddr.port <<
282             "/a/room" << queryInterface[TEST].text;
283     cbData.cb = putReqCB;
284     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
285     cbData.cd = NULL;
286     OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str());
287
288     ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(),
289                         OC_CONNTYPE, OC_LOW_QOS, &cbData, NULL, 0);
290     if (ret != OC_STACK_OK)
291     {
292         OC_LOG(ERROR, TAG, "OCStack resource error");
293     }
294     return ret;
295 }
296
297
298 int InitGetRequest(OCClientResponse * clientResponse)
299 {
300     OCStackResult ret;
301     OCCallbackData cbData;
302
303     //* Make a GET query*/
304     std::ostringstream getQuery;
305     getQuery << "coap://" << clientResponse->devAddr.addr << ":" <<
306             clientResponse->devAddr.port <<
307             "/a/room" << queryInterface[TEST].text;
308
309     std::cout << "Get Query: " << getQuery.str() << std::endl;
310
311     cbData.cb = getReqCB;
312     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
313     cbData.cd = NULL;
314     ret = OCDoResource(NULL, OC_REST_GET,
315             getQuery.str().c_str(), 0, 0, OC_CONNTYPE, OC_LOW_QOS,
316             &cbData, NULL, 0);
317     if (ret != OC_STACK_OK)
318     {
319         OC_LOG(ERROR, TAG, "OCStack resource error");
320     }
321     return ret;
322 }
323
324 int InitDiscovery()
325 {
326     OCStackResult ret;
327     OCCallbackData cbData;
328     /* Start a discovery query*/
329     char szQueryUri[64] = { 0 };
330
331     strcpy(szQueryUri, MULTICAST_RESOURCE_DISCOVERY_QUERY);
332
333     cbData.cb = discoveryReqCB;
334     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
335     cbData.cd = NULL;
336     ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
337                         OC_LOW_QOS,
338             &cbData, NULL, 0);
339     if (ret != OC_STACK_OK)
340     {
341         OC_LOG(ERROR, TAG, "OCStack resource error");
342     }
343     return ret;
344 }
345
346 int main(int argc, char* argv[])
347 {
348     int opt;
349
350     while ((opt = getopt(argc, argv, "t:c:")) != -1)
351     {
352         switch (opt)
353         {
354             case 't':
355                 TEST = atoi(optarg);
356                 break;
357             case 'c':
358                 CONNECTIVITY = atoi(optarg);
359                 break;
360             default:
361                 PrintUsage();
362                 return -1;
363         }
364     }
365     if ((TEST <= TEST_INVALID || TEST >= MAX_TESTS) ||
366         (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
367     {
368         PrintUsage();
369         return -1;
370     }
371
372     /* Initialize OCStack*/
373     if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
374     {
375         OC_LOG(ERROR, TAG, "OCStack init error");
376         return 0;
377     }
378
379     if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IP)
380     {
381         OC_CONNTYPE = CT_ADAPTER_IP;
382     }
383     else
384     {
385         OC_LOG(INFO, TAG, "Default Connectivity type selected...");
386         OC_CONNTYPE = CT_ADAPTER_IP;
387     }
388
389     InitDiscovery();
390
391     // Break from loop with Ctrl+C
392     OC_LOG(INFO, TAG, "Entering occlient main loop...");
393     signal(SIGINT, handleSigInt);
394     while (!gQuitFlag)
395     {
396
397         if (OCProcess() != OC_STACK_OK)
398         {
399             OC_LOG(ERROR, TAG, "OCStack process error");
400             return 0;
401         }
402
403         sleep(2);
404     } OC_LOG(INFO, TAG, "Exiting occlient main loop...");
405
406     if (OCStop() != OC_STACK_OK)
407     {
408         OC_LOG(ERROR, TAG, "OCStack stop error");
409     }
410
411     return 0;
412 }
413
414 std::string getQueryStrForGetPut(const char * responsePayload)
415 {
416
417     std::string jsonPayload(responsePayload);
418
419     return "/a/room";
420 }
421