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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #include "iotivity_config.h"
38 #include "oic_malloc.h"
42 #include "ocpayload.h"
46 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
48 const int URI_MAXSIZE = 19;
50 static int gObserveNotifyType = 3;
53 int gLightUnderObservation = 0;
54 #ifdef WITH_PROCESS_EVENT
55 static oc_event processEvent = NULL;
58 static LightResource Light;
59 // This variable determines instance number of the Light resource.
60 // Used by POST method to create a new instance of Light resource.
61 static int gCurrLightInstance = 0;
63 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
65 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
67 pthread_t threadId_observe;
68 pthread_t threadId_presence;
70 static bool observeThreadStarted = false;
73 #define numPresenceResources (2)
76 char *gResourceUri= (char *)"/a/light";
77 const char *dateOfManufacture = "2016-01-15";
78 const char *deviceName = "myDeviceName";
79 const char *deviceUUID = "51b55ddc-ccbb-4cb3-a57f-494eeca13a21";
80 const char *firmwareVersion = "myFirmwareVersion";
81 const char *manufacturerName = "myName";
82 const char *operatingSystemVersion = "myOS";
83 const char *hardwareVersion = "myHardwareVersion";
84 const char *platformID = "0A3E0D6F-DBF5-404E-8719-D6880042463A";
85 const char *manufacturerLink = "https://www.iotivity.org";
86 const char *modelNumber = "myModelNumber";
87 const char *platformVersion = "myPlatformVersion";
88 const char *supportLink = "https://www.iotivity.org";
89 const char *version = "myVersion";
90 const char *systemTime = "2015-05-15T11.04";
91 const char *specVersion = "core.1.1.0";
92 const char *dataModelVersions = "res.1.1.0,sh.1.1.0";
94 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
95 // the existence of a known resource
96 const char *resourceTypeName = "core.light";
97 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
99 OCPlatformInfo platformInfo;
100 OCDeviceInfo deviceInfo;
102 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
104 OCRepPayload* payload = OCRepPayloadCreate();
107 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
111 OCRepPayloadSetUri(payload, uri);
112 OCRepPayloadSetPropBool(payload, "state", state);
113 OCRepPayloadSetPropInt(payload, "power", power);
118 //This function takes the request as an input and returns the response
119 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
121 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
123 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
127 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
129 LightResource *currLightResource = &Light;
131 if (ehRequest->resource == gLightInstance[0].handle)
133 currLightResource = &gLightInstance[0];
134 gResourceUri = (char *) "a/light/0";
136 else if (ehRequest->resource == gLightInstance[1].handle)
138 currLightResource = &gLightInstance[1];
139 gResourceUri = (char *) "a/light/1";
142 if(OC_REST_PUT == ehRequest->method)
144 // Get pointer to query
146 if(OCRepPayloadGetPropInt(input, "power", &pow))
148 currLightResource->power =pow;
152 if(OCRepPayloadGetPropBool(input, "state", &state))
154 currLightResource->state = state;
158 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
162 * Very simple example of query parsing.
163 * The query may have multiple filters separated by ';'.
164 * It is upto the entity handler to parse the query for the individual filters,
165 * VALIDATE them and respond as it sees fit.
167 * This function only returns false if the query is exactly "power<X" and
168 * current power is greater than X. If X cannot be parsed for an int,
171 bool checkIfQueryForPowerPassed(char * query)
173 if (query && strncmp(query, "power<", strlen("power<")) == 0)
175 char * pointerToOperator = strstr(query, "<");
177 if (pointerToOperator)
179 int powerRequested = atoi(pointerToOperator + 1);
180 if (Light.power > powerRequested)
182 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
192 * Application should validate and process these as desired.
194 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
196 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
197 OIC_LOG(INFO, TAG, PCF("Not processing query"));
201 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
202 OCRepPayload **payload)
204 OCEntityHandlerResult ehResult;
205 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
207 // Empty payload if the query has no match.
210 OCRepPayload *getResp = constructResponse(ehRequest);
213 OIC_LOG(ERROR, TAG, "constructResponse failed");
228 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
229 OCRepPayload** payload)
231 OCEntityHandlerResult ehResult;
232 OCRepPayload *putResp = constructResponse(ehRequest);
236 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
246 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
247 OCEntityHandlerResponse *response, OCRepPayload** payload)
249 OCEntityHandlerResult ehResult = OC_EH_OK;
250 OCRepPayload *respPLPost_light = nullptr;
253 * The entity handler determines how to process a POST request.
254 * Per the REST paradigm, POST can also be used to update representation of existing
255 * resource or create a new resource.
256 * In the sample below, if the POST is for /a/light then a new instance of the Light
257 * resource is created with default representation (if representation is included in
258 * POST payload it can be used as initial values) as long as the instance is
259 * lesser than max new instance count. Once max instance count is reached, POST on
260 * /a/light updated the representation of /a/light (just like PUT)
263 if (ehRequest->resource == Light.handle)
265 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
267 // Create new Light instance
268 char newLightUri[URI_MAXSIZE];
269 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
271 respPLPost_light = OCRepPayloadCreate();
272 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
273 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
275 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
277 OIC_LOG (INFO, TAG, "Created new Light instance\n");
278 gLightInstance[gCurrLightInstance].state = 0;
279 gLightInstance[gCurrLightInstance].power = 0;
280 gCurrLightInstance++;
281 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
282 ehResult = OC_EH_RESOURCE_CREATED;
287 // Update repesentation of /a/light
290 respPLPost_light = constructResponse(ehRequest);
295 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
297 if (ehRequest->resource == gLightInstance[i].handle)
299 gLightInstance[i].state = true;
300 gLightInstance[i].power = 22;
303 respPLPost_light = constructResponse(ehRequest);
308 respPLPost_light = constructResponse(ehRequest);
314 if ((respPLPost_light != NULL))
316 *payload = respPLPost_light;
320 OIC_LOG(INFO, TAG, "Payload was NULL");
321 ehResult = OC_EH_ERROR;
327 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
329 if(ehRequest == NULL)
331 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
334 OCEntityHandlerResult ehResult = OC_EH_OK;
336 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
339 * In the sample below, the application will:
340 * 1a. pass the delete request to the c stack
341 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
342 * (e.g. send observers notification, remove observers...)
343 * 1c. the c stack returns with the result whether the request is fullfilled.
344 * 2. optionally, app removes observers out of its array 'interestedObservers'
347 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
349 //Step 1: Ask stack to do the work.
350 OCStackResult result = OCDeleteResource(ehRequest->resource);
352 if (result == OC_STACK_OK)
354 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
357 //Step 2: clear observers who wanted to observe this resource at the app level.
358 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
360 if (interestedObservers[i].resourceHandle == ehRequest->resource)
362 interestedObservers[i].valid = false;
363 interestedObservers[i].observationId = 0;
364 interestedObservers[i].resourceHandle = NULL;
368 else if (result == OC_STACK_NO_RESOURCE)
370 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
371 ehResult = OC_EH_RESOURCE_DELETED;
375 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
376 ehResult = OC_EH_ERROR;
379 else if (ehRequest->resource != Light.handle)
381 //Let's this app not supporting DELETE on some resources so
382 //consider the DELETE request is received for a non-support resource.
383 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
384 ehResult = OC_EH_FORBIDDEN;
390 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
392 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
394 return OC_EH_RESOURCE_NOT_FOUND;
397 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
399 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
400 ehRequest->obsInfo.obsId);
402 if (!observeThreadStarted)
404 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
405 observeThreadStarted = 1;
407 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
409 if (interestedObservers[i].valid == false)
411 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
412 interestedObservers[i].valid = true;
413 gLightUnderObservation = 1;
419 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
421 bool clientStillObserving = false;
423 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
424 ehRequest->obsInfo.obsId);
425 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
427 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
429 interestedObservers[i].valid = false;
431 if (interestedObservers[i].valid == true)
433 // Even if there is one single client observing we continue notifying entity handler
434 clientStillObserving = true;
437 if (clientStillObserving == false)
438 gLightUnderObservation = 0;
441 OCEntityHandlerResult
442 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
443 OCEntityHandlerRequest *entityHandlerRequest,
445 void* /*callbackParam*/)
447 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
449 OCEntityHandlerResult ehResult = OC_EH_OK;
450 OCEntityHandlerResponse response;
453 if (!entityHandlerRequest)
455 OIC_LOG (ERROR, TAG, "Invalid request pointer");
458 // Initialize certain response fields
459 response.numSendVendorSpecificHeaderOptions = 0;
460 memset(response.sendVendorSpecificHeaderOptions, 0,
461 sizeof response.sendVendorSpecificHeaderOptions);
462 memset(response.resourceUri, 0, sizeof response.resourceUri);
463 OCRepPayload* payload = nullptr;
466 if (flag & OC_REQUEST_FLAG)
468 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
470 if (entityHandlerRequest->resource == NULL)
472 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
473 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
475 else if (OC_REST_GET == entityHandlerRequest->method)
477 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
478 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
480 else if (OC_REST_PUT == entityHandlerRequest->method)
482 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
483 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
485 else if (OC_REST_DELETE == entityHandlerRequest->method)
487 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
488 ehResult = ProcessDeleteRequest (entityHandlerRequest);
492 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
493 entityHandlerRequest->method);
494 ehResult = OC_EH_ERROR;
496 // If the result isn't an error or forbidden, send response
497 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
499 // Format the response. Note this requires some info about the request
500 response.requestHandle = entityHandlerRequest->requestHandle;
501 response.resourceHandle = entityHandlerRequest->resource;
502 response.ehResult = ehResult;
503 response.payload = reinterpret_cast<OCPayload*>(payload);
504 // Indicate that response is NOT in a persistent buffer
505 response.persistentBufferFlag = 0;
508 if (OCDoResponse(&response) != OC_STACK_OK)
510 OIC_LOG(ERROR, TAG, "Error sending response");
511 ehResult = OC_EH_ERROR;
515 if (flag & OC_OBSERVE_FLAG)
517 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
518 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
520 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
522 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
524 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
528 OCPayloadDestroy(response.payload);
532 OCEntityHandlerResult
533 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
534 OCEntityHandlerRequest * /*entityHandlerRequest*/,
535 void* /*callbackParam*/)
537 // This is callback is associated with the 2 presence notification
538 // resources. They are non-operational.
542 OCEntityHandlerResult
543 OCEntityHandlerCb (OCEntityHandlerFlag flag,
544 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
546 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
548 OCEntityHandlerResult ehResult = OC_EH_OK;
549 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
552 if (!entityHandlerRequest)
554 OIC_LOG (ERROR, TAG, "Invalid request pointer");
558 // Initialize certain response fields
559 response.numSendVendorSpecificHeaderOptions = 0;
560 memset(response.sendVendorSpecificHeaderOptions,
561 0, sizeof response.sendVendorSpecificHeaderOptions);
562 memset(response.resourceUri, 0, sizeof response.resourceUri);
563 OCRepPayload* payload = nullptr;
565 if (flag & OC_REQUEST_FLAG)
567 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
569 if (OC_REST_GET == entityHandlerRequest->method)
571 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
572 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
574 else if (OC_REST_PUT == entityHandlerRequest->method)
576 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
577 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
579 else if (OC_REST_POST == entityHandlerRequest->method)
581 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
582 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
584 else if (OC_REST_DELETE == entityHandlerRequest->method)
586 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
587 ehResult = ProcessDeleteRequest (entityHandlerRequest);
591 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
592 entityHandlerRequest->method);
593 ehResult = OC_EH_ERROR;
595 // If the result isn't an error or forbidden, send response
596 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
598 // Format the response. Note this requires some info about the request
599 response.requestHandle = entityHandlerRequest->requestHandle;
600 response.resourceHandle = entityHandlerRequest->resource;
601 response.ehResult = ehResult;
602 response.payload = reinterpret_cast<OCPayload*>(payload);
603 // Indicate that response is NOT in a persistent buffer
604 response.persistentBufferFlag = 0;
606 // Handle vendor specific options
607 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
608 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
610 OIC_LOG (INFO, TAG, "Received vendor specific options");
612 OCHeaderOption * rcvdOptions =
613 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
614 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
616 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
618 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
619 ((OCHeaderOption)rcvdOptions[i]).optionID );
621 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
622 MAX_HEADER_OPTION_DATA_LENGTH);
626 OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
627 size_t numOptions = response.numSendVendorSpecificHeaderOptions;
628 // Check if the option header has already existed before adding it in.
629 uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
630 size_t optionDataSize = sizeof(optionData);
631 uint16_t actualDataSize = 0;
632 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
633 response.numSendVendorSpecificHeaderOptions,
638 if (actualDataSize == 0)
640 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
641 uint16_t optionID2 = 2248;
642 size_t optionDataSize2 = sizeof(option2);
643 OCSetHeaderOption(sendOptions,
650 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
651 response.numSendVendorSpecificHeaderOptions,
656 if (actualDataSize == 0)
658 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
659 uint16_t optionID3 = 2600;
660 size_t optionDataSize3 = sizeof(option3);
661 OCSetHeaderOption(sendOptions,
667 response.numSendVendorSpecificHeaderOptions = 2;
671 if (OCDoResponse(&response) != OC_STACK_OK)
673 OIC_LOG(ERROR, TAG, "Error sending response");
674 ehResult = OC_EH_ERROR;
678 if (flag & OC_OBSERVE_FLAG)
680 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
682 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
684 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
685 ProcessObserveRegister (entityHandlerRequest);
687 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
689 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
690 ProcessObserveDeregister (entityHandlerRequest);
694 OCPayloadDestroy(response.payload);
698 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
699 void handleSigInt(int signum)
701 if (signum == SIGINT)
704 #ifdef WITH_PROCESS_EVENT
706 oc_event_signal(processEvent);
711 void *ChangeLightRepresentation (void *param)
714 OCStackResult result = OC_STACK_ERROR;
717 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
723 if (gLightUnderObservation)
725 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
726 if (gObserveNotifyType == 1)
728 // Notify list of observers. Alternate observers on the list will be notified.
730 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
732 if (interestedObservers[i].valid == true)
734 obsNotify[j] = interestedObservers[i].observationId;
739 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
740 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
742 OCRepPayloadDestroy(payload);
744 else if (gObserveNotifyType == 0)
746 // Notifying all observers
747 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
748 if (OC_STACK_NO_OBSERVERS == result)
751 "=======> No more observers exist, stop sending observations");
752 gLightUnderObservation = 0;
757 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
765 void *presenceNotificationGenerator(void *param)
767 uint8_t secondsBeforePresence = 10;
768 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
769 sleep(secondsBeforePresence);
771 OCDoHandle presenceNotificationHandles[numPresenceResources];
772 OCStackResult res = OC_STACK_OK;
774 std::array<std::string, numPresenceResources> presenceNotificationResources { {
775 std::string("core.fan"),
776 std::string("core.led") } };
777 std::array<std::string, numPresenceResources> presenceNotificationUris { {
778 std::string("/a/fan"),
779 std::string("/a/led") } };
781 for(int i=0; i<numPresenceResources; i++)
783 if(res == OC_STACK_OK)
786 res = OCCreateResource(&presenceNotificationHandles[i],
787 presenceNotificationResources.at(i).c_str(),
788 OC_RSRVD_INTERFACE_DEFAULT,
789 presenceNotificationUris.at(i).c_str(),
790 OCNOPEntityHandlerCb,
792 OC_DISCOVERABLE|OC_OBSERVABLE);
794 if(res != OC_STACK_OK)
796 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
797 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
801 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
802 presenceNotificationUris[i].c_str());
805 for(int i=0; i<numPresenceResources; i++)
807 if(res == OC_STACK_OK)
809 res = OCDeleteResource(presenceNotificationHandles[i]);
811 if(res != OC_STACK_OK)
813 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
814 "resource %s.", presenceNotificationResources.at(i).c_str());
817 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
818 presenceNotificationUris[i].c_str());
821 OIC_LOG(INFO, TAG, "================ stopping presence");
828 int createLightResource (char *uri, LightResource *lightResource)
832 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
836 lightResource->state = false;
837 lightResource->power= 0;
838 OCStackResult res = OCCreateResource(&(lightResource->handle),
844 OC_DISCOVERABLE|OC_OBSERVABLE);
845 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
850 void DeletePlatformInfo()
852 free (platformInfo.platformID);
853 free (platformInfo.manufacturerName);
854 free (platformInfo.manufacturerUrl);
855 free (platformInfo.modelNumber);
856 free (platformInfo.dateOfManufacture);
857 free (platformInfo.platformVersion);
858 free (platformInfo.operatingSystemVersion);
859 free (platformInfo.hardwareVersion);
860 free (platformInfo.firmwareVersion);
861 free (platformInfo.supportUrl);
862 free (platformInfo.systemTime);
865 void DeleteDeviceInfo()
867 free (deviceInfo.deviceName);
868 free (deviceInfo.specVersion);
869 OCFreeOCStringLL (deviceInfo.dataModelVersions);
872 bool DuplicateString(char** targetString, const char* sourceString)
880 *targetString = (char *) malloc(strlen(sourceString) + 1);
884 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
891 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
892 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
893 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
894 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
899 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_PLATFORM_NAME_LENGTH))
901 return OC_STACK_INVALID_PARAM;
904 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_PLATFORM_URL_LENGTH))
906 return OC_STACK_INVALID_PARAM;
909 if(!DuplicateString(&platformInfo.platformID, platformID))
914 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
919 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
924 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
929 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
934 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
939 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
944 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
949 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
954 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
959 if(!DuplicateString(&platformInfo.systemTime, systemTime))
969 DeletePlatformInfo();
970 return OC_STACK_ERROR;
973 OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModelVersions)
975 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
977 return OC_STACK_ERROR;
979 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
981 return OC_STACK_ERROR;
983 OCFreeOCStringLL(deviceInfo.dataModelVersions);
984 deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions);
985 if (!deviceInfo.dataModelVersions)
987 return OC_STACK_ERROR;
992 static void PrintUsage()
994 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
995 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
996 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
1000 static void jidbound(char *jid)
1002 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
1006 int main(int argc, char* argv[])
1010 char host[] = "localhost";
1011 char user[] = "test1";
1012 char pass[] = "intel123";
1014 OCRAInfo_t rainfo = {};
1016 rainfo.hostname = host;
1018 rainfo.xmpp_domain = host;
1019 rainfo.username = user;
1020 rainfo.password = pass;
1021 rainfo.resource = empstr;
1022 rainfo.user_jid = empstr;
1023 rainfo.jidbound = jidbound;
1027 while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
1032 gObserveNotifyType = atoi(optarg);
1036 rainfo.hostname = optarg;
1039 rainfo.port = atoi(optarg);
1042 rainfo.xmpp_domain = optarg;
1045 rainfo.username = optarg;
1048 rainfo.password = optarg;
1051 rainfo.user_jid = optarg;
1054 rainfo.resource = optarg;
1063 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
1070 OCSetRAInfo(&rainfo);
1073 #ifdef WITH_PROCESS_EVENT
1074 processEvent = oc_event_new();
1077 OIC_LOG(INFO, TAG, "oc_event_new failed!");
1078 exit (EXIT_FAILURE);
1082 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1084 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1086 OIC_LOG(ERROR, TAG, "OCStack init error");
1089 #ifdef WITH_PRESENCE
1090 if (OCStartPresence(0) != OC_STACK_OK)
1092 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1097 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1099 OCStackResult registrationResult =
1100 SetPlatformInfo(platformID, manufacturerName, manufacturerLink, modelNumber,
1101 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1102 firmwareVersion, supportLink, systemTime);
1104 if (registrationResult != OC_STACK_OK)
1106 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1107 exit (EXIT_FAILURE);
1110 registrationResult = OCSetPlatformInfo(platformInfo);
1112 if (registrationResult != OC_STACK_OK)
1114 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1115 exit (EXIT_FAILURE);
1118 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);
1120 if (registrationResult != OC_STACK_OK)
1122 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1123 exit (EXIT_FAILURE);
1126 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1128 registrationResult = OCSetDeviceInfo(deviceInfo);
1130 if (registrationResult != OC_STACK_OK)
1132 OIC_LOG(INFO, TAG, "Device Registration failed!");
1133 exit (EXIT_FAILURE);
1136 #ifdef WITH_PROCESS_EVENT
1137 OCRegisterProcessEvent(processEvent);
1141 * Declare and create the example resource: Light
1143 createLightResource(gResourceUri, &Light);
1145 // Initialize observations data structure for the resource
1146 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1148 interestedObservers[i].valid = false;
1153 * Create a thread for generating changes that cause presence notifications
1154 * to be sent to clients
1157 #ifdef WITH_PRESENCE
1158 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1161 // Break from loop with Ctrl-C
1162 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1164 DeletePlatformInfo();
1167 signal(SIGINT, handleSigInt);
1171 #ifdef WITH_PROCESS_EVENT
1172 uint32_t nextEventTime;
1173 if (OCProcessEvent(&nextEventTime) != OC_STACK_OK)
1175 OIC_LOG(ERROR, TAG, "OCStack process error");
1178 oc_event_wait_for(processEvent, nextEventTime);
1180 if (OCProcess() != OC_STACK_OK)
1182 OIC_LOG(ERROR, TAG, "OCStack process error");
1188 if (observeThreadStarted)
1190 #ifdef HAVE_PTHREAD_H
1191 pthread_cancel(threadId_observe);
1192 pthread_join(threadId_observe, NULL);
1196 #ifdef HAVE_PTHREAD_H
1197 pthread_cancel(threadId_presence);
1198 pthread_join(threadId_presence, NULL);
1201 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1203 if (OCStop() != OC_STACK_OK)
1205 OIC_LOG(ERROR, TAG, "OCStack process error");
1208 #ifdef WITH_PROCESS_EVENT
1211 oc_event_free(processEvent);
1212 processEvent = NULL;