1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
30 #include "ocpayload.h"
31 #include "payload_logging.h"
32 #include "ocremoteaccessclient.h"
35 #define SET_BUT_NOT_USED(x) (void) x
36 // Tracking user input
37 static int TEST_CASE = 0;
39 static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
41 static std::string coapServerIP = "255.255.255.255";
42 static std::string coapServerPort = "5683";
43 static std::string coapServerResource = "/a/light";
44 static OCDevAddr responseAddr;
45 //Use ipv4addr for both InitDiscovery and InitPlatformOrDeviceDiscovery
46 char remoteServerJabberID[MAX_ADDR_STR_SIZE];
47 static uint16_t maxNotification = 15;
49 // The handle for the observe registration
50 OCDoHandle gObserveDoHandle;
52 // The handle for observe registration
53 OCDoHandle gPresenceHandle;
55 // After this crosses a threshold client deregisters for further notifications
56 int gNumObserveNotifies = 0;
59 int gNumPresenceNotifies = 0;
63 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
64 void handleSigInt(int signum)
72 OCPayload* putPayload()
74 OCRepPayload* payload = OCRepPayloadCreate();
78 std::cout << "Failed to create put payload object"<<std::endl;
81 OCRepPayloadSetPropInt(payload, "power", 42);
82 OCRepPayloadSetPropBool(payload, "state", true);
83 return (OCPayload*) payload;
86 static void PrintUsage()
88 OIC_LOG(INFO, TAG, "This sample makes all requests via the remote access adapter");
89 OIC_LOG(INFO, TAG, "Usage : ocremoteaccessclient -t <number>");
90 OIC_LOG(INFO, TAG, "-t 1 : Discover Resources");
91 OIC_LOG(INFO, TAG, "-t 2 : Discover & Get");
92 OIC_LOG(INFO, TAG, "-t 3 : Discover & Put");
93 OIC_LOG(INFO, TAG, "-t 4 : Discover & Post");
94 OIC_LOG(INFO, TAG, "-t 5 : Discover & Delete");
95 OIC_LOG(INFO, TAG, "-t 6 : Discover & Observe");
96 OIC_LOG(INFO, TAG, "-t 7 : Discover & Observe then cancel immediately with High QOS");
99 OCStackResult InvokeOCDoResource(std::ostringstream &query,
101 OCQualityOfService qos,
102 OCClientResponseHandler cb,
103 OCHeaderOption * options,
106 OCCallbackData cbData;
110 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
113 OCStackResult ret = OCDoResource(
118 (method == OC_REST_PUT) ? putPayload() : NULL,
119 CT_ADAPTER_REMOTE_ACCESS,
125 if (ret != OC_STACK_OK)
127 OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
129 else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
131 gObserveDoHandle = handle;
134 else if (method == OC_REST_PRESENCE)
136 gPresenceHandle = handle;
143 OCStackApplicationResult restRequestCB(void* ctx,
144 OCDoHandle handle, OCClientResponse * clientResponse)
146 if(clientResponse == NULL)
148 OIC_LOG(INFO, TAG, "Received NULL response");
149 return OC_STACK_DELETE_TRANSACTION;
151 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
153 OIC_LOG(INFO, TAG, "Callback Context recvd successfully");
156 OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
157 OIC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
158 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
160 if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
162 OIC_LOG (INFO, TAG, "Received vendor specific options. Ignoring");
164 SET_BUT_NOT_USED(handle);
165 return OC_STACK_DELETE_TRANSACTION;
168 OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
172 OIC_LOG_V(INFO, TAG, "obsReqCB received NULL response");
174 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
176 OIC_LOG(INFO, TAG, "Callback Context recvd successfully");
178 OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
179 OIC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
180 OIC_LOG_V(INFO, TAG, "OBSERVE notification %d recvd", gNumObserveNotifies);
181 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
183 gNumObserveNotifies++;
184 if (gNumObserveNotifies == maxNotification)
186 if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
188 OIC_LOG(ERROR, TAG, "Observe cancel error");
190 return OC_STACK_DELETE_TRANSACTION;
192 if (gNumObserveNotifies == 1 && TEST_CASE == TEST_OBS_REQ_NON_CANCEL_IMM)
194 if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
196 OIC_LOG(ERROR, TAG, "Observe cancel error");
199 if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
201 OIC_LOG(INFO, TAG, "Registration confirmed");
203 else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
205 OIC_LOG(INFO, TAG, "de-registration confirmed");
206 return OC_STACK_DELETE_TRANSACTION;
208 else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
210 OIC_LOG(INFO, TAG, "Registration/deregistration failed");
211 return OC_STACK_DELETE_TRANSACTION;
214 SET_BUT_NOT_USED(handle);
215 return OC_STACK_KEEP_TRANSACTION;
218 OCStackApplicationResult presenceCB(void* ctx,
219 OCDoHandle handle, OCClientResponse * clientResponse)
221 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
223 OIC_LOG(INFO, TAG, "Callback Context recvd successfully");
228 OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
229 OIC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
230 OIC_LOG_V(INFO, TAG, "PRESENCE notification %d recvd", gNumPresenceNotifies);
231 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
233 gNumPresenceNotifies++;
234 if (gNumPresenceNotifies == maxNotification)
236 if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
238 OIC_LOG(ERROR, TAG, "Presence cancel error");
240 return OC_STACK_DELETE_TRANSACTION;
245 OIC_LOG_V(INFO, TAG, "presenceCB received Null clientResponse");
247 SET_BUT_NOT_USED(handle);
248 return OC_STACK_KEEP_TRANSACTION;
252 // This is a function called back when a device is discovered
253 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
254 OCClientResponse * clientResponse)
256 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
258 OIC_LOG(INFO, TAG, "DISCOVER callback recvd");
263 OIC_LOG_V(INFO, TAG, "discoveryReqCB received Null clientResponse");
266 OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
267 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
269 responseAddr = clientResponse->devAddr;
273 OIC_LOG_V(INFO, TAG, "TEST_CASE %u\n", TEST_CASE);
274 case TEST_GET_REQ_NON:
275 InitGetRequest(OC_LOW_QOS);
277 case TEST_PUT_REQ_NON:
278 InitPutRequest(OC_LOW_QOS);
280 case TEST_POST_REQ_NON:
281 InitPostRequest(OC_LOW_QOS);
283 case TEST_DELETE_REQ_NON:
284 InitDeleteRequest(OC_LOW_QOS);
286 case TEST_OBS_REQ_NON:
287 case TEST_OBS_REQ_NON_CANCEL_IMM:
288 InitObserveRequest(OC_LOW_QOS);
294 SET_BUT_NOT_USED(handle);
295 return OC_STACK_KEEP_TRANSACTION;
298 OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
299 OCClientResponse * clientResponse)
301 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
303 OIC_LOG(INFO, TAG, "Callback Context for Platform DISCOVER query recvd successfully");
308 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
312 OIC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
315 SET_BUT_NOT_USED(handle);
316 return OC_STACK_DELETE_TRANSACTION;
319 OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
320 OCClientResponse * clientResponse)
322 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
324 OIC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
329 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
333 OIC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
336 SET_BUT_NOT_USED(handle);
337 return OC_STACK_DELETE_TRANSACTION;
340 int InitObserveRequest(OCQualityOfService qos)
342 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
343 std::ostringstream query;
344 query << coapServerResource;
345 return (InvokeOCDoResource(query,
346 OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
349 int InitPutRequest(OCQualityOfService qos)
351 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
352 std::ostringstream query;
353 query << coapServerResource;
354 return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
355 restRequestCB, NULL, 0));
358 int InitPostRequest(OCQualityOfService qos)
360 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
361 std::ostringstream query;
362 query << coapServerResource;
363 // First POST operation (to create an Light instance)
364 OCStackResult result = InvokeOCDoResource(query, OC_REST_POST,
365 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
366 restRequestCB, NULL, 0);
367 if (OC_STACK_OK != result)
369 // Error can happen if for example, network connectivity is down
370 OIC_LOG(INFO, TAG, "First POST call did not succeed");
373 // Second POST operation (to create an Light instance)
374 result = InvokeOCDoResource(query, OC_REST_POST,
375 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
376 restRequestCB, NULL, 0);
377 if (OC_STACK_OK != result)
379 OIC_LOG(INFO, TAG, "Second POST call did not succeed");
382 // This POST operation will update the original resourced /a/light
383 return (InvokeOCDoResource(query, OC_REST_POST,
384 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
385 restRequestCB, NULL, 0));
388 int InitDeleteRequest(OCQualityOfService qos)
390 std::ostringstream query;
391 query << coapServerResource;
392 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
394 // First DELETE operation
395 OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
397 restRequestCB, NULL, 0);
398 if (OC_STACK_OK != result)
400 // Error can happen if for example, network connectivity is down
401 OIC_LOG(INFO, TAG, "DELETE call did not succeed");
406 int InitGetRequest(OCQualityOfService qos)
408 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
409 std::ostringstream query;
410 query << coapServerResource;
411 return (InvokeOCDoResource(query, OC_REST_GET,
412 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, restRequestCB, NULL, 0));
415 int InitDiscovery(OCQualityOfService qos)
417 OCCallbackData cbData;
418 cbData.cb = discoveryReqCB;
419 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
423 dest.adapter = OC_ADAPTER_REMOTE_ACCESS;
424 dest.flags = OC_DEFAULT_FLAGS;
425 strncpy (dest.addr, remoteServerJabberID, MAX_ADDR_STR_SIZE - 1);
427 OCStackResult ret = OCDoResource(NULL,
429 MULTICAST_RESOURCE_DISCOVERY_QUERY,
432 CT_ADAPTER_REMOTE_ACCESS,
433 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
439 if (ret != OC_STACK_OK)
441 OIC_LOG_V(ERROR, TAG, "Error %u in OCDoResource with discovery", ret);
446 static void jidbound(char *jid)
448 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
451 int main(int argc, char* argv[])
453 char host[] = "localhost";
454 char user[] = "test1";
455 char pass[] = "intel123";
457 OCRAInfo_t rainfo = {};
459 rainfo.hostname = host;
461 rainfo.xmpp_domain = host;
462 rainfo.username = user;
463 rainfo.password = pass;
464 rainfo.resource = empstr;
465 rainfo.user_jid = empstr;
466 rainfo.jidbound = jidbound;
469 while ((opt = getopt(argc, argv, "t:s:p:d:u:w:r:j:")) != -1)
474 TEST_CASE = atoi(optarg);
477 rainfo.hostname = optarg;
480 rainfo.port = atoi(optarg);
483 rainfo.xmpp_domain = optarg;
486 rainfo.username = optarg;
489 rainfo.password = optarg;
492 rainfo.user_jid = optarg;
495 rainfo.resource = optarg;
503 if (OCSetRAInfo(&rainfo) != OC_STACK_OK)
505 OIC_LOG(ERROR, TAG, "Error initiating remote access adapter");
509 if ((TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS))
515 if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
517 OIC_LOG(ERROR, TAG, "OCStack init error");
521 OIC_LOG(INFO, TAG, "Enter JID of remote server");
522 if (fgets(remoteServerJabberID, MAX_ADDR_STR_SIZE, stdin))
524 StripNewLineChar(remoteServerJabberID);
528 OIC_LOG(ERROR, TAG, "Bad input for jabberID");
529 return OC_STACK_INVALID_PARAM;
532 InitDiscovery(OC_LOW_QOS);
534 // Break from loop with Ctrl+C
535 OIC_LOG(INFO, TAG, "Press CTRL+C to stop the stack");
536 signal(SIGINT, handleSigInt);
539 if (OCProcess() != OC_STACK_OK)
541 OIC_LOG(ERROR, TAG, "OCStack process error");
547 OIC_LOG(INFO, TAG, "Exiting ocremoteaccessclient main loop...");
549 if (OCStop() != OC_STACK_OK)
551 OIC_LOG(ERROR, TAG, "OCStack stop error");