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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
30 #include "oic_malloc.h"
33 #include "ocpayload.h"
36 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
38 const int URI_MAXSIZE = 19;
40 static int gObserveNotifyType = 3;
43 int gLightUnderObservation = 0;
45 static LightResource Light;
46 // This variable determines instance number of the Light resource.
47 // Used by POST method to create a new instance of Light resource.
48 static int gCurrLightInstance = 0;
50 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
52 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
54 pthread_t threadId_observe;
55 pthread_t threadId_presence;
57 static bool observeThreadStarted = false;
60 #define numPresenceResources (2)
63 char *gResourceUri= (char *)"/a/light";
64 const char *dateOfManufacture = "myDateOfManufacture";
65 const char *deviceName = "myDeviceName";
66 const char *deviceUUID = "myDeviceUUID";
67 const char *firmwareVersion = "myFirmwareVersion";
68 const char *manufacturerName = "myName";
69 const char *operatingSystemVersion = "myOS";
70 const char *hardwareVersion = "myHardwareVersion";
71 const char* platformID = "myPlatformID";
72 const char *manufacturerUrl = "myManufacturerUrl";
73 const char *modelNumber = "myModelNumber";
74 const char *platformVersion = "myPlatformVersion";
75 const char *supportUrl = "mySupportUrl";
76 const char *version = "myVersion";
77 const char *systemTime = "2015-05-15T11.04";
78 const char *specVersion = "myDeviceSpecVersion";
79 const char *dataModelVersions = "myDeviceModelVersions";
81 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
82 // the existence of a known resource
83 const char *resourceTypeName = "core.light";
84 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
86 OCPlatformInfo platformInfo;
87 OCDeviceInfo deviceInfo;
89 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
91 OCRepPayload* payload = OCRepPayloadCreate();
94 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
98 OCRepPayloadSetUri(payload, uri);
99 OCRepPayloadSetPropBool(payload, "state", state);
100 OCRepPayloadSetPropInt(payload, "power", power);
105 //This function takes the request as an input and returns the response
106 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
108 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
110 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
114 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
116 LightResource *currLightResource = &Light;
118 if (ehRequest->resource == gLightInstance[0].handle)
120 currLightResource = &gLightInstance[0];
121 gResourceUri = (char *) "a/light/0";
123 else if (ehRequest->resource == gLightInstance[1].handle)
125 currLightResource = &gLightInstance[1];
126 gResourceUri = (char *) "a/light/1";
129 if(OC_REST_PUT == ehRequest->method)
131 // Get pointer to query
133 if(OCRepPayloadGetPropInt(input, "power", &pow))
135 currLightResource->power =pow;
139 if(OCRepPayloadGetPropBool(input, "state", &state))
141 currLightResource->state = state;
145 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
149 * Very simple example of query parsing.
150 * The query may have multiple filters separated by ';'.
151 * It is upto the entity handler to parse the query for the individual filters,
152 * VALIDATE them and respond as it sees fit.
154 * This function only returns false if the query is exactly "power<X" and
155 * current power is greater than X. If X cannot be parsed for an int,
158 bool checkIfQueryForPowerPassed(char * query)
160 if (query && strncmp(query, "power<", strlen("power<")) == 0)
162 char * pointerToOperator = strstr(query, "<");
164 if (pointerToOperator)
166 int powerRequested = atoi(pointerToOperator + 1);
167 if (Light.power > powerRequested)
169 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
179 * Application should validate and process these as desired.
181 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
183 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
184 OIC_LOG(INFO, TAG, PCF("Not processing query"));
188 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
189 OCRepPayload **payload)
191 OCEntityHandlerResult ehResult;
192 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
194 // Empty payload if the query has no match.
197 OCRepPayload *getResp = constructResponse(ehRequest);
200 OIC_LOG(ERROR, TAG, "constructResponse failed");
215 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
216 OCRepPayload** payload)
218 OCEntityHandlerResult ehResult;
219 OCRepPayload *putResp = constructResponse(ehRequest);
223 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
233 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
234 OCEntityHandlerResponse *response, OCRepPayload** payload)
236 OCEntityHandlerResult ehResult = OC_EH_OK;
237 OCRepPayload *respPLPost_light = nullptr;
240 * The entity handler determines how to process a POST request.
241 * Per the REST paradigm, POST can also be used to update representation of existing
242 * resource or create a new resource.
243 * In the sample below, if the POST is for /a/light then a new instance of the Light
244 * resource is created with default representation (if representation is included in
245 * POST payload it can be used as initial values) as long as the instance is
246 * lesser than max new instance count. Once max instance count is reached, POST on
247 * /a/light updated the representation of /a/light (just like PUT)
250 if (ehRequest->resource == Light.handle)
252 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
254 // Create new Light instance
255 char newLightUri[URI_MAXSIZE];
256 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
258 respPLPost_light = OCRepPayloadCreate();
259 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
260 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
262 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
264 OIC_LOG (INFO, TAG, "Created new Light instance\n");
265 gLightInstance[gCurrLightInstance].state = 0;
266 gLightInstance[gCurrLightInstance].power = 0;
267 gCurrLightInstance++;
268 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
269 ehResult = OC_EH_RESOURCE_CREATED;
274 // Update repesentation of /a/light
277 respPLPost_light = constructResponse(ehRequest);
282 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
284 if (ehRequest->resource == gLightInstance[i].handle)
286 gLightInstance[i].state = true;
287 gLightInstance[i].power = 22;
290 respPLPost_light = constructResponse(ehRequest);
295 respPLPost_light = constructResponse(ehRequest);
301 if ((respPLPost_light != NULL))
303 *payload = respPLPost_light;
307 OIC_LOG(INFO, TAG, "Payload was NULL");
308 ehResult = OC_EH_ERROR;
314 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
316 if(ehRequest == NULL)
318 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
321 OCEntityHandlerResult ehResult = OC_EH_OK;
323 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
326 * In the sample below, the application will:
327 * 1a. pass the delete request to the c stack
328 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
329 * (e.g. send observers notification, remove observers...)
330 * 1c. the c stack returns with the result whether the request is fullfilled.
331 * 2. optionally, app removes observers out of its array 'interestedObservers'
334 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
336 //Step 1: Ask stack to do the work.
337 OCStackResult result = OCDeleteResource(ehRequest->resource);
339 if (result == OC_STACK_OK)
341 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
344 //Step 2: clear observers who wanted to observe this resource at the app level.
345 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
347 if (interestedObservers[i].resourceHandle == ehRequest->resource)
349 interestedObservers[i].valid = false;
350 interestedObservers[i].observationId = 0;
351 interestedObservers[i].resourceHandle = NULL;
355 else if (result == OC_STACK_NO_RESOURCE)
357 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
358 ehResult = OC_EH_RESOURCE_DELETED;
362 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
363 ehResult = OC_EH_ERROR;
366 else if (ehRequest->resource != Light.handle)
368 //Let's this app not supporting DELETE on some resources so
369 //consider the DELETE request is received for a non-support resource.
370 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
371 ehResult = OC_EH_FORBIDDEN;
377 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
379 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
381 return OC_EH_RESOURCE_NOT_FOUND;
384 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
386 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
387 ehRequest->obsInfo.obsId);
389 if (!observeThreadStarted)
391 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
392 observeThreadStarted = 1;
394 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
396 if (interestedObservers[i].valid == false)
398 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
399 interestedObservers[i].valid = true;
400 gLightUnderObservation = 1;
406 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
408 bool clientStillObserving = false;
410 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
411 ehRequest->obsInfo.obsId);
412 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
414 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
416 interestedObservers[i].valid = false;
418 if (interestedObservers[i].valid == true)
420 // Even if there is one single client observing we continue notifying entity handler
421 clientStillObserving = true;
424 if (clientStillObserving == false)
425 gLightUnderObservation = 0;
428 OCEntityHandlerResult
429 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
430 OCEntityHandlerRequest *entityHandlerRequest,
432 void* /*callbackParam*/)
434 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
436 OCEntityHandlerResult ehResult = OC_EH_OK;
437 OCEntityHandlerResponse response;
440 if (!entityHandlerRequest)
442 OIC_LOG (ERROR, TAG, "Invalid request pointer");
445 // Initialize certain response fields
446 response.numSendVendorSpecificHeaderOptions = 0;
447 memset(response.sendVendorSpecificHeaderOptions, 0,
448 sizeof response.sendVendorSpecificHeaderOptions);
449 memset(response.resourceUri, 0, sizeof response.resourceUri);
450 OCRepPayload* payload = nullptr;
453 if (flag & OC_REQUEST_FLAG)
455 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
457 if (entityHandlerRequest->resource == NULL)
459 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
460 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
462 else if (OC_REST_GET == entityHandlerRequest->method)
464 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
465 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
467 else if (OC_REST_PUT == entityHandlerRequest->method)
469 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
470 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
472 else if (OC_REST_DELETE == entityHandlerRequest->method)
474 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
475 ehResult = ProcessDeleteRequest (entityHandlerRequest);
479 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
480 entityHandlerRequest->method);
481 ehResult = OC_EH_ERROR;
483 // If the result isn't an error or forbidden, send response
484 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
486 // Format the response. Note this requires some info about the request
487 response.requestHandle = entityHandlerRequest->requestHandle;
488 response.resourceHandle = entityHandlerRequest->resource;
489 response.ehResult = ehResult;
490 response.payload = reinterpret_cast<OCPayload*>(payload);
491 // Indicate that response is NOT in a persistent buffer
492 response.persistentBufferFlag = 0;
495 if (OCDoResponse(&response) != OC_STACK_OK)
497 OIC_LOG(ERROR, TAG, "Error sending response");
498 ehResult = OC_EH_ERROR;
502 if (flag & OC_OBSERVE_FLAG)
504 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
505 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
507 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
509 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
511 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
518 OCEntityHandlerResult
519 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
520 OCEntityHandlerRequest * /*entityHandlerRequest*/,
521 void* /*callbackParam*/)
523 // This is callback is associated with the 2 presence notification
524 // resources. They are non-operational.
528 OCEntityHandlerResult
529 OCEntityHandlerCb (OCEntityHandlerFlag flag,
530 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
532 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
534 OCEntityHandlerResult ehResult = OC_EH_OK;
535 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
538 if (!entityHandlerRequest)
540 OIC_LOG (ERROR, TAG, "Invalid request pointer");
544 // Initialize certain response fields
545 response.numSendVendorSpecificHeaderOptions = 0;
546 memset(response.sendVendorSpecificHeaderOptions,
547 0, sizeof response.sendVendorSpecificHeaderOptions);
548 memset(response.resourceUri, 0, sizeof response.resourceUri);
549 OCRepPayload* payload = nullptr;
551 if (flag & OC_REQUEST_FLAG)
553 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
555 if (OC_REST_GET == entityHandlerRequest->method)
557 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
558 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
560 else if (OC_REST_PUT == entityHandlerRequest->method)
562 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
563 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
565 else if (OC_REST_POST == entityHandlerRequest->method)
567 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
568 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
570 else if (OC_REST_DELETE == entityHandlerRequest->method)
572 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
573 ehResult = ProcessDeleteRequest (entityHandlerRequest);
577 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
578 entityHandlerRequest->method);
579 ehResult = OC_EH_ERROR;
581 // If the result isn't an error or forbidden, send response
582 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
584 // Format the response. Note this requires some info about the request
585 response.requestHandle = entityHandlerRequest->requestHandle;
586 response.resourceHandle = entityHandlerRequest->resource;
587 response.ehResult = ehResult;
588 response.payload = reinterpret_cast<OCPayload*>(payload);
589 // Indicate that response is NOT in a persistent buffer
590 response.persistentBufferFlag = 0;
592 // Handle vendor specific options
593 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
594 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
596 OIC_LOG (INFO, TAG, "Received vendor specific options");
598 OCHeaderOption * rcvdOptions =
599 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
600 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
602 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
604 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
605 ((OCHeaderOption)rcvdOptions[i]).optionID );
607 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
608 MAX_HEADER_OPTION_DATA_LENGTH);
611 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
612 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
613 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
614 sendOptions[0].protocolID = OC_COAP_ID;
615 sendOptions[0].optionID = 2248;
616 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
617 sendOptions[0].optionLength = 10;
618 sendOptions[1].protocolID = OC_COAP_ID;
619 sendOptions[1].optionID = 2600;
620 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
621 sendOptions[1].optionLength = 10;
622 response.numSendVendorSpecificHeaderOptions = 2;
626 if (OCDoResponse(&response) != OC_STACK_OK)
628 OIC_LOG(ERROR, TAG, "Error sending response");
629 ehResult = OC_EH_ERROR;
633 if (flag & OC_OBSERVE_FLAG)
635 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
637 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
639 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
640 ProcessObserveRegister (entityHandlerRequest);
642 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
644 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
645 ProcessObserveDeregister (entityHandlerRequest);
649 OCPayloadDestroy(response.payload);
653 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
654 void handleSigInt(int signum)
656 if (signum == SIGINT)
662 void *ChangeLightRepresentation (void *param)
665 OCStackResult result = OC_STACK_ERROR;
668 uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
669 OCObservationId obsNotify[numNotifies];
675 if (gLightUnderObservation)
677 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
678 if (gObserveNotifyType == 1)
680 // Notify list of observers. Alternate observers on the list will be notified.
682 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
684 if (interestedObservers[i].valid == true)
686 obsNotify[j] = interestedObservers[i].observationId;
691 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
692 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
694 OCRepPayloadDestroy(payload);
696 else if (gObserveNotifyType == 0)
698 // Notifying all observers
699 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
700 if (OC_STACK_NO_OBSERVERS == result)
703 "=======> No more observers exist, stop sending observations");
704 gLightUnderObservation = 0;
709 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
717 void *presenceNotificationGenerator(void *param)
719 uint8_t secondsBeforePresence = 10;
720 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
721 sleep(secondsBeforePresence);
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 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
749 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
753 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
754 presenceNotificationUris[i].c_str());
757 for(int i=0; i<numPresenceResources; i++)
759 if(res == OC_STACK_OK)
761 res = OCDeleteResource(presenceNotificationHandles[i]);
763 if(res != OC_STACK_OK)
765 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
766 "resource %s.", presenceNotificationResources.at(i).c_str());
769 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
770 presenceNotificationUris[i].c_str());
773 OIC_LOG(INFO, TAG, "================ stopping presence");
780 int createLightResource (char *uri, LightResource *lightResource)
784 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
788 lightResource->state = false;
789 lightResource->power= 0;
790 OCStackResult res = OCCreateResource(&(lightResource->handle),
796 OC_DISCOVERABLE|OC_OBSERVABLE);
797 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
802 void DeletePlatformInfo()
804 free (platformInfo.platformID);
805 free (platformInfo.manufacturerName);
806 free (platformInfo.manufacturerUrl);
807 free (platformInfo.modelNumber);
808 free (platformInfo.dateOfManufacture);
809 free (platformInfo.platformVersion);
810 free (platformInfo.operatingSystemVersion);
811 free (platformInfo.hardwareVersion);
812 free (platformInfo.firmwareVersion);
813 free (platformInfo.supportUrl);
814 free (platformInfo.systemTime);
817 void DeleteDeviceInfo()
819 free (deviceInfo.deviceName);
820 free (deviceInfo.specVersion);
821 OCFreeOCStringLL (deviceInfo.dataModelVersions);
824 bool DuplicateString(char** targetString, const char* sourceString)
832 *targetString = (char *) malloc(strlen(sourceString) + 1);
836 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
843 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
844 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
845 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
846 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
851 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
853 return OC_STACK_INVALID_PARAM;
856 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
858 return OC_STACK_INVALID_PARAM;
861 if(!DuplicateString(&platformInfo.platformID, platformID))
866 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
871 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
876 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
881 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
886 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
891 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
896 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
901 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
906 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
911 if(!DuplicateString(&platformInfo.systemTime, systemTime))
921 DeletePlatformInfo();
922 return OC_STACK_ERROR;
925 OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModelVersions)
927 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
929 return OC_STACK_ERROR;
931 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
933 return OC_STACK_ERROR;
935 OCFreeOCStringLL(deviceInfo.dataModelVersions);
936 deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions);
937 if (!deviceInfo.dataModelVersions)
939 return OC_STACK_ERROR;
944 static void PrintUsage()
946 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
947 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
948 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
952 static void jidbound(char *jid)
954 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
958 int main(int argc, char* argv[])
962 char host[] = "localhost";
963 char user[] = "test1";
964 char pass[] = "intel123";
966 OCRAInfo_t rainfo = {};
968 rainfo.hostname = host;
970 rainfo.xmpp_domain = host;
971 rainfo.username = user;
972 rainfo.password = pass;
973 rainfo.resource = empstr;
974 rainfo.user_jid = empstr;
975 rainfo.jidbound = jidbound;
979 while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
984 gObserveNotifyType = atoi(optarg);
988 rainfo.hostname = optarg;
991 rainfo.port = atoi(optarg);
994 rainfo.xmpp_domain = optarg;
997 rainfo.username = optarg;
1000 rainfo.password = optarg;
1003 rainfo.user_jid = optarg;
1006 rainfo.resource = optarg;
1015 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
1022 OCSetRAInfo(&rainfo);
1025 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1027 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1029 OIC_LOG(ERROR, TAG, "OCStack init error");
1032 #ifdef WITH_PRESENCE
1033 if (OCStartPresence(0) != OC_STACK_OK)
1035 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1040 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1042 OCStackResult registrationResult =
1043 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
1044 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1045 firmwareVersion, supportUrl, systemTime);
1047 if (registrationResult != OC_STACK_OK)
1049 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1050 exit (EXIT_FAILURE);
1053 registrationResult = OCSetPlatformInfo(platformInfo);
1055 if (registrationResult != OC_STACK_OK)
1057 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1058 exit (EXIT_FAILURE);
1061 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);
1063 if (registrationResult != OC_STACK_OK)
1065 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1066 exit (EXIT_FAILURE);
1069 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1071 registrationResult = OCSetDeviceInfo(deviceInfo);
1073 if (registrationResult != OC_STACK_OK)
1075 OIC_LOG(INFO, TAG, "Device Registration failed!");
1076 exit (EXIT_FAILURE);
1080 * Declare and create the example resource: Light
1082 createLightResource(gResourceUri, &Light);
1084 // Initialize observations data structure for the resource
1085 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1087 interestedObservers[i].valid = false;
1092 * Create a thread for generating changes that cause presence notifications
1093 * to be sent to clients
1096 #ifdef WITH_PRESENCE
1097 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1100 // Break from loop with Ctrl-C
1101 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1103 DeletePlatformInfo();
1106 signal(SIGINT, handleSigInt);
1110 if (OCProcess() != OC_STACK_OK)
1112 OIC_LOG(ERROR, TAG, "OCStack process error");
1117 if (observeThreadStarted)
1119 pthread_cancel(threadId_observe);
1120 pthread_join(threadId_observe, NULL);
1123 pthread_cancel(threadId_presence);
1124 pthread_join(threadId_presence, NULL);
1126 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1128 if (OCStop() != OC_STACK_OK)
1130 OIC_LOG(ERROR, TAG, "OCStack process error");