1 //******************************************************************
3 // Copyright 2014 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
32 const char *getResult(OCStackResult result);
34 #define TAG PCF("ocservercontainer")
36 volatile sig_atomic_t gQuitFlag = 0;
37 int gLightUnderObservation = 0;
38 void createResources();
39 typedef struct LIGHTRESOURCE{
40 OCResourceHandle handle;
45 static LightResource light;
47 // TODO : hard coded for now, change after Sprint10
48 const char rspGetRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
49 const char rspGetRoomCollection[] = "{\"href\":\"/a/room\"}";
50 // TODO : Needs to be changed to retrieve current status of room and return that in response
51 const char rspPutRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
52 const char rspPutRoomCollection[] = "{\"href\":\"/a/room\"}";
53 const char rspFailureRoom[] = "{\"href\":\"/a/room\",\"rep\":{\"error\":\"ROOM_OP_FAIL\"}}";
55 // TODO : hard coded for now, change after Sprint4
56 const char rspGetLightDefault[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":\"false\",\"color\":\"0\"}}";
57 const char rspGetLightCollection[] = "{\"href\":\"/a/light\"}";
58 // TODO : Needs to be changed to retrieve current status of light and return that in response
59 const char rspPutLightDefault[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":\"true\",\"color\":\"0\"}}";
60 const char rspPutLightCollection[] = "{\"href\":\"/a/light\"}";
61 const char rspFailureLight[] = "{\"href\":\"/a/light\",\"rep\":{\"error\":\"LIGHT_OP_FAIL\"}}";
64 // TODO : hard coded for now, change after Sprint4
65 const char rspGetFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"true\",\"speed\":10}}";
66 const char rspGetFanCollection[] = "{\"href\":\"/a/fan\"}";
67 // TODO : Needs to be changed to retrieve current status of fan and return that in response
68 const char rspPutFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"false\",\"speed\":0}}";
69 const char rspPutFanCollection[] = "{\"href\":\"/a/fan\"}";
70 const char rspFailureFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"error\":\"FAN_OP_FAIL\"}}";
81 OC_LOG(INFO, TAG, "Usage : ocservercoll -t <Test Case>");
82 OC_LOG(INFO, TAG, "Test Case 1 : Create room resource with default collection entity handler.");
83 OC_LOG(INFO, TAG, "Test Case 2 : Create room resource with application collection entity handler.");
86 unsigned static int TEST = TEST_INVALID;
88 static OCEntityHandlerResult
89 HandleCallback(OCEntityHandlerRequest * ehRequest,
93 uint16_t maxPayloadSize)
95 OCEntityHandlerResult ret = OC_EH_OK;
97 // Append opStr or errStr, after making sure there is
98 // enough room in the payload
99 if (strlen(opStr) < (maxPayloadSize - strlen(payload)))
101 strncat((char*)payload, opStr, strlen(opStr));
103 else if (strlen(errStr) < (maxPayloadSize - strlen(payload)))
105 strncat((char*)payload, errStr, strlen(errStr));
117 PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest)
119 const char* typeOfMessage;
123 typeOfMessage = "OC_INIT_FLAG";
125 case OC_REQUEST_FLAG:
126 typeOfMessage = "OC_REQUEST_FLAG";
128 case OC_OBSERVE_FLAG:
129 typeOfMessage = "OC_OBSERVE_FLAG";
132 typeOfMessage = "UNKNOWN";
135 OC_LOG_V(INFO, TAG, "Receiving message type: %s, method %s",
137 (ehRequest->method == OC_REST_GET) ? "OC_REST_GET" : "OC_REST_PUT" );
140 OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
141 OCEntityHandlerRequest * ehRequest)
143 OCEntityHandlerResult ret = OC_EH_OK;
144 OCEntityHandlerResponse response;
145 char payload[MAX_RESPONSE_LENGTH] = {0};
147 OC_LOG_V(INFO, TAG, "Callback for Room");
148 PrintReceivedMsgInfo(flag, ehRequest );
150 if(ehRequest && flag == OC_REQUEST_FLAG )
152 std::string query = (const char*)ehRequest->query;
154 if(OC_REST_GET == ehRequest->method)
156 if(query.find("oc.mi.def") != std::string::npos)
158 ret = HandleCallback(ehRequest, rspGetRoomDefault, rspFailureRoom, payload, sizeof(payload));
159 if(ret != OC_EH_ERROR)
161 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
162 ret = HandleCallback(ehRequest, rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
164 if(ret != OC_EH_ERROR)
166 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
167 ret = HandleCallback(ehRequest, rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
170 else if(query.find("oc.mi.ll") != std::string::npos)
172 ret = HandleCallback(ehRequest, rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
173 if(ret != OC_EH_ERROR)
175 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
176 ret = HandleCallback(ehRequest, rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
178 if(ret != OC_EH_ERROR)
180 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
181 ret = HandleCallback(ehRequest, rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
184 else if(query.find("oc.mi.b") != std::string::npos)
186 ret = HandleCallback(ehRequest, rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
187 if(ret != OC_EH_ERROR)
189 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
190 ret = HandleCallback(ehRequest, rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
192 if(ret != OC_EH_ERROR)
194 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
195 ret = HandleCallback(ehRequest, rspGetFanDefault, rspFailureFan, payload, sizeof(payload));
200 // Format the response. Note this requires some info about the request
201 response.requestHandle = ehRequest->requestHandle;
202 response.resourceHandle = ehRequest->resource;
203 response.ehResult = ret;
204 response.payload = (unsigned char *)payload;
205 response.payloadSize = strlen(payload);
206 response.numSendVendorSpecificHeaderOptions = 0;
207 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
208 memset(response.resourceUri, 0, sizeof response.resourceUri);
209 // Indicate that response is NOT in a persistent buffer
210 response.persistentBufferFlag = 0;
212 if (OCDoResponse(&response) != OC_STACK_OK)
214 OC_LOG(ERROR, TAG, "Error sending response");
219 else if(OC_REST_PUT == ehRequest->method)
221 if(query.find("oc.mi.def") != std::string::npos)
223 if(ret != OC_EH_ERROR)
225 ret = HandleCallback(ehRequest, rspPutRoomDefault, rspFailureRoom, payload, sizeof(payload));
228 if(query.find("oc.mi.ll") != std::string::npos)
230 if(ret != OC_EH_ERROR)
232 ret = HandleCallback(ehRequest, rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
234 if(ret != OC_EH_ERROR)
236 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
237 ret = HandleCallback(ehRequest, rspPutLightCollection, rspFailureLight, payload, sizeof(payload));
239 if(ret != OC_EH_ERROR)
241 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
242 ret = HandleCallback(ehRequest, rspPutFanCollection, rspFailureFan, payload, sizeof(payload));
245 if(query.find("oc.mi.b") != std::string::npos)
247 if(ret != OC_EH_ERROR)
249 ret = HandleCallback(ehRequest, rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
251 if(ret != OC_EH_ERROR)
253 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
254 ret = HandleCallback(ehRequest, rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
256 if(ret != OC_EH_ERROR)
258 ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
259 ret = HandleCallback(ehRequest, rspPutFanDefault, rspFailureFan, payload, sizeof(payload));
264 // Format the response. Note this requires some info about the request
265 response.requestHandle = ehRequest->requestHandle;
266 response.resourceHandle = ehRequest->resource;
267 response.ehResult = ret;
268 response.payload = (unsigned char *)payload;
269 response.payloadSize = strlen(payload);
270 response.numSendVendorSpecificHeaderOptions = 0;
271 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
272 memset(response.resourceUri, 0, sizeof response.resourceUri);
273 // Indicate that response is NOT in a persistent buffer
274 response.persistentBufferFlag = 0;
276 if (OCDoResponse(&response) != OC_STACK_OK)
278 OC_LOG(ERROR, TAG, "Error sending response");
285 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
290 else if (ehRequest && flag == OC_OBSERVE_FLAG)
292 gLightUnderObservation = 1;
297 OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest)
299 OCEntityHandlerResult ret = OC_EH_OK;
300 OCEntityHandlerResponse response;
301 char payload[MAX_RESPONSE_LENGTH] = {0};
303 OC_LOG_V(INFO, TAG, "Callback for Light");
304 PrintReceivedMsgInfo(flag, ehRequest );
306 if(ehRequest && flag == OC_REQUEST_FLAG)
308 if(OC_REST_GET == ehRequest->method)
310 ret = HandleCallback(ehRequest, rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
312 else if(OC_REST_PUT == ehRequest->method)
314 ret = HandleCallback(ehRequest, rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
318 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
325 // Format the response. Note this requires some info about the request
326 response.requestHandle = ehRequest->requestHandle;
327 response.resourceHandle = ehRequest->resource;
328 response.ehResult = ret;
329 response.payload = (unsigned char *)payload;
330 response.payloadSize = strlen(payload);
331 response.numSendVendorSpecificHeaderOptions = 0;
332 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
333 memset(response.resourceUri, 0, sizeof response.resourceUri);
334 // Indicate that response is NOT in a persistent buffer
335 response.persistentBufferFlag = 0;
338 if (OCDoResponse(&response) != OC_STACK_OK)
340 OC_LOG(ERROR, TAG, "Error sending response");
345 else if (ehRequest && flag == OC_OBSERVE_FLAG)
347 gLightUnderObservation = 1;
353 OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest)
355 OCEntityHandlerResult ret = OC_EH_OK;
356 OCEntityHandlerResponse response;
357 char payload[MAX_RESPONSE_LENGTH] = {0};
359 OC_LOG_V(INFO, TAG, "Callback for Fan");
360 PrintReceivedMsgInfo(flag, ehRequest );
362 if(ehRequest && flag == OC_REQUEST_FLAG)
364 if(OC_REST_GET == ehRequest->method)
366 ret = HandleCallback(ehRequest, rspGetFanDefault, rspFailureFan, payload, sizeof(payload));
368 else if(OC_REST_PUT == ehRequest->method)
370 ret = HandleCallback(ehRequest, rspPutFanDefault, rspFailureFan, payload, sizeof(payload));
374 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
381 // Format the response. Note this requires some info about the request
382 response.requestHandle = ehRequest->requestHandle;
383 response.resourceHandle = ehRequest->resource;
384 response.ehResult = ret;
385 response.payload = (unsigned char *)payload;
386 response.payloadSize = strlen(payload);
387 response.numSendVendorSpecificHeaderOptions = 0;
388 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
389 memset(response.resourceUri, 0, sizeof response.resourceUri);
390 // Indicate that response is NOT in a persistent buffer
391 response.persistentBufferFlag = 0;
394 if (OCDoResponse(&response) != OC_STACK_OK)
396 OC_LOG(ERROR, TAG, "Error sending response");
402 else if (ehRequest && flag == OC_OBSERVE_FLAG)
404 gLightUnderObservation = 1;
410 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
411 void handleSigInt(int signum)
413 if (signum == SIGINT)
419 void *ChangeLightRepresentation (void *param)
422 OCStackResult result = OC_STACK_ERROR;
428 if (gLightUnderObservation)
430 OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", light.power);
431 result = OCNotifyAllObservers (light.handle, OC_NA_QOS);
432 if (OC_STACK_NO_OBSERVERS == result)
434 gLightUnderObservation = 0;
441 int main(int argc, char* argv[])
443 uint8_t addr[20] = {0};
444 uint8_t* paddr = NULL;
446 uint8_t ifname[] = "eth0";
450 while ((opt = getopt(argc, argv, "t:")) != -1)
462 if(TEST <= TEST_INVALID || TEST >= MAX_TESTS){
467 OC_LOG(DEBUG, TAG, "OCServer is starting...");
468 /*Get Ip address on defined interface and initialize coap on it with random port number
469 * this port number will be used as a source port in all coap communications*/
470 if (OCGetInterfaceAddress(ifname, sizeof(ifname), AF_INET, addr,
471 sizeof(addr)) == ERR_SUCCESS)
473 OC_LOG_V(INFO, TAG, "Starting ocserver on address %s:%d",addr,port);
477 if (OCInit((char *) paddr, port, OC_SERVER) != OC_STACK_OK) {
478 OC_LOG(ERROR, TAG, "OCStack init error");
483 * Declare and create the example resource: light
488 * Create a thread for changing the representation of the light
490 pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
492 // Break from loop with Ctrl-C
493 OC_LOG(INFO, TAG, "Entering ocserver main loop...");
494 signal(SIGINT, handleSigInt);
497 if (OCProcess() != OC_STACK_OK)
499 OC_LOG(ERROR, TAG, "OCStack process error");
506 * Cancel the light thread and wait for it to terminate
508 pthread_cancel(threadId);
509 pthread_join(threadId, NULL);
511 OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
513 if (OCStop() != OC_STACK_OK)
515 OC_LOG(ERROR, TAG, "OCStack process error");
520 void createResources()
524 OCResourceHandle fan;
525 OCStackResult res = OCCreateResource(&fan,
529 OCEntityHandlerFanCb,
530 OC_DISCOVERABLE|OC_OBSERVABLE);
531 OC_LOG_V(INFO, TAG, "Created fan resource with result: %s", getResult(res));
533 OCResourceHandle light;
534 res = OCCreateResource(&light,
538 OCEntityHandlerLightCb,
539 OC_DISCOVERABLE|OC_OBSERVABLE);
540 OC_LOG_V(INFO, TAG, "Created light resource with result: %s", getResult(res));
542 OCResourceHandle room;
544 if(TEST == TEST_APP_COLL_EH)
546 res = OCCreateResource(&room,
550 OCEntityHandlerRoomCb,
555 res = OCCreateResource(&room,
563 OC_LOG_V(INFO, TAG, "Created room resource with result: %s", getResult(res));
564 OCBindResourceInterfaceToResource(room, "oc.mi.ll");
565 OCBindResourceInterfaceToResource(room, "oc.mi.def");
567 res = OCBindResource(room, light);
568 OC_LOG_V(INFO, TAG, "OC Bind Contained Resource to resource: %s", getResult(res));
570 res = OCBindResource(room, fan);
571 OC_LOG_V(INFO, TAG, "OC Bind Contained Resource to resource: %s", getResult(res));