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 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
49 const int URI_MAXSIZE = 19;
51 static int gObserveNotifyType = 3;
52 static int gResourceCreateType = ENDPOINT_OPT_NONE;
55 int gLightUnderObservation = 0;
57 static LightResource Light;
58 // This variable determines instance number of the Light resource.
59 // Used by POST method to create a new instance of Light resource.
60 static int gCurrLightInstance = 0;
62 static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
64 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
66 pthread_t threadId_observe;
67 pthread_t threadId_presence;
69 static bool observeThreadStarted = false;
72 #define numPresenceResources (2)
75 char *gResourceUri= (char *)"/a/light";
76 const char *dateOfManufacture = "2016-01-15";
77 const char *deviceName = "myDeviceName";
78 const char *deviceUUID = "51b55ddc-ccbb-4cb3-a57f-494eeca13a21";
79 const char *firmwareVersion = "myFirmwareVersion";
80 const char *manufacturerName = "myName";
81 const char *operatingSystemVersion = "myOS";
82 const char *hardwareVersion = "myHardwareVersion";
83 const char *platformID = "0A3E0D6F-DBF5-404E-8719-D6880042463A";
84 const char *manufacturerLink = "https://www.iotivity.org";
85 const char *modelNumber = "myModelNumber";
86 const char *platformVersion = "myPlatformVersion";
87 const char *supportLink = "https://www.iotivity.org";
88 const char *version = "myVersion";
89 const char *systemTime = "2015-05-15T11.04";
90 const char *specVersion = "core.1.1.0";
91 const char *dataModelVersions = "res.1.1.0,sh.1.1.0";
93 // Entity handler should check for resourceTypeName and ResourceInterface in order to GET
94 // the existence of a known resource
95 const char *resourceTypeName = "core.light";
96 const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
98 OCPlatformInfo platformInfo;
99 OCDeviceInfo deviceInfo;
101 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
103 OCRepPayload* payload = OCRepPayloadCreate();
106 OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
110 OCRepPayloadSetUri(payload, uri);
111 OCRepPayloadSetPropBool(payload, "state", state);
112 OCRepPayloadSetPropInt(payload, "power", power);
117 //This function takes the request as an input and returns the response
118 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
120 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
122 OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
126 OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
128 LightResource *currLightResource = &Light;
130 if (ehRequest->resource == gLightInstance[0].handle)
132 currLightResource = &gLightInstance[0];
133 gResourceUri = (char *) "a/light/0";
135 else if (ehRequest->resource == gLightInstance[1].handle)
137 currLightResource = &gLightInstance[1];
138 gResourceUri = (char *) "a/light/1";
141 if(OC_REST_PUT == ehRequest->method)
143 // Get pointer to query
145 if(OCRepPayloadGetPropInt(input, "power", &pow))
147 currLightResource->power =pow;
151 if(OCRepPayloadGetPropBool(input, "state", &state))
153 currLightResource->state = state;
157 return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
161 * Very simple example of query parsing.
162 * The query may have multiple filters separated by ';'.
163 * It is upto the entity handler to parse the query for the individual filters,
164 * VALIDATE them and respond as it sees fit.
166 * This function only returns false if the query is exactly "power<X" and
167 * current power is greater than X. If X cannot be parsed for an int,
170 bool checkIfQueryForPowerPassed(char * query)
172 if (query && strncmp(query, "power<", strlen("power<")) == 0)
174 char * pointerToOperator = strstr(query, "<");
176 if (pointerToOperator)
178 int powerRequested = atoi(pointerToOperator + 1);
179 if (Light.power > powerRequested)
181 OIC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
191 * Application should validate and process these as desired.
193 OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
195 OIC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
196 OIC_LOG(INFO, TAG, PCF("Not processing query"));
200 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
201 OCRepPayload **payload)
203 OCEntityHandlerResult ehResult;
204 bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
206 // Empty payload if the query has no match.
209 OCRepPayload *getResp = constructResponse(ehRequest);
212 OIC_LOG(ERROR, TAG, "constructResponse failed");
227 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
228 OCRepPayload** payload)
230 OCEntityHandlerResult ehResult;
231 OCRepPayload *putResp = constructResponse(ehRequest);
235 OIC_LOG(ERROR, TAG, "Failed to construct Json response");
245 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
246 OCEntityHandlerResponse *response, OCRepPayload** payload)
248 OCEntityHandlerResult ehResult = OC_EH_OK;
249 OCRepPayload *respPLPost_light = nullptr;
252 * The entity handler determines how to process a POST request.
253 * Per the REST paradigm, POST can also be used to update representation of existing
254 * resource or create a new resource.
255 * In the sample below, if the POST is for /a/light then a new instance of the Light
256 * resource is created with default representation (if representation is included in
257 * POST payload it can be used as initial values) as long as the instance is
258 * lesser than max new instance count. Once max instance count is reached, POST on
259 * /a/light updated the representation of /a/light (just like PUT)
262 if (ehRequest->resource == Light.handle)
264 if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
266 // Create new Light instance
267 char newLightUri[URI_MAXSIZE];
268 snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
270 respPLPost_light = OCRepPayloadCreate();
271 OCRepPayloadSetUri(respPLPost_light, gResourceUri);
272 OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
274 if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
276 OIC_LOG (INFO, TAG, "Created new Light instance\n");
277 gLightInstance[gCurrLightInstance].state = 0;
278 gLightInstance[gCurrLightInstance].power = 0;
279 gCurrLightInstance++;
280 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
281 ehResult = OC_EH_RESOURCE_CREATED;
286 // Update repesentation of /a/light
289 respPLPost_light = constructResponse(ehRequest);
294 for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
296 if (ehRequest->resource == gLightInstance[i].handle)
298 gLightInstance[i].state = true;
299 gLightInstance[i].power = 22;
302 respPLPost_light = constructResponse(ehRequest);
307 respPLPost_light = constructResponse(ehRequest);
313 if ((respPLPost_light != NULL))
315 *payload = respPLPost_light;
319 OIC_LOG(INFO, TAG, "Payload was NULL");
320 ehResult = OC_EH_ERROR;
326 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
328 if(ehRequest == NULL)
330 OIC_LOG(INFO, TAG, "The ehRequest is NULL");
333 OCEntityHandlerResult ehResult = OC_EH_OK;
335 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
338 * In the sample below, the application will:
339 * 1a. pass the delete request to the c stack
340 * 1b. internally, the c stack figures out what needs to be done and does it accordingly
341 * (e.g. send observers notification, remove observers...)
342 * 1c. the c stack returns with the result whether the request is fullfilled.
343 * 2. optionally, app removes observers out of its array 'interestedObservers'
346 if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
348 //Step 1: Ask stack to do the work.
349 OCStackResult result = OCDeleteResource(ehRequest->resource);
351 if (result == OC_STACK_OK)
353 OIC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
356 //Step 2: clear observers who wanted to observe this resource at the app level.
357 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
359 if (interestedObservers[i].resourceHandle == ehRequest->resource)
361 interestedObservers[i].valid = false;
362 interestedObservers[i].observationId = 0;
363 interestedObservers[i].resourceHandle = NULL;
367 else if (result == OC_STACK_NO_RESOURCE)
369 OIC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
370 ehResult = OC_EH_RESOURCE_DELETED;
374 OIC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
375 ehResult = OC_EH_ERROR;
378 else if (ehRequest->resource != Light.handle)
380 //Let's this app not supporting DELETE on some resources so
381 //consider the DELETE request is received for a non-support resource.
382 OIC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
383 ehResult = OC_EH_FORBIDDEN;
389 OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest * /*ehRequest*/)
391 OIC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
393 return OC_EH_RESOURCE_NOT_FOUND;
396 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
398 OIC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
399 ehRequest->obsInfo.obsId);
401 if (!observeThreadStarted)
403 pthread_create (&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
404 observeThreadStarted = 1;
406 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
408 if (interestedObservers[i].valid == false)
410 interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
411 interestedObservers[i].valid = true;
412 gLightUnderObservation = 1;
418 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
420 bool clientStillObserving = false;
422 OIC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
423 ehRequest->obsInfo.obsId);
424 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
426 if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
428 interestedObservers[i].valid = false;
430 if (interestedObservers[i].valid == true)
432 // Even if there is one single client observing we continue notifying entity handler
433 clientStillObserving = true;
436 if (clientStillObserving == false)
437 gLightUnderObservation = 0;
440 OCEntityHandlerResult
441 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
442 OCEntityHandlerRequest *entityHandlerRequest,
444 void* /*callbackParam*/)
446 OIC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
448 OCEntityHandlerResult ehResult = OC_EH_OK;
449 OCEntityHandlerResponse response;
452 if (!entityHandlerRequest)
454 OIC_LOG (ERROR, TAG, "Invalid request pointer");
457 // Initialize certain response fields
458 response.numSendVendorSpecificHeaderOptions = 0;
459 memset(response.sendVendorSpecificHeaderOptions, 0,
460 sizeof response.sendVendorSpecificHeaderOptions);
461 memset(response.resourceUri, 0, sizeof response.resourceUri);
462 OCRepPayload* payload = nullptr;
465 if (flag & OC_REQUEST_FLAG)
467 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
469 if (entityHandlerRequest->resource == NULL)
471 OIC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
472 ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
474 else if (OC_REST_GET == entityHandlerRequest->method)
476 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
477 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
479 else if (OC_REST_PUT == entityHandlerRequest->method)
481 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
482 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
484 else if (OC_REST_DELETE == entityHandlerRequest->method)
486 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
487 ehResult = ProcessDeleteRequest (entityHandlerRequest);
491 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
492 entityHandlerRequest->method);
493 ehResult = OC_EH_ERROR;
495 // If the result isn't an error or forbidden, send response
496 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
498 // Format the response. Note this requires some info about the request
499 response.requestHandle = entityHandlerRequest->requestHandle;
500 response.resourceHandle = entityHandlerRequest->resource;
501 response.ehResult = ehResult;
502 response.payload = reinterpret_cast<OCPayload*>(payload);
503 // Indicate that response is NOT in a persistent buffer
504 response.persistentBufferFlag = 0;
507 if (OCDoResponse(&response) != OC_STACK_OK)
509 OIC_LOG(ERROR, TAG, "Error sending response");
510 ehResult = OC_EH_ERROR;
514 if (flag & OC_OBSERVE_FLAG)
516 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
517 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
519 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
521 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
523 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
527 OCPayloadDestroy(response.payload);
531 OCEntityHandlerResult
532 OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
533 OCEntityHandlerRequest * /*entityHandlerRequest*/,
534 void* /*callbackParam*/)
536 // This is callback is associated with the 2 presence notification
537 // resources. They are non-operational.
541 OCEntityHandlerResult
542 OCEntityHandlerCb (OCEntityHandlerFlag flag,
543 OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
545 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
547 OCEntityHandlerResult ehResult = OC_EH_OK;
548 OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
551 if (!entityHandlerRequest)
553 OIC_LOG (ERROR, TAG, "Invalid request pointer");
557 // Initialize certain response fields
558 response.numSendVendorSpecificHeaderOptions = 0;
559 memset(response.sendVendorSpecificHeaderOptions,
560 0, sizeof response.sendVendorSpecificHeaderOptions);
561 memset(response.resourceUri, 0, sizeof response.resourceUri);
562 OCRepPayload* payload = nullptr;
564 if (flag & OC_REQUEST_FLAG)
566 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
568 if (OC_REST_GET == entityHandlerRequest->method)
570 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
571 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
573 else if (OC_REST_PUT == entityHandlerRequest->method)
575 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
576 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
578 else if (OC_REST_POST == entityHandlerRequest->method)
580 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
581 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
583 else if (OC_REST_DELETE == entityHandlerRequest->method)
585 OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
586 ehResult = ProcessDeleteRequest (entityHandlerRequest);
590 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
591 entityHandlerRequest->method);
592 ehResult = OC_EH_ERROR;
594 // If the result isn't an error or forbidden, send response
595 if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
597 // Format the response. Note this requires some info about the request
598 response.requestHandle = entityHandlerRequest->requestHandle;
599 response.resourceHandle = entityHandlerRequest->resource;
600 response.ehResult = ehResult;
601 response.payload = reinterpret_cast<OCPayload*>(payload);
602 // Indicate that response is NOT in a persistent buffer
603 response.persistentBufferFlag = 0;
605 // Handle vendor specific options
606 if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
607 entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
609 OIC_LOG (INFO, TAG, "Received vendor specific options");
611 OCHeaderOption * rcvdOptions =
612 entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
613 for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
615 if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
617 OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
618 ((OCHeaderOption)rcvdOptions[i]).optionID );
620 OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
621 MAX_HEADER_OPTION_DATA_LENGTH);
625 OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
626 size_t numOptions = response.numSendVendorSpecificHeaderOptions;
627 // Check if the option header has already existed before adding it in.
628 uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
629 size_t optionDataSize = sizeof(optionData);
630 uint16_t actualDataSize = 0;
631 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
632 response.numSendVendorSpecificHeaderOptions,
637 if (actualDataSize == 0)
639 uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
640 uint16_t optionID2 = 2248;
641 size_t optionDataSize2 = sizeof(option2);
642 OCSetHeaderOption(sendOptions,
649 OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
650 response.numSendVendorSpecificHeaderOptions,
655 if (actualDataSize == 0)
657 uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
658 uint16_t optionID3 = 2600;
659 size_t optionDataSize3 = sizeof(option3);
660 OCSetHeaderOption(sendOptions,
666 response.numSendVendorSpecificHeaderOptions = 2;
670 if (OCDoResponse(&response) != OC_STACK_OK)
672 OIC_LOG(ERROR, TAG, "Error sending response");
673 ehResult = OC_EH_ERROR;
677 if (flag & OC_OBSERVE_FLAG)
679 OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
681 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
683 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
684 ProcessObserveRegister (entityHandlerRequest);
686 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
688 OIC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
689 ProcessObserveDeregister (entityHandlerRequest);
693 OCPayloadDestroy(response.payload);
697 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
698 void handleSigInt(int signum)
700 if (signum == SIGINT)
706 void *ChangeLightRepresentation (void *param)
709 OCStackResult result = OC_STACK_ERROR;
712 OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2];
718 if (gLightUnderObservation)
720 OIC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
721 if (gObserveNotifyType == 1)
723 // Notify list of observers. Alternate observers on the list will be notified.
725 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
727 if (interestedObservers[i].valid == true)
729 obsNotify[j] = interestedObservers[i].observationId;
734 OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
735 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
737 OCRepPayloadDestroy(payload);
739 else if (gObserveNotifyType == 0)
741 // Notifying all observers
742 result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
743 if (OC_STACK_NO_OBSERVERS == result)
746 "=======> No more observers exist, stop sending observations");
747 gLightUnderObservation = 0;
752 OIC_LOG (ERROR, TAG, "Incorrect notification type selected");
760 void *presenceNotificationGenerator(void *param)
762 uint8_t secondsBeforePresence = 10;
763 OIC_LOG_V(INFO, TAG, "Will send out presence in %u seconds", secondsBeforePresence);
764 sleep(secondsBeforePresence);
766 OCDoHandle presenceNotificationHandles[numPresenceResources];
767 OCStackResult res = OC_STACK_OK;
769 std::array<std::string, numPresenceResources> presenceNotificationResources { {
770 std::string("core.fan"),
771 std::string("core.led") } };
772 std::array<std::string, numPresenceResources> presenceNotificationUris { {
773 std::string("/a/fan"),
774 std::string("/a/led") } };
776 for(int i=0; i<numPresenceResources; i++)
778 if(res == OC_STACK_OK)
781 res = OCCreateResource(&presenceNotificationHandles[i],
782 presenceNotificationResources.at(i).c_str(),
783 OC_RSRVD_INTERFACE_DEFAULT,
784 presenceNotificationUris.at(i).c_str(),
785 OCNOPEntityHandlerCb,
787 OC_DISCOVERABLE|OC_OBSERVABLE);
789 if(res != OC_STACK_OK)
791 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
792 "%s with result %s.", presenceNotificationResources.at(i).c_str(),
796 OIC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
797 presenceNotificationUris[i].c_str());
800 for(int i=0; i<numPresenceResources; i++)
802 if(res == OC_STACK_OK)
804 res = OCDeleteResource(presenceNotificationHandles[i]);
806 if(res != OC_STACK_OK)
808 OIC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
809 "resource %s.", presenceNotificationResources.at(i).c_str());
812 OIC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
813 presenceNotificationUris[i].c_str());
816 OIC_LOG(INFO, TAG, "================ stopping presence");
823 int createLightResource (char *uri, LightResource *lightResource)
827 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
831 lightResource->state = false;
832 lightResource->power= 0;
833 OCTpsSchemeFlags endpointFlags = OC_NO_TPS;
834 switch (gResourceCreateType)
836 case DISPLAY_SUPPORTED_EPS_FLAG:
837 case CREATE_RESOURCE_OC_ALL:
838 // same as OCCreateResource(args...)
839 endpointFlags = OC_ALL;
842 case CREATE_RESOURCE_OC_COAP:
843 endpointFlags = OC_COAP;
847 case CREATE_RESOURCE_OC_COAP_TCP:
848 endpointFlags = OC_COAP_TCP;
851 case CREATE_RESOURCE_OC_COAP_WITH_TCP:
852 endpointFlags = (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP);
856 endpointFlags = OC_ALL;
859 OCStackResult res = OCCreateResourceWithEp(&(lightResource->handle),
865 OC_DISCOVERABLE|OC_OBSERVABLE,
868 OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
873 void DeletePlatformInfo()
875 free (platformInfo.platformID);
876 free (platformInfo.manufacturerName);
877 free (platformInfo.manufacturerUrl);
878 free (platformInfo.modelNumber);
879 free (platformInfo.dateOfManufacture);
880 free (platformInfo.platformVersion);
881 free (platformInfo.operatingSystemVersion);
882 free (platformInfo.hardwareVersion);
883 free (platformInfo.firmwareVersion);
884 free (platformInfo.supportUrl);
885 free (platformInfo.systemTime);
888 void DeleteDeviceInfo()
890 free (deviceInfo.deviceName);
891 free (deviceInfo.specVersion);
892 OCFreeOCStringLL (deviceInfo.dataModelVersions);
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(const char* deviceName, const char* specVersion, const char* dataModelVersions)
998 if(!DuplicateString(&deviceInfo.deviceName, deviceName))
1000 return OC_STACK_ERROR;
1002 if(!DuplicateString(&deviceInfo.specVersion, specVersion))
1004 return OC_STACK_ERROR;
1006 OCFreeOCStringLL(deviceInfo.dataModelVersions);
1007 deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions);
1008 if (!deviceInfo.dataModelVersions)
1010 return OC_STACK_ERROR;
1015 static void PrintUsage()
1017 OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
1018 OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
1019 OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
1020 OIC_LOG(INFO, TAG, "-e 0 : Display supported endpoint flags");
1021 OIC_LOG(INFO, TAG, "-e 1 : Create resource without endpoint flags");
1022 OIC_LOG(INFO, TAG, "-e 2 : Create resource with endpoint flag OC_COAP");
1024 OIC_LOG(INFO, TAG, "-e 3 : Create resource with endpoint flag OC_COAP_TCP");
1025 OIC_LOG(INFO, TAG, "-e 4 : Create resource with endpoint flag OC_COAP | OC_COAP_TCP");
1030 static void jidbound(char *jid)
1032 OIC_LOG_V(INFO, TAG, "\n\n Bound JID: %s\n\n", jid);
1036 int main(int argc, char* argv[])
1040 char host[] = "localhost";
1041 char user[] = "test1";
1042 char pass[] = "intel123";
1044 OCRAInfo_t rainfo = {};
1046 rainfo.hostname = host;
1048 rainfo.xmpp_domain = host;
1049 rainfo.username = user;
1050 rainfo.password = pass;
1051 rainfo.resource = empstr;
1052 rainfo.user_jid = empstr;
1053 rainfo.jidbound = jidbound;
1057 while ((opt = getopt(argc, argv, "o:e:s:p:d:u:w:r:j:")) != -1)
1062 gObserveNotifyType = atoi(optarg);
1065 gResourceCreateType = atoi(optarg);
1069 rainfo.hostname = optarg;
1072 rainfo.port = atoi(optarg);
1075 rainfo.xmpp_domain = optarg;
1078 rainfo.username = optarg;
1081 rainfo.password = optarg;
1084 rainfo.user_jid = optarg;
1087 rainfo.resource = optarg;
1096 if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) &&
1097 gResourceCreateType == ENDPOINT_OPT_NONE)
1103 if (gResourceCreateType < DISPLAY_SUPPORTED_EPS_FLAG ||
1104 gResourceCreateType > ENDPOINT_OPT_NONE)
1111 OCSetRAInfo(&rainfo);
1114 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
1116 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
1118 OIC_LOG(ERROR, TAG, "OCStack init error");
1121 #ifdef WITH_PRESENCE
1122 if (OCStartPresence(0) != OC_STACK_OK)
1124 OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
1129 if (DISPLAY_SUPPORTED_EPS_FLAG == gResourceCreateType)
1131 char strBuff[SAMPLE_MAX_STR_BUFF_SIZE] = {0};
1132 OCTpsSchemeFlags deviceFlags = OCGetSupportedEndpointTpsFlags();
1134 if (deviceFlags & OC_COAP)
1136 OICStrcat(strBuff, sizeof(strBuff), "OC_COAP");
1138 if (deviceFlags & OC_COAPS)
1140 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS");
1143 if (deviceFlags & OC_COAP_TCP)
1145 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_TCP");
1147 if (deviceFlags & OC_COAPS_TCP)
1149 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS_TCP");
1153 if (deviceFlags & OC_COAP_RFCOMM)
1155 OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_RFCOMM");
1158 OIC_LOG_V(INFO, TAG, "Endpoint flag %s is supported", strBuff);
1162 OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
1164 OCStackResult registrationResult =
1165 SetPlatformInfo(platformID, manufacturerName, manufacturerLink, modelNumber,
1166 dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
1167 firmwareVersion, supportLink, systemTime);
1169 if (registrationResult != OC_STACK_OK)
1171 OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
1172 exit (EXIT_FAILURE);
1175 registrationResult = OCSetPlatformInfo(platformInfo);
1177 if (registrationResult != OC_STACK_OK)
1179 OIC_LOG(INFO, TAG, "Platform Registration failed!");
1180 exit (EXIT_FAILURE);
1183 registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);
1185 if (registrationResult != OC_STACK_OK)
1187 OIC_LOG(INFO, TAG, "Device info setting failed locally!");
1188 exit (EXIT_FAILURE);
1191 OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
1193 registrationResult = OCSetDeviceInfo(deviceInfo);
1195 if (registrationResult != OC_STACK_OK)
1197 OIC_LOG(INFO, TAG, "Device Registration failed!");
1198 exit (EXIT_FAILURE);
1202 * Declare and create the example resource: Light
1204 createLightResource(gResourceUri, &Light);
1206 // Initialize observations data structure for the resource
1207 for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
1209 interestedObservers[i].valid = false;
1214 * Create a thread for generating changes that cause presence notifications
1215 * to be sent to clients
1218 #ifdef WITH_PRESENCE
1219 pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
1222 // Break from loop with Ctrl-C
1223 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
1225 DeletePlatformInfo();
1228 signal(SIGINT, handleSigInt);
1232 if (OCProcess() != OC_STACK_OK)
1234 OIC_LOG(ERROR, TAG, "OCStack process error");
1239 if (observeThreadStarted)
1241 #ifdef HAVE_PTHREAD_H
1242 pthread_cancel(threadId_observe);
1243 pthread_join(threadId_observe, NULL);
1247 #ifdef HAVE_PTHREAD_H
1248 pthread_cancel(threadId_presence);
1249 pthread_join(threadId_presence, NULL);
1252 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
1254 if (OCStop() != OC_STACK_OK)
1256 OIC_LOG(ERROR, TAG, "OCStack process error");