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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // The source file for sample application "IotivityandZigbee".
23 // This application will utilize our interface (ie. zpluginz.h).
24 // The application may still be responsible for making any IoTivity API calls,
25 // except for resource-specific IoTivity APIs (ie. OCCreateResource(),
26 // OCDeleteResource(), EntityHandler()..etc.)
28 #include "IotivityandZigbeeClient.h"
36 #include "ocpayload.h"
37 #include "payload_logging.h"
38 #include "oic_string.h"
40 #define DEFAULT_CONTEXT_VALUE (0x99)
41 #define MAX_QUERY_SIZE (1024)
42 #define MAX_URI_SIZE (256)
43 #define MAX_RESOURCE_TYPE_SIZE (32)
44 #define MAX_RESOURCE_TYPE_LENGTH (MAX_RESOURCE_TYPE_SIZE - 1)
45 #define MAX_RESOURCES_REMEMBERED (10)
47 #define TAG "oc_zb_client"
49 static uint32_t countDiscoveredResources = 0;
50 static bool promptUser = false;
52 static OCDevAddr destinationAddress = {
53 .adapter = OC_ADAPTER_IP
58 char uri[MAX_URI_SIZE];
59 char resourceType[MAX_RESOURCE_TYPE_SIZE];
61 } DiscoveredResourceInfo;
63 static DiscoveredResourceInfo g_discoveredResources[MAX_RESOURCES_REMEMBERED];
65 static void PrintTestCases()
67 printf("\nTest Cases:\n");
68 printf ("\n\t%d : Quit %d: GET %d: Build PUT payload %d: OBSERVE\n\n",
69 TEST_QUIT, TEST_GET, TEST_CUSTOM_PUT, TEST_OBSERVE);
70 printf ("\t%d : Turn binary switch for light ON\n", TEST_TURN_SWITCH_ON);
71 printf ("\t%d : Turn binary switch for light OFF\n", TEST_TURN_SWITCH_OFF);
72 printf ("\t%d : Change light brightness\n", TEST_SET_LIGHT_BRIGHTNESS);
73 printf ("\n\t%d : Check for observation updates.\n", TEST_CYCLE);
76 static void PrintResources ()
78 printf("\nResources: \n");
79 for (uint32_t i = 0; i < countDiscoveredResources; ++i)
81 printf("\t# : %u \t URI: %s \t Type:%s\n", i, g_discoveredResources[i].uri,
82 g_discoveredResources[i].resourceType);
86 void rememberDiscoveredResources (OCClientResponse *clientResponse)
88 OCResourcePayload* itr = NULL;
89 if(!(OCDiscoveryPayload*)clientResponse->payload)
91 OC_LOG (INFO, TAG, "No resources discovered.");
95 itr = ((OCDiscoveryPayload*)(clientResponse->payload))->resources;
97 while(itr && itr != itr->next)
99 if (countDiscoveredResources == MAX_RESOURCES_REMEMBERED)
101 OC_LOG_V (INFO, TAG, "Only remembering %u resources. Ignoring rest.",
102 MAX_RESOURCES_REMEMBERED);
105 strncpy (g_discoveredResources[countDiscoveredResources].uri,
106 itr->uri, MAX_URI_SIZE - 1);
107 strncpy (g_discoveredResources[countDiscoveredResources].resourceType,
108 itr->types->value, MAX_RESOURCE_TYPE_SIZE - 1);
109 ++countDiscoveredResources;
114 OCStackResult InvokeOCDoResource (const char *query,
117 OCClientResponseHandler cb)
119 OCCallbackData cbData = {
120 .context = (void*)DEFAULT_CONTEXT_VALUE,
124 OCDoHandle handle = NULL;
126 OCStackResult ret = OCDoResource(&handle, method, query, &destinationAddress,
127 payload, CT_ADAPTER_IP, OC_LOW_QOS, &cbData, NULL, 0);
129 if (ret != OC_STACK_OK)
132 OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
137 OCStackApplicationResult responseCallbacks(void* ctx,
139 OCClientResponse * clientResponse)
143 if(clientResponse == NULL)
145 OC_LOG(INFO, TAG, "responseCallbacks received NULL clientResponse");
146 return OC_STACK_DELETE_TRANSACTION;
149 OC_LOG_PAYLOAD(INFO, clientResponse->payload);
151 return OC_STACK_KEEP_TRANSACTION;
154 int InitGetRequest (const char *resourceUri)
156 OC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
157 return (InvokeOCDoResource(resourceUri, NULL, OC_REST_GET, responseCallbacks));
160 int InitPutRequest (const char *resourceUri, OCPayload* payload)
162 OC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
163 return (InvokeOCDoResource(resourceUri, payload, OC_REST_PUT, responseCallbacks));
166 int InitObserveRequest(const char *resourceUri)
168 OC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
169 return (InvokeOCDoResource(resourceUri, NULL, OC_REST_OBSERVE, responseCallbacks));
172 OCPayload * getSwitchStatePayload (bool state)
174 OCRepPayload* payload = OCRepPayloadCreate();
177 OC_LOG (ERROR, TAG, "Failed to create payload object");
180 OCRepPayloadSetPropBool(payload, "value", state);
181 return (OCPayload*) payload;
184 OCPayload* getChangeLevelPayload(uint32_t level)
186 OCRepPayload* payload = OCRepPayloadCreate();
189 OC_LOG (ERROR, TAG, "Failed to create payload object");
193 OC_LOG_V(INFO, TAG, "Setting level to : %u", level);
194 OCRepPayloadSetPropInt(payload, "dimmingSetting", level);
195 return (OCPayload*) payload;
198 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
199 OCClientResponse * clientResponse)
205 OC_LOG(INFO, TAG, "Discovery response is NULL");
206 return OC_STACK_KEEP_TRANSACTION;
209 OC_LOG_PAYLOAD(INFO, clientResponse->payload);
210 OC_LOG_V(INFO, TAG, "Discovered @ %s:%d", clientResponse->devAddr.addr,
211 clientResponse->devAddr.port);
213 destinationAddress = clientResponse->devAddr;
215 rememberDiscoveredResources (clientResponse);
219 return OC_STACK_KEEP_TRANSACTION;
222 OCPayload* getCustomPutPayload ()
224 OCRepPayload* payload = OCRepPayloadCreate();
227 OC_LOG (ERROR, TAG, "Failed to create payload object");
232 char input[100] = {0};
233 char valueString[100] = {0};
235 double valueDouble = 0.0;
238 printf("\nEnter key value pairs as:\t<type(int)> <key> <value>\n");
239 printf("\nType: 0:bool \t 1:int \t 2:double\n");
242 printf ("Blank line / press ENTER to finish :");
243 char *ret = fgets (input, sizeof(input), stdin);
245 int inCount = sscanf (input, "%d %s %s", &type, key, valueString);
253 printf("Invalid input\n");
254 OCRepPayloadDestroy (payload);
259 if (type == 0) //bool
261 if (sscanf(valueString, "%d", &value) == 1)
263 OCRepPayloadSetPropBool(payload, key, value);
266 else if (type == 1) //int
268 if (sscanf(valueString, "%d", &value) == 1)
270 OCRepPayloadSetPropInt(payload, key, value);
273 else if (type == 2) //double
275 if (sscanf(valueString, "%lf", &valueDouble) == 1)
277 OCRepPayloadSetPropDouble(payload, key, valueDouble);
282 OC_LOG(ERROR, TAG, "Invalid entry. Stopping accepting key-values");
283 OCRepPayloadDestroy (payload);
287 memset (input, 0, sizeof (input));
288 memset (key, 0, sizeof (key));
289 memset (valueString, 0, sizeof (valueString));
294 return (OCPayload *) payload;
298 OCRepPayloadDestroy (payload);
303 void processUserInput (int resourceNo, int testCase)
308 InitGetRequest (g_discoveredResources[resourceNo].uri);
311 case TEST_CUSTOM_PUT:
313 OCPayload *payload = getCustomPutPayload ();
316 InitPutRequest (g_discoveredResources[resourceNo].uri, payload);
320 OC_LOG(ERROR, TAG, "Error creating payload. Not sending PUT request");
327 InitObserveRequest (g_discoveredResources[resourceNo].uri);
330 case TEST_TURN_SWITCH_ON:
331 InitPutRequest (g_discoveredResources[resourceNo].uri, getSwitchStatePayload (true));
334 case TEST_TURN_SWITCH_OFF:
335 InitPutRequest (g_discoveredResources[resourceNo].uri, getSwitchStatePayload (false));
338 case TEST_SET_LIGHT_BRIGHTNESS:
339 printf ("Change bulb level [0-100] to ? :");
341 if (scanf ("%d", &level) > 0)
343 InitPutRequest (g_discoveredResources[resourceNo].uri,
344 getChangeLevelPayload (level));
348 printf("Invalid value\n");
364 OC_LOG(INFO, TAG, "Invalid test case");
368 void getTestCaseFromUser ()
372 printf("\nUsage:<resource number> <test case> :");
374 char input[10] = {0};
375 uint32_t resourceNo = 0;
378 char * ret = fgets (input, sizeof(input), stdin);
380 int inCount = sscanf (input, "%d %d", &resourceNo, &testCase);
384 printf("Invalid input\n");
388 if (resourceNo >= countDiscoveredResources)
390 printf("Invalid resource\n");
394 processUserInput (resourceNo, testCase);
397 OCStackResult DiscoverResources ()
399 OCCallbackData cbData = {
400 .context = (void*)DEFAULT_CONTEXT_VALUE,
404 OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, OC_RSRVD_WELL_KNOWN_URI,
405 0, 0, CT_ADAPTER_IP,OC_LOW_QOS, &cbData, NULL, 0);
407 if (ret != OC_STACK_OK)
409 OC_LOG(ERROR, TAG, "OCDoResource error");
414 bool processSignal(bool set)
416 static sig_atomic_t signal = 0;
424 void processCancel(int signal)
432 int main(int argc, char* argv[])
436 OCStackResult result;
437 OC_LOG(INFO, TAG, "Initializing IoTivity...");
439 result = OCInit(NULL, 0, OC_CLIENT);
440 if (result != OC_STACK_OK)
442 OC_LOG_V(ERROR, TAG, "OCInit Failed %d", result);
446 DiscoverResources ();
448 if (signal(SIGINT, processCancel) == SIG_ERR)
450 OC_LOG(ERROR, TAG, "Unable to catch SIGINT, terminating...");
454 OC_LOG(INFO, TAG, "Press Ctrl-C to terminate");
456 while (!processSignal(false) && result == OC_STACK_OK)
458 result = OCProcess();
459 if (result != OC_STACK_OK)
461 OC_LOG_V(ERROR, TAG, "OCProcess Failed: %d", result);
468 getTestCaseFromUser ();
473 OC_LOG(INFO, TAG, "Stopping IoTivity...");
475 if (result != OC_STACK_OK)
477 OC_LOG_V(ERROR, TAG, "OCStop Failed: %d", result);