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";
88 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
89 // the existence of a known resource
90 const char *resourceTypeName = "core.light";
91 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
93 OCPlatformInfo platformInfo;
94 OCDeviceInfo deviceInfo;
96 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
98 OCRepPayload* payload = OCRepPayloadCreate();
101 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
105 OCRepPayloadSetUri(payload, uri);
106 OCRepPayloadSetPropBool(payload, "state", state);
107 OCRepPayloadSetPropInt(payload, "power", power);
112 //This function takes the request as an input and returns the response
113 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
115 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
117 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
121 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
123 LightResource *currLightResource = &Light;
125 if (ehRequest->resource == gLightInstance[0].handle)
127 currLightResource = &gLightInstance[0];
128 gResourceUri = (char *) "a/light/0";
130 else if (ehRequest->resource == gLightInstance[1].handle)
132 currLightResource = &gLightInstance[1];
133 gResourceUri = (char *) "a/light/1";
136 if(OC_REST_PUT == ehRequest->method)
138 // Get pointer to query
140 if(OCRepPayloadGetPropInt(input, "power", &pow))
142 currLightResource->power =pow;
146 if(OCRepPayloadGetPropBool(input, "state", &state))
148 currLightResource->state = state;
152 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
156 * Very simple example of query parsing.
157 * The query may have multiple filters separated by ';'.
158 * It is upto the entity handler to parse the query for the individual filters,
159 * VALIDATE them and respond as it sees fit.
161 * This function only returns false if the query is exactly "power<X" and
162 * current power is greater than X. If X cannot be parsed for an int,
165 bool checkIfQueryForPowerPassed(char * query)
167 if (query && strncmp(query, "power<", strlen("power<")) == 0)
169 char * pointerToOperator = strstr(query, "<");
171 if (pointerToOperator)
173 int powerRequested = atoi(pointerToOperator + 1);
174 if (Light.power > powerRequested)
176 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
186 * Application should validate and process these as desired.
188 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
190 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
191 OIC_LOG(INFO, TAG, PCF("Not processing query"));
195 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
196 OCRepPayload **payload)
198 OCEntityHandlerResult ehResult;
199 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
201 // Empty payload if the query has no match.
204 OCRepPayload *getResp = constructResponse(ehRequest);
207 OIC_LOG(ERROR, TAG, "constructResponse failed");
222 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
223 OCRepPayload** payload)
225 OCEntityHandlerResult ehResult;
226 OCRepPayload *putResp = constructResponse(ehRequest);
230 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
240 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
241 OCEntityHandlerResponse *response, OCRepPayload** payload)
243 OCEntityHandlerResult ehResult = OC_EH_OK;
244 OCRepPayload *respPLPost_light = nullptr;
247 * The entity handler determines how to process a POST request.
248 * Per the REST paradigm, POST can also be used to update representation of existing
249 * resource or create a new resource.
250 * In the sample below, if the POST is for /a/light then a new instance of the Light
251 * resource is created with default representation (if representation is included in
252 * POST payload it can be used as initial values) as long as the instance is
253 * lesser than max new instance count. Once max instance count is reached, POST on
254 * /a/light updated the representation of /a/light (just like PUT)
257 if (ehRequest->resource == Light.handle)
259 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
261 // Create new Light instance
262 char newLightUri[URI_MAXSIZE];
263 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
265 respPLPost_light = OCRepPayloadCreate();
266 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
267 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
269 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
271 OIC_LOG (INFO, TAG, "Created new Light instance\n");
272 gLightInstance[gCurrLightInstance].state = 0;
273 gLightInstance[gCurrLightInstance].power = 0;
274 gCurrLightInstance++;
275 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
276 ehResult = OC_EH_RESOURCE_CREATED;
281 // Update repesentation of /a/light
284 respPLPost_light = constructResponse(ehRequest);
289 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
291 if (ehRequest->resource == gLightInstance[i].handle)
293 gLightInstance[i].state = true;
294 gLightInstance[i].power = 22;
297 respPLPost_light = constructResponse(ehRequest);
302 respPLPost_light = constructResponse(ehRequest);
308 if ((respPLPost_light != NULL))
310 *payload = respPLPost_light;
314 OIC_LOG(INFO, TAG, "Payload was NULL");
315 ehResult = OC_EH_ERROR;
321 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
323 if(ehRequest == NULL)
325 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
328 OCEntityHandlerResult ehResult = OC_EH_OK;
330 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
333 * In the sample below, the application will:
334 * 1a. pass the delete request to the c stack
335 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
336 * (e.g. send observers notification, remove observers...)
337 * 1c. the c stack returns with the result whether the request is fullfilled.
338 * 2. optionally, app removes observers out of its array 'interestedObservers'
341 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
343 //Step 1: Ask stack to do the work.
344 OCStackResult result = OCDeleteResource(ehRequest->resource);
346 if (result == OC_STACK_OK)
348 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
351 //Step 2: clear observers who wanted to observe this resource at the app level.
352 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
354 if (interestedObservers[i].resourceHandle == ehRequest->resource)
356 interestedObservers[i].valid = false;
357 interestedObservers[i].observationId = 0;
358 interestedObservers[i].resourceHandle = NULL;
362 else if (result == OC_STACK_NO_RESOURCE)
364 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
365 ehResult = OC_EH_RESOURCE_DELETED;
369 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
370 ehResult = OC_EH_ERROR;
373 else if (ehRequest->resource != Light.handle)
375 //Let's this app not supporting DELETE on some resources so
376 //consider the DELETE request is received for a non-support resource.
377 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
378 ehResult = OC_EH_FORBIDDEN;
384 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
386 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
388 return OC_EH_RESOURCE_NOT_FOUND;
391 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
393 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
394 ehRequest->obsInfo.obsId);
396 if (!observeThreadStarted)
398 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
399 observeThreadStarted = 1;
401 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
403 if (interestedObservers[i].valid == false)
405 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
406 interestedObservers[i].valid = true;
407 gLightUnderObservation = 1;
413 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
415 bool clientStillObserving = false;
417 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
418 ehRequest->obsInfo.obsId);
419 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
421 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
423 interestedObservers[i].valid = false;
425 if (interestedObservers[i].valid == true)
427 // Even if there is one single client observing we continue notifying entity handler
428 clientStillObserving = true;
431 if (clientStillObserving == false)
432 gLightUnderObservation = 0;
435 OCEntityHandlerResult
436 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
437 OCEntityHandlerRequest *entityHandlerRequest,
439 void* /*callbackParam*/)
441 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
443 OCEntityHandlerResult ehResult = OC_EH_OK;
444 OCEntityHandlerResponse response;
447 if (!entityHandlerRequest)
449 OIC_LOG (ERROR, TAG, "Invalid request pointer");
452 // Initialize certain response fields
453 response.numSendVendorSpecificHeaderOptions = 0;
454 memset(response.sendVendorSpecificHeaderOptions, 0,
455 sizeof response.sendVendorSpecificHeaderOptions);
456 memset(response.resourceUri, 0, sizeof response.resourceUri);
457 OCRepPayload* payload = nullptr;
460 if (flag & OC_REQUEST_FLAG)
462 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
464 if (entityHandlerRequest->resource == NULL)
466 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
467 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
469 else if (OC_REST_GET == entityHandlerRequest->method)
471 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
472 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
474 else if (OC_REST_PUT == entityHandlerRequest->method)
476 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
477 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
479 else if (OC_REST_DELETE == entityHandlerRequest->method)
481 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
482 ehResult = ProcessDeleteRequest (entityHandlerRequest);
486 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
487 entityHandlerRequest->method);
488 ehResult = OC_EH_ERROR;
490 // If the result isn't an error or forbidden, send response
491 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
493 // Format the response. Note this requires some info about the request
494 response.requestHandle = entityHandlerRequest->requestHandle;
495 response.resourceHandle = entityHandlerRequest->resource;
496 response.ehResult = ehResult;
497 response.payload = reinterpret_cast<OCPayload*>(payload);
498 // Indicate that response is NOT in a persistent buffer
499 response.persistentBufferFlag = 0;
502 if (OCDoResponse(&response) != OC_STACK_OK)
504 OIC_LOG(ERROR, TAG, "Error sending response");
505 ehResult = OC_EH_ERROR;
509 if (flag & OC_OBSERVE_FLAG)
511 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
512 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
514 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
516 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
518 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
525 OCEntityHandlerResult
526 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
527 OCEntityHandlerRequest * /*entityHandlerRequest*/,
528 void* /*callbackParam*/)
530 // This is callback is associated with the 2 presence notification
531 // resources. They are non-operational.
535 OCEntityHandlerResult
536 OCEntityHandlerCb (OCEntityHandlerFlag flag,
537 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
539 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
541 OCEntityHandlerResult ehResult = OC_EH_OK;
542 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
545 if (!entityHandlerRequest)
547 OIC_LOG (ERROR, TAG, "Invalid request pointer");
551 // Initialize certain response fields
552 response.numSendVendorSpecificHeaderOptions = 0;
553 memset(response.sendVendorSpecificHeaderOptions,
554 0, sizeof response.sendVendorSpecificHeaderOptions);
555 memset(response.resourceUri, 0, sizeof response.resourceUri);
556 OCRepPayload* payload = nullptr;
558 if (flag & OC_REQUEST_FLAG)
560 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
562 if (OC_REST_GET == entityHandlerRequest->method)
564 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
565 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
567 else if (OC_REST_PUT == entityHandlerRequest->method)
569 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
570 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
572 else if (OC_REST_POST == entityHandlerRequest->method)
574 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
575 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
577 else if (OC_REST_DELETE == entityHandlerRequest->method)
579 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
580 ehResult = ProcessDeleteRequest (entityHandlerRequest);
584 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
585 entityHandlerRequest->method);
586 ehResult = OC_EH_ERROR;
588 // If the result isn't an error or forbidden, send response
589 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
591 // Format the response. Note this requires some info about the request
592 response.requestHandle = entityHandlerRequest->requestHandle;
593 response.resourceHandle = entityHandlerRequest->resource;
594 response.ehResult = ehResult;
595 response.payload = reinterpret_cast<OCPayload*>(payload);
596 // Indicate that response is NOT in a persistent buffer
597 response.persistentBufferFlag = 0;
599 // Handle vendor specific options
600 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
601 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
603 OIC_LOG (INFO, TAG, "Received vendor specific options");
605 OCHeaderOption * rcvdOptions =
606 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
607 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
609 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
611 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
612 ((OCHeaderOption)rcvdOptions[i]).optionID );
614 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
615 MAX_HEADER_OPTION_DATA_LENGTH);
618 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
619 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
620 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
621 sendOptions[0].protocolID = OC_COAP_ID;
622 sendOptions[0].optionID = 2248;
623 memcpy(sendOptions[0].optionData, option2, sizeof(option2));
624 sendOptions[0].optionLength = 10;
625 sendOptions[1].protocolID = OC_COAP_ID;
626 sendOptions[1].optionID = 2600;
627 memcpy(sendOptions[1].optionData, option3, sizeof(option3));
628 sendOptions[1].optionLength = 10;
629 response.numSendVendorSpecificHeaderOptions = 2;
633 if (OCDoResponse(&response) != OC_STACK_OK)
635 OIC_LOG(ERROR, TAG, "Error sending response");
636 ehResult = OC_EH_ERROR;
640 if (flag & OC_OBSERVE_FLAG)
642 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
644 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
646 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
647 ProcessObserveRegister (entityHandlerRequest);
649 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
651 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
652 ProcessObserveDeregister (entityHandlerRequest);
656 OCPayloadDestroy(response.payload);
660 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
661 void handleSigInt(int signum)
663 if (signum == SIGINT)
669 void *ChangeLightRepresentation (void *param)
672 OCStackResult result = OC_STACK_ERROR;
675 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
681 if (gLightUnderObservation)
683 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
684 if (gObserveNotifyType == 1)
686 // Notify list of observers. Alternate observers on the list will be notified.
688 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
690 if (interestedObservers[i].valid == true)
692 obsNotify[j] = interestedObservers[i].observationId;
697 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
698 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
700 OCRepPayloadDestroy(payload);
702 else if (gObserveNotifyType == 0)
704 // Notifying all observers
705 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
706 if (OC_STACK_NO_OBSERVERS == result)
709 "=======> No more observers exist, stop sending observations");
710 gLightUnderObservation = 0;
715 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
723 void *presenceNotificationGenerator(void *param)
725 uint8_t secondsBeforePresence = 10;
726 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
727 sleep(secondsBeforePresence);
729 OCDoHandle presenceNotificationHandles[numPresenceResources];
730 OCStackResult res = OC_STACK_OK;
732 std::array<std::string, numPresenceResources> presenceNotificationResources { {
733 std::string("core.fan"),
734 std::string("core.led") } };
735 std::array<std::string, numPresenceResources> presenceNotificationUris { {
736 std::string("/a/fan"),
737 std::string("/a/led") } };
739 for(int i=0; i<numPresenceResources; i++)
741 if(res == OC_STACK_OK)
744 res = OCCreateResource(&presenceNotificationHandles[i],
745 presenceNotificationResources.at(i).c_str(),
746 OC_RSRVD_INTERFACE_DEFAULT,
747 presenceNotificationUris.at(i).c_str(),
748 OCNOPEntityHandlerCb,
750 OC_DISCOVERABLE|OC_OBSERVABLE);
752 if(res != OC_STACK_OK)
754 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
755 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
759 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
760 presenceNotificationUris[i].c_str());
763 for(int i=0; i<numPresenceResources; i++)
765 if(res == OC_STACK_OK)
767 res = OCDeleteResource(presenceNotificationHandles[i]);
769 if(res != OC_STACK_OK)
771 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
772 "resource %s.", presenceNotificationResources.at(i).c_str());
775 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
776 presenceNotificationUris[i].c_str());
779 OIC_LOG(INFO, TAG, "================ stopping presence");
786 int createLightResource (char *uri, LightResource *lightResource)
790 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
794 lightResource->state = false;
795 lightResource->power= 0;
796 OCStackResult res = OCCreateResource(&(lightResource->handle),
802 OC_DISCOVERABLE|OC_OBSERVABLE);
803 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
808 void DeletePlatformInfo()
810 free (platformInfo.platformID);
811 free (platformInfo.manufacturerName);
812 free (platformInfo.manufacturerUrl);
813 free (platformInfo.modelNumber);
814 free (platformInfo.dateOfManufacture);
815 free (platformInfo.platformVersion);
816 free (platformInfo.operatingSystemVersion);
817 free (platformInfo.hardwareVersion);
818 free (platformInfo.firmwareVersion);
819 free (platformInfo.supportUrl);
820 free (platformInfo.systemTime);
823 void DeleteDeviceInfo()
825 free (deviceInfo.deviceName);
828 bool DuplicateString(char** targetString, const char* sourceString)
836 *targetString = (char *) malloc(strlen(sourceString) + 1);
840 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
847 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
848 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
849 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
850 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
855 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
857 return OC_STACK_INVALID_PARAM;
860 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
862 return OC_STACK_INVALID_PARAM;
865 if(!DuplicateString(&platformInfo.platformID, platformID))
870 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
875 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
880 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
885 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
890 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
895 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
900 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
905 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
910 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
915 if(!DuplicateString(&platformInfo.systemTime, systemTime))
925 DeletePlatformInfo();
926 return OC_STACK_ERROR;
929 OCStackResult SetDeviceInfo(const char* deviceName)
931 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
933 return OC_STACK_ERROR;
938 static void PrintUsage()
940 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
941 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
942 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
946 static void jidbound(char *jid)
948 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
952 int main(int argc, char* argv[])
956 char host[] = "localhost";
957 char user[] = "test1";
958 char pass[] = "intel123";
960 OCRAInfo_t rainfo = {};
962 rainfo.hostname = host;
964 rainfo.xmpp_domain = host;
965 rainfo.username = user;
966 rainfo.password = pass;
967 rainfo.resource = empstr;
968 rainfo.user_jid = empstr;
969 rainfo.jidbound = jidbound;
973 while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
978 gObserveNotifyType = atoi(optarg);
982 rainfo.hostname = optarg;
985 rainfo.port = atoi(optarg);
988 rainfo.xmpp_domain = optarg;
991 rainfo.username = optarg;
994 rainfo.password = optarg;
997 rainfo.user_jid = optarg;
1000 rainfo.resource = optarg;
1009 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
1016 OCSetRAInfo(&rainfo);
1019 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1021 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1023 OIC_LOG(ERROR, TAG, "OCStack init error");
1026 #ifdef WITH_PRESENCE
1027 if (OCStartPresence(0) != OC_STACK_OK)
1029 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1034 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1036 OCStackResult registrationResult =
1037 SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
1038 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1039 firmwareVersion, supportUrl, systemTime);
1041 if (registrationResult != OC_STACK_OK)
1043 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1044 exit (EXIT_FAILURE);
1047 registrationResult = OCSetPlatformInfo(platformInfo);
1049 if (registrationResult != OC_STACK_OK)
1051 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1052 exit (EXIT_FAILURE);
1055 registrationResult = SetDeviceInfo(deviceName);
1057 if (registrationResult != OC_STACK_OK)
1059 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1060 exit (EXIT_FAILURE);
1063 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1065 registrationResult = OCSetDeviceInfo(deviceInfo);
1067 if (registrationResult != OC_STACK_OK)
1069 OIC_LOG(INFO, TAG, "Device Registration failed!");
1070 exit (EXIT_FAILURE);
1074 * Declare and create the example resource: Light
1076 createLightResource(gResourceUri, &Light);
1078 // Initialize observations data structure for the resource
1079 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1081 interestedObservers[i].valid = false;
1086 * Create a thread for generating changes that cause presence notifications
1087 * to be sent to clients
1090 #ifdef WITH_PRESENCE
1091 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1094 // Break from loop with Ctrl-C
1095 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1097 DeletePlatformInfo();
1100 signal(SIGINT, handleSigInt);
1104 if (OCProcess() != OC_STACK_OK)
1106 OIC_LOG(ERROR, TAG, "OCStack process error");
1111 if (observeThreadStarted)
1113 #ifdef HAVE_PTHREAD_H
1114 pthread_cancel(threadId_observe);
1115 pthread_join(threadId_observe, NULL);
1119 #ifdef HAVE_PTHREAD_H
1120 pthread_cancel(threadId_presence);
1121 pthread_join(threadId_presence, NULL);
1124 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1126 if (OCStop() != OC_STACK_OK)
1128 OIC_LOG(ERROR, TAG, "OCStack process error");