1 //******************************************************************
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
4 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
6 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
20 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
32 #include "ocpayload.h"
35 // Tracking user input
36 static int UNICAST_DISCOVERY = 0;
37 static int TEST_CASE = 0;
38 static int CONNECTIVITY = 0;
40 static const char * UNICAST_DEVICE_DISCOVERY_QUERY = "coap://%s/oic/d";
41 static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
42 static const char * UNICAST_PLATFORM_DISCOVERY_QUERY = "coap://%s/oic/p";
43 static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
45 static const char * UNICAST_RESOURCE_DISCOVERY_QUERY = "coap://%s/oic/res";
46 static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
47 // The following variable determines the interface protocol (IPv4, IPv6, etc)
48 //to be used for sending unicast messages. Default set to IPv4.
49 static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
50 static std::string coapServerIP = "255.255.255.255";
51 static std::string coapServerPort = "5683";
52 static std::string coapServerResource = "/a/light";
53 // Size to hold ADDRESS
54 static const int MAX_ADDR_SIZE = 24;
55 //Use unicastAddr for both InitDiscovery and InitPlatformOrDeviceDiscovery
56 char unicastAddr[MAX_ADDR_SIZE];
57 void StripNewLineChar(char* str);
59 // The handle for the observe registration
60 OCDoHandle gObserveDoHandle;
62 // The handle for observe registration
63 OCDoHandle gPresenceHandle;
65 // After this crosses a threshold client deregisters for further notifications
66 int gNumObserveNotifies = 0;
69 int gNumPresenceNotifies = 0;
73 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
74 void handleSigInt(int signum)
82 OCPayload* putPayload()
84 OCRepPayload* payload = OCRepPayloadCreate();
88 std::cout << "Failed to create put payload object"<<std::endl;
92 OCRepPayloadSetPropInt(payload, "power", 15);
93 OCRepPayloadSetPropBool(payload, "state", true);
95 return (OCPayload*) payload;
98 static void PrintUsage()
101 cout << "\nUsage : occlient -u <0|1> -t <1..17> -c <0|1|2>";
102 cout << "\n-u <0|1> : Perform multicast/unicast discovery of resources";
103 cout << "\n-c 0 : Default IPv4 and IPv6 auto-selection";
104 cout << "\n-c 1 : IPv4 Connectivity Type";
105 cout << "\n-c 2 : IPv6 Connectivity Type (IPv6 not currently supported)";
106 cout << "\n-c 3 : EDR Connectivity Type (IPv6 not currently supported)";
107 cout << "\n-t 1 : Discover Resources";
108 cout << "\n-t 2 : Discover Resources and Initiate Nonconfirmable Get Request";
109 cout << "\n-t 3 : Discover Resources and Initiate Nonconfirmable Get Request with query filter";
110 cout << "\n-t 4 : Discover Resources and Initiate Nonconfirmable Put Requests";
111 cout << "\n-t 5 : Discover Resources and Initiate Nonconfirmable Post Requests";
112 cout << "\n-t 6 : Discover Resources and Initiate Nonconfirmable Delete Requests";
113 cout << "\n-t 7 : Discover Resources and Initiate Nonconfirmable Observe Requests";
114 cout << "\n-t 8 : Discover Resources and Initiate Nonconfirmable Get Request for a resource";
115 cout << "which is unavailable";
116 cout << "\n-t 9 : Discover Resources and Initiate Confirmable Get Request";
117 cout << "\n-t 10 : Discover Resources and Initiate Confirmable Post Request";
118 cout << "\n-t 11 : Discover Resources and Initiate Confirmable Delete Requests";
119 cout << "\n-t 12 : Discover Resources and Initiate Confirmable Observe Requests and";
120 cout << "cancel with Low QoS";
123 cout << "\n-t 13 : Discover Resources and Initiate Nonconfirmable presence";
124 cout << "\n-t 14 : Discover Resources and Initiate Nonconfirmable presence with filter";
125 cout << "\n-t 15 : Discover Resources and Initiate Nonconfirmable presence with 2 filters";
126 cout << "\n-t 16 : Discover Resources and Initiate Nonconfirmable multicast presence.";
129 cout << "\n-t 17 : Discover Resources and Initiate Nonconfirmable Observe Requests";
130 cout << "then cancel immediately with High QOS";
131 cout << "\n-t 18 : Discover Resources and Initiate Nonconfirmable Get Request and add";
132 cout << "vendor specific header options";
133 cout << "\n-t 19 : Discover Platform";
134 cout << "\n-t 20 : Discover Devices";
137 OCStackResult InvokeOCDoResource(std::ostringstream &query,
139 OCQualityOfService qos,
140 OCClientResponseHandler cb,
141 OCHeaderOption * options,
145 OCCallbackData cbData;
149 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
152 ret = OCDoResource(&handle, method, query.str().c_str(), 0,
153 (method == OC_REST_PUT) ? putPayload() : NULL,
154 (OC_CONNTYPE), qos, &cbData, options, numOptions);
156 if (ret != OC_STACK_OK)
158 cout << "\nOCDoResource returns error "<< ret;
159 cout << " with method " << method;
161 else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
163 gObserveDoHandle = handle;
166 else if (method == OC_REST_PRESENCE)
168 gPresenceHandle = handle;
175 OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
177 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
179 cout << "\nCallback Context for PUT recvd successfully";
184 cout << "\nStackResult: " << getResult(clientResponse->result);
185 cout << "\nJSON = " << clientResponse->payload;
189 cout << "\nputReqCB received Null clientResponse";
191 return OC_STACK_DELETE_TRANSACTION;
194 OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientResponse *clientResponse)
196 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
198 cout << "\nCallback Context for POST recvd successfully";
203 cout << "\nStackResult: " << getResult(clientResponse->result);
204 cout << "\nJSON = " << clientResponse->payload;
208 cout << "\npostReqCB received Null clientResponse";
210 return OC_STACK_DELETE_TRANSACTION;
213 OCStackApplicationResult deleteReqCB(void *ctx,
214 OCDoHandle handle, OCClientResponse *clientResponse)
216 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
218 cout << "\nCallback Context for DELETE recvd successfully";
223 cout << "\nStackResult: " << getResult(clientResponse->result);
224 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
228 cout << "\ndeleteReqCB received Null clientResponse";
230 return OC_STACK_DELETE_TRANSACTION;
233 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
235 if(clientResponse == NULL)
237 cout << "\ngetReqCB received NULL clientResponse";
238 return OC_STACK_DELETE_TRANSACTION;
241 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
243 cout << "\nCallback Context for GET query recvd successfully";
246 cout << "\nStackResult: " << getResult(clientResponse->result);
247 cout << "\nSEQUENCE NUMBER: " << clientResponse->sequenceNumber;
248 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
250 if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
252 cout << "\nReceived vendor specific options";
254 OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
255 for( i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
257 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
259 cout << "\nReceived option ID " << ((OCHeaderOption)rcvdOptions[i]).optionID;
263 return OC_STACK_DELETE_TRANSACTION;
266 OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
268 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
270 cout << "\nCallback Context for OBS query recvd successfully";
275 cout << "\nStackResult: " << getResult(clientResponse->result);
276 cout << "\nSEQUENCE NUMBER: " << clientResponse->sequenceNumber;
277 cout << "\nCallback Context for OBSERVE notification recvd successfully ";
278 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
279 gNumObserveNotifies++;
280 if (gNumObserveNotifies == 15) //large number to test observing in DELETE case.
282 if(TEST_CASE == TEST_OBS_REQ_NON || TEST_CASE == TEST_OBS_REQ_CON)
284 if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
286 cout << "\nObserve cancel error";
288 return OC_STACK_DELETE_TRANSACTION;
290 else if(TEST_CASE == TEST_OBS_REQ_NON_CANCEL_IMM)
292 if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
294 cout << "\nObserve cancel error";
298 if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
300 cout << "\nThis also serves as a registration confirmation";
302 else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
304 cout << "\nThis also serves as a deregistration confirmation";
305 return OC_STACK_DELETE_TRANSACTION;
307 else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
309 cout << "\nThis also tells you that registration/deregistration failed";
310 return OC_STACK_DELETE_TRANSACTION;
315 cout << "\nobsReqCB received Null clientResponse";
317 return OC_STACK_KEEP_TRANSACTION;
320 OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
322 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
324 cout << "\nCallback Context for Presence recvd successfully";
329 cout << "\nStackResult: " << getResult(clientResponse->result);
330 cout << "\nNONCE NUMBER: " << clientResponse->sequenceNumber;
331 cout << "\nCallback Context for Presence notification recvd successfully ";
332 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
333 gNumPresenceNotifies++;
334 if (gNumPresenceNotifies == 20)
336 if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
338 cout << "\nPresence cancel error";
340 return OC_STACK_DELETE_TRANSACTION;
345 cout << "\npresenceCB received Null clientResponse";
347 return OC_STACK_KEEP_TRANSACTION;
351 // This is a function called back when a device is discovered
352 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
353 OCClientResponse * clientResponse)
355 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
357 cout << "\nCallback Context for DISCOVER query recvd successfully";
362 cout << "\nStackResult: " << getResult(clientResponse->result);
364 std::string connectionType = getConnectivityType (clientResponse->connType);
365 cout << "\nDiscovered on " << connectionType.c_str();
366 cout << "\nDevice ======> Discovered ";
367 cout << clientResponse->devAddr.addr;
368 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
369 if (65600 == clientResponse->connType)
371 cout << ":" << clientResponse->devAddr.port;
373 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
374 cout << "\nConnectivity type: " << clientResponse->connType;
375 OC_CONNTYPE = clientResponse->connType;
376 parseClientResponse(clientResponse);
380 case TEST_GET_REQ_NON:
381 InitGetRequest(OC_LOW_QOS, 0, 0);
383 case TEST_GET_REQ_NON_WITH_FILTERS:
384 InitGetRequest(OC_LOW_QOS, 0, 1);
386 case TEST_PUT_REQ_NON:
387 InitPutRequest(OC_LOW_QOS);
389 case TEST_POST_REQ_NON:
390 InitPostRequest(OC_LOW_QOS);
392 case TEST_DELETE_REQ_NON:
393 InitDeleteRequest(OC_LOW_QOS);
395 case TEST_OBS_REQ_NON:
396 case TEST_OBS_REQ_NON_CANCEL_IMM:
397 InitObserveRequest(OC_LOW_QOS);
399 case TEST_GET_UNAVAILABLE_RES_REQ_NON:
400 InitGetRequestToUnavailableResource(OC_LOW_QOS);
402 case TEST_GET_REQ_CON:
403 InitGetRequest(OC_HIGH_QOS, 0, 0);
405 case TEST_POST_REQ_CON:
406 InitPostRequest(OC_HIGH_QOS);
408 case TEST_DELETE_REQ_CON:
409 InitDeleteRequest(OC_HIGH_QOS);
411 case TEST_OBS_REQ_CON:
412 InitObserveRequest(OC_HIGH_QOS);
415 case TEST_OBS_PRESENCE:
416 case TEST_OBS_PRESENCE_WITH_FILTER:
417 case TEST_OBS_PRESENCE_WITH_FILTERS:
418 case TEST_OBS_MULTICAST_PRESENCE:
422 case TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS:
423 InitGetRequest(OC_LOW_QOS, 1, 0);
425 case TEST_DISCOVER_PLATFORM_REQ:
426 InitPlatformDiscovery(OC_LOW_QOS);
428 case TEST_DISCOVER_DEV_REQ:
429 InitDeviceDiscovery(OC_LOW_QOS);
438 cout << "\ndiscoveryReqCB received Null clientResponse";
440 return OC_STACK_KEEP_TRANSACTION;
443 OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
444 OCClientResponse * clientResponse)
446 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
448 cout << "\nCallback Context for Platform DISCOVER query recvd successfully";
453 //OC_LOG truncates the response as it is too long.
454 //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
458 cout << "\nPlatformDiscoveryReqCB received Null clientResponse";
461 return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
464 OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
465 OCClientResponse * clientResponse)
467 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
469 cout << "\nCallback Context for Device DISCOVER query recvd successfully";
474 //OC_LOG truncates the response as it is too long.
475 cout << "\nDiscovery response: ";
476 cout << clientResponse->payload;
480 cout << "\nPlatformDiscoveryReqCB received Null clientResponse";
483 return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
489 OCStackResult result = OC_STACK_OK;
490 cout << "\nExecuting " << __func__;
491 std::ostringstream query;
492 std::ostringstream querySuffix;
493 query << "coap://" << coapServerIP << ":" << coapServerPort << OC_RSRVD_PRESENCE_URI;
494 if(TEST_CASE == TEST_OBS_PRESENCE)
496 result = InvokeOCDoResource(query, OC_REST_PRESENCE, OC_LOW_QOS,
497 presenceCB, NULL, 0);
499 if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTER || TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
502 querySuffix << query.str() << "?rt=core.led";
503 result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
504 presenceCB, NULL, 0);
506 if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
508 if(result == OC_STACK_OK)
511 querySuffix << query.str() << "?rt=core.fan";
512 result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
513 presenceCB, NULL, 0);
516 if(TEST_CASE == TEST_OBS_MULTICAST_PRESENCE)
518 if(result == OC_STACK_OK)
520 std::ostringstream multicastPresenceQuery;
521 multicastPresenceQuery.str("");
522 multicastPresenceQuery << "coap://" << OC_MULTICAST_PREFIX << OC_RSRVD_PRESENCE_URI;
523 result = InvokeOCDoResource(multicastPresenceQuery, OC_REST_PRESENCE, OC_LOW_QOS,
524 presenceCB, NULL, 0);
531 int InitGetRequestToUnavailableResource(OCQualityOfService qos)
533 cout << "\nExecuting " << __func__;
534 std::ostringstream query;
536 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
537 if (65600 == OC_CONNTYPE)
539 query << "coap://" << coapServerIP << ":" << coapServerPort << "/SomeUnknownResource";
543 query << "coap://" << coapServerIP << "/SomeUnknownResource";
546 return (InvokeOCDoResource(query, OC_REST_GET, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
550 int InitObserveRequest(OCQualityOfService qos)
552 cout << "\nExecuting " << __func__;
553 std::ostringstream query;
554 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
555 if (65600 == OC_CONNTYPE)
557 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
561 query << "coap://" << coapServerIP << coapServerResource;
563 return (InvokeOCDoResource(query,
564 OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
567 int InitPutRequest(OCQualityOfService qos)
569 cout << "\nExecuting " << __func__;
570 std::ostringstream query;
571 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
572 if (65600 == OC_CONNTYPE)
574 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
578 query << "coap://" << coapServerIP << coapServerResource;
580 return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
584 int InitPostRequest(OCQualityOfService qos)
586 OCStackResult result;
587 cout << "\nExecuting " << __func__;
588 std::ostringstream query;
590 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
591 if (65600 == OC_CONNTYPE)
593 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
597 query << "coap://" << coapServerIP << coapServerResource;
600 // First POST operation (to create an Light instance)
601 result = InvokeOCDoResource(query, OC_REST_POST,
602 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
604 if (OC_STACK_OK != result)
606 // Error can happen if for example, network connectivity is down
607 cout << "\nFirst POST call did not succeed";
610 // Second POST operation (to create an Light instance)
611 result = InvokeOCDoResource(query, OC_REST_POST,
612 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
614 if (OC_STACK_OK != result)
616 cout << "\nSecond POST call did not succeed";
619 // This POST operation will update the original resourced /a/light
620 return (InvokeOCDoResource(query, OC_REST_POST,
621 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
622 postReqCB, NULL, 0));
625 void* RequestDeleteDeathResourceTask(void* myqos)
627 sleep (30);//long enough to give the server time to finish deleting the resource.
628 std::ostringstream query;
630 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
631 if (65600 == OC_CONNTYPE)
633 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
637 query << "coap://" << coapServerIP << coapServerResource;
640 cout << "\nExecuting " << __func__;
642 // Second DELETE operation to delete the resource that might have been removed already.
643 OCQualityOfService qos;
653 OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
655 deleteReqCB, NULL, 0);
657 if (OC_STACK_OK != result)
659 cout << "\nSecond DELETE call did not succeed";
665 int InitDeleteRequest(OCQualityOfService qos)
667 OCStackResult result;
668 std::ostringstream query;
669 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
670 if (65600 == OC_CONNTYPE)
672 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
676 query << "coap://" << coapServerIP << coapServerResource;
679 cout << "\nExecuting " << __func__;
681 // First DELETE operation
682 result = InvokeOCDoResource(query, OC_REST_DELETE,
684 deleteReqCB, NULL, 0);
685 if (OC_STACK_OK != result)
687 // Error can happen if for example, network connectivity is down
688 cout << "\nFirst DELETE call did not succeed";
692 //Create a thread to delete this resource again
694 pthread_create (&threadId, NULL, RequestDeleteDeathResourceTask, (void*)qos);
697 cout << "\nExit " << __func__;
701 int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions, bool getWithQuery)
704 OCHeaderOption options[MAX_HEADER_OPTIONS];
706 cout << "\nExecuting " << __func__;
707 std::ostringstream query;
709 //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
710 if (65600 == OC_CONNTYPE)
712 query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
716 query << "coap://" << coapServerIP << coapServerResource;
719 // ocserver is written to only process "power<X" query.
722 cout << "\nUsing query power<30";
723 query << "?power<50";
726 if (withVendorSpecificHeaderOptions)
728 uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
729 uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
730 memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
731 options[0].protocolID = OC_COAP_ID;
732 options[0].optionID = 2048;
733 memcpy(options[0].optionData, option0, sizeof(option0));
734 options[0].optionLength = 10;
735 options[1].protocolID = OC_COAP_ID;
736 options[1].optionID = 3000;
737 memcpy(options[1].optionData, option1, sizeof(option1));
738 options[1].optionLength = 10;
740 if (withVendorSpecificHeaderOptions)
742 return (InvokeOCDoResource(query, OC_REST_GET,
743 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, getReqCB, options, 2));
747 return (InvokeOCDoResource(query, OC_REST_GET,
748 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, getReqCB, NULL, 0));
752 int InitPlatformDiscovery(OCQualityOfService qos)
754 cout << "\nExecuting " << __func__;
757 OCCallbackData cbData;
758 char szQueryUri[64] = { 0 };
760 cbData.cb = PlatformDiscoveryReqCB;
761 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
764 if(UNICAST_DISCOVERY)
766 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PLATFORM_DISCOVERY_QUERY, unicastAddr);
770 strncpy(szQueryUri, MULTICAST_PLATFORM_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
772 szQueryUri[sizeof(szQueryUri) -1] = '\0';
774 if(UNICAST_DISCOVERY)
776 ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
777 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
782 ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
783 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
786 if (ret != OC_STACK_OK)
788 cout << "\nOCStack device error";
794 int InitDeviceDiscovery(OCQualityOfService qos)
796 cout << "\nExecuting " << __func__;
799 OCCallbackData cbData;
800 char szQueryUri[64] = { 0 };
802 cbData.cb = DeviceDiscoveryReqCB;
803 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
806 if(UNICAST_DISCOVERY)
808 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_DEVICE_DISCOVERY_QUERY, unicastAddr);
812 strncpy(szQueryUri, MULTICAST_DEVICE_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
814 szQueryUri[sizeof(szQueryUri) -1] = '\0';
816 if(UNICAST_DISCOVERY)
818 ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
819 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
823 ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
824 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
827 if (ret != OC_STACK_OK)
829 cout << "\nOCStack device error";
835 int InitDiscovery(OCQualityOfService qos)
838 OCCallbackData cbData;
839 /* Start a discovery query*/
840 char szQueryUri[64] = { 0 };
842 if (UNICAST_DISCOVERY)
844 snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_RESOURCE_DISCOVERY_QUERY, unicastAddr);
848 strcpy(szQueryUri, MULTICAST_RESOURCE_DISCOVERY_QUERY);
851 cbData.cb = discoveryReqCB;
852 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
854 if(UNICAST_DISCOVERY)
856 ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
857 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
861 ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
862 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
864 if (ret != OC_STACK_OK)
866 cout << "\nOCStack resource error";
871 int main(int argc, char* argv[])
875 while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
880 UNICAST_DISCOVERY = atoi(optarg);
883 TEST_CASE = atoi(optarg);
886 CONNECTIVITY = atoi(optarg);
894 if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
895 (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
896 (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
902 cout << "\nEntering occlient main loop...\n";
904 /* Initialize OCStack*/
905 if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
907 cout << "\nOCStack init error";
911 if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IPV4)
913 OC_CONNTYPE = CT_ADAPTER_IP;
915 else if(CONNECTIVITY == CT_IPV6)
917 //TODO: Remove when IPv6 is available.
918 cout << "\nIPv6 is currently not supported !!!!";
922 else if(CONNECTIVITY == CT_EDR)
924 OC_CONNTYPE = CT_ADAPTER_RFCOMM_BTEDR;
926 cout << "\nSelected EDR Adapter\n";
930 cout << "\nDefault Connectivity type selected...";
934 if (UNICAST_DISCOVERY)
936 cout << "\nEnter address of Server hosting resource as given below:";
937 cout << "\nIP Adapter: 192.168.0.15:45454(IP:Port)";
938 cout << "\nEDR/BLE Adapter: AB:BC:CD:DE:EF:FG(MAC Address)";
941 if (fgets(unicastAddr, MAX_ADDR_SIZE, stdin))
943 //Strip newline char from unicastAddr
944 StripNewLineChar(unicastAddr);
948 cout << "\n!! Bad input for IPV4 address. !!";
949 return OC_STACK_INVALID_PARAM;
953 if(UNICAST_DISCOVERY == 0 && TEST_CASE == TEST_DISCOVER_DEV_REQ)
955 InitDeviceDiscovery(OC_LOW_QOS);
957 else if(UNICAST_DISCOVERY == 0 && TEST_CASE == TEST_DISCOVER_PLATFORM_REQ)
959 InitPlatformDiscovery(OC_LOW_QOS);
963 InitDiscovery(OC_LOW_QOS);
966 // Break from loop with Ctrl+C
967 signal(SIGINT, handleSigInt);
971 if (OCProcess() != OC_STACK_OK)
973 cout << "\nOCStack process error\n";
980 cout << "\nExiting occlient main loop...\n";
982 if (OCStop() != OC_STACK_OK)
984 cout << "\nOCStack stop error\n";
990 std::string getIPAddrTBServer(OCClientResponse * clientResponse)
996 if (!clientResponse->addr)
1001 return std::string(clientResponse->devAddr.addr);
1004 std::string getPortTBServer(OCClientResponse * clientResponse)
1006 if (!clientResponse)
1010 if (!clientResponse->addr)
1014 std::ostringstream ss;
1015 ss << clientResponse->devAddr.port;
1019 std::string getConnectivityType (OCConnectivityType connType)
1021 switch (connType & CT_MASK_ADAPTER)
1032 case CT_ADAPTER_GATT_BTLE:
1035 case CT_ADAPTER_RFCOMM_BTEDR:
1039 return "Incorrect connectivity";
1043 std::string getQueryStrForGetPut(OCClientResponse * clientResponse)
1049 void parseClientResponse(OCClientResponse * clientResponse)
1051 coapServerIP = getIPAddrTBServer(clientResponse);
1052 coapServerPort = getPortTBServer(clientResponse);
1053 coapServerResource = getQueryStrForGetPut(clientResponse);