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];
53 pthread_t threadId_observe;
54 pthread_t threadId_presence;
56 static bool observeThreadStarted = false;
59 #define numPresenceResources (2)
62 char *gResourceUri= (char *)"/a/light";
63 const char *dateOfManufacture = "myDateOfManufacture";
64 const char *deviceName = "myDeviceName";
65 const char *deviceUUID = "myDeviceUUID";
66 const char *firmwareVersion = "myFirmwareVersion";
67 const char *manufacturerName = "myName";
68 const char *operatingSystemVersion = "myOS";
69 const char *hardwareVersion = "myHardwareVersion";
70 const char* platformID = "myPlatformID";
71 const char *manufacturerUrl = "myManufacturerUrl";
72 const char *modelNumber = "myModelNumber";
73 const char *platformVersion = "myPlatformVersion";
74 const char *supportUrl = "mySupportUrl";
75 const char *version = "myVersion";
76 const char *systemTime = "2015-05-15T11.04";
77 const char *specVersion = "myDeviceSpecVersion";
78 const char* dataModelVersion = "myDeviceModelVersion";
80 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
81 // the existence of a known resource
82 const char *resourceTypeName = "core.light";
83 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
85 OCPlatformInfo platformInfo;
86 OCDeviceInfo deviceInfo;
88 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
90 OCRepPayload* payload = OCRepPayloadCreate();
93 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
97 OCRepPayloadSetUri(payload, uri);
98 OCRepPayloadSetPropBool(payload, "state", state);
99 OCRepPayloadSetPropInt(payload, "power", power);
104 //This function takes the request as an input and returns the response
105 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
107 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
109 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
113 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
115 LightResource *currLightResource = &Light;
117 if (ehRequest->resource == gLightInstance[0].handle)
119 currLightResource = &gLightInstance[0];
120 gResourceUri = (char *) "a/light/0";
122 else if (ehRequest->resource == gLightInstance[1].handle)
124 currLightResource = &gLightInstance[1];
125 gResourceUri = (char *) "a/light/1";
128 if(OC_REST_PUT == ehRequest->method)
130 // Get pointer to query
132 if(OCRepPayloadGetPropInt(input, "power", &pow))
134 currLightResource->power =pow;
138 if(OCRepPayloadGetPropBool(input, "state", &state))
140 currLightResource->state = state;
144 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
148 * Very simple example of query parsing.
149 * The query may have multiple filters separated by ';'.
150 * It is upto the entity handler to parse the query for the individual filters,
151 * VALIDATE them and respond as it sees fit.
153 * This function only returns false if the query is exactly "power<X" and
154 * current power is greater than X. If X cannot be parsed for an int,
157 bool checkIfQueryForPowerPassed(char * query)
159 if (query && strncmp(query, "power<", strlen("power<")) == 0)
161 char * pointerToOperator = strstr(query, "<");
163 if (pointerToOperator)
165 int powerRequested = atoi(pointerToOperator + 1);
166 if (Light.power > powerRequested)
168 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
178 * Application should validate and process these as desired.
180 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
182 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
183 OIC_LOG(INFO, TAG, PCF("Not processing query"));
187 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
188 OCRepPayload **payload)
190 OCEntityHandlerResult ehResult;
191 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
193 // Empty payload if the query has no match.
196 OCRepPayload *getResp = constructResponse(ehRequest);
199 OIC_LOG(ERROR, TAG, "constructResponse failed");
214 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
215 OCRepPayload** payload)
217 OCEntityHandlerResult ehResult;
218 OCRepPayload *putResp = constructResponse(ehRequest);
222 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
232 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
233 OCEntityHandlerResponse *response, OCRepPayload** payload)
235 OCEntityHandlerResult ehResult = OC_EH_OK;
236 OCRepPayload *respPLPost_light = nullptr;
239 * The entity handler determines how to process a POST request.
240 * Per the REST paradigm, POST can also be used to update representation of existing
241 * resource or create a new resource.
242 * In the sample below, if the POST is for /a/light then a new instance of the Light
243 * resource is created with default representation (if representation is included in
244 * POST payload it can be used as initial values) as long as the instance is
245 * lesser than max new instance count. Once max instance count is reached, POST on
246 * /a/light updated the representation of /a/light (just like PUT)
249 if (ehRequest->resource == Light.handle)
251 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
253 // Create new Light instance
254 char newLightUri[URI_MAXSIZE];
255 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
257 respPLPost_light = OCRepPayloadCreate();
258 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
259 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
261 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
263 OIC_LOG (INFO, TAG, "Created new Light instance\n");
264 gLightInstance[gCurrLightInstance].state = 0;
265 gLightInstance[gCurrLightInstance].power = 0;
266 gCurrLightInstance++;
267 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
268 ehResult = OC_EH_RESOURCE_CREATED;
273 // Update repesentation of /a/light
276 respPLPost_light = constructResponse(ehRequest);
281 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
283 if (ehRequest->resource == gLightInstance[i].handle)
285 gLightInstance[i].state = true;
286 gLightInstance[i].power = 22;
289 respPLPost_light = constructResponse(ehRequest);
294 respPLPost_light = constructResponse(ehRequest);
300 if ((respPLPost_light != NULL))
302 *payload = respPLPost_light;
306 OIC_LOG(INFO, TAG, "Payload was NULL");
307 ehResult = OC_EH_ERROR;
313 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
315 if(ehRequest == NULL)
317 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
320 OCEntityHandlerResult ehResult = OC_EH_OK;
322 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
325 * In the sample below, the application will:
326 * 1a. pass the delete request to the c stack
327 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
328 * (e.g. send observers notification, remove observers...)
329 * 1c. the c stack returns with the result whether the request is fullfilled.
330 * 2. optionally, app removes observers out of its array 'interestedObservers'
333 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
335 //Step 1: Ask stack to do the work.
336 OCStackResult result = OCDeleteResource(ehRequest->resource);
338 if (result == OC_STACK_OK)
340 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
343 //Step 2: clear observers who wanted to observe this resource at the app level.
344 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
346 if (interestedObservers[i].resourceHandle == ehRequest->resource)
348 interestedObservers[i].valid = false;
349 interestedObservers[i].observationId = 0;
350 interestedObservers[i].resourceHandle = NULL;
354 else if (result == OC_STACK_NO_RESOURCE)
356 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
357 ehResult = OC_EH_RESOURCE_DELETED;
361 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
362 ehResult = OC_EH_ERROR;
365 else if (ehRequest->resource != Light.handle)
367 //Let's this app not supporting DELETE on some resources so
368 //consider the DELETE request is received for a non-support resource.
369 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
370 ehResult = OC_EH_FORBIDDEN;
376 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
378 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
380 return OC_EH_RESOURCE_NOT_FOUND;
383 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
385 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
386 ehRequest->obsInfo.obsId);
388 if (!observeThreadStarted)
390 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
391 observeThreadStarted = 1;
393 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
395 if (interestedObservers[i].valid == false)
397 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
398 interestedObservers[i].valid = true;
399 gLightUnderObservation = 1;
405 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
407 bool clientStillObserving = false;
409 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
410 ehRequest->obsInfo.obsId);
411 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
413 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
415 interestedObservers[i].valid = false;
417 if (interestedObservers[i].valid == true)
419 // Even if there is one single client observing we continue notifying entity handler
420 clientStillObserving = true;
423 if (clientStillObserving == false)
424 gLightUnderObservation = 0;
427 OCEntityHandlerResult
428 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
429 OCEntityHandlerRequest *entityHandlerRequest,
431 void* /*callbackParam*/)
433 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
435 OCEntityHandlerResult ehResult = OC_EH_OK;
436 OCEntityHandlerResponse response;
439 if (!entityHandlerRequest)
441 OIC_LOG (ERROR, TAG, "Invalid request pointer");
444 // Initialize certain response fields
445 response.numSendVendorSpecificHeaderOptions = 0;
446 memset(response.sendVendorSpecificHeaderOptions, 0,
447 sizeof response.sendVendorSpecificHeaderOptions);
448 memset(response.resourceUri, 0, sizeof response.resourceUri);
449 OCRepPayload* payload = nullptr;
452 if (flag & OC_REQUEST_FLAG)
454 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
456 if (entityHandlerRequest->resource == NULL)
458 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
459 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
461 else if (OC_REST_GET == entityHandlerRequest->method)
463 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
464 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
466 else if (OC_REST_PUT == entityHandlerRequest->method)
468 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
469 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
471 else if (OC_REST_DELETE == entityHandlerRequest->method)
473 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
474 ehResult = ProcessDeleteRequest (entityHandlerRequest);
478 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
479 entityHandlerRequest->method);
480 ehResult = OC_EH_ERROR;
482 // If the result isn't an error or forbidden, send response
483 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
485 // Format the response. Note this requires some info about the request
486 response.requestHandle = entityHandlerRequest->requestHandle;
487 response.resourceHandle = entityHandlerRequest->resource;
488 response.ehResult = ehResult;
489 response.payload = reinterpret_cast<OCPayload*>(payload);
490 // Indicate that response is NOT in a persistent buffer
491 response.persistentBufferFlag = 0;
494 if (OCDoResponse(&response) != OC_STACK_OK)
496 OIC_LOG(ERROR, TAG, "Error sending response");
497 ehResult = OC_EH_ERROR;
501 if (flag & OC_OBSERVE_FLAG)
503 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
504 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
506 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
508 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
510 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
517 OCEntityHandlerResult
518 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
519 OCEntityHandlerRequest * /*entityHandlerRequest*/,
520 void* /*callbackParam*/)
522 // This is callback is associated with the 2 presence notification
523 // resources. They are non-operational.
527 OCEntityHandlerResult
528 OCEntityHandlerCb (OCEntityHandlerFlag flag,
529 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
531 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
533 OCEntityHandlerResult ehResult = OC_EH_OK;
534 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
537 if (!entityHandlerRequest)
539 OIC_LOG (ERROR, TAG, "Invalid request pointer");
543 // Initialize certain response fields
544 response.numSendVendorSpecificHeaderOptions = 0;
545 memset(response.sendVendorSpecificHeaderOptions,
546 0, sizeof response.sendVendorSpecificHeaderOptions);
547 memset(response.resourceUri, 0, sizeof response.resourceUri);
548 OCRepPayload* payload = nullptr;
550 if (flag & OC_REQUEST_FLAG)
552 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
554 if (OC_REST_GET == entityHandlerRequest->method)
556 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
557 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
559 else if (OC_REST_PUT == entityHandlerRequest->method)
561 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
562 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
564 else if (OC_REST_POST == entityHandlerRequest->method)
566 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
567 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
569 else if (OC_REST_DELETE == entityHandlerRequest->method)
571 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
572 ehResult = ProcessDeleteRequest (entityHandlerRequest);
576 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
577 entityHandlerRequest->method);
578 ehResult = OC_EH_ERROR;
580 // If the result isn't an error or forbidden, send response
581 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
583 // Format the response. Note this requires some info about the request
584 response.requestHandle = entityHandlerRequest->requestHandle;
585 response.resourceHandle = entityHandlerRequest->resource;
586 response.ehResult = ehResult;
587 response.payload = reinterpret_cast<OCPayload*>(payload);
588 // Indicate that response is NOT in a persistent buffer
589 response.persistentBufferFlag = 0;
591 // Handle vendor specific options
592 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
593 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
595 OIC_LOG (INFO, TAG, "Received vendor specific options");
597 OCHeaderOption * rcvdOptions =
598 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
599 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
601 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
603 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
604 ((OCHeaderOption)rcvdOptions[i]).optionID );
606 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
607 MAX_HEADER_OPTION_DATA_LENGTH);
610 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
611 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
612 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
613 sendOptions[0].protocolID = OC_COAP_ID;
614 sendOptions[0].optionID = 2248;
615 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
616 sendOptions[0].optionLength = 10;
617 sendOptions[1].protocolID = OC_COAP_ID;
618 sendOptions[1].optionID = 2600;
619 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
620 sendOptions[1].optionLength = 10;
621 response.numSendVendorSpecificHeaderOptions = 2;
625 if (OCDoResponse(&response) != OC_STACK_OK)
627 OIC_LOG(ERROR, TAG, "Error sending response");
628 ehResult = OC_EH_ERROR;
632 if (flag & OC_OBSERVE_FLAG)
634 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
636 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
638 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
639 ProcessObserveRegister (entityHandlerRequest);
641 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
643 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
644 ProcessObserveDeregister (entityHandlerRequest);
648 OCPayloadDestroy(response.payload);
652 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
653 void handleSigInt(int signum)
655 if (signum == SIGINT)
661 void *ChangeLightRepresentation (void *param)
664 OCStackResult result = OC_STACK_ERROR;
667 uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
668 OCObservationId obsNotify[numNotifies];
674 if (gLightUnderObservation)
676 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
677 if (gObserveNotifyType == 1)
679 // Notify list of observers. Alternate observers on the list will be notified.
681 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
683 if (interestedObservers[i].valid == true)
685 obsNotify[j] = interestedObservers[i].observationId;
690 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
691 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
693 OCRepPayloadDestroy(payload);
695 else if (gObserveNotifyType == 0)
697 // Notifying all observers
698 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
699 if (OC_STACK_NO_OBSERVERS == result)
702 "=======> No more observers exist, stop sending observations");
703 gLightUnderObservation = 0;
708 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
716 void *presenceNotificationGenerator(void *param)
718 uint8_t secondsBeforePresence = 10;
719 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
720 sleep(secondsBeforePresence);
722 OCDoHandle presenceNotificationHandles[numPresenceResources];
723 OCStackResult res = OC_STACK_OK;
725 std::array<std::string, numPresenceResources> presenceNotificationResources { {
726 std::string("core.fan"),
727 std::string("core.led") } };
728 std::array<std::string, numPresenceResources> presenceNotificationUris { {
729 std::string("/a/fan"),
730 std::string("/a/led") } };
732 for(int i=0; i<numPresenceResources; i++)
734 if(res == OC_STACK_OK)
737 res = OCCreateResource(&presenceNotificationHandles[i],
738 presenceNotificationResources.at(i).c_str(),
739 OC_RSRVD_INTERFACE_DEFAULT,
740 presenceNotificationUris.at(i).c_str(),
741 OCNOPEntityHandlerCb,
743 OC_DISCOVERABLE|OC_OBSERVABLE);
745 if(res != OC_STACK_OK)
747 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
748 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
752 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
753 presenceNotificationUris[i].c_str());
756 for(int i=0; i<numPresenceResources; i++)
758 if(res == OC_STACK_OK)
760 res = OCDeleteResource(presenceNotificationHandles[i]);
762 if(res != OC_STACK_OK)
764 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
765 "resource %s.", presenceNotificationResources.at(i).c_str());
768 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
769 presenceNotificationUris[i].c_str());
772 OIC_LOG(INFO, TAG, "================ stopping presence");
779 int createLightResource (char *uri, LightResource *lightResource)
783 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
787 lightResource->state = false;
788 lightResource->power= 0;
789 OCStackResult res = OCCreateResource(&(lightResource->handle),
795 OC_DISCOVERABLE|OC_OBSERVABLE);
796 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
801 void DeletePlatformInfo()
803 free (platformInfo.platformID);
804 free (platformInfo.manufacturerName);
805 free (platformInfo.manufacturerUrl);
806 free (platformInfo.modelNumber);
807 free (platformInfo.dateOfManufacture);
808 free (platformInfo.platformVersion);
809 free (platformInfo.operatingSystemVersion);
810 free (platformInfo.hardwareVersion);
811 free (platformInfo.firmwareVersion);
812 free (platformInfo.supportUrl);
813 free (platformInfo.systemTime);
816 void DeleteDeviceInfo()
818 free (deviceInfo.deviceName);
819 free (deviceInfo.specVersion);
820 free (deviceInfo.dataModelVersion);
823 bool DuplicateString(char** targetString, const char* sourceString)
831 *targetString = (char *) malloc(strlen(sourceString) + 1);
835 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
842 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
843 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
844 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
845 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
850 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
852 return OC_STACK_INVALID_PARAM;
855 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
857 return OC_STACK_INVALID_PARAM;
860 if(!DuplicateString(&platformInfo.platformID, platformID))
865 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
870 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
875 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
880 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
885 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
890 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
895 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
900 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
905 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
910 if(!DuplicateString(&platformInfo.systemTime, systemTime))
920 DeletePlatformInfo();
921 return OC_STACK_ERROR;
924 OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModelVersion)
926 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
928 return OC_STACK_ERROR;
930 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
932 return OC_STACK_ERROR;
934 if(!DuplicateString(&deviceInfo.dataModelVersion, dataModelVersion))
936 return OC_STACK_ERROR;
941 static void PrintUsage()
943 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
944 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
945 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
949 static void jidbound(char *jid)
951 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
955 int main(int argc, char* argv[])
959 char host[] = "localhost";
960 char user[] = "test1";
961 char pass[] = "intel123";
963 OCRAInfo_t rainfo = {};
965 rainfo.hostname = host;
967 rainfo.xmpp_domain = host;
968 rainfo.username = user;
969 rainfo.password = pass;
970 rainfo.resource = empstr;
971 rainfo.user_jid = empstr;
972 rainfo.jidbound = jidbound;
976 while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
981 gObserveNotifyType = atoi(optarg);
985 rainfo.hostname = optarg;
988 rainfo.port = atoi(optarg);
991 rainfo.xmpp_domain = optarg;
994 rainfo.username = optarg;
997 rainfo.password = optarg;
1000 rainfo.user_jid = optarg;
1003 rainfo.resource = optarg;
1012 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
1019 OCSetRAInfo(&rainfo);
1022 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1024 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1026 OIC_LOG(ERROR, TAG, "OCStack init error");
1029 #ifdef WITH_PRESENCE
1030 if (OCStartPresence(0) != OC_STACK_OK)
1032 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1037 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1039 OCStackResult registrationResult =
1040 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
1041 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1042 firmwareVersion, supportUrl, systemTime);
1044 if (registrationResult != OC_STACK_OK)
1046 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1047 exit (EXIT_FAILURE);
1050 registrationResult = OCSetPlatformInfo(platformInfo);
1052 if (registrationResult != OC_STACK_OK)
1054 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1055 exit (EXIT_FAILURE);
1058 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersion);
1060 if (registrationResult != OC_STACK_OK)
1062 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1063 exit (EXIT_FAILURE);
1066 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1068 registrationResult = OCSetDeviceInfo(deviceInfo);
1070 if (registrationResult != OC_STACK_OK)
1072 OIC_LOG(INFO, TAG, "Device Registration failed!");
1073 exit (EXIT_FAILURE);
1077 * Declare and create the example resource: Light
1079 createLightResource(gResourceUri, &Light);
1081 // Initialize observations data structure for the resource
1082 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1084 interestedObservers[i].valid = false;
1089 * Create a thread for generating changes that cause presence notifications
1090 * to be sent to clients
1093 #ifdef WITH_PRESENCE
1094 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1097 // Break from loop with Ctrl-C
1098 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1100 DeletePlatformInfo();
1103 signal(SIGINT, handleSigInt);
1107 if (OCProcess() != OC_STACK_OK)
1109 OIC_LOG(ERROR, TAG, "OCStack process error");
1114 if (observeThreadStarted)
1116 pthread_cancel(threadId_observe);
1117 pthread_join(threadId_observe, NULL);
1120 pthread_cancel(threadId_presence);
1121 pthread_join(threadId_presence, NULL);
1123 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1125 if (OCStop() != OC_STACK_OK)
1127 OIC_LOG(ERROR, TAG, "OCStack process error");