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"
34 // Tracking user input
35 static int TEST_CASE = 0;
37 static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
38 static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
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 void StripNewLineChar(char* str);
48 static uint16_t maxNotification = 15;
50 // The handle for the observe registration
51 OCDoHandle gObserveDoHandle;
53 // The handle for observe registration
54 OCDoHandle gPresenceHandle;
56 // After this crosses a threshold client deregisters for further notifications
57 int gNumObserveNotifies = 0;
60 int gNumPresenceNotifies = 0;
64 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
65 void handleSigInt(int signum)
73 OCPayload* putPayload()
75 OCRepPayload* payload = OCRepPayloadCreate();
79 std::cout << "Failed to create put payload object"<<std::endl;
82 OCRepPayloadSetPropInt(payload, "power", 42);
83 OCRepPayloadSetPropBool(payload, "state", true);
84 return (OCPayload*) payload;
87 static void PrintUsage()
89 OC_LOG(INFO, TAG, "This sample makes all requests via the remote access adapter");
90 OC_LOG(INFO, TAG, "Usage : ocremoteaccessclient -t <number>");
91 OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
92 OC_LOG(INFO, TAG, "-t 2 : Discover & Get");
93 OC_LOG(INFO, TAG, "-t 3 : Discover & Put");
94 OC_LOG(INFO, TAG, "-t 4 : Discover & Post");
95 OC_LOG(INFO, TAG, "-t 5 : Discover & Delete");
96 OC_LOG(INFO, TAG, "-t 6 : Discover & Observe");
97 OC_LOG(INFO, TAG, "-t 7 : Discover & Observe then cancel immediately with High QOS");
100 OCStackResult InvokeOCDoResource(std::ostringstream &query,
102 OCQualityOfService qos,
103 OCClientResponseHandler cb,
104 OCHeaderOption * options,
107 OCCallbackData cbData;
111 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
114 OCStackResult ret = OCDoResource(
119 (method == OC_REST_PUT) ? putPayload() : NULL,
120 CT_ADAPTER_REMOTE_ACCESS,
126 if (ret != OC_STACK_OK)
128 OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
130 else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
132 gObserveDoHandle = handle;
135 else if (method == OC_REST_PRESENCE)
137 gPresenceHandle = handle;
144 OCStackApplicationResult restRequestCB(void* ctx,
145 OCDoHandle handle, OCClientResponse * clientResponse)
147 if(clientResponse == NULL)
149 OC_LOG(INFO, TAG, "Received NULL response");
150 return OC_STACK_DELETE_TRANSACTION;
152 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
154 OC_LOG(INFO, TAG, "Callback Context recvd successfully");
157 OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
158 OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
159 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
161 if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
163 OC_LOG (INFO, TAG, "Received vendor specific options. Ignoring");
165 return OC_STACK_DELETE_TRANSACTION;
168 OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
172 OC_LOG_V(INFO, TAG, "obsReqCB received NULL response");
174 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
176 OC_LOG(INFO, TAG, "Callback Context recvd successfully");
178 OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
179 OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
180 OC_LOG_V(INFO, TAG, "OBSERVE notification %d recvd", gNumObserveNotifies);
181 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
183 gNumObserveNotifies++;
184 if (gNumObserveNotifies == maxNotification)
186 if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
188 OC_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 OC_LOG(ERROR, TAG, "Observe cancel error");
199 if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
201 OC_LOG(INFO, TAG, "Registration confirmed");
203 else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
205 OC_LOG(INFO, TAG, "de-registration confirmed");
206 return OC_STACK_DELETE_TRANSACTION;
208 else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
210 OC_LOG(INFO, TAG, "Registration/deregistration failed");
211 return OC_STACK_DELETE_TRANSACTION;
214 return OC_STACK_KEEP_TRANSACTION;
217 OCStackApplicationResult presenceCB(void* ctx,
218 OCDoHandle handle, OCClientResponse * clientResponse)
220 if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
222 OC_LOG(INFO, TAG, "Callback Context recvd successfully");
227 OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
228 OC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
229 OC_LOG_V(INFO, TAG, "PRESENCE notification %d recvd", gNumPresenceNotifies);
230 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
232 gNumPresenceNotifies++;
233 if (gNumPresenceNotifies == maxNotification)
235 if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
237 OC_LOG(ERROR, TAG, "Presence cancel error");
239 return OC_STACK_DELETE_TRANSACTION;
244 OC_LOG_V(INFO, TAG, "presenceCB received Null clientResponse");
246 return OC_STACK_KEEP_TRANSACTION;
250 // This is a function called back when a device is discovered
251 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
252 OCClientResponse * clientResponse)
254 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
256 OC_LOG(INFO, TAG, "DISCOVER callback recvd");
261 OC_LOG_V(INFO, TAG, "discoveryReqCB received Null clientResponse");
264 OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
265 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
267 responseAddr = clientResponse->devAddr;
271 OC_LOG_V(INFO, TAG, "TEST_CASE %u\n", TEST_CASE);
272 case TEST_GET_REQ_NON:
273 InitGetRequest(OC_LOW_QOS);
275 case TEST_PUT_REQ_NON:
276 InitPutRequest(OC_LOW_QOS);
278 case TEST_POST_REQ_NON:
279 InitPostRequest(OC_LOW_QOS);
281 case TEST_DELETE_REQ_NON:
282 InitDeleteRequest(OC_LOW_QOS);
284 case TEST_OBS_REQ_NON:
285 case TEST_OBS_REQ_NON_CANCEL_IMM:
286 InitObserveRequest(OC_LOW_QOS);
292 return OC_STACK_KEEP_TRANSACTION;
295 OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
296 OCClientResponse * clientResponse)
298 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
300 OC_LOG(INFO, TAG, "Callback Context for Platform DISCOVER query recvd successfully");
305 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
309 OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
312 return OC_STACK_DELETE_TRANSACTION;
315 OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
316 OCClientResponse * clientResponse)
318 if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
320 OC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
325 OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
329 OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
332 return OC_STACK_DELETE_TRANSACTION;
335 int InitObserveRequest(OCQualityOfService qos)
337 OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
338 std::ostringstream query;
339 query << coapServerResource;
340 return (InvokeOCDoResource(query,
341 OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
344 int InitPutRequest(OCQualityOfService qos)
346 OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
347 std::ostringstream query;
348 query << coapServerResource;
349 return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
350 restRequestCB, NULL, 0));
353 int InitPostRequest(OCQualityOfService qos)
355 OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
356 std::ostringstream query;
357 query << coapServerResource;
358 // First POST operation (to create an Light instance)
359 OCStackResult result = InvokeOCDoResource(query, OC_REST_POST,
360 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
361 restRequestCB, NULL, 0);
362 if (OC_STACK_OK != result)
364 // Error can happen if for example, network connectivity is down
365 OC_LOG(INFO, TAG, "First POST call did not succeed");
368 // Second POST operation (to create an Light instance)
369 result = InvokeOCDoResource(query, OC_REST_POST,
370 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
371 restRequestCB, NULL, 0);
372 if (OC_STACK_OK != result)
374 OC_LOG(INFO, TAG, "Second POST call did not succeed");
377 // This POST operation will update the original resourced /a/light
378 return (InvokeOCDoResource(query, OC_REST_POST,
379 ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
380 restRequestCB, NULL, 0));
383 int InitDeleteRequest(OCQualityOfService qos)
385 std::ostringstream query;
386 query << coapServerResource;
387 OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
389 // First DELETE operation
390 OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
392 restRequestCB, NULL, 0);
393 if (OC_STACK_OK != result)
395 // Error can happen if for example, network connectivity is down
396 OC_LOG(INFO, TAG, "DELETE call did not succeed");
401 int InitGetRequest(OCQualityOfService qos)
403 OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
404 std::ostringstream query;
405 query << coapServerResource;
406 return (InvokeOCDoResource(query, OC_REST_GET,
407 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, restRequestCB, NULL, 0));
410 int InitDiscovery(OCQualityOfService qos)
412 OCCallbackData cbData;
413 cbData.cb = discoveryReqCB;
414 cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
418 dest.adapter = OC_ADAPTER_REMOTE_ACCESS;
419 dest.flags = OC_DEFAULT_FLAGS;
420 strncpy (dest.addr, remoteServerJabberID, MAX_ADDR_STR_SIZE - 1);
422 OCStackResult ret = OCDoResource(NULL,
424 MULTICAST_RESOURCE_DISCOVERY_QUERY,
427 CT_ADAPTER_REMOTE_ACCESS,
428 (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
434 if (ret != OC_STACK_OK)
436 OC_LOG_V(ERROR, TAG, "Error %u in OCDoResource with discovery", ret);
441 OCStackResult initRemoteAccessAdapter ()
444 rainfo.hostname = "localhost";
446 rainfo.xmpp_domain = "localhost";
447 rainfo.username = "test1";
448 rainfo.password = "intel123";
449 rainfo.resource = "";
450 rainfo.user_jid = "";
452 return OCSetRAInfo(&rainfo);
455 int main(int argc, char* argv[])
459 while ((opt = getopt(argc, argv, "t:")) != -1)
464 TEST_CASE = atoi(optarg);
472 if (initRemoteAccessAdapter() != OC_STACK_OK)
474 OC_LOG(ERROR, TAG, "Error initiating remote access adapter");
478 if ((TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS))
484 if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
486 OC_LOG(ERROR, TAG, "OCStack init error");
490 OC_LOG(INFO, TAG, "Enter JID of remote server");
491 if (fgets(remoteServerJabberID, MAX_ADDR_STR_SIZE, stdin))
493 StripNewLineChar(remoteServerJabberID);
497 OC_LOG(ERROR, TAG, "Bad input for jabberID");
498 return OC_STACK_INVALID_PARAM;
501 InitDiscovery(OC_LOW_QOS);
503 // Break from loop with Ctrl+C
504 OC_LOG(INFO, TAG, "Press CTRL+C to stop the stack");
505 signal(SIGINT, handleSigInt);
508 if (OCProcess() != OC_STACK_OK)
510 OC_LOG(ERROR, TAG, "OCStack process error");
516 OC_LOG(INFO, TAG, "Exiting ocremoteaccessclient main loop...");
518 if (OCStop() != OC_STACK_OK)
520 OC_LOG(ERROR, TAG, "OCStack stop error");