1 //******************************************************************
3 // Copyright 2014 Samsung Electronics All Rights Reserved.
4 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
6 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
20 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
34 #include "ocpayload.h"
38 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
40 const int URI_MAXSIZE = 19;
42 static int gObserveNotifyType = 3;
45 int gLightUnderObservation = 0;
47 static LightResource Light;
48 // This variable determines instance number of the Light resource.
49 // Used by POST method to create a new instance of Light resource.
50 static int gCurrLightInstance = 0;
52 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
54 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
57 static int stopPresenceCount = 10;
58 #define numPresenceResources (2)
61 char *gResourceUri= (char *)"/a/light";
62 const char *dateOfManufacture = "myDateOfManufacture";
63 const char *deviceName = "myDeviceName";
64 const char *deviceUUID = "myDeviceUUID";
65 const char *firmwareVersion = "myFirmwareVersion";
66 const char *manufacturerName = "myName";
67 const char *operatingSystemVersion = "myOS";
68 const char *hardwareVersion = "myHardwareVersion";
69 const char* platformID = "myPlatformID";
70 const char *manufacturerUrl = "myManufacturerUrl";
71 const char *modelNumber = "myModelNumber";
72 const char *platformVersion = "myPlatformVersion";
73 const char *supportUrl = "mySupportUrl";
74 const char *version = "myVersion";
75 const char *systemTime = "2015-05-15T11.04";
77 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
78 // the existence of a known resource
79 const char *resourceTypeName = "core.light";
80 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
82 OCPlatformInfo platformInfo;
83 OCDeviceInfo deviceInfo;
85 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
87 OCRepPayload* payload = OCRepPayloadCreate();
90 cout << "Failed to allocate Payload";
94 OCRepPayloadSetUri(payload, uri);
95 OCRepPayloadSetPropBool(payload, "state", state);
96 OCRepPayloadSetPropInt(payload, "power", power);
101 //This function takes the request as an input and returns the response
102 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
104 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
106 cout << "Incoming payload not a representation";
110 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
112 LightResource *currLightResource = &Light;
114 if (ehRequest->resource == gLightInstance[0].handle)
116 currLightResource = &gLightInstance[0];
117 gResourceUri = (char *) "a/light/0";
119 else if (ehRequest->resource == gLightInstance[1].handle)
121 currLightResource = &gLightInstance[1];
122 gResourceUri = (char *) "a/light/1";
125 if(OC_REST_PUT == ehRequest->method)
127 // Get pointer to query
129 if(OCRepPayloadGetPropInt(input, "power", &pow))
131 currLightResource->power =pow;
135 if(OCRepPayloadGetPropBool(input, "state", &state))
137 currLightResource->state = state;
141 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
145 * Very simple example of query parsing.
146 * The query may have multiple filters separated by ';'.
147 * It is upto the entity handler to parse the query for the individual filters,
148 * VALIDATE them and respond as it sees fit.
150 * This function only returns false if the query is exactly "power<X" and
151 * current power is greater than X. If X cannot be parsed for an int,
154 bool checkIfQueryForPowerPassed(char * query)
156 if (query && strncmp(query, "power<", strlen("power<")) == 0)
158 char * pointerToOperator = strstr(query, "<");
160 if (pointerToOperator)
162 int powerRequested = atoi(pointerToOperator + 1);
163 if (Light.power > powerRequested)
165 cout << "\nCurrent power: "<< Light.power << "Requested: " << powerRequested;
174 * Application should validate and process these as desired.
176 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
178 cout << "\nReceived query %s" << entityHandlerRequest->query;
179 cout << "\nNot processing query";
183 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
184 OCRepPayload **payload)
186 OCEntityHandlerResult ehResult;
187 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
189 // Empty payload if the query has no match.
192 OCRepPayload *getResp = constructResponse(ehRequest);
195 cout << "\nconstructResponse failed";
210 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
211 OCRepPayload** payload)
213 OCEntityHandlerResult ehResult;
214 OCRepPayload *putResp = constructResponse(ehRequest);
218 cout << "\nFailed to construct response";
228 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
229 OCEntityHandlerResponse *response, OCRepPayload** payload)
231 OCEntityHandlerResult ehResult = OC_EH_OK;
232 OCRepPayload *respPLPost_light = nullptr;
235 * The entity handler determines how to process a POST request.
236 * Per the REST paradigm, POST can also be used to update representation of existing
237 * resource or create a new resource.
238 * In the sample below, if the POST is for /a/light then a new instance of the Light
239 * resource is created with default representation (if representation is included in
240 * POST payload it can be used as initial values) as long as the instance is
241 * lesser than max new instance count. Once max instance count is reached, POST on
242 * /a/light updated the representation of /a/light (just like PUT).
245 if (ehRequest->resource == Light.handle)
247 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
249 // Create new Light instance
250 char newLightUri[URI_MAXSIZE];
251 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
253 respPLPost_light = OCRepPayloadCreate();
254 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
255 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
257 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
259 cout << "\nCreated new Light instance";
260 gLightInstance[gCurrLightInstance].state = 0;
261 gLightInstance[gCurrLightInstance].power = 0;
262 gCurrLightInstance++;
263 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
264 ehResult = OC_EH_RESOURCE_CREATED;
269 // Update repesentation of /a/light
272 respPLPost_light = constructResponse(ehRequest);
277 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
279 if (ehRequest->resource == gLightInstance[i].handle)
281 gLightInstance[i].state = true;
282 gLightInstance[i].power = 22;
285 respPLPost_light = constructResponse(ehRequest);
290 respPLPost_light = constructResponse(ehRequest);
296 if ((respPLPost_light != NULL))
298 *payload = respPLPost_light;
302 cout << "\n Payload was NULL";
303 ehResult = OC_EH_ERROR;
309 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
311 if(ehRequest == NULL)
313 cout << "\nThe ehRequest is NULL";
316 OCEntityHandlerResult ehResult = OC_EH_OK;
318 cout << "\nExecuting " << __func__ << " for resource " << ehRequest->resource;
321 * In the sample below, the application will:
322 * 1a. pass the delete request to the c stack
323 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
324 * (e.g. send observers notification, remove observers...)
325 * 1c. the c stack returns with the result whether the request is fullfilled.
326 * 2. optionally, app removes observers out of its array 'interestedObservers'
329 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
331 //Step 1: Ask stack to do the work.
332 OCStackResult result = OCDeleteResource(ehRequest->resource);
334 if (result == OC_STACK_OK)
336 cout << "\nDelete Resource operation succeeded.";
339 //Step 2: clear observers who wanted to observe this resource at the app level.
340 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
342 if (interestedObservers[i].resourceHandle == ehRequest->resource)
344 interestedObservers[i].valid = false;
345 interestedObservers[i].observationId = 0;
346 interestedObservers[i].resourceHandle = NULL;
350 else if (result == OC_STACK_NO_RESOURCE)
352 cout << "\nThe resource doesn't exist or it might have been deleted.";
353 ehResult = OC_EH_RESOURCE_DELETED;
357 cout << "\nEncountered error from OCDeleteResource().";
358 ehResult = OC_EH_ERROR;
361 else if (ehRequest->resource != Light.handle)
363 //Let's this app not supporting DELETE on some resources so
364 //consider the DELETE request is received for a non-support resource.
365 cout << "\nThe request is received for a non-support resource.";
366 ehResult = OC_EH_FORBIDDEN;
372 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
374 cout << "\nExecuting " << __func__;
376 return OC_EH_RESOURCE_NOT_FOUND;
379 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
381 cout << "\nReceived observation registration request with observation Id "
382 << ehRequest->obsInfo.obsId;
383 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
385 if (interestedObservers[i].valid == false)
387 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
388 interestedObservers[i].valid = true;
389 gLightUnderObservation = 1;
395 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
397 bool clientStillObserving = false;
399 cout << "\nReceived observation deregistration request for observation Id "
400 << ehRequest->obsInfo.obsId;
401 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
403 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
405 interestedObservers[i].valid = false;
407 if (interestedObservers[i].valid == true)
409 // Even if there is one single client observing we continue notifying entity handler
410 clientStillObserving = true;
413 if (clientStillObserving == false)
414 gLightUnderObservation = 0;
417 OCEntityHandlerResult
418 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
419 OCEntityHandlerRequest *entityHandlerRequest, char* uri, void* callbackParam)
421 cout << "\nInside device default entity handler - flags: " << flag << ", uri: %s" << uri;
423 OCEntityHandlerResult ehResult = OC_EH_OK;
424 OCEntityHandlerResponse response;
427 if (!entityHandlerRequest)
429 cout << "\nInvalid 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 cout << "\nFlag includes OC_REQUEST_FLAG";
444 if (entityHandlerRequest->resource == NULL)
446 cout << "\nReceived request from client to a non-existing resource";
447 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
449 else if (OC_REST_GET == entityHandlerRequest->method)
451 cout << "\nReceived OC_REST_GET from client";
452 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
454 else if (OC_REST_PUT == entityHandlerRequest->method)
456 cout << "\nReceived OC_REST_PUT from client";
457 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
459 else if (OC_REST_DELETE == entityHandlerRequest->method)
461 cout << "\nReceived OC_REST_DELETE from client";
462 ehResult = ProcessDeleteRequest (entityHandlerRequest);
466 cout << "\nReceived unsupported method " << 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 cout << "\nError sending response";
485 ehResult = OC_EH_ERROR;
489 if (flag & OC_OBSERVE_FLAG)
491 cout << "\nFlag includes OC_OBSERVE_FLAG";
492 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
494 cout << "\nReceived OC_OBSERVE_REGISTER from client";
496 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
498 cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
505 OCEntityHandlerResult
506 OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
507 OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
509 // This is callback is associated with the 2 presence notification
510 // resources. They are non-operational.
514 OCEntityHandlerResult
515 OCEntityHandlerCb (OCEntityHandlerFlag flag,
516 OCEntityHandlerRequest *entityHandlerRequest, void* callback)
518 cout << "\nInside entity handler - flags: " << flag;
520 OCEntityHandlerResult ehResult = OC_EH_OK;
521 OCEntityHandlerResponse response;
524 if (!entityHandlerRequest)
526 cout << "\nInvalid request pointer";
530 // Initialize certain response fields
531 response.numSendVendorSpecificHeaderOptions = 0;
532 memset(response.sendVendorSpecificHeaderOptions,
533 0, sizeof response.sendVendorSpecificHeaderOptions);
534 memset(response.resourceUri, 0, sizeof response.resourceUri);
535 OCRepPayload* payload = nullptr;
537 if (flag & OC_REQUEST_FLAG)
539 cout << "\n=================================\n";
540 cout << "\nFlag includes OC_REQUEST_FLAG\n";
542 if (OC_REST_GET == entityHandlerRequest->method)
544 cout << "\nReceived OC_REST_GET from client";
545 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
546 cout << "\n=================================\n";
548 else if (OC_REST_PUT == entityHandlerRequest->method)
550 cout << "\nReceived OC_REST_PUT from client";
551 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
552 cout << "\n=================================\n";
554 else if (OC_REST_POST == entityHandlerRequest->method)
556 cout << "\nReceived OC_REST_POST from client";
557 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
558 cout << "\n=================================\n";
560 else if (OC_REST_DELETE == entityHandlerRequest->method)
562 cout << "\nReceived OC_REST_DELETE from client";
563 ehResult = ProcessDeleteRequest (entityHandlerRequest);
564 cout << "\n=================================\n";
568 cout << "\nReceived unsupported method " << entityHandlerRequest->method << " from client";
569 ehResult = OC_EH_ERROR;
571 // If the result isn't an error or forbidden, send response
572 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
574 // Format the response. Note this requires some info about the request
575 response.requestHandle = entityHandlerRequest->requestHandle;
576 response.resourceHandle = entityHandlerRequest->resource;
577 response.ehResult = ehResult;
578 response.payload = reinterpret_cast<OCPayload*>(payload);
579 // Indicate that response is NOT in a persistent buffer
580 response.persistentBufferFlag = 0;
582 // Handle vendor specific options
583 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
584 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
586 cout << "\nReceived vendor specific options";
588 OCHeaderOption * rcvdOptions =
589 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
590 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
592 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
594 cout << "\nReceived option with ID " << ((OCHeaderOption)rcvdOptions[i]).optionID;
597 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
598 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
599 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
600 sendOptions[0].protocolID = OC_COAP_ID;
601 sendOptions[0].optionID = 2248;
602 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
603 sendOptions[0].optionLength = 10;
604 sendOptions[1].protocolID = OC_COAP_ID;
605 sendOptions[1].optionID = 2600;
606 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
607 sendOptions[1].optionLength = 10;
608 response.numSendVendorSpecificHeaderOptions = 2;
612 if (OCDoResponse(&response) != OC_STACK_OK)
614 cout << "\nError sending response";
615 ehResult = OC_EH_ERROR;
619 if (flag & OC_OBSERVE_FLAG)
621 cout << "\nFlag includes OC_OBSERVE_FLAG";
623 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
625 cout << "\nReceived OC_OBSERVE_REGISTER from client";
626 ProcessObserveRegister (entityHandlerRequest);
628 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
630 cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
631 ProcessObserveDeregister (entityHandlerRequest);
635 OCPayloadDestroy(response.payload);
639 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
640 void handleSigInt(int signum)
642 if (signum == SIGINT)
648 void *ChangeLightRepresentation (void *param)
651 OCStackResult result = OC_STACK_ERROR;
654 uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
655 OCObservationId obsNotify[numNotifies];
661 if (gLightUnderObservation)
663 cout << "\n=====> Notifying stack of new power level" << Light.power;
664 if (gObserveNotifyType == 1)
666 // Notify list of observers. Alternate observers on the list will be notified.
668 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
670 if (interestedObservers[i].valid == true)
672 obsNotify[j] = interestedObservers[i].observationId;
677 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
678 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
680 OCRepPayloadDestroy(payload);
682 else if (gObserveNotifyType == 0)
684 // Notifying all observers
685 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
686 if (OC_STACK_NO_OBSERVERS == result)
688 cout << "\n=====> No more observers exist, stop sending observations";
689 gLightUnderObservation = 0;
694 cout << "\nIncorrect notification type selected";
698 if(stopPresenceCount > 0)
700 cout << "\n=====> Counting down to stop presence " << stopPresenceCount;
702 if(!stopPresenceCount--)
704 cout << "\n=====> stopping presence";
713 void *presenceNotificationGenerator(void *param)
717 OCDoHandle presenceNotificationHandles[numPresenceResources];
718 OCStackResult res = OC_STACK_OK;
720 std::array<std::string, numPresenceResources> presenceNotificationResources { {
721 std::string("core.fan"),
722 std::string("core.led") } };
723 std::array<std::string, numPresenceResources> presenceNotificationUris { {
724 std::string("/a/fan"),
725 std::string("/a/led") } };
727 for(int i=0; i<numPresenceResources; i++)
729 if(res == OC_STACK_OK)
732 res = OCCreateResource(&presenceNotificationHandles[i],
733 presenceNotificationResources.at(i).c_str(),
734 OC_RSRVD_INTERFACE_DEFAULT,
735 presenceNotificationUris.at(i).c_str(),
736 OCNOPEntityHandlerCb,
738 OC_DISCOVERABLE|OC_OBSERVABLE);
740 if(res != OC_STACK_OK)
742 cout << "\nPresence Notification Generator failed[" << getResult(res)
743 << "] to create resource " << presenceNotificationResources.at(i).c_str();
746 cout << "\nCreated " << presenceNotificationUris[i].c_str() << " for presence notification";
749 for(int i=0; i<numPresenceResources; i++)
751 if(res == OC_STACK_OK)
753 res = OCDeleteResource(presenceNotificationHandles[i]);
755 if(res != OC_STACK_OK)
757 cout << "\nPresence Notification Generator failed to delete resource"
758 << presenceNotificationResources.at(i).c_str();
761 cout << "\nDeleted " << presenceNotificationUris[i].c_str() << " for presence notification";
767 int createLightResource (char *uri, LightResource *lightResource)
771 cout << "\nResource URI cannot be NULL";
775 lightResource->state = false;
776 lightResource->power= 0;
777 OCStackResult res = OCCreateResource(&(lightResource->handle),
783 OC_DISCOVERABLE|OC_OBSERVABLE);
784 cout << "\nCreated Light resource with result " << getResult(res);
789 void DeletePlatformInfo()
791 free (platformInfo.platformID);
792 free (platformInfo.manufacturerName);
793 free (platformInfo.manufacturerUrl);
794 free (platformInfo.modelNumber);
795 free (platformInfo.dateOfManufacture);
796 free (platformInfo.platformVersion);
797 free (platformInfo.operatingSystemVersion);
798 free (platformInfo.hardwareVersion);
799 free (platformInfo.firmwareVersion);
800 free (platformInfo.supportUrl);
801 free (platformInfo.systemTime);
804 void DeleteDeviceInfo()
806 free (deviceInfo.deviceName);
809 bool DuplicateString(char** targetString, const char* sourceString)
817 *targetString = (char *) malloc(strlen(sourceString) + 1);
821 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
828 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
829 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
830 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
831 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
836 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
838 return OC_STACK_INVALID_PARAM;
841 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
843 return OC_STACK_INVALID_PARAM;
846 if(!DuplicateString(&platformInfo.platformID, platformID))
851 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
856 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
861 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
866 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
871 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
876 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
881 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
886 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
891 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
896 if(!DuplicateString(&platformInfo.systemTime, systemTime))
906 DeletePlatformInfo();
907 return OC_STACK_ERROR;
910 OCStackResult SetDeviceInfo(const char* deviceName)
912 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
914 return OC_STACK_ERROR;
919 static void PrintUsage()
921 cout << "\nUsage : ocserver -o <0|1>";
922 cout << "\n-o 0 : Notify all observers";
923 cout << "\n-o 1 : Notify list of observers";
926 int main(int argc, char* argv[])
929 pthread_t threadId_presence;
932 while ((opt = getopt(argc, argv, "o:")) != -1)
937 gObserveNotifyType = atoi(optarg);
945 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
951 cout << "\nOCServer is starting...";
953 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
955 cout << "\nOCStack init error";
959 if (OCStartPresence(0) != OC_STACK_OK)
961 cout << "\nOCStack presence/discovery error";
966 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
968 OCStackResult registrationResult =
969 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
970 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
971 firmwareVersion, supportUrl, systemTime);
973 if (registrationResult != OC_STACK_OK)
975 cout << "\nPlatform info setting failed locally!";
979 registrationResult = OCSetPlatformInfo(platformInfo);
981 if (registrationResult != OC_STACK_OK)
983 cout << "\nPlatform Registration failed!";
987 registrationResult = SetDeviceInfo(deviceName);
989 if (registrationResult != OC_STACK_OK)
991 cout << "\nDevice info setting failed locally!";
995 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
997 registrationResult = OCSetDeviceInfo(deviceInfo);
999 if (registrationResult != OC_STACK_OK)
1001 cout << "\nDevice Registration failed!";
1002 exit (EXIT_FAILURE);
1006 * Declare and create the example resource: Light
1008 createLightResource(gResourceUri, &Light);
1010 // Initialize observations data structure for the resource
1011 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1013 interestedObservers[i].valid = false;
1017 * Create a thread for changing the representation of the Light
1019 pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
1022 * Create a thread for generating changes that cause presence notifications
1023 * to be sent to clients
1026 #ifdef WITH_PRESENCE
1027 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1030 // Break from loop with Ctrl-C
1031 cout << "\nEntering ocserver main loop...";
1033 DeletePlatformInfo();
1036 signal(SIGINT, handleSigInt);
1040 if (OCProcess() != OC_STACK_OK)
1042 cout << "\nOCStack process error";
1045 #ifndef ROUTING_GATEWAY
1051 * Cancel the Light thread and wait for it to terminate
1053 pthread_cancel(threadId);
1054 pthread_join(threadId, NULL);
1055 pthread_cancel(threadId_presence);
1056 pthread_join(threadId_presence, NULL);
1058 cout << "\nExiting ocserver main loop...\n";
1060 if (OCStop() != OC_STACK_OK)
1062 cout << "\nOCStack process error";