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"
45 #include "oic_string.h"
47 #define VERIFY_SUCCESS(op) \
49 if (op != OC_STACK_OK) \
51 OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); \
56 // string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
58 const int URI_MAXSIZE = 19;
60 static int gObserveNotifyType = 3;
61 static int gResourceCreateType = ENDPOINT_OPT_NONE;
64 int gLightUnderObservation = 0;
66 static LightResource Light;
67 // This variable determines instance number of the Light resource.
68 // Used by POST method to create a new instance of Light resource.
69 static int gCurrLightInstance = 0;
71 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
73 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
75 pthread_t threadId_observe;
76 pthread_t threadId_presence;
78 static bool observeThreadStarted = false;
81 #define NUM_PRESENCE_RESOURCES 2
84 char *gResourceUri = (char *)"/a/light";
85 const char *dateOfManufacture = "2016-01-15";
86 const char *deviceName = "myDeviceName";
87 const char *deviceUUID = "51b55ddc-ccbb-4cb3-a57f-494eeca13a21";
88 const char *firmwareVersion = "myFirmwareVersion";
89 const char *manufacturerName = "myName";
90 const char *operatingSystemVersion = "myOS";
91 const char *hardwareVersion = "myHardwareVersion";
92 const char *platformID = "0A3E0D6F-DBF5-404E-8719-D6880042463A";
93 const char *protocolIndependentID = "6ef9211d-2d5c-401e-8e5d-4b3af48a054f";
94 const char *manufacturerLink = "https://www.iotivity.org";
95 const char *modelNumber = "myModelNumber";
96 const char *platformVersion = "myPlatformVersion";
97 const char *supportLink = "https://www.iotivity.org";
98 const char *version = "myVersion";
99 const char *systemTime = "2015-05-15T11.04";
100 const char *specVersion = "core.1.1.0";
101 const char *dataModelVersions = "res.1.1.0,sh.1.1.0";
102 const char *deviceType = "oic.d.tv";
104 OCPlatformInfo platformInfo;
106 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
108 OCRepPayload* payload = OCRepPayloadCreate();
111 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
115 OCRepPayloadSetUri(payload, uri);
116 OCRepPayloadSetPropBool(payload, "state", state);
117 OCRepPayloadSetPropInt(payload, "power", power);
122 //This function takes the request as an input and returns the response
123 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
125 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
127 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
131 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
133 LightResource *currLightResource = &Light;
135 if (ehRequest->resource == gLightInstance[0].handle)
137 currLightResource = &gLightInstance[0];
138 gResourceUri = (char *) "a/light/0";
140 else if (ehRequest->resource == gLightInstance[1].handle)
142 currLightResource = &gLightInstance[1];
143 gResourceUri = (char *) "a/light/1";
146 if(OC_REST_PUT == ehRequest->method)
148 // Get pointer to query
150 if(OCRepPayloadGetPropInt(input, "power", &pow))
152 currLightResource->power =pow;
156 if(OCRepPayloadGetPropBool(input, "state", &state))
158 currLightResource->state = state;
162 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
166 * Very simple example of query parsing.
167 * The query may have multiple filters separated by ';'.
168 * It is upto the entity handler to parse the query for the individual filters,
169 * VALIDATE them and respond as it sees fit.
171 * This function only returns false if the query is exactly "power<X" and
172 * current power is greater than X. If X cannot be parsed for an int,
175 bool checkIfQueryForPowerPassed(char * query)
177 if (query && strncmp(query, "power<", strlen("power<")) == 0)
179 char * pointerToOperator = strstr(query, "<");
181 if (pointerToOperator)
183 int powerRequested = atoi(pointerToOperator + 1);
184 if (Light.power > powerRequested)
186 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power,
196 * Application should validate and process these as desired.
198 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
200 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
201 OIC_LOG(INFO, TAG, PCF("Not processing query"));
205 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
206 OCRepPayload **payload)
208 OCEntityHandlerResult ehResult;
209 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
211 // Empty payload if the query has no match.
214 OCRepPayload *getResp = constructResponse(ehRequest);
217 OIC_LOG(ERROR, TAG, "constructResponse failed");
232 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
233 OCRepPayload** payload)
235 OCEntityHandlerResult ehResult;
236 OCRepPayload *putResp = constructResponse(ehRequest);
240 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
250 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
251 OCEntityHandlerResponse *response, OCRepPayload** payload)
253 OCEntityHandlerResult ehResult = OC_EH_OK;
254 OCRepPayload *respPLPost_light = nullptr;
257 * The entity handler determines how to process a POST request.
258 * Per the REST paradigm, POST can also be used to update representation of existing
259 * resource or create a new resource.
260 * In the sample below, if the POST is for /a/light then a new instance of the Light
261 * resource is created with default representation (if representation is included in
262 * POST payload it can be used as initial values) as long as the instance is
263 * lesser than max new instance count. Once max instance count is reached, POST on
264 * /a/light updated the representation of /a/light (just like PUT)
267 if (ehRequest->resource == Light.handle)
269 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
271 // Create new Light instance
272 char newLightUri[URI_MAXSIZE];
273 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
275 respPLPost_light = OCRepPayloadCreate();
276 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
277 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
279 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
281 OIC_LOG (INFO, TAG, "Created new Light instance\n");
282 gLightInstance[gCurrLightInstance].state = 0;
283 gLightInstance[gCurrLightInstance].power = 0;
284 gCurrLightInstance++;
285 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
286 ehResult = OC_EH_RESOURCE_CREATED;
291 // Update repesentation of /a/light
294 respPLPost_light = constructResponse(ehRequest);
299 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
301 if (ehRequest->resource == gLightInstance[i].handle)
303 gLightInstance[i].state = true;
304 gLightInstance[i].power = 22;
307 respPLPost_light = constructResponse(ehRequest);
312 respPLPost_light = constructResponse(ehRequest);
318 if ((respPLPost_light != NULL))
320 *payload = respPLPost_light;
324 OIC_LOG(INFO, TAG, "Payload was NULL");
325 ehResult = OC_EH_ERROR;
331 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
333 if(ehRequest == NULL)
335 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
338 OCEntityHandlerResult ehResult = OC_EH_OK;
340 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
343 * In the sample below, the application will:
344 * 1a. pass the delete request to the c stack
345 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
346 * (e.g. send observers notification, remove observers...)
347 * 1c. the c stack returns with the result whether the request is fullfilled.
348 * 2. optionally, app removes observers out of its array 'interestedObservers'
351 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
353 //Step 1: Ask stack to do the work.
354 OCStackResult result = OCDeleteResource(ehRequest->resource);
356 if (result == OC_STACK_OK)
358 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
361 //Step 2: clear observers who wanted to observe this resource at the app level.
362 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
364 if (interestedObservers[i].resourceHandle == ehRequest->resource)
366 interestedObservers[i].valid = false;
367 interestedObservers[i].observationId = 0;
368 interestedObservers[i].resourceHandle = NULL;
372 else if (result == OC_STACK_NO_RESOURCE)
374 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
375 ehResult = OC_EH_RESOURCE_DELETED;
379 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
380 ehResult = OC_EH_ERROR;
383 else if (ehRequest->resource != Light.handle)
385 //Let's this app not supporting DELETE on some resources so
386 //consider the DELETE request is received for a non-support resource.
387 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
388 ehResult = OC_EH_FORBIDDEN;
394 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
396 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
398 return OC_EH_RESOURCE_NOT_FOUND;
401 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
403 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
404 ehRequest->obsInfo.obsId);
406 if (!observeThreadStarted)
408 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
409 observeThreadStarted = 1;
411 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
413 if (interestedObservers[i].valid == false)
415 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
416 interestedObservers[i].valid = true;
417 gLightUnderObservation = 1;
423 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
425 bool clientStillObserving = false;
427 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
428 ehRequest->obsInfo.obsId);
429 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
431 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
433 interestedObservers[i].valid = false;
435 if (interestedObservers[i].valid == true)
437 // Even if there is one single client observing we continue notifying entity handler
438 clientStillObserving = true;
441 if (clientStillObserving == false)
443 gLightUnderObservation = 0;
447 OCEntityHandlerResult
448 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
449 OCEntityHandlerRequest *entityHandlerRequest,
451 void* /*callbackParam*/)
453 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
455 OCEntityHandlerResult ehResult = OC_EH_OK;
456 OCEntityHandlerResponse response;
459 if (!entityHandlerRequest)
461 OIC_LOG (ERROR, TAG, "Invalid request pointer");
464 // Initialize certain response fields
465 response.numSendVendorSpecificHeaderOptions = 0;
466 memset(response.sendVendorSpecificHeaderOptions, 0,
467 sizeof response.sendVendorSpecificHeaderOptions);
468 memset(response.resourceUri, 0, sizeof response.resourceUri);
469 OCRepPayload* payload = nullptr;
472 if (flag & OC_REQUEST_FLAG)
474 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
476 if (entityHandlerRequest->resource == NULL)
478 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
479 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
481 else if (OC_REST_GET == entityHandlerRequest->method)
483 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
484 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
486 else if (OC_REST_PUT == entityHandlerRequest->method)
488 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
489 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
491 else if (OC_REST_DELETE == entityHandlerRequest->method)
493 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
494 ehResult = ProcessDeleteRequest (entityHandlerRequest);
498 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
499 entityHandlerRequest->method);
500 ehResult = OC_EH_ERROR;
502 // If the result isn't an error or forbidden, send response
503 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
505 // Format the response. Note this requires some info about the request
506 response.requestHandle = entityHandlerRequest->requestHandle;
507 response.resourceHandle = entityHandlerRequest->resource;
508 response.ehResult = ehResult;
509 response.payload = reinterpret_cast<OCPayload*>(payload);
510 // Indicate that response is NOT in a persistent buffer
511 response.persistentBufferFlag = 0;
514 if (OCDoResponse(&response) != OC_STACK_OK)
516 OIC_LOG(ERROR, TAG, "Error sending response");
517 ehResult = OC_EH_ERROR;
521 if (flag & OC_OBSERVE_FLAG)
523 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
524 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
526 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
528 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
530 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
534 OCPayloadDestroy(response.payload);
538 OCEntityHandlerResult
539 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
540 OCEntityHandlerRequest * /*entityHandlerRequest*/,
541 void* /*callbackParam*/)
543 // This is callback is associated with the 2 presence notification
544 // resources. They are non-operational.
548 OCEntityHandlerResult
549 OCEntityHandlerCb (OCEntityHandlerFlag flag,
550 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
552 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
554 OCEntityHandlerResult ehResult = OC_EH_OK;
555 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
558 if (!entityHandlerRequest)
560 OIC_LOG (ERROR, TAG, "Invalid request pointer");
564 // Initialize certain response fields
565 response.numSendVendorSpecificHeaderOptions = 0;
566 memset(response.sendVendorSpecificHeaderOptions,
567 0, sizeof response.sendVendorSpecificHeaderOptions);
568 memset(response.resourceUri, 0, sizeof response.resourceUri);
569 OCRepPayload* payload = nullptr;
571 if (flag & OC_REQUEST_FLAG)
573 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
575 if (OC_REST_GET == entityHandlerRequest->method)
577 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
578 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
580 else if (OC_REST_PUT == entityHandlerRequest->method)
582 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
583 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
585 else if (OC_REST_POST == entityHandlerRequest->method)
587 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
588 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
590 else if (OC_REST_DELETE == entityHandlerRequest->method)
592 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
593 ehResult = ProcessDeleteRequest (entityHandlerRequest);
597 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
598 entityHandlerRequest->method);
599 ehResult = OC_EH_ERROR;
601 // If the result isn't an error or forbidden, send response
602 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
604 // Format the response. Note this requires some info about the request
605 response.requestHandle = entityHandlerRequest->requestHandle;
606 response.resourceHandle = entityHandlerRequest->resource;
607 response.ehResult = ehResult;
608 response.payload = reinterpret_cast<OCPayload*>(payload);
609 // Indicate that response is NOT in a persistent buffer
610 response.persistentBufferFlag = 0;
612 // Handle vendor specific options
613 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
614 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
616 OIC_LOG (INFO, TAG, "Received vendor specific options");
618 OCHeaderOption * rcvdOptions =
619 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
620 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
622 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
624 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
625 ((OCHeaderOption)rcvdOptions[i]).optionID );
627 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
628 MAX_HEADER_OPTION_DATA_LENGTH);
632 OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
633 size_t numOptions = response.numSendVendorSpecificHeaderOptions;
634 // Check if the option header has already existed before adding it in.
635 uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
636 size_t optionDataSize = sizeof(optionData);
637 uint16_t actualDataSize = 0;
638 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
639 response.numSendVendorSpecificHeaderOptions,
644 if (actualDataSize == 0)
646 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
647 uint16_t optionID2 = 2248;
648 size_t optionDataSize2 = sizeof(option2);
649 OCSetHeaderOption(sendOptions,
656 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
657 response.numSendVendorSpecificHeaderOptions,
662 if (actualDataSize == 0)
664 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
665 uint16_t optionID3 = 2600;
666 size_t optionDataSize3 = sizeof(option3);
667 OCSetHeaderOption(sendOptions,
673 response.numSendVendorSpecificHeaderOptions = 2;
677 if (OCDoResponse(&response) != OC_STACK_OK)
679 OIC_LOG(ERROR, TAG, "Error sending response");
680 ehResult = OC_EH_ERROR;
684 if (flag & OC_OBSERVE_FLAG)
686 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
688 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
690 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
691 ProcessObserveRegister (entityHandlerRequest);
693 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
695 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
696 ProcessObserveDeregister (entityHandlerRequest);
700 OCPayloadDestroy(response.payload);
704 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
705 void handleSigInt(int signum)
707 if (signum == SIGINT)
713 void *ChangeLightRepresentation (void *param)
716 OCStackResult result = OC_STACK_ERROR;
719 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
725 if (gLightUnderObservation)
727 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
728 if (gObserveNotifyType == 1)
730 // Notify list of observers. Alternate observers on the list will be notified.
732 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
734 if (interestedObservers[i].valid == true)
736 obsNotify[j] = interestedObservers[i].observationId;
741 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
742 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
744 OCRepPayloadDestroy(payload);
746 else if (gObserveNotifyType == 0)
748 // Notifying all observers
749 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
750 if (OC_STACK_NO_OBSERVERS == result)
753 "=======> No more observers exist, stop sending observations");
754 gLightUnderObservation = 0;
759 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
767 void *presenceNotificationGenerator(void *param)
769 uint8_t secondsBeforePresence = 10;
770 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
771 sleep(secondsBeforePresence);
773 OCDoHandle presenceNotificationHandles[NUM_PRESENCE_RESOURCES];
774 OCStackResult res = OC_STACK_OK;
776 std::array<std::string, NUM_PRESENCE_RESOURCES> presenceNotificationResources { {
777 std::string("core.fan"),
778 std::string("core.led") } };
779 std::array<std::string, NUM_PRESENCE_RESOURCES> presenceNotificationUris { {
780 std::string("/a/fan"),
781 std::string("/a/led") } };
783 for(int i=0; i<NUM_PRESENCE_RESOURCES; i++)
785 if(res == OC_STACK_OK)
788 res = OCCreateResource(&presenceNotificationHandles[i],
789 presenceNotificationResources.at(i).c_str(),
790 OC_RSRVD_INTERFACE_DEFAULT,
791 presenceNotificationUris.at(i).c_str(),
792 OCNOPEntityHandlerCb,
794 OC_DISCOVERABLE|OC_OBSERVABLE);
796 if(res != OC_STACK_OK)
798 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
799 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
803 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
804 presenceNotificationUris[i].c_str());
807 for(int i=0; i<NUM_PRESENCE_RESOURCES; i++)
809 if(res == OC_STACK_OK)
811 res = OCDeleteResource(presenceNotificationHandles[i]);
813 if(res != OC_STACK_OK)
815 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
816 "resource %s.", presenceNotificationResources.at(i).c_str());
819 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
820 presenceNotificationUris[i].c_str());
823 OIC_LOG(INFO, TAG, "================ stopping presence");
830 int createLightResource (char *uri, LightResource *lightResource)
834 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
838 lightResource->state = false;
839 lightResource->power= 0;
840 OCTpsSchemeFlags endpointFlags = OC_NO_TPS;
841 switch (gResourceCreateType)
843 case DISPLAY_SUPPORTED_EPS_FLAG:
844 case CREATE_RESOURCE_OC_ALL:
845 // same as OCCreateResource(args...)
846 endpointFlags = OC_ALL;
849 case CREATE_RESOURCE_OC_COAP:
850 endpointFlags = OC_COAP;
854 case CREATE_RESOURCE_OC_COAP_TCP:
855 endpointFlags = OC_COAP_TCP;
858 case CREATE_RESOURCE_OC_COAP_WITH_TCP:
859 endpointFlags = (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP);
863 endpointFlags = OC_ALL;
866 OCStackResult res = OCCreateResourceWithEp(&(lightResource->handle),
872 OC_DISCOVERABLE|OC_OBSERVABLE,
875 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
880 void DeletePlatformInfo()
882 free(platformInfo.platformID);
883 free(platformInfo.manufacturerName);
884 free(platformInfo.manufacturerUrl);
885 free(platformInfo.modelNumber);
886 free(platformInfo.dateOfManufacture);
887 free(platformInfo.platformVersion);
888 free(platformInfo.operatingSystemVersion);
889 free(platformInfo.hardwareVersion);
890 free(platformInfo.firmwareVersion);
891 free(platformInfo.supportUrl);
892 free(platformInfo.systemTime);
895 bool DuplicateString(char** targetString, const char* sourceString)
903 *targetString = (char *) malloc(strlen(sourceString) + 1);
907 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
914 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
915 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
916 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
917 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
922 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_PLATFORM_NAME_LENGTH))
924 return OC_STACK_INVALID_PARAM;
927 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_PLATFORM_URL_LENGTH))
929 return OC_STACK_INVALID_PARAM;
932 if(!DuplicateString(&platformInfo.platformID, platformID))
937 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
942 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
947 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
952 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
957 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
962 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
967 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
972 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
977 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
982 if(!DuplicateString(&platformInfo.systemTime, systemTime))
992 DeletePlatformInfo();
993 return OC_STACK_ERROR;
996 OCStackResult SetDeviceInfo()
998 OCResourceHandle resourceHandle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
999 if (resourceHandle == NULL)
1001 OIC_LOG(ERROR, TAG, "Device Resource does not exist.");
1005 VERIFY_SUCCESS(OCBindResourceTypeToResource(resourceHandle, deviceType));
1006 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, deviceName));
1007 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, specVersion));
1008 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION,
1009 dataModelVersions));
1010 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_PROTOCOL_INDEPENDENT_ID,
1011 protocolIndependentID));
1013 OIC_LOG(INFO, TAG, "Device information initialized successfully.");
1017 return OC_STACK_ERROR;
1020 static void PrintUsage()
1022 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
1023 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
1024 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
1025 OIC_LOG(INFO, TAG, "-e 0 : Display supported endpoint flags");
1026 OIC_LOG(INFO, TAG, "-e 1 : Create resource without endpoint flags");
1027 OIC_LOG(INFO, TAG, "-e 2 : Create resource with endpoint flag OC_COAP");
1029 OIC_LOG(INFO, TAG, "-e 3 : Create resource with endpoint flag OC_COAP_TCP");
1030 OIC_LOG(INFO, TAG, "-e 4 : Create resource with endpoint flag OC_COAP | OC_COAP_TCP");
1035 static void jidbound(char *jid)
1037 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
1041 int main(int argc, char* argv[])
1045 char host[] = "localhost";
1046 char user[] = "test1";
1047 char pass[] = "intel123";
1049 OCRAInfo_t rainfo = {};
1051 rainfo.hostname = host;
1053 rainfo.xmpp_domain = host;
1054 rainfo.username = user;
1055 rainfo.password = pass;
1056 rainfo.resource = empstr;
1057 rainfo.user_jid = empstr;
1058 rainfo.jidbound = jidbound;
1062 while ((opt = getopt(argc, argv, "o:e:s:p:d:u:w:r:j:")) != -1)
1067 gObserveNotifyType = atoi(optarg);
1070 gResourceCreateType = atoi(optarg);
1074 rainfo.hostname = optarg;
1077 rainfo.port = atoi(optarg);
1080 rainfo.xmpp_domain = optarg;
1083 rainfo.username = optarg;
1086 rainfo.password = optarg;
1089 rainfo.user_jid = optarg;
1092 rainfo.resource = optarg;
1101 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) &&
1102 gResourceCreateType == ENDPOINT_OPT_NONE)
1108 if (gResourceCreateType < DISPLAY_SUPPORTED_EPS_FLAG ||
1109 gResourceCreateType > ENDPOINT_OPT_NONE)
1116 OCSetRAInfo(&rainfo);
1119 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1121 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1123 OIC_LOG(ERROR, TAG, "OCStack init error");
1126 #ifdef WITH_PRESENCE
1127 if (OCStartPresence(0) != OC_STACK_OK)
1129 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1134 if (DISPLAY_SUPPORTED_EPS_FLAG == gResourceCreateType)
1136 char strBuff[SAMPLE_MAX_STR_BUFF_SIZE] = {0};
1137 OCTpsSchemeFlags deviceFlags = OCGetSupportedEndpointTpsFlags();
1139 if (deviceFlags & OC_COAP)
1141 OICStrcat(strBuff, sizeof(strBuff), "OC_COAP");
1143 if (deviceFlags & OC_COAPS)
1145 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS");
1148 if (deviceFlags & OC_COAP_TCP)
1150 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_TCP");
1152 if (deviceFlags & OC_COAPS_TCP)
1154 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS_TCP");
1158 if (deviceFlags & OC_COAP_RFCOMM)
1160 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_RFCOMM");
1163 OIC_LOG_V(INFO, TAG, "Endpoint flag %s is supported", strBuff);
1167 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1169 OCStackResult registrationResult =
1170 SetPlatformInfo(platformID, manufacturerName, manufacturerLink, modelNumber,
1171 dateOfManufacture, platformVersion, operatingSystemVersion,
1172 hardwareVersion, firmwareVersion, supportLink, systemTime);
1174 if (registrationResult != OC_STACK_OK)
1176 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1177 exit (EXIT_FAILURE);
1180 registrationResult = OCSetPlatformInfo(platformInfo);
1182 if (registrationResult != OC_STACK_OK)
1184 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1185 exit (EXIT_FAILURE);
1188 registrationResult = SetDeviceInfo();
1190 if (registrationResult != OC_STACK_OK)
1192 OIC_LOG(INFO, TAG, "Device Registration failed!");
1193 exit (EXIT_FAILURE);
1197 * Declare and create the example resource: Light
1199 createLightResource(gResourceUri, &Light);
1201 // Initialize observations data structure for the resource
1202 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1204 interestedObservers[i].valid = false;
1209 * Create a thread for generating changes that cause presence notifications
1210 * to be sent to clients
1212 #ifdef WITH_PRESENCE
1213 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1216 // Break from loop with Ctrl-C
1217 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1219 DeletePlatformInfo();
1221 signal(SIGINT, handleSigInt);
1225 if (OCProcess() != OC_STACK_OK)
1227 OIC_LOG(ERROR, TAG, "OCStack process error");
1232 if (observeThreadStarted)
1234 #ifdef HAVE_PTHREAD_H
1235 pthread_cancel(threadId_observe);
1236 pthread_join(threadId_observe, NULL);
1240 #ifdef HAVE_PTHREAD_H
1241 pthread_cancel(threadId_presence);
1242 pthread_join(threadId_presence, NULL);
1245 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1247 if (OCStop() != OC_STACK_OK)
1249 OIC_LOG(ERROR, TAG, "OCStack process error");