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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
40 #include "ocpayload.h"
43 #include "platform_features.h"
45 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
47 const int URI_MAXSIZE = 19;
49 static int gObserveNotifyType = 3;
52 int gLightUnderObservation = 0;
54 static LightResource Light;
55 // This variable determines instance number of the Light resource.
56 // Used by POST method to create a new instance of Light resource.
57 static int gCurrLightInstance = 0;
59 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
61 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
63 pthread_t threadId_observe;
64 pthread_t threadId_presence;
66 static bool observeThreadStarted = false;
69 #define numPresenceResources (2)
72 char *gResourceUri= (char *)"/a/light";
73 const char *dateOfManufacture = "myDateOfManufacture";
74 const char *deviceName = "myDeviceName";
75 const char *deviceUUID = "myDeviceUUID";
76 const char *firmwareVersion = "myFirmwareVersion";
77 const char *manufacturerName = "myName";
78 const char *operatingSystemVersion = "myOS";
79 const char *hardwareVersion = "myHardwareVersion";
80 const char* platformID = "myPlatformID";
81 const char *manufacturerUrl = "myManufacturerUrl";
82 const char *modelNumber = "myModelNumber";
83 const char *platformVersion = "myPlatformVersion";
84 const char *supportUrl = "mySupportUrl";
85 const char *version = "myVersion";
86 const char *systemTime = "2015-05-15T11.04";
87 const char *specVersion = "myDeviceSpecVersion";
88 const char* dataModleVersion = "myDeviceModleVersion";
90 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
91 // the existence of a known resource
92 const char *resourceTypeName = "core.light";
93 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
95 OCPlatformInfo platformInfo;
96 OCDeviceInfo deviceInfo;
98 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
100 OCRepPayload* payload = OCRepPayloadCreate();
103 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
107 OCRepPayloadSetUri(payload, uri);
108 OCRepPayloadSetPropBool(payload, "state", state);
109 OCRepPayloadSetPropInt(payload, "power", power);
114 //This function takes the request as an input and returns the response
115 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
117 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
119 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
123 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
125 LightResource *currLightResource = &Light;
127 if (ehRequest->resource == gLightInstance[0].handle)
129 currLightResource = &gLightInstance[0];
130 gResourceUri = (char *) "a/light/0";
132 else if (ehRequest->resource == gLightInstance[1].handle)
134 currLightResource = &gLightInstance[1];
135 gResourceUri = (char *) "a/light/1";
138 if(OC_REST_PUT == ehRequest->method)
140 // Get pointer to query
142 if(OCRepPayloadGetPropInt(input, "power", &pow))
144 currLightResource->power =pow;
148 if(OCRepPayloadGetPropBool(input, "state", &state))
150 currLightResource->state = state;
154 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
158 * Very simple example of query parsing.
159 * The query may have multiple filters separated by ';'.
160 * It is upto the entity handler to parse the query for the individual filters,
161 * VALIDATE them and respond as it sees fit.
163 * This function only returns false if the query is exactly "power<X" and
164 * current power is greater than X. If X cannot be parsed for an int,
167 bool checkIfQueryForPowerPassed(char * query)
169 if (query && strncmp(query, "power<", strlen("power<")) == 0)
171 char * pointerToOperator = strstr(query, "<");
173 if (pointerToOperator)
175 int powerRequested = atoi(pointerToOperator + 1);
176 if (Light.power > powerRequested)
178 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
188 * Application should validate and process these as desired.
190 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
192 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
193 OIC_LOG(INFO, TAG, PCF("Not processing query"));
197 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
198 OCRepPayload **payload)
200 OCEntityHandlerResult ehResult;
201 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
203 // Empty payload if the query has no match.
206 OCRepPayload *getResp = constructResponse(ehRequest);
209 OIC_LOG(ERROR, TAG, "constructResponse failed");
224 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
225 OCRepPayload** payload)
227 OCEntityHandlerResult ehResult;
228 OCRepPayload *putResp = constructResponse(ehRequest);
232 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
242 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
243 OCEntityHandlerResponse *response, OCRepPayload** payload)
245 OCEntityHandlerResult ehResult = OC_EH_OK;
246 OCRepPayload *respPLPost_light = nullptr;
249 * The entity handler determines how to process a POST request.
250 * Per the REST paradigm, POST can also be used to update representation of existing
251 * resource or create a new resource.
252 * In the sample below, if the POST is for /a/light then a new instance of the Light
253 * resource is created with default representation (if representation is included in
254 * POST payload it can be used as initial values) as long as the instance is
255 * lesser than max new instance count. Once max instance count is reached, POST on
256 * /a/light updated the representation of /a/light (just like PUT)
259 if (ehRequest->resource == Light.handle)
261 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
263 // Create new Light instance
264 char newLightUri[URI_MAXSIZE];
265 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
267 respPLPost_light = OCRepPayloadCreate();
268 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
269 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
271 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
273 OIC_LOG (INFO, TAG, "Created new Light instance\n");
274 gLightInstance[gCurrLightInstance].state = 0;
275 gLightInstance[gCurrLightInstance].power = 0;
276 gCurrLightInstance++;
277 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
278 ehResult = OC_EH_RESOURCE_CREATED;
283 // Update repesentation of /a/light
286 respPLPost_light = constructResponse(ehRequest);
291 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
293 if (ehRequest->resource == gLightInstance[i].handle)
295 gLightInstance[i].state = true;
296 gLightInstance[i].power = 22;
299 respPLPost_light = constructResponse(ehRequest);
304 respPLPost_light = constructResponse(ehRequest);
310 if ((respPLPost_light != NULL))
312 *payload = respPLPost_light;
316 OIC_LOG(INFO, TAG, "Payload was NULL");
317 ehResult = OC_EH_ERROR;
323 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
325 if(ehRequest == NULL)
327 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
330 OCEntityHandlerResult ehResult = OC_EH_OK;
332 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
335 * In the sample below, the application will:
336 * 1a. pass the delete request to the c stack
337 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
338 * (e.g. send observers notification, remove observers...)
339 * 1c. the c stack returns with the result whether the request is fullfilled.
340 * 2. optionally, app removes observers out of its array 'interestedObservers'
343 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
345 //Step 1: Ask stack to do the work.
346 OCStackResult result = OCDeleteResource(ehRequest->resource);
348 if (result == OC_STACK_OK)
350 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
353 //Step 2: clear observers who wanted to observe this resource at the app level.
354 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
356 if (interestedObservers[i].resourceHandle == ehRequest->resource)
358 interestedObservers[i].valid = false;
359 interestedObservers[i].observationId = 0;
360 interestedObservers[i].resourceHandle = NULL;
364 else if (result == OC_STACK_NO_RESOURCE)
366 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
367 ehResult = OC_EH_RESOURCE_DELETED;
371 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
372 ehResult = OC_EH_ERROR;
375 else if (ehRequest->resource != Light.handle)
377 //Let's this app not supporting DELETE on some resources so
378 //consider the DELETE request is received for a non-support resource.
379 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
380 ehResult = OC_EH_FORBIDDEN;
386 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
388 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
390 return OC_EH_RESOURCE_NOT_FOUND;
393 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
395 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
396 ehRequest->obsInfo.obsId);
398 if (!observeThreadStarted)
400 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
401 observeThreadStarted = 1;
403 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
405 if (interestedObservers[i].valid == false)
407 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
408 interestedObservers[i].valid = true;
409 gLightUnderObservation = 1;
415 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
417 bool clientStillObserving = false;
419 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
420 ehRequest->obsInfo.obsId);
421 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
423 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
425 interestedObservers[i].valid = false;
427 if (interestedObservers[i].valid == true)
429 // Even if there is one single client observing we continue notifying entity handler
430 clientStillObserving = true;
433 if (clientStillObserving == false)
434 gLightUnderObservation = 0;
437 OCEntityHandlerResult
438 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
439 OCEntityHandlerRequest *entityHandlerRequest,
441 void* /*callbackParam*/)
443 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
445 OCEntityHandlerResult ehResult = OC_EH_OK;
446 OCEntityHandlerResponse response;
449 if (!entityHandlerRequest)
451 OIC_LOG (ERROR, TAG, "Invalid request pointer");
454 // Initialize certain response fields
455 response.numSendVendorSpecificHeaderOptions = 0;
456 memset(response.sendVendorSpecificHeaderOptions, 0,
457 sizeof response.sendVendorSpecificHeaderOptions);
458 memset(response.resourceUri, 0, sizeof response.resourceUri);
459 OCRepPayload* payload = nullptr;
462 if (flag & OC_REQUEST_FLAG)
464 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
466 if (entityHandlerRequest->resource == NULL)
468 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
469 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
471 else if (OC_REST_GET == entityHandlerRequest->method)
473 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
474 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
476 else if (OC_REST_PUT == entityHandlerRequest->method)
478 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
479 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
481 else if (OC_REST_DELETE == entityHandlerRequest->method)
483 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
484 ehResult = ProcessDeleteRequest (entityHandlerRequest);
488 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
489 entityHandlerRequest->method);
490 ehResult = OC_EH_ERROR;
492 // If the result isn't an error or forbidden, send response
493 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
495 // Format the response. Note this requires some info about the request
496 response.requestHandle = entityHandlerRequest->requestHandle;
497 response.resourceHandle = entityHandlerRequest->resource;
498 response.ehResult = ehResult;
499 response.payload = reinterpret_cast<OCPayload*>(payload);
500 // Indicate that response is NOT in a persistent buffer
501 response.persistentBufferFlag = 0;
504 if (OCDoResponse(&response) != OC_STACK_OK)
506 OIC_LOG(ERROR, TAG, "Error sending response");
507 ehResult = OC_EH_ERROR;
511 if (flag & OC_OBSERVE_FLAG)
513 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
514 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
516 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
518 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
520 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
527 OCEntityHandlerResult
528 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
529 OCEntityHandlerRequest * /*entityHandlerRequest*/,
530 void* /*callbackParam*/)
532 // This is callback is associated with the 2 presence notification
533 // resources. They are non-operational.
537 OCEntityHandlerResult
538 OCEntityHandlerCb (OCEntityHandlerFlag flag,
539 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
541 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
543 OCEntityHandlerResult ehResult = OC_EH_OK;
544 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
547 if (!entityHandlerRequest)
549 OIC_LOG (ERROR, TAG, "Invalid request pointer");
553 // Initialize certain response fields
554 response.numSendVendorSpecificHeaderOptions = 0;
555 memset(response.sendVendorSpecificHeaderOptions,
556 0, sizeof response.sendVendorSpecificHeaderOptions);
557 memset(response.resourceUri, 0, sizeof response.resourceUri);
558 OCRepPayload* payload = nullptr;
560 if (flag & OC_REQUEST_FLAG)
562 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
564 if (OC_REST_GET == entityHandlerRequest->method)
566 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
567 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
569 else if (OC_REST_PUT == entityHandlerRequest->method)
571 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
572 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
574 else if (OC_REST_POST == entityHandlerRequest->method)
576 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
577 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
579 else if (OC_REST_DELETE == entityHandlerRequest->method)
581 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
582 ehResult = ProcessDeleteRequest (entityHandlerRequest);
586 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
587 entityHandlerRequest->method);
588 ehResult = OC_EH_ERROR;
590 // If the result isn't an error or forbidden, send response
591 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
593 // Format the response. Note this requires some info about the request
594 response.requestHandle = entityHandlerRequest->requestHandle;
595 response.resourceHandle = entityHandlerRequest->resource;
596 response.ehResult = ehResult;
597 response.payload = reinterpret_cast<OCPayload*>(payload);
598 // Indicate that response is NOT in a persistent buffer
599 response.persistentBufferFlag = 0;
601 // Handle vendor specific options
602 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
603 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
605 OIC_LOG (INFO, TAG, "Received vendor specific options");
607 OCHeaderOption * rcvdOptions =
608 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
609 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
611 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
613 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
614 ((OCHeaderOption)rcvdOptions[i]).optionID );
616 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
617 MAX_HEADER_OPTION_DATA_LENGTH);
620 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
621 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
622 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
623 sendOptions[0].protocolID = OC_COAP_ID;
624 sendOptions[0].optionID = 2248;
625 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
626 sendOptions[0].optionLength = 10;
627 sendOptions[1].protocolID = OC_COAP_ID;
628 sendOptions[1].optionID = 2600;
629 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
630 sendOptions[1].optionLength = 10;
631 response.numSendVendorSpecificHeaderOptions = 2;
635 if (OCDoResponse(&response) != OC_STACK_OK)
637 OIC_LOG(ERROR, TAG, "Error sending response");
638 ehResult = OC_EH_ERROR;
642 if (flag & OC_OBSERVE_FLAG)
644 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
646 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
648 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
649 ProcessObserveRegister (entityHandlerRequest);
651 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
653 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
654 ProcessObserveDeregister (entityHandlerRequest);
658 OCPayloadDestroy(response.payload);
662 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
663 void handleSigInt(int signum)
665 if (signum == SIGINT)
671 void *ChangeLightRepresentation (void *param)
674 OCStackResult result = OC_STACK_ERROR;
677 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
683 if (gLightUnderObservation)
685 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
686 if (gObserveNotifyType == 1)
688 // Notify list of observers. Alternate observers on the list will be notified.
690 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
692 if (interestedObservers[i].valid == true)
694 obsNotify[j] = interestedObservers[i].observationId;
699 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
700 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
702 OCRepPayloadDestroy(payload);
704 else if (gObserveNotifyType == 0)
706 // Notifying all observers
707 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
708 if (OC_STACK_NO_OBSERVERS == result)
711 "=======> No more observers exist, stop sending observations");
712 gLightUnderObservation = 0;
717 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
725 void *presenceNotificationGenerator(void *param)
727 uint8_t secondsBeforePresence = 10;
728 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
729 sleep(secondsBeforePresence);
731 OCDoHandle presenceNotificationHandles[numPresenceResources];
732 OCStackResult res = OC_STACK_OK;
734 std::array<std::string, numPresenceResources> presenceNotificationResources { {
735 std::string("core.fan"),
736 std::string("core.led") } };
737 std::array<std::string, numPresenceResources> presenceNotificationUris { {
738 std::string("/a/fan"),
739 std::string("/a/led") } };
741 for(int i=0; i<numPresenceResources; i++)
743 if(res == OC_STACK_OK)
746 res = OCCreateResource(&presenceNotificationHandles[i],
747 presenceNotificationResources.at(i).c_str(),
748 OC_RSRVD_INTERFACE_DEFAULT,
749 presenceNotificationUris.at(i).c_str(),
750 OCNOPEntityHandlerCb,
752 OC_DISCOVERABLE|OC_OBSERVABLE);
754 if(res != OC_STACK_OK)
756 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
757 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
761 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
762 presenceNotificationUris[i].c_str());
765 for(int i=0; i<numPresenceResources; i++)
767 if(res == OC_STACK_OK)
769 res = OCDeleteResource(presenceNotificationHandles[i]);
771 if(res != OC_STACK_OK)
773 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
774 "resource %s.", presenceNotificationResources.at(i).c_str());
777 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
778 presenceNotificationUris[i].c_str());
781 OIC_LOG(INFO, TAG, "================ stopping presence");
788 int createLightResource (char *uri, LightResource *lightResource)
792 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
796 lightResource->state = false;
797 lightResource->power= 0;
798 OCStackResult res = OCCreateResource(&(lightResource->handle),
804 OC_DISCOVERABLE|OC_OBSERVABLE);
805 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
810 void DeletePlatformInfo()
812 free (platformInfo.platformID);
813 free (platformInfo.manufacturerName);
814 free (platformInfo.manufacturerUrl);
815 free (platformInfo.modelNumber);
816 free (platformInfo.dateOfManufacture);
817 free (platformInfo.platformVersion);
818 free (platformInfo.operatingSystemVersion);
819 free (platformInfo.hardwareVersion);
820 free (platformInfo.firmwareVersion);
821 free (platformInfo.supportUrl);
822 free (platformInfo.systemTime);
825 void DeleteDeviceInfo()
827 free (deviceInfo.deviceName);
828 free (deviceInfo.specVersion);
829 free (deviceInfo.dataModleVersion);
832 bool DuplicateString(char** targetString, const char* sourceString)
840 *targetString = (char *) malloc(strlen(sourceString) + 1);
844 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
851 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
852 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
853 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
854 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
859 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
861 return OC_STACK_INVALID_PARAM;
864 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
866 return OC_STACK_INVALID_PARAM;
869 if(!DuplicateString(&platformInfo.platformID, platformID))
874 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
879 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
884 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
889 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
894 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
899 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
904 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
909 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
914 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
919 if(!DuplicateString(&platformInfo.systemTime, systemTime))
929 DeletePlatformInfo();
930 return OC_STACK_ERROR;
933 OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModleVersion)
935 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
937 return OC_STACK_ERROR;
939 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
941 return OC_STACK_ERROR;
943 if(!DuplicateString(&deviceInfo.dataModleVersion, dataModleVersion))
945 return OC_STACK_ERROR;
950 static void PrintUsage()
952 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
953 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
954 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
958 static void jidbound(char *jid)
960 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
964 int main(int argc, char* argv[])
968 char host[] = "localhost";
969 char user[] = "test1";
970 char pass[] = "intel123";
972 OCRAInfo_t rainfo = {};
974 rainfo.hostname = host;
976 rainfo.xmpp_domain = host;
977 rainfo.username = user;
978 rainfo.password = pass;
979 rainfo.resource = empstr;
980 rainfo.user_jid = empstr;
981 rainfo.jidbound = jidbound;
985 while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
990 gObserveNotifyType = atoi(optarg);
994 rainfo.hostname = optarg;
997 rainfo.port = atoi(optarg);
1000 rainfo.xmpp_domain = optarg;
1003 rainfo.username = optarg;
1006 rainfo.password = optarg;
1009 rainfo.user_jid = optarg;
1012 rainfo.resource = optarg;
1021 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
1028 OCSetRAInfo(&rainfo);
1031 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1033 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1035 OIC_LOG(ERROR, TAG, "OCStack init error");
1038 #ifdef WITH_PRESENCE
1039 if (OCStartPresence(0) != OC_STACK_OK)
1041 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1046 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1048 OCStackResult registrationResult =
1049 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
1050 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1051 firmwareVersion, supportUrl, systemTime);
1053 if (registrationResult != OC_STACK_OK)
1055 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1056 exit (EXIT_FAILURE);
1059 registrationResult = OCSetPlatformInfo(platformInfo);
1061 if (registrationResult != OC_STACK_OK)
1063 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1064 exit (EXIT_FAILURE);
1067 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModleVersion);
1069 if (registrationResult != OC_STACK_OK)
1071 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1072 exit (EXIT_FAILURE);
1075 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1077 registrationResult = OCSetDeviceInfo(deviceInfo);
1079 if (registrationResult != OC_STACK_OK)
1081 OIC_LOG(INFO, TAG, "Device Registration failed!");
1082 exit (EXIT_FAILURE);
1086 * Declare and create the example resource: Light
1088 createLightResource(gResourceUri, &Light);
1090 // Initialize observations data structure for the resource
1091 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1093 interestedObservers[i].valid = false;
1098 * Create a thread for generating changes that cause presence notifications
1099 * to be sent to clients
1102 #ifdef WITH_PRESENCE
1103 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1106 // Break from loop with Ctrl-C
1107 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1109 DeletePlatformInfo();
1112 signal(SIGINT, handleSigInt);
1116 if (OCProcess() != OC_STACK_OK)
1118 OIC_LOG(ERROR, TAG, "OCStack process error");
1123 if (observeThreadStarted)
1125 #ifdef HAVE_PTHREAD_H
1126 pthread_cancel(threadId_observe);
1127 pthread_join(threadId_observe, NULL);
1131 #ifdef HAVE_PTHREAD_H
1132 pthread_cancel(threadId_presence);
1133 pthread_join(threadId_presence, NULL);
1136 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1138 if (OCStop() != OC_STACK_OK)
1140 OIC_LOG(ERROR, TAG, "OCStack process error");