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 #include "ocpayload.h"
35 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
37 const int URI_MAXSIZE = 19;
39 static int gObserveNotifyType = 3;
42 int gLightUnderObservation = 0;
44 static LightResource Light;
45 // This variable determines instance number of the Light resource.
46 // Used by POST method to create a new instance of Light resource.
47 static int gCurrLightInstance = 0;
49 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
51 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
54 static int stopPresenceCount = 10;
55 #define numPresenceResources (2)
58 char *gResourceUri= (char *)"/a/light";
59 const char *dateOfManufacture = "myDateOfManufacture";
60 const char *deviceName = "myDeviceName";
61 const char *deviceUUID = "myDeviceUUID";
62 const char *firmwareVersion = "myFirmwareVersion";
63 const char *manufacturerName = "myName";
64 const char *operatingSystemVersion = "myOS";
65 const char *hardwareVersion = "myHardwareVersion";
66 const char* platformID = "myPlatformID";
67 const char *manufacturerUrl = "myManufacturerUrl";
68 const char *modelNumber = "myModelNumber";
69 const char *platformVersion = "myPlatformVersion";
70 const char *supportUrl = "mySupportUrl";
71 const char *version = "myVersion";
72 const char *systemTime = "2015-05-15T11.04";
74 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
75 // the existence of a known resource
76 const char *resourceTypeName = "core.light";
77 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
79 OCPlatformInfo platformInfo;
80 OCDeviceInfo deviceInfo;
82 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
84 OCRepPayload* payload = OCRepPayloadCreate();
87 OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
91 OCRepPayloadSetUri(payload, uri);
92 OCRepPayloadSetPropBool(payload, "state", state);
93 OCRepPayloadSetPropInt(payload, "power", power);
98 //This function takes the request as an input and returns the response
99 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
101 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
103 OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
107 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
109 LightResource *currLightResource = &Light;
111 if (ehRequest->resource == gLightInstance[0].handle)
113 currLightResource = &gLightInstance[0];
114 gResourceUri = (char *) "a/light/0";
116 else if (ehRequest->resource == gLightInstance[1].handle)
118 currLightResource = &gLightInstance[1];
119 gResourceUri = (char *) "a/light/1";
122 if(OC_REST_PUT == ehRequest->method)
124 // Get pointer to query
126 if(OCRepPayloadGetPropInt(input, "power", &pow))
128 currLightResource->power =pow;
132 if(OCRepPayloadGetPropBool(input, "state", &state))
134 currLightResource->state = state;
138 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
142 * Very simple example of query parsing.
143 * The query may have multiple filters separated by ';'.
144 * It is upto the entity handler to parse the query for the individual filters,
145 * VALIDATE them and respond as it sees fit.
147 * This function only returns false if the query is exactly "power<X" and
148 * current power is greater than X. If X cannot be parsed for an int,
151 bool checkIfQueryForPowerPassed(char * query)
153 if (query && strncmp(query, "power<", strlen("power<")) == 0)
155 char * pointerToOperator = strstr(query, "<");
157 if (pointerToOperator)
159 int powerRequested = atoi(pointerToOperator + 1);
160 if (Light.power > powerRequested)
162 OC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
172 * Application should validate and process these as desired.
174 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
176 OC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
177 OC_LOG(INFO, TAG, PCF("Not processing query"));
181 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
182 OCRepPayload **payload)
184 OCEntityHandlerResult ehResult;
185 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
187 // Empty payload if the query has no match.
190 OCRepPayload *getResp = constructResponse(ehRequest);
193 OC_LOG(ERROR, TAG, "constructResponse failed");
208 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
209 OCRepPayload** payload)
211 OCEntityHandlerResult ehResult;
212 OCRepPayload *putResp = constructResponse(ehRequest);
216 OC_LOG(ERROR, TAG, "Failed to construct Json response");
226 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
227 OCEntityHandlerResponse *response, OCRepPayload** payload)
229 OCEntityHandlerResult ehResult = OC_EH_OK;
230 OCRepPayload *respPLPost_light = nullptr;
233 * The entity handler determines how to process a POST request.
234 * Per the REST paradigm, POST can also be used to update representation of existing
235 * resource or create a new resource.
236 * In the sample below, if the POST is for /a/light then a new instance of the Light
237 * resource is created with default representation (if representation is included in
238 * POST payload it can be used as initial values) as long as the instance is
239 * lesser than max new instance count. Once max instance count is reached, POST on
240 * /a/light updated the representation of /a/light (just like PUT)
243 if (ehRequest->resource == Light.handle)
245 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
247 // Create new Light instance
248 char newLightUri[URI_MAXSIZE];
249 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
251 respPLPost_light = OCRepPayloadCreate();
252 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
253 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
255 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
257 OC_LOG (INFO, TAG, "Created new Light instance\n");
258 gLightInstance[gCurrLightInstance].state = 0;
259 gLightInstance[gCurrLightInstance].power = 0;
260 gCurrLightInstance++;
261 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
262 ehResult = OC_EH_RESOURCE_CREATED;
267 // Update repesentation of /a/light
270 respPLPost_light = constructResponse(ehRequest);
275 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
277 if (ehRequest->resource == gLightInstance[i].handle)
279 gLightInstance[i].state = true;
280 gLightInstance[i].power = 22;
283 respPLPost_light = constructResponse(ehRequest);
288 respPLPost_light = constructResponse(ehRequest);
294 if ((respPLPost_light != NULL))
296 *payload = respPLPost_light;
300 OC_LOG(INFO, TAG, "Payload was NULL");
301 ehResult = OC_EH_ERROR;
307 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
309 if(ehRequest == NULL)
311 OC_LOG(INFO, TAG, "The ehRequest is NULL");
314 OCEntityHandlerResult ehResult = OC_EH_OK;
316 OC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %d ", __func__, ehRequest->resource);
319 * In the sample below, the application will:
320 * 1a. pass the delete request to the c stack
321 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
322 * (e.g. send observers notification, remove observers...)
323 * 1c. the c stack returns with the result whether the request is fullfilled.
324 * 2. optionally, app removes observers out of its array 'interestedObservers'
327 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
329 //Step 1: Ask stack to do the work.
330 OCStackResult result = OCDeleteResource(ehRequest->resource);
332 if (result == OC_STACK_OK)
334 OC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
337 //Step 2: clear observers who wanted to observe this resource at the app level.
338 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
340 if (interestedObservers[i].resourceHandle == ehRequest->resource)
342 interestedObservers[i].valid = false;
343 interestedObservers[i].observationId = 0;
344 interestedObservers[i].resourceHandle = NULL;
348 else if (result == OC_STACK_NO_RESOURCE)
350 OC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
351 ehResult = OC_EH_RESOURCE_DELETED;
355 OC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
356 ehResult = OC_EH_ERROR;
359 else if (ehRequest->resource != Light.handle)
361 //Let's this app not supporting DELETE on some resources so
362 //consider the DELETE request is received for a non-support resource.
363 OC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
364 ehResult = OC_EH_FORBIDDEN;
370 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
372 OC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
374 return OC_EH_RESOURCE_NOT_FOUND;
377 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
379 OC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
380 ehRequest->obsInfo.obsId);
381 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
383 if (interestedObservers[i].valid == false)
385 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
386 interestedObservers[i].valid = true;
387 gLightUnderObservation = 1;
393 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
395 bool clientStillObserving = false;
397 OC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
398 ehRequest->obsInfo.obsId);
399 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
401 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
403 interestedObservers[i].valid = false;
405 if (interestedObservers[i].valid == true)
407 // Even if there is one single client observing we continue notifying entity handler
408 clientStillObserving = true;
411 if (clientStillObserving == false)
412 gLightUnderObservation = 0;
415 OCEntityHandlerResult
416 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
417 OCEntityHandlerRequest *entityHandlerRequest,
419 void* /*callbackParam*/)
421 OC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
423 OCEntityHandlerResult ehResult = OC_EH_OK;
424 OCEntityHandlerResponse response;
427 if (!entityHandlerRequest)
429 OC_LOG (ERROR, TAG, "Invalid request pointer");
432 // Initialize certain response fields
433 response.numSendVendorSpecificHeaderOptions = 0;
434 memset(response.sendVendorSpecificHeaderOptions, 0,
435 sizeof response.sendVendorSpecificHeaderOptions);
436 memset(response.resourceUri, 0, sizeof response.resourceUri);
437 OCRepPayload* payload = nullptr;
440 if (flag & OC_REQUEST_FLAG)
442 OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
444 if (entityHandlerRequest->resource == NULL)
446 OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
447 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
449 else if (OC_REST_GET == entityHandlerRequest->method)
451 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
452 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
454 else if (OC_REST_PUT == entityHandlerRequest->method)
456 OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
457 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
459 else if (OC_REST_DELETE == entityHandlerRequest->method)
461 OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
462 ehResult = ProcessDeleteRequest (entityHandlerRequest);
466 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
467 entityHandlerRequest->method);
468 ehResult = OC_EH_ERROR;
470 // If the result isn't an error or forbidden, send response
471 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
473 // Format the response. Note this requires some info about the request
474 response.requestHandle = entityHandlerRequest->requestHandle;
475 response.resourceHandle = entityHandlerRequest->resource;
476 response.ehResult = ehResult;
477 response.payload = reinterpret_cast<OCPayload*>(payload);
478 // Indicate that response is NOT in a persistent buffer
479 response.persistentBufferFlag = 0;
482 if (OCDoResponse(&response) != OC_STACK_OK)
484 OC_LOG(ERROR, TAG, "Error sending response");
485 ehResult = OC_EH_ERROR;
489 if (flag & OC_OBSERVE_FLAG)
491 OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
492 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
494 OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
496 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
498 OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
505 OCEntityHandlerResult
506 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
507 OCEntityHandlerRequest * /*entityHandlerRequest*/,
508 void* /*callbackParam*/)
510 // This is callback is associated with the 2 presence notification
511 // resources. They are non-operational.
515 OCEntityHandlerResult
516 OCEntityHandlerCb (OCEntityHandlerFlag flag,
517 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
519 OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
521 OCEntityHandlerResult ehResult = OC_EH_OK;
522 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
525 if (!entityHandlerRequest)
527 OC_LOG (ERROR, TAG, "Invalid request pointer");
531 // Initialize certain response fields
532 response.numSendVendorSpecificHeaderOptions = 0;
533 memset(response.sendVendorSpecificHeaderOptions,
534 0, sizeof response.sendVendorSpecificHeaderOptions);
535 memset(response.resourceUri, 0, sizeof response.resourceUri);
536 OCRepPayload* payload = nullptr;
538 if (flag & OC_REQUEST_FLAG)
540 OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
542 if (OC_REST_GET == entityHandlerRequest->method)
544 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
545 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
547 else if (OC_REST_PUT == entityHandlerRequest->method)
549 OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
550 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
552 else if (OC_REST_POST == entityHandlerRequest->method)
554 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
555 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
557 else if (OC_REST_DELETE == entityHandlerRequest->method)
559 OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
560 ehResult = ProcessDeleteRequest (entityHandlerRequest);
564 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
565 entityHandlerRequest->method);
566 ehResult = OC_EH_ERROR;
568 // If the result isn't an error or forbidden, send response
569 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
571 // Format the response. Note this requires some info about the request
572 response.requestHandle = entityHandlerRequest->requestHandle;
573 response.resourceHandle = entityHandlerRequest->resource;
574 response.ehResult = ehResult;
575 response.payload = reinterpret_cast<OCPayload*>(payload);
576 // Indicate that response is NOT in a persistent buffer
577 response.persistentBufferFlag = 0;
579 // Handle vendor specific options
580 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
581 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
583 OC_LOG (INFO, TAG, "Received vendor specific options");
585 OCHeaderOption * rcvdOptions =
586 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
587 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
589 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
591 OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
592 ((OCHeaderOption)rcvdOptions[i]).optionID );
594 OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
595 MAX_HEADER_OPTION_DATA_LENGTH);
598 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
599 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
600 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
601 sendOptions[0].protocolID = OC_COAP_ID;
602 sendOptions[0].optionID = 2248;
603 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
604 sendOptions[0].optionLength = 10;
605 sendOptions[1].protocolID = OC_COAP_ID;
606 sendOptions[1].optionID = 2600;
607 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
608 sendOptions[1].optionLength = 10;
609 response.numSendVendorSpecificHeaderOptions = 2;
613 if (OCDoResponse(&response) != OC_STACK_OK)
615 OC_LOG(ERROR, TAG, "Error sending response");
616 ehResult = OC_EH_ERROR;
620 if (flag & OC_OBSERVE_FLAG)
622 OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
624 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
626 OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
627 ProcessObserveRegister (entityHandlerRequest);
629 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
631 OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
632 ProcessObserveDeregister (entityHandlerRequest);
636 OCPayloadDestroy(response.payload);
640 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
641 void handleSigInt(int signum)
643 if (signum == SIGINT)
649 void *ChangeLightRepresentation (void *param)
652 OCStackResult result = OC_STACK_ERROR;
655 uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
656 OCObservationId obsNotify[numNotifies];
662 if (gLightUnderObservation)
664 OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
665 if (gObserveNotifyType == 1)
667 // Notify list of observers. Alternate observers on the list will be notified.
669 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
671 if (interestedObservers[i].valid == true)
673 obsNotify[j] = interestedObservers[i].observationId;
678 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
679 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
681 OCRepPayloadDestroy(payload);
683 else if (gObserveNotifyType == 0)
685 // Notifying all observers
686 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
687 if (OC_STACK_NO_OBSERVERS == result)
690 "=======> No more observers exist, stop sending observations");
691 gLightUnderObservation = 0;
696 OC_LOG (ERROR, TAG, "Incorrect notification type selected");
700 if(stopPresenceCount > 0)
702 OC_LOG_V(INFO, TAG, "================ Counting down to stop presence %d", stopPresenceCount);
704 if(!stopPresenceCount--)
706 OC_LOG(INFO, TAG, "================ stopping presence");
715 void *presenceNotificationGenerator(void *param)
719 OCDoHandle presenceNotificationHandles[numPresenceResources];
720 OCStackResult res = OC_STACK_OK;
722 std::array<std::string, numPresenceResources> presenceNotificationResources { {
723 std::string("core.fan"),
724 std::string("core.led") } };
725 std::array<std::string, numPresenceResources> presenceNotificationUris { {
726 std::string("/a/fan"),
727 std::string("/a/led") } };
729 for(int i=0; i<numPresenceResources; i++)
731 if(res == OC_STACK_OK)
734 res = OCCreateResource(&presenceNotificationHandles[i],
735 presenceNotificationResources.at(i).c_str(),
736 OC_RSRVD_INTERFACE_DEFAULT,
737 presenceNotificationUris.at(i).c_str(),
738 OCNOPEntityHandlerCb,
740 OC_DISCOVERABLE|OC_OBSERVABLE);
742 if(res != OC_STACK_OK)
744 OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
745 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
749 OC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
750 presenceNotificationUris[i].c_str());
753 for(int i=0; i<numPresenceResources; i++)
755 if(res == OC_STACK_OK)
757 res = OCDeleteResource(presenceNotificationHandles[i]);
759 if(res != OC_STACK_OK)
761 OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
762 "resource %s.", presenceNotificationResources.at(i).c_str());
765 OC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
766 presenceNotificationUris[i].c_str());
772 int createLightResource (char *uri, LightResource *lightResource)
776 OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
780 lightResource->state = false;
781 lightResource->power= 0;
782 OCStackResult res = OCCreateResource(&(lightResource->handle),
788 OC_DISCOVERABLE|OC_OBSERVABLE);
789 OC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
794 void DeletePlatformInfo()
796 free (platformInfo.platformID);
797 free (platformInfo.manufacturerName);
798 free (platformInfo.manufacturerUrl);
799 free (platformInfo.modelNumber);
800 free (platformInfo.dateOfManufacture);
801 free (platformInfo.platformVersion);
802 free (platformInfo.operatingSystemVersion);
803 free (platformInfo.hardwareVersion);
804 free (platformInfo.firmwareVersion);
805 free (platformInfo.supportUrl);
806 free (platformInfo.systemTime);
809 void DeleteDeviceInfo()
811 free (deviceInfo.deviceName);
814 bool DuplicateString(char** targetString, const char* sourceString)
822 *targetString = (char *) malloc(strlen(sourceString) + 1);
826 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
833 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
834 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
835 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
836 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
841 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
843 return OC_STACK_INVALID_PARAM;
846 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
848 return OC_STACK_INVALID_PARAM;
851 if(!DuplicateString(&platformInfo.platformID, platformID))
856 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
861 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
866 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
871 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
876 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
881 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
886 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
891 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
896 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
901 if(!DuplicateString(&platformInfo.systemTime, systemTime))
911 DeletePlatformInfo();
912 return OC_STACK_ERROR;
915 OCStackResult SetDeviceInfo(const char* deviceName)
917 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
919 return OC_STACK_ERROR;
924 static void PrintUsage()
926 OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
927 OC_LOG(INFO, TAG, "-o 0 : Notify all observers");
928 OC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
931 int main(int argc, char* argv[])
934 pthread_t threadId_presence;
937 while ((opt = getopt(argc, argv, "o:")) != -1)
942 gObserveNotifyType = atoi(optarg);
950 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
957 rainfo.hostname = "localhost";
959 rainfo.xmpp_domain = "localhost";
960 rainfo.username = "test1";
961 rainfo.password = "intel123";
962 rainfo.resource = "";
963 rainfo.user_jid = "";
965 OCSetRAInfo(&rainfo);
968 OC_LOG(DEBUG, TAG, "OCServer is starting...");
970 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
972 OC_LOG(ERROR, TAG, "OCStack init error");
976 if (OCStartPresence(0) != OC_STACK_OK)
978 OC_LOG(ERROR, TAG, "OCStack presence/discovery error");
983 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
985 OCStackResult registrationResult =
986 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
987 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
988 firmwareVersion, supportUrl, systemTime);
990 if (registrationResult != OC_STACK_OK)
992 OC_LOG(INFO, TAG, "Platform info setting failed locally!");
996 registrationResult = OCSetPlatformInfo(platformInfo);
998 if (registrationResult != OC_STACK_OK)
1000 OC_LOG(INFO, TAG, "Platform Registration failed!");
1001 exit (EXIT_FAILURE);
1004 registrationResult = SetDeviceInfo(deviceName);
1006 if (registrationResult != OC_STACK_OK)
1008 OC_LOG(INFO, TAG, "Device info setting failed locally!");
1009 exit (EXIT_FAILURE);
1012 registrationResult = OCSetDeviceInfo(deviceInfo);
1014 if (registrationResult != OC_STACK_OK)
1016 OC_LOG(INFO, TAG, "Device Registration failed!");
1017 exit (EXIT_FAILURE);
1021 * Declare and create the example resource: Light
1023 createLightResource(gResourceUri, &Light);
1025 // Initialize observations data structure for the resource
1026 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1028 interestedObservers[i].valid = false;
1032 * Create a thread for changing the representation of the Light
1034 pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
1037 * Create a thread for generating changes that cause presence notifications
1038 * to be sent to clients
1041 #ifdef WITH_PRESENCE
1042 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1045 // Break from loop with Ctrl-C
1046 OC_LOG(INFO, TAG, "Entering ocserver main loop...");
1048 DeletePlatformInfo();
1051 signal(SIGINT, handleSigInt);
1055 if (OCProcess() != OC_STACK_OK)
1057 OC_LOG(ERROR, TAG, "OCStack process error");
1060 #ifndef ROUTING_GATEWAY
1066 * Cancel the Light thread and wait for it to terminate
1068 pthread_cancel(threadId);
1069 pthread_join(threadId, NULL);
1070 pthread_cancel(threadId_presence);
1071 pthread_join(threadId_presence, NULL);
1073 OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1075 if (OCStop() != OC_STACK_OK)
1077 OC_LOG(ERROR, TAG, "OCStack process error");