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 *manufacturerLink = "https://www.iotivity.org";
94 const char *modelNumber = "myModelNumber";
95 const char *platformVersion = "myPlatformVersion";
96 const char *supportLink = "https://www.iotivity.org";
97 const char *version = "myVersion";
98 const char *systemTime = "2015-05-15T11.04";
99 const char *specVersion = "core.1.1.0";
100 const char *dataModelVersions = "res.1.1.0,sh.1.1.0";
101 const char *deviceType = "oic.d.tv";
103 OCPlatformInfo platformInfo;
105 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
107 OCRepPayload* payload = OCRepPayloadCreate();
110 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
114 OCRepPayloadSetUri(payload, uri);
115 OCRepPayloadSetPropBool(payload, "state", state);
116 OCRepPayloadSetPropInt(payload, "power", power);
121 //This function takes the request as an input and returns the response
122 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
124 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
126 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
130 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
132 LightResource *currLightResource = &Light;
134 if (ehRequest->resource == gLightInstance[0].handle)
136 currLightResource = &gLightInstance[0];
137 gResourceUri = (char *) "a/light/0";
139 else if (ehRequest->resource == gLightInstance[1].handle)
141 currLightResource = &gLightInstance[1];
142 gResourceUri = (char *) "a/light/1";
145 if(OC_REST_PUT == ehRequest->method)
147 // Get pointer to query
149 if(OCRepPayloadGetPropInt(input, "power", &pow))
151 currLightResource->power =pow;
155 if(OCRepPayloadGetPropBool(input, "state", &state))
157 currLightResource->state = state;
161 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
165 * Very simple example of query parsing.
166 * The query may have multiple filters separated by ';'.
167 * It is upto the entity handler to parse the query for the individual filters,
168 * VALIDATE them and respond as it sees fit.
170 * This function only returns false if the query is exactly "power<X" and
171 * current power is greater than X. If X cannot be parsed for an int,
174 bool checkIfQueryForPowerPassed(char * query)
176 if (query && strncmp(query, "power<", strlen("power<")) == 0)
178 char * pointerToOperator = strstr(query, "<");
180 if (pointerToOperator)
182 int powerRequested = atoi(pointerToOperator + 1);
183 if (Light.power > powerRequested)
185 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power,
195 * Application should validate and process these as desired.
197 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
199 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
200 OIC_LOG(INFO, TAG, PCF("Not processing query"));
204 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
205 OCRepPayload **payload)
207 OCEntityHandlerResult ehResult;
208 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
210 // Empty payload if the query has no match.
213 OCRepPayload *getResp = constructResponse(ehRequest);
216 OIC_LOG(ERROR, TAG, "constructResponse failed");
231 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
232 OCRepPayload** payload)
234 OCEntityHandlerResult ehResult;
235 OCRepPayload *putResp = constructResponse(ehRequest);
239 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
249 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
250 OCEntityHandlerResponse *response, OCRepPayload** payload)
252 OCEntityHandlerResult ehResult = OC_EH_OK;
253 OCRepPayload *respPLPost_light = nullptr;
256 * The entity handler determines how to process a POST request.
257 * Per the REST paradigm, POST can also be used to update representation of existing
258 * resource or create a new resource.
259 * In the sample below, if the POST is for /a/light then a new instance of the Light
260 * resource is created with default representation (if representation is included in
261 * POST payload it can be used as initial values) as long as the instance is
262 * lesser than max new instance count. Once max instance count is reached, POST on
263 * /a/light updated the representation of /a/light (just like PUT)
266 if (ehRequest->resource == Light.handle)
268 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
270 // Create new Light instance
271 char newLightUri[URI_MAXSIZE];
272 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
274 respPLPost_light = OCRepPayloadCreate();
275 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
276 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
278 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
280 OIC_LOG (INFO, TAG, "Created new Light instance\n");
281 gLightInstance[gCurrLightInstance].state = 0;
282 gLightInstance[gCurrLightInstance].power = 0;
283 gCurrLightInstance++;
284 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
285 ehResult = OC_EH_RESOURCE_CREATED;
290 // Update repesentation of /a/light
293 respPLPost_light = constructResponse(ehRequest);
298 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
300 if (ehRequest->resource == gLightInstance[i].handle)
302 gLightInstance[i].state = true;
303 gLightInstance[i].power = 22;
306 respPLPost_light = constructResponse(ehRequest);
311 respPLPost_light = constructResponse(ehRequest);
317 if ((respPLPost_light != NULL))
319 *payload = respPLPost_light;
323 OIC_LOG(INFO, TAG, "Payload was NULL");
324 ehResult = OC_EH_ERROR;
330 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
332 if(ehRequest == NULL)
334 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
337 OCEntityHandlerResult ehResult = OC_EH_OK;
339 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
342 * In the sample below, the application will:
343 * 1a. pass the delete request to the c stack
344 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
345 * (e.g. send observers notification, remove observers...)
346 * 1c. the c stack returns with the result whether the request is fullfilled.
347 * 2. optionally, app removes observers out of its array 'interestedObservers'
350 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
352 //Step 1: Ask stack to do the work.
353 OCStackResult result = OCDeleteResource(ehRequest->resource);
355 if (result == OC_STACK_OK)
357 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
360 //Step 2: clear observers who wanted to observe this resource at the app level.
361 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
363 if (interestedObservers[i].resourceHandle == ehRequest->resource)
365 interestedObservers[i].valid = false;
366 interestedObservers[i].observationId = 0;
367 interestedObservers[i].resourceHandle = NULL;
371 else if (result == OC_STACK_NO_RESOURCE)
373 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
374 ehResult = OC_EH_RESOURCE_DELETED;
378 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
379 ehResult = OC_EH_ERROR;
382 else if (ehRequest->resource != Light.handle)
384 //Let's this app not supporting DELETE on some resources so
385 //consider the DELETE request is received for a non-support resource.
386 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
387 ehResult = OC_EH_FORBIDDEN;
393 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
395 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
397 return OC_EH_RESOURCE_NOT_FOUND;
400 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
402 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
403 ehRequest->obsInfo.obsId);
405 if (!observeThreadStarted)
407 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
408 observeThreadStarted = 1;
410 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
412 if (interestedObservers[i].valid == false)
414 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
415 interestedObservers[i].valid = true;
416 gLightUnderObservation = 1;
422 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
424 bool clientStillObserving = false;
426 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
427 ehRequest->obsInfo.obsId);
428 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
430 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
432 interestedObservers[i].valid = false;
434 if (interestedObservers[i].valid == true)
436 // Even if there is one single client observing we continue notifying entity handler
437 clientStillObserving = true;
440 if (clientStillObserving == false)
442 gLightUnderObservation = 0;
446 OCEntityHandlerResult
447 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
448 OCEntityHandlerRequest *entityHandlerRequest,
450 void* /*callbackParam*/)
452 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
454 OCEntityHandlerResult ehResult = OC_EH_OK;
455 OCEntityHandlerResponse response;
458 if (!entityHandlerRequest)
460 OIC_LOG (ERROR, TAG, "Invalid request pointer");
463 // Initialize certain response fields
464 response.numSendVendorSpecificHeaderOptions = 0;
465 memset(response.sendVendorSpecificHeaderOptions, 0,
466 sizeof response.sendVendorSpecificHeaderOptions);
467 memset(response.resourceUri, 0, sizeof response.resourceUri);
468 OCRepPayload* payload = nullptr;
471 if (flag & OC_REQUEST_FLAG)
473 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
475 if (entityHandlerRequest->resource == NULL)
477 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
478 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
480 else if (OC_REST_GET == entityHandlerRequest->method)
482 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
483 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
485 else if (OC_REST_PUT == entityHandlerRequest->method)
487 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
488 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
490 else if (OC_REST_DELETE == entityHandlerRequest->method)
492 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
493 ehResult = ProcessDeleteRequest (entityHandlerRequest);
497 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
498 entityHandlerRequest->method);
499 ehResult = OC_EH_ERROR;
501 // If the result isn't an error or forbidden, send response
502 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
504 // Format the response. Note this requires some info about the request
505 response.requestHandle = entityHandlerRequest->requestHandle;
506 response.resourceHandle = entityHandlerRequest->resource;
507 response.ehResult = ehResult;
508 response.payload = reinterpret_cast<OCPayload*>(payload);
509 // Indicate that response is NOT in a persistent buffer
510 response.persistentBufferFlag = 0;
513 if (OCDoResponse(&response) != OC_STACK_OK)
515 OIC_LOG(ERROR, TAG, "Error sending response");
516 ehResult = OC_EH_ERROR;
520 if (flag & OC_OBSERVE_FLAG)
522 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
523 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
525 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
527 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
529 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
533 OCPayloadDestroy(response.payload);
537 OCEntityHandlerResult
538 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
539 OCEntityHandlerRequest * /*entityHandlerRequest*/,
540 void* /*callbackParam*/)
542 // This is callback is associated with the 2 presence notification
543 // resources. They are non-operational.
547 OCEntityHandlerResult
548 OCEntityHandlerCb (OCEntityHandlerFlag flag,
549 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
551 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
553 OCEntityHandlerResult ehResult = OC_EH_OK;
554 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
557 if (!entityHandlerRequest)
559 OIC_LOG (ERROR, TAG, "Invalid request pointer");
563 // Initialize certain response fields
564 response.numSendVendorSpecificHeaderOptions = 0;
565 memset(response.sendVendorSpecificHeaderOptions,
566 0, sizeof response.sendVendorSpecificHeaderOptions);
567 memset(response.resourceUri, 0, sizeof response.resourceUri);
568 OCRepPayload* payload = nullptr;
570 if (flag & OC_REQUEST_FLAG)
572 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
574 if (OC_REST_GET == entityHandlerRequest->method)
576 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
577 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
579 else if (OC_REST_PUT == entityHandlerRequest->method)
581 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
582 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
584 else if (OC_REST_POST == entityHandlerRequest->method)
586 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
587 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
589 else if (OC_REST_DELETE == entityHandlerRequest->method)
591 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
592 ehResult = ProcessDeleteRequest (entityHandlerRequest);
596 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
597 entityHandlerRequest->method);
598 ehResult = OC_EH_ERROR;
600 // If the result isn't an error or forbidden, send response
601 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
603 // Format the response. Note this requires some info about the request
604 response.requestHandle = entityHandlerRequest->requestHandle;
605 response.resourceHandle = entityHandlerRequest->resource;
606 response.ehResult = ehResult;
607 response.payload = reinterpret_cast<OCPayload*>(payload);
608 // Indicate that response is NOT in a persistent buffer
609 response.persistentBufferFlag = 0;
611 // Handle vendor specific options
612 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
613 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
615 OIC_LOG (INFO, TAG, "Received vendor specific options");
617 OCHeaderOption * rcvdOptions =
618 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
619 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
621 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
623 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
624 ((OCHeaderOption)rcvdOptions[i]).optionID );
626 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
627 MAX_HEADER_OPTION_DATA_LENGTH);
631 OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
632 size_t numOptions = response.numSendVendorSpecificHeaderOptions;
633 // Check if the option header has already existed before adding it in.
634 uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
635 size_t optionDataSize = sizeof(optionData);
636 uint16_t actualDataSize = 0;
637 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
638 response.numSendVendorSpecificHeaderOptions,
643 if (actualDataSize == 0)
645 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
646 uint16_t optionID2 = 2248;
647 size_t optionDataSize2 = sizeof(option2);
648 OCSetHeaderOption(sendOptions,
655 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
656 response.numSendVendorSpecificHeaderOptions,
661 if (actualDataSize == 0)
663 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
664 uint16_t optionID3 = 2600;
665 size_t optionDataSize3 = sizeof(option3);
666 OCSetHeaderOption(sendOptions,
672 response.numSendVendorSpecificHeaderOptions = 2;
676 if (OCDoResponse(&response) != OC_STACK_OK)
678 OIC_LOG(ERROR, TAG, "Error sending response");
679 ehResult = OC_EH_ERROR;
683 if (flag & OC_OBSERVE_FLAG)
685 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
687 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
689 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
690 ProcessObserveRegister (entityHandlerRequest);
692 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
694 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
695 ProcessObserveDeregister (entityHandlerRequest);
699 OCPayloadDestroy(response.payload);
703 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
704 void handleSigInt(int signum)
706 if (signum == SIGINT)
712 void *ChangeLightRepresentation (void *param)
715 OCStackResult result = OC_STACK_ERROR;
718 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
724 if (gLightUnderObservation)
726 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
727 if (gObserveNotifyType == 1)
729 // Notify list of observers. Alternate observers on the list will be notified.
731 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
733 if (interestedObservers[i].valid == true)
735 obsNotify[j] = interestedObservers[i].observationId;
740 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
741 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
743 OCRepPayloadDestroy(payload);
745 else if (gObserveNotifyType == 0)
747 // Notifying all observers
748 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
749 if (OC_STACK_NO_OBSERVERS == result)
752 "=======> No more observers exist, stop sending observations");
753 gLightUnderObservation = 0;
758 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
766 void *presenceNotificationGenerator(void *param)
768 uint8_t secondsBeforePresence = 10;
769 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
770 sleep(secondsBeforePresence);
772 OCDoHandle presenceNotificationHandles[NUM_PRESENCE_RESOURCES];
773 OCStackResult res = OC_STACK_OK;
775 std::array<std::string, NUM_PRESENCE_RESOURCES> presenceNotificationResources { {
776 std::string("core.fan"),
777 std::string("core.led") } };
778 std::array<std::string, NUM_PRESENCE_RESOURCES> presenceNotificationUris { {
779 std::string("/a/fan"),
780 std::string("/a/led") } };
782 for(int i=0; i<NUM_PRESENCE_RESOURCES; i++)
784 if(res == OC_STACK_OK)
787 res = OCCreateResource(&presenceNotificationHandles[i],
788 presenceNotificationResources.at(i).c_str(),
789 OC_RSRVD_INTERFACE_DEFAULT,
790 presenceNotificationUris.at(i).c_str(),
791 OCNOPEntityHandlerCb,
793 OC_DISCOVERABLE|OC_OBSERVABLE);
795 if(res != OC_STACK_OK)
797 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
798 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
802 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
803 presenceNotificationUris[i].c_str());
806 for(int i=0; i<NUM_PRESENCE_RESOURCES; i++)
808 if(res == OC_STACK_OK)
810 res = OCDeleteResource(presenceNotificationHandles[i]);
812 if(res != OC_STACK_OK)
814 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
815 "resource %s.", presenceNotificationResources.at(i).c_str());
818 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
819 presenceNotificationUris[i].c_str());
822 OIC_LOG(INFO, TAG, "================ stopping presence");
829 int createLightResource (char *uri, LightResource *lightResource)
833 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
837 lightResource->state = false;
838 lightResource->power= 0;
839 OCTpsSchemeFlags endpointFlags = OC_NO_TPS;
840 switch (gResourceCreateType)
842 case DISPLAY_SUPPORTED_EPS_FLAG:
843 case CREATE_RESOURCE_OC_ALL:
844 // same as OCCreateResource(args...)
845 endpointFlags = OC_ALL;
848 case CREATE_RESOURCE_OC_COAP:
849 endpointFlags = OC_COAP;
853 case CREATE_RESOURCE_OC_COAP_TCP:
854 endpointFlags = OC_COAP_TCP;
857 case CREATE_RESOURCE_OC_COAP_WITH_TCP:
858 endpointFlags = (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP);
862 endpointFlags = OC_ALL;
865 OCStackResult res = OCCreateResourceWithEp(&(lightResource->handle),
871 OC_DISCOVERABLE|OC_OBSERVABLE,
874 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
879 void DeletePlatformInfo()
881 free(platformInfo.platformID);
882 free(platformInfo.manufacturerName);
883 free(platformInfo.manufacturerUrl);
884 free(platformInfo.modelNumber);
885 free(platformInfo.dateOfManufacture);
886 free(platformInfo.platformVersion);
887 free(platformInfo.operatingSystemVersion);
888 free(platformInfo.hardwareVersion);
889 free(platformInfo.firmwareVersion);
890 free(platformInfo.supportUrl);
891 free(platformInfo.systemTime);
894 bool DuplicateString(char** targetString, const char* sourceString)
902 *targetString = (char *) malloc(strlen(sourceString) + 1);
906 strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
913 OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
914 const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
915 const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
916 const char *firmwareVersion, const char* supportUrl, const char* systemTime)
921 if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_PLATFORM_NAME_LENGTH))
923 return OC_STACK_INVALID_PARAM;
926 if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_PLATFORM_URL_LENGTH))
928 return OC_STACK_INVALID_PARAM;
931 if(!DuplicateString(&platformInfo.platformID, platformID))
936 if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
941 if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
946 if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
951 if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
956 if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
961 if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
966 if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
971 if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
976 if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
981 if(!DuplicateString(&platformInfo.systemTime, systemTime))
991 DeletePlatformInfo();
992 return OC_STACK_ERROR;
995 OCStackResult SetDeviceInfo()
997 OCResourceHandle resourceHandle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
998 if (resourceHandle == NULL)
1000 OIC_LOG(ERROR, TAG, "Device Resource does not exist.");
1004 VERIFY_SUCCESS(OCBindResourceTypeToResource(resourceHandle, deviceType));
1005 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, deviceName));
1006 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, specVersion));
1007 VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION,
1008 dataModelVersions));
1010 OIC_LOG(INFO, TAG, "Device information initialized successfully.");
1014 return OC_STACK_ERROR;
1017 static void PrintUsage()
1019 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
1020 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
1021 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
1022 OIC_LOG(INFO, TAG, "-e 0 : Display supported endpoint flags");
1023 OIC_LOG(INFO, TAG, "-e 1 : Create resource without endpoint flags");
1024 OIC_LOG(INFO, TAG, "-e 2 : Create resource with endpoint flag OC_COAP");
1026 OIC_LOG(INFO, TAG, "-e 3 : Create resource with endpoint flag OC_COAP_TCP");
1027 OIC_LOG(INFO, TAG, "-e 4 : Create resource with endpoint flag OC_COAP | OC_COAP_TCP");
1032 static void jidbound(char *jid)
1034 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
1038 int main(int argc, char* argv[])
1042 char host[] = "localhost";
1043 char user[] = "test1";
1044 char pass[] = "intel123";
1046 OCRAInfo_t rainfo = {};
1048 rainfo.hostname = host;
1050 rainfo.xmpp_domain = host;
1051 rainfo.username = user;
1052 rainfo.password = pass;
1053 rainfo.resource = empstr;
1054 rainfo.user_jid = empstr;
1055 rainfo.jidbound = jidbound;
1059 while ((opt = getopt(argc, argv, "o:e:s:p:d:u:w:r:j:")) != -1)
1064 gObserveNotifyType = atoi(optarg);
1067 gResourceCreateType = atoi(optarg);
1071 rainfo.hostname = optarg;
1074 rainfo.port = atoi(optarg);
1077 rainfo.xmpp_domain = optarg;
1080 rainfo.username = optarg;
1083 rainfo.password = optarg;
1086 rainfo.user_jid = optarg;
1089 rainfo.resource = optarg;
1098 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) &&
1099 gResourceCreateType == ENDPOINT_OPT_NONE)
1105 if (gResourceCreateType < DISPLAY_SUPPORTED_EPS_FLAG ||
1106 gResourceCreateType > ENDPOINT_OPT_NONE)
1113 OCSetRAInfo(&rainfo);
1116 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1118 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1120 OIC_LOG(ERROR, TAG, "OCStack init error");
1123 #ifdef WITH_PRESENCE
1124 if (OCStartPresence(0) != OC_STACK_OK)
1126 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1131 if (DISPLAY_SUPPORTED_EPS_FLAG == gResourceCreateType)
1133 char strBuff[SAMPLE_MAX_STR_BUFF_SIZE] = {0};
1134 OCTpsSchemeFlags deviceFlags = OCGetSupportedEndpointTpsFlags();
1136 if (deviceFlags & OC_COAP)
1138 OICStrcat(strBuff, sizeof(strBuff), "OC_COAP");
1140 if (deviceFlags & OC_COAPS)
1142 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS");
1145 if (deviceFlags & OC_COAP_TCP)
1147 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_TCP");
1149 if (deviceFlags & OC_COAPS_TCP)
1151 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS_TCP");
1155 if (deviceFlags & OC_COAP_RFCOMM)
1157 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_RFCOMM");
1160 OIC_LOG_V(INFO, TAG, "Endpoint flag %s is supported", strBuff);
1164 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1166 OCStackResult registrationResult =
1167 SetPlatformInfo(platformID, manufacturerName, manufacturerLink, modelNumber,
1168 dateOfManufacture, platformVersion, operatingSystemVersion,
1169 hardwareVersion, firmwareVersion, supportLink, systemTime);
1171 if (registrationResult != OC_STACK_OK)
1173 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1174 exit (EXIT_FAILURE);
1177 registrationResult = OCSetPlatformInfo(platformInfo);
1179 if (registrationResult != OC_STACK_OK)
1181 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1182 exit (EXIT_FAILURE);
1185 registrationResult = SetDeviceInfo();
1187 if (registrationResult != OC_STACK_OK)
1189 OIC_LOG(INFO, TAG, "Device Registration failed!");
1190 exit (EXIT_FAILURE);
1194 * Declare and create the example resource: Light
1196 createLightResource(gResourceUri, &Light);
1198 // Initialize observations data structure for the resource
1199 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1201 interestedObservers[i].valid = false;
1206 * Create a thread for generating changes that cause presence notifications
1207 * to be sent to clients
1209 #ifdef WITH_PRESENCE
1210 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1213 // Break from loop with Ctrl-C
1214 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1216 DeletePlatformInfo();
1218 signal(SIGINT, handleSigInt);
1222 if (OCProcess() != OC_STACK_OK)
1224 OIC_LOG(ERROR, TAG, "OCStack process error");
1229 if (observeThreadStarted)
1231 #ifdef HAVE_PTHREAD_H
1232 pthread_cancel(threadId_observe);
1233 pthread_join(threadId_observe, NULL);
1237 #ifdef HAVE_PTHREAD_H
1238 pthread_cancel(threadId_presence);
1239 pthread_join(threadId_presence, NULL);
1242 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1244 if (OCStop() != OC_STACK_OK)
1246 OIC_LOG(ERROR, TAG, "OCStack process error");