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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
32 #include "oic_malloc.h"
35 #include "ocpayload.h"
39 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
41 const int URI_MAXSIZE = 19;
43 static int gObserveNotifyType = 3;
46 int gLightUnderObservation = 0;
48 static GMainLoop *g_mainloop = NULL;
51 static LightResource Light;
52 // This variable determines instance number of the Light resource.
53 // Used by POST method to create a new instance of Light resource.
54 static int gCurrLightInstance = 0;
56 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
58 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
61 static int stopPresenceCount = 10;
62 #define numPresenceResources (2)
65 char *gResourceUri= (char *)"/a/light";
66 const char *dateOfManufacture = "myDateOfManufacture";
67 const char *deviceName = "myDeviceName";
68 const char *deviceUUID = "myDeviceUUID";
69 const char *firmwareVersion = "myFirmwareVersion";
70 const char *manufacturerName = "myName";
71 const char *operatingSystemVersion = "myOS";
72 const char *hardwareVersion = "myHardwareVersion";
73 const char* platformID = "myPlatformID";
74 const char *manufacturerUrl = "myManufacturerUrl";
75 const char *modelNumber = "myModelNumber";
76 const char *platformVersion = "myPlatformVersion";
77 const char *supportUrl = "mySupportUrl";
78 const char *version = "myVersion";
79 const char *systemTime = "2015-05-15T11.04";
80 const char *specVersion = "myDeviceSpecVersion";
81 const char *dataModelVersions = "myDeviceModelVersions";
83 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
84 // the existence of a known resource
85 const char *resourceTypeName = "core.light";
86 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
88 OCPlatformInfo platformInfo;
89 OCDeviceInfo deviceInfo;
91 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
93 OCRepPayload* payload = OCRepPayloadCreate();
96 cout << "Failed to allocate Payload";
100 OCRepPayloadSetUri(payload, uri);
101 OCRepPayloadSetPropBool(payload, "state", state);
102 OCRepPayloadSetPropInt(payload, "power", power);
107 //This function takes the request as an input and returns the response
108 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
110 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
112 cout << "Incoming payload not a representation";
116 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
118 LightResource *currLightResource = &Light;
120 if (ehRequest->resource == gLightInstance[0].handle)
122 currLightResource = &gLightInstance[0];
123 gResourceUri = (char *) "a/light/0";
125 else if (ehRequest->resource == gLightInstance[1].handle)
127 currLightResource = &gLightInstance[1];
128 gResourceUri = (char *) "a/light/1";
131 if(OC_REST_PUT == ehRequest->method)
133 // Get pointer to query
135 if(OCRepPayloadGetPropInt(input, "power", &pow))
137 currLightResource->power =pow;
141 if(OCRepPayloadGetPropBool(input, "state", &state))
143 currLightResource->state = state;
147 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
151 * Very simple example of query parsing.
152 * The query may have multiple filters separated by ';'.
153 * It is upto the entity handler to parse the query for the individual filters,
154 * VALIDATE them and respond as it sees fit.
156 * This function only returns false if the query is exactly "power<X" and
157 * current power is greater than X. If X cannot be parsed for an int,
160 bool checkIfQueryForPowerPassed(char * query)
162 if (query && strncmp(query, "power<", strlen("power<")) == 0)
164 char * pointerToOperator = strstr(query, "<");
166 if (pointerToOperator)
168 int powerRequested = atoi(pointerToOperator + 1);
169 if (Light.power > powerRequested)
171 cout << "\nCurrent power: "<< Light.power << "Requested: " << powerRequested;
180 * Application should validate and process these as desired.
182 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
184 cout << "\nReceived query %s" << entityHandlerRequest->query;
185 cout << "\nNot processing query";
189 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
190 OCRepPayload **payload)
192 OCEntityHandlerResult ehResult;
193 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
195 // Empty payload if the query has no match.
198 OCRepPayload *getResp = constructResponse(ehRequest);
201 cout << "\nconstructResponse failed";
216 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
217 OCRepPayload** payload)
219 OCEntityHandlerResult ehResult;
220 OCRepPayload *putResp = constructResponse(ehRequest);
224 cout << "\nFailed to construct response";
234 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
235 OCEntityHandlerResponse *response, OCRepPayload** payload)
237 OCEntityHandlerResult ehResult = OC_EH_OK;
238 OCRepPayload *respPLPost_light = nullptr;
241 * The entity handler determines how to process a POST request.
242 * Per the REST paradigm, POST can also be used to update representation of existing
243 * resource or create a new resource.
244 * In the sample below, if the POST is for /a/light then a new instance of the Light
245 * resource is created with default representation (if representation is included in
246 * POST payload it can be used as initial values) as long as the instance is
247 * lesser than max new instance count. Once max instance count is reached, POST on
248 * /a/light updated the representation of /a/light (just like PUT).
251 if (ehRequest->resource == Light.handle)
253 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
255 // Create new Light instance
256 char newLightUri[URI_MAXSIZE];
257 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
259 respPLPost_light = OCRepPayloadCreate();
260 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
261 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
263 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
265 cout << "\nCreated new Light instance";
266 gLightInstance[gCurrLightInstance].state = 0;
267 gLightInstance[gCurrLightInstance].power = 0;
268 gCurrLightInstance++;
269 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
270 ehResult = OC_EH_RESOURCE_CREATED;
275 // Update repesentation of /a/light
278 respPLPost_light = constructResponse(ehRequest);
283 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
285 if (ehRequest->resource == gLightInstance[i].handle)
287 gLightInstance[i].state = true;
288 gLightInstance[i].power = 22;
291 respPLPost_light = constructResponse(ehRequest);
296 respPLPost_light = constructResponse(ehRequest);
302 if ((respPLPost_light != NULL))
304 *payload = respPLPost_light;
308 cout << "\n Payload was NULL";
309 ehResult = OC_EH_ERROR;
315 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
317 if(ehRequest == NULL)
319 cout << "\nThe ehRequest is NULL";
322 OCEntityHandlerResult ehResult = OC_EH_OK;
324 cout << "\nExecuting " << __func__ << " for resource " << ehRequest->resource;
327 * In the sample below, the application will:
328 * 1a. pass the delete request to the c stack
329 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
330 * (e.g. send observers notification, remove observers...)
331 * 1c. the c stack returns with the result whether the request is fullfilled.
332 * 2. optionally, app removes observers out of its array 'interestedObservers'
335 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
337 //Step 1: Ask stack to do the work.
338 OCStackResult result = OCDeleteResource(ehRequest->resource);
340 if (result == OC_STACK_OK)
342 cout << "\nDelete Resource operation succeeded.";
345 //Step 2: clear observers who wanted to observe this resource at the app level.
346 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
348 if (interestedObservers[i].resourceHandle == ehRequest->resource)
350 interestedObservers[i].valid = false;
351 interestedObservers[i].observationId = 0;
352 interestedObservers[i].resourceHandle = NULL;
356 else if (result == OC_STACK_NO_RESOURCE)
358 cout << "\nThe resource doesn't exist or it might have been deleted.";
359 ehResult = OC_EH_RESOURCE_DELETED;
363 cout << "\nEncountered error from OCDeleteResource().";
364 ehResult = OC_EH_ERROR;
367 else if (ehRequest->resource != Light.handle)
369 //Let's this app not supporting DELETE on some resources so
370 //consider the DELETE request is received for a non-support resource.
371 cout << "\nThe request is received for a non-support resource.";
372 ehResult = OC_EH_FORBIDDEN;
378 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
380 cout << "\nExecuting " << __func__;
382 return OC_EH_RESOURCE_NOT_FOUND;
385 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
387 cout << "\nReceived observation registration request with observation Id "
388 << ehRequest->obsInfo.obsId;
389 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
391 if (interestedObservers[i].valid == false)
393 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
394 interestedObservers[i].valid = true;
395 gLightUnderObservation = 1;
401 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
403 bool clientStillObserving = false;
405 cout << "\nReceived observation deregistration request for observation Id "
406 << ehRequest->obsInfo.obsId;
407 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
409 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
411 interestedObservers[i].valid = false;
413 if (interestedObservers[i].valid == true)
415 // Even if there is one single client observing we continue notifying entity handler
416 clientStillObserving = true;
419 if (clientStillObserving == false)
420 gLightUnderObservation = 0;
423 OCEntityHandlerResult
424 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
425 OCEntityHandlerRequest *entityHandlerRequest, char* uri, void* callbackParam)
427 cout << "\nInside device default entity handler - flags: " << flag << ", uri: %s" << uri;
429 OCEntityHandlerResult ehResult = OC_EH_OK;
430 OCEntityHandlerResponse response;
433 if (!entityHandlerRequest)
435 cout << "\nInvalid request pointer";
438 // Initialize certain response fields
439 response.numSendVendorSpecificHeaderOptions = 0;
440 memset(response.sendVendorSpecificHeaderOptions, 0,
441 sizeof response.sendVendorSpecificHeaderOptions);
442 memset(response.resourceUri, 0, sizeof response.resourceUri);
443 OCRepPayload* payload = nullptr;
446 if (flag & OC_REQUEST_FLAG)
448 cout << "\nFlag includes OC_REQUEST_FLAG";
450 if (entityHandlerRequest->resource == NULL)
452 cout << "\nReceived request from client to a non-existing resource";
453 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
455 else if (OC_REST_GET == entityHandlerRequest->method)
457 cout << "\nReceived OC_REST_GET from client";
458 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
460 else if (OC_REST_PUT == entityHandlerRequest->method)
462 cout << "\nReceived OC_REST_PUT from client";
463 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
465 else if (OC_REST_DELETE == entityHandlerRequest->method)
467 cout << "\nReceived OC_REST_DELETE from client";
468 ehResult = ProcessDeleteRequest (entityHandlerRequest);
472 cout << "\nReceived unsupported method " << entityHandlerRequest->method
474 ehResult = OC_EH_ERROR;
476 // If the result isn't an error or forbidden, send response
477 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
479 // Format the response. Note this requires some info about the request
480 response.requestHandle = entityHandlerRequest->requestHandle;
481 response.resourceHandle = entityHandlerRequest->resource;
482 response.ehResult = ehResult;
483 response.payload = reinterpret_cast<OCPayload*>(payload);
484 // Indicate that response is NOT in a persistent buffer
485 response.persistentBufferFlag = 0;
488 if (OCDoResponse(&response) != OC_STACK_OK)
490 cout << "\nError sending response";
491 ehResult = OC_EH_ERROR;
495 if (flag & OC_OBSERVE_FLAG)
497 cout << "\nFlag includes OC_OBSERVE_FLAG";
498 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
500 cout << "\nReceived OC_OBSERVE_REGISTER from client";
502 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
504 cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
511 OCEntityHandlerResult
512 OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
513 OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
515 // This is callback is associated with the 2 presence notification
516 // resources. They are non-operational.
520 OCEntityHandlerResult
521 OCEntityHandlerCb (OCEntityHandlerFlag flag,
522 OCEntityHandlerRequest *entityHandlerRequest, void* callback)
524 cout << "\nInside entity handler - flags: " << flag;
526 OCEntityHandlerResult ehResult = OC_EH_OK;
527 OCEntityHandlerResponse response;
530 if (!entityHandlerRequest)
532 cout << "\nInvalid request pointer";
536 // Initialize certain response fields
537 response.numSendVendorSpecificHeaderOptions = 0;
538 memset(response.sendVendorSpecificHeaderOptions,
539 0, sizeof response.sendVendorSpecificHeaderOptions);
540 memset(response.resourceUri, 0, sizeof response.resourceUri);
541 OCRepPayload* payload = nullptr;
543 if (flag & OC_REQUEST_FLAG)
545 cout << "\n=================================\n";
546 cout << "\nFlag includes OC_REQUEST_FLAG\n";
548 if (OC_REST_GET == entityHandlerRequest->method)
550 cout << "\nReceived OC_REST_GET from client";
551 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
552 cout << "\n=================================\n";
554 else if (OC_REST_PUT == entityHandlerRequest->method)
556 cout << "\nReceived OC_REST_PUT from client";
557 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
558 cout << "\n=================================\n";
560 else if (OC_REST_POST == entityHandlerRequest->method)
562 cout << "\nReceived OC_REST_POST from client";
563 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
564 cout << "\n=================================\n";
566 else if (OC_REST_DELETE == entityHandlerRequest->method)
568 cout << "\nReceived OC_REST_DELETE from client";
569 ehResult = ProcessDeleteRequest (entityHandlerRequest);
570 cout << "\n=================================\n";
574 cout << "\nReceived unsupported method " << entityHandlerRequest->method << " from client";
575 ehResult = OC_EH_ERROR;
577 // If the result isn't an error or forbidden, send response
578 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
580 // Format the response. Note this requires some info about the request
581 response.requestHandle = entityHandlerRequest->requestHandle;
582 response.resourceHandle = entityHandlerRequest->resource;
583 response.ehResult = ehResult;
584 response.payload = reinterpret_cast<OCPayload*>(payload);
585 // Indicate that response is NOT in a persistent buffer
586 response.persistentBufferFlag = 0;
588 // Handle vendor specific options
589 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
590 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
592 cout << "\nReceived vendor specific options";
594 OCHeaderOption * rcvdOptions =
595 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
596 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
598 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
600 cout << "\nReceived option with ID " << ((OCHeaderOption)rcvdOptions[i]).optionID;
603 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
604 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
605 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
606 sendOptions[0].protocolID = OC_COAP_ID;
607 sendOptions[0].optionID = 2248;
608 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
609 sendOptions[0].optionLength = 10;
610 sendOptions[1].protocolID = OC_COAP_ID;
611 sendOptions[1].optionID = 2600;
612 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
613 sendOptions[1].optionLength = 10;
614 response.numSendVendorSpecificHeaderOptions = 2;
618 if (OCDoResponse(&response) != OC_STACK_OK)
620 cout << "\nError sending response";
621 ehResult = OC_EH_ERROR;
625 if (flag & OC_OBSERVE_FLAG)
627 cout << "\nFlag includes OC_OBSERVE_FLAG";
629 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
631 cout << "\nReceived OC_OBSERVE_REGISTER from client";
632 ProcessObserveRegister (entityHandlerRequest);
634 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
636 cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
637 ProcessObserveDeregister (entityHandlerRequest);
641 OCPayloadDestroy(response.payload);
645 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
646 void handleSigInt(int signum)
648 if (signum == SIGINT)
654 void *ChangeLightRepresentation (void *param)
657 OCStackResult result = OC_STACK_ERROR;
660 uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
661 OCObservationId obsNotify[numNotifies];
667 if (gLightUnderObservation)
669 cout << "\n=====> Notifying stack of new power level" << Light.power;
670 if (gObserveNotifyType == 1)
672 // Notify list of observers. Alternate observers on the list will be notified.
674 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
676 if (interestedObservers[i].valid == true)
678 obsNotify[j] = interestedObservers[i].observationId;
683 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
684 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
686 OCRepPayloadDestroy(payload);
688 else if (gObserveNotifyType == 0)
690 // Notifying all observers
691 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
692 if (OC_STACK_NO_OBSERVERS == result)
694 cout << "\n=====> No more observers exist, stop sending observations";
695 gLightUnderObservation = 0;
700 cout << "\nIncorrect notification type selected";
704 if(stopPresenceCount > 0)
706 cout << "\n=====> Counting down to stop presence " << stopPresenceCount;
708 if(!stopPresenceCount--)
710 cout << "\n=====> stopping presence";
719 void *presenceNotificationGenerator(void *param)
723 OCDoHandle presenceNotificationHandles[numPresenceResources];
724 OCStackResult res = OC_STACK_OK;
726 std::array<std::string, numPresenceResources> presenceNotificationResources { {
727 std::string("core.fan"),
728 std::string("core.led") } };
729 std::array<std::string, numPresenceResources> presenceNotificationUris { {
730 std::string("/a/fan"),
731 std::string("/a/led") } };
733 for(int i=0; i<numPresenceResources; i++)
735 if(res == OC_STACK_OK)
738 res = OCCreateResource(&presenceNotificationHandles[i],
739 presenceNotificationResources.at(i).c_str(),
740 OC_RSRVD_INTERFACE_DEFAULT,
741 presenceNotificationUris.at(i).c_str(),
742 OCNOPEntityHandlerCb,
744 OC_DISCOVERABLE|OC_OBSERVABLE);
746 if(res != OC_STACK_OK)
748 cout << "\nPresence Notification Generator failed[" << getResult(res)
749 << "] to create resource " << presenceNotificationResources.at(i).c_str();
752 cout << "\nCreated " << presenceNotificationUris[i].c_str() << " for presence notification";
755 for(int i=0; i<numPresenceResources; i++)
757 if(res == OC_STACK_OK)
759 res = OCDeleteResource(presenceNotificationHandles[i]);
761 if(res != OC_STACK_OK)
763 cout << "\nPresence Notification Generator failed to delete resource"
764 << presenceNotificationResources.at(i).c_str();
767 cout << "\nDeleted " << presenceNotificationUris[i].c_str() << " for presence notification";
773 int createLightResource (char *uri, LightResource *lightResource)
777 cout << "\nResource URI cannot be NULL";
781 lightResource->state = false;
782 lightResource->power= 0;
783 OCStackResult res = OCCreateResource(&(lightResource->handle),
789 OC_DISCOVERABLE|OC_OBSERVABLE);
790 cout << "\nCreated Light resource with result " << getResult(res);
795 void DeletePlatformInfo()
797 free (platformInfo.platformID);
798 free (platformInfo.manufacturerName);
799 free (platformInfo.manufacturerUrl);
800 free (platformInfo.modelNumber);
801 free (platformInfo.dateOfManufacture);
802 free (platformInfo.platformVersion);
803 free (platformInfo.operatingSystemVersion);
804 free (platformInfo.hardwareVersion);
805 free (platformInfo.firmwareVersion);
806 free (platformInfo.supportUrl);
807 free (platformInfo.systemTime);
810 void DeleteDeviceInfo()
812 free (deviceInfo.deviceName);
813 free (deviceInfo.specVersion);
814 OCFreeOCStringLL (deviceInfo.dataModelVersions);
817 bool DuplicateString(char** targetString, const char* sourceString)
825 *targetString = (char *) malloc(strlen(sourceString) + 1);
829 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
836 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
837 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
838 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
839 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
844 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
846 return OC_STACK_INVALID_PARAM;
849 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
851 return OC_STACK_INVALID_PARAM;
854 if(!DuplicateString(&platformInfo.platformID, platformID))
859 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
864 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
869 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
874 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
879 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
884 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
889 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
894 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
899 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
904 if(!DuplicateString(&platformInfo.systemTime, systemTime))
914 DeletePlatformInfo();
915 return OC_STACK_ERROR;
918 OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModelVersions)
920 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
922 return OC_STACK_ERROR;
924 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
926 return OC_STACK_ERROR;
928 OCFreeOCStringLL(deviceInfo.dataModelVersions);
929 deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions);
930 if (!deviceInfo.dataModelVersions)
932 return OC_STACK_ERROR;
937 static void PrintUsage()
939 cout << "\nUsage : ocserver -o <0|1>";
940 cout << "\n-o 0 : Notify all observers";
941 cout << "\n-o 1 : Notify list of observers";
944 void *GMainLoopThread(void *param)
949 if (OCProcess() != OC_STACK_OK)
951 cout << "\nOCStack process error";
954 #ifndef ROUTING_GATEWAY
961 g_main_loop_quit(g_mainloop);
966 int main(int argc, char* argv[])
969 pthread_t threadId_presence;
972 g_mainloop = g_main_loop_new(NULL, FALSE);
975 printf("g_main_loop_new failed\n");
979 while ((opt = getopt(argc, argv, "o:")) != -1)
984 gObserveNotifyType = atoi(optarg);
992 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
998 cout << "\nOCServer is starting...";
1000 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1002 cout << "\nOCStack init error";
1006 #ifdef WITH_PRESENCE
1007 if (OCStartPresence(0) != OC_STACK_OK)
1009 cout << "\nOCStack presence/discovery error";
1014 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1016 OCStackResult registrationResult =
1017 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
1018 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1019 firmwareVersion, supportUrl, systemTime);
1021 if (registrationResult != OC_STACK_OK)
1023 cout << "\nPlatform info setting failed locally!";
1024 exit (EXIT_FAILURE);
1027 registrationResult = OCSetPlatformInfo(platformInfo);
1029 if (registrationResult != OC_STACK_OK)
1031 cout << "\nPlatform Registration failed!";
1032 exit (EXIT_FAILURE);
1035 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);
1037 if (registrationResult != OC_STACK_OK)
1039 cout << "\nDevice info setting failed locally!";
1040 exit (EXIT_FAILURE);
1043 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1045 registrationResult = OCSetDeviceInfo(deviceInfo);
1047 if (registrationResult != OC_STACK_OK)
1049 cout << "\nDevice Registration failed!";
1050 exit (EXIT_FAILURE);
1054 * Declare and create the example resource: Light
1056 createLightResource(gResourceUri, &Light);
1058 // Initialize observations data structure for the resource
1059 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1061 interestedObservers[i].valid = false;
1065 * Create a thread for changing the representation of the Light
1067 pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
1070 * Create a thread for generating changes that cause presence notifications
1071 * to be sent to clients
1074 #ifdef WITH_PRESENCE
1075 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1078 // Break from loop with Ctrl-C
1079 cout << "\nEntering ocserver main loop...";
1081 DeletePlatformInfo();
1084 signal(SIGINT, handleSigInt);
1086 int result = pthread_create(&g_thread, NULL, GMainLoopThread, (void *)NULL);
1089 printf("pthread_create failed in initialize\n");
1093 g_main_loop_run(g_mainloop);
1096 * Cancel the Light thread and wait for it to terminate
1098 pthread_cancel(threadId);
1099 pthread_join(threadId, NULL);
1100 pthread_cancel(threadId_presence);
1101 pthread_join(threadId_presence, NULL);
1103 cout << "\nExiting ocserver main loop...\n";
1105 if (OCStop() != OC_STACK_OK)
1107 cout << "\nOCStack process error";