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"
37 #include "ocpayload.h"
38 #include "payload_logging.h"
39 #include "oic_string.h"
41 #define DEFAULT_CONTEXT_VALUE (0x99)
42 #define MAX_QUERY_SIZE (1024)
43 #define MAX_URI_SIZE (256)
44 #define MAX_RESOURCE_TYPE_SIZE (32)
45 #define MAX_RESOURCE_TYPE_LENGTH (MAX_RESOURCE_TYPE_SIZE - 1)
46 #define MAX_RESOURCES_REMEMBERED (100)
48 #define MAX_USER_INPUT (100)
50 #define TAG "oc_zb_client"
52 static uint32_t countDiscoveredResources = 0;
53 static bool promptUser = false;
55 static OCDevAddr destinationAddress = {
56 .adapter = OC_ADAPTER_IP
61 char uri[MAX_URI_SIZE];
62 char resourceType[MAX_RESOURCE_TYPE_SIZE];
64 } DiscoveredResourceInfo;
66 static DiscoveredResourceInfo g_discoveredResources[MAX_RESOURCES_REMEMBERED];
68 static void PrintTestCases()
70 printf("\nTest Cases:\n");
71 printf("\n\t%d : Quit %d: GET %d: Build PUT payload %d: OBSERVE\n\n",
72 TEST_QUIT, TEST_GET, TEST_CUSTOM_PUT, TEST_OBSERVE);
73 printf("\t%d : Turn binary switch for light ON\n", TEST_TURN_SWITCH_ON);
74 printf("\t%d : Turn binary switch for light OFF\n", TEST_TURN_SWITCH_OFF);
75 printf("\t%d : Change light brightness\n", TEST_SET_LIGHT_BRIGHTNESS);
76 printf("\t%d : Change light temperature\n", TEST_SET_LIGHT_TEMPERATURE);
77 printf("\n\t%d : Check for observation updates.\n", TEST_CYCLE);
80 static void PrintResources()
82 printf("\nResources: \n");
83 for(uint32_t i = 0; i < countDiscoveredResources; ++i)
85 printf("\t# : %u \t URI: %s \t Type:%s\n", i, g_discoveredResources[i].uri,
86 g_discoveredResources[i].resourceType);
90 void rememberDiscoveredResources(OCClientResponse *clientResponse)
92 OCResourcePayload* itr = NULL;
93 if (!(OCDiscoveryPayload*)clientResponse->payload)
95 OIC_LOG(INFO, TAG, "No resources discovered.");
99 itr = ((OCDiscoveryPayload*)(clientResponse->payload))->resources;
101 while (itr && itr != itr->next)
103 if (countDiscoveredResources == MAX_RESOURCES_REMEMBERED)
105 OIC_LOG_V(INFO, TAG, "Only remembering %u resources. Ignoring rest.",
106 MAX_RESOURCES_REMEMBERED);
109 strncpy(g_discoveredResources[countDiscoveredResources].uri,
110 itr->uri, MAX_URI_SIZE - 1);
111 strncpy(g_discoveredResources[countDiscoveredResources].resourceType,
112 itr->types->value, MAX_RESOURCE_TYPE_SIZE - 1);
113 ++countDiscoveredResources;
118 OCStackResult InvokeOCDoResource(const char *query,
121 OCClientResponseHandler cb)
123 OCCallbackData cbData = {
124 .context = (void*)DEFAULT_CONTEXT_VALUE,
128 OCDoHandle handle = NULL;
130 OCStackResult ret = OCDoResource(&handle, method, query, &destinationAddress,
131 payload, CT_ADAPTER_IP, OC_LOW_QOS, &cbData, NULL, 0);
133 if (ret != OC_STACK_OK)
136 OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
141 OCStackApplicationResult responseCallbacks(void* ctx,
143 OCClientResponse * clientResponse)
147 if (clientResponse == NULL)
149 OIC_LOG(INFO, TAG, "responseCallbacks received NULL clientResponse");
150 return OC_STACK_DELETE_TRANSACTION;
153 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
155 return OC_STACK_KEEP_TRANSACTION;
158 int InitGetRequest(const char *resourceUri)
160 OIC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
161 return (InvokeOCDoResource(resourceUri, NULL, OC_REST_GET, responseCallbacks));
164 int InitPutRequest(const char *resourceUri, OCPayload* payload)
166 OIC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
167 return (InvokeOCDoResource(resourceUri, payload, OC_REST_PUT, responseCallbacks));
170 int InitObserveRequest(const char *resourceUri)
172 OIC_LOG_V(INFO, TAG, "Executing %s for resource: %s", __func__, resourceUri);
173 return (InvokeOCDoResource(resourceUri, NULL, OC_REST_OBSERVE, responseCallbacks));
176 OCPayload * getSwitchStatePayload(bool state)
178 OCRepPayload* payload = OCRepPayloadCreate();
181 OIC_LOG(ERROR, TAG, "Failed to create payload object");
184 OCRepPayloadSetPropBool(payload, "value", state);
185 return (OCPayload*) payload;
188 OCPayload* getChangeBulbTempLevelPayload(uint32_t level)
190 OCRepPayload* payload = OCRepPayloadCreate();
193 OIC_LOG(ERROR, TAG, "Failed to create payload object");
197 OIC_LOG_V(INFO, TAG, "Setting level to : %u", level);
200 size_t sizeValue = sizeof(value);
201 int strRet = snprintf(value, sizeValue, "%d", level);
202 if (strRet < 0 || (size_t)strRet >= sizeValue)
204 OIC_LOG_V(ERROR, TAG, "Failed to parse string due to errno: %d", errno);
207 OCRepPayloadSetPropString(payload, "colourspacevalue", value);
208 return (OCPayload*) payload;
211 OCPayload* getChangeDimLevelPayload(uint32_t level)
213 OCRepPayload* payload = OCRepPayloadCreate();
216 OIC_LOG(ERROR, TAG, "Failed to create payload object");
220 OIC_LOG_V(INFO, TAG, "Setting level to : %u", level);
221 OCRepPayloadSetPropInt(payload, "dimmingSetting", level);
222 return (OCPayload*) payload;
225 OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
226 OCClientResponse * clientResponse)
232 OIC_LOG(INFO, TAG, "Discovery response is NULL");
233 return OC_STACK_KEEP_TRANSACTION;
236 OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
237 OIC_LOG_V(INFO, TAG, "Discovered @ %s:%d", clientResponse->devAddr.addr,
238 clientResponse->devAddr.port);
240 destinationAddress = clientResponse->devAddr;
242 rememberDiscoveredResources(clientResponse);
246 return OC_STACK_KEEP_TRANSACTION;
249 OCPayload* getCustomPutPayload()
251 OCRepPayload* payload = OCRepPayloadCreate();
254 OIC_LOG(ERROR, TAG, "Failed to create payload object");
258 char key[MAX_USER_INPUT] = {0};
259 char input[MAX_USER_INPUT] = {0};
260 char valueString[MAX_USER_INPUT] = {0};
262 double valueDouble = 0.0;
265 printf("\nEnter key value pairs as:\t<type(int)> <key> <value>\n");
266 printf("\nType: 0:bool \t 1:int \t 2:double\n");
269 printf("Blank line / press ENTER to finish :");
270 char *ret = fgets(input, sizeof(input), stdin);
272 int inCount = sscanf(input, "%d %s %s", &type, key, valueString);
280 printf("Invalid input\n");
281 OCRepPayloadDestroy(payload);
286 if (type == 0) //bool
288 if (sscanf(valueString, "%d", &value) == 1)
290 OCRepPayloadSetPropBool(payload, key, value);
293 else if (type == 1) //int
295 if (sscanf(valueString, "%d", &value) == 1)
297 OCRepPayloadSetPropInt(payload, key, value);
300 else if (type == 2) //double
302 if (sscanf(valueString, "%lf", &valueDouble) == 1)
304 OCRepPayloadSetPropDouble(payload, key, valueDouble);
309 OIC_LOG(ERROR, TAG, "Invalid entry. Stopping accepting key-values");
310 OCRepPayloadDestroy(payload);
314 memset(input, 0, sizeof (input));
315 memset(key, 0, sizeof (key));
316 memset(valueString, 0, sizeof (valueString));
321 return (OCPayload *) payload;
325 OCRepPayloadDestroy(payload);
330 void processUserInput(int resourceNo, int testCase)
333 if (!resourceNo && !testCase)
335 testCase = TEST_QUIT;
340 InitGetRequest(g_discoveredResources[resourceNo].uri);
343 case TEST_CUSTOM_PUT:
345 OCPayload *payload = getCustomPutPayload();
348 InitPutRequest(g_discoveredResources[resourceNo].uri, payload);
352 OIC_LOG(ERROR, TAG, "Error creating payload. Not sending PUT request");
359 InitObserveRequest(g_discoveredResources[resourceNo].uri);
362 case TEST_TURN_SWITCH_ON:
363 InitPutRequest(g_discoveredResources[resourceNo].uri, getSwitchStatePayload (true));
366 case TEST_TURN_SWITCH_OFF:
367 InitPutRequest(g_discoveredResources[resourceNo].uri, getSwitchStatePayload (false));
370 case TEST_SET_LIGHT_BRIGHTNESS:
371 printf("Change bulb level [0-100] to ? :");
372 if (scanf("%d", &level) > 0)
374 InitPutRequest(g_discoveredResources[resourceNo].uri,
375 getChangeDimLevelPayload (level));
379 printf("Invalid value\n");
384 case TEST_SET_LIGHT_TEMPERATURE:
385 printf("Change bulb temp level [0-100] to ? :");
386 if (scanf("%d", &level) > 0)
388 InitPutRequest(g_discoveredResources[resourceNo].uri,
389 getChangeBulbTempLevelPayload(level));
393 printf("Invalid value\n");
409 OIC_LOG(INFO, TAG, "Invalid test case");
413 void getTestCaseFromUser()
417 printf("\nUsage:<resource number> <test case> :");
419 char input[10] = {0};
420 uint32_t resourceNo = 0;
423 char * ret = fgets(input, sizeof(input), stdin);
425 int inCount = sscanf(input, "%d %d", &resourceNo, &testCase);
429 printf("Invalid input\n");
433 if (resourceNo >= countDiscoveredResources)
435 printf("Invalid resource\n");
439 processUserInput(resourceNo, testCase);
442 OCStackResult DiscoverResources()
444 OCCallbackData cbData = {
445 .context = (void*)DEFAULT_CONTEXT_VALUE,
449 OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, OC_RSRVD_WELL_KNOWN_URI,
450 0, 0, CT_ADAPTER_IP,OC_LOW_QOS, &cbData, NULL, 0);
452 if (ret != OC_STACK_OK)
454 OIC_LOG(ERROR, TAG, "OCDoResource error");
459 bool processSignal(bool set)
461 static sig_atomic_t signal = 0;
469 void processCancel(int signal)
471 if (signal == SIGINT)
477 int main(int argc, char* argv[])
481 OCStackResult result;
482 OIC_LOG(INFO, TAG, "Initializing IoTivity...");
484 result = OCInit(NULL, 0, OC_CLIENT);
485 if (result != OC_STACK_OK)
487 OIC_LOG_V(ERROR, TAG, "OCInit Failed %d", result);
493 if (signal(SIGINT, processCancel) == SIG_ERR)
495 OIC_LOG(ERROR, TAG, "Unable to catch SIGINT, terminating...");
499 OIC_LOG(INFO, TAG, "Press Ctrl-C to terminate");
501 while (!processSignal(false) && result == OC_STACK_OK)
503 result = OCProcess();
504 if (result != OC_STACK_OK)
506 OIC_LOG_V(ERROR, TAG, "OCProcess Failed: %d", result);
513 getTestCaseFromUser();
518 OIC_LOG(INFO, TAG, "Stopping IoTivity...");
520 if (result != OC_STACK_OK)
522 OIC_LOG_V(ERROR, TAG, "OCStop Failed: %d", result);