#endif
//TODO: Follow the pattern used in constructJsonResponse() when the payload is decided.
-const char responsePayloadDeleteOk[] = "{App determines payload: Delete Resource operation succeeded.}";
-const char responsePayloadDeleteNotOK[] = "{App determines payload: Delete Resource operation failed.}";
-const char responsePayloadResourceDoesNotExist[] = "{App determines payload: The resource does not exist.}";
+const char responsePayloadDeleteOk[] =
+ "{App determines payload: Delete Resource operation succeeded.}";
+const char responsePayloadDeleteNotOK[] =
+ "{App determines payload: Delete Resource operation failed.}";
+const char responsePayloadResourceDoesNotExist[] =
+ "{App determines payload: The resource does not exist.}";
const char responsePayloadDeleteResourceNotSupported[] =
"{App determines payload: The request is received for a non-support resource.}";
const char *deviceUUID = "myDeviceUUID";
const char *firmwareVersion = "myFirmwareVersion";
const char *hostName = "myHostName";
-const char *manufacturerName = "myManufacturerNa";
+const char *manufacturerName = "myName";
+const char *operatingSystemVersion = "myOS";
+const char *hardwareVersion = "myHardwareVersion";
+const char* platformID = "myPlatformID";
const char *manufacturerUrl = "myManufacturerUrl";
const char *modelNumber = "myModelNumber";
const char *platformVersion = "myPlatformVersion";
const char *supportUrl = "mySupportUrl";
const char *version = "myVersion";
+const char *systemTime = "2015-05-15T11.04";
-OCDeviceInfo deviceInfo;
+// Entity handler should check for resourceTypeName and ResourceInterface in order to GET
+// the existence of a known resource
+const char *resourceTypeName = "core.light";
+const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
-static uint16_t OC_WELL_KNOWN_PORT = 5683;
+OCPlatformInfo platformInfo;
//This function takes the request as an input and returns the response
//in JSON format.
if(OC_REST_PUT == ehRequest->method)
{
- cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
- currLightResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring,
- "on") ? true:false);
- currLightResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
+ // Get cJSON pointer to query
+ cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
+
+ if(!putJson)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+ return NULL;
+ }
+
+ // Get root of JSON payload, then the 1st resource.
+ cJSON* carrier = cJSON_GetObjectItem(putJson, "oc");
+ carrier = cJSON_GetArrayItem(carrier, 0);
+ carrier = cJSON_GetObjectItem(carrier, "rep");
+
+ cJSON* prop = cJSON_GetObjectItem(carrier,"power");
+ if (prop)
+ {
+ currLightResource->power =prop->valueint;
+ }
+
+ prop = cJSON_GetObjectItem(carrier,"state");
+ if (prop)
+ {
+ currLightResource->state = prop->valueint;
+ }
+
cJSON_Delete(putJson);
}
cJSON_AddStringToObject(json,"href",gResourceUri);
cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
- cJSON_AddStringToObject(format, "state", (char *) (currLightResource->state ? "on":"off"));
+ cJSON_AddBoolToObject(format, "state", currLightResource->state);
cJSON_AddNumberToObject(format, "power", currLightResource->power);
jsonResponse = cJSON_Print(json);
return jsonResponse;
}
-OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, char *payload, uint16_t maxPayloadSize)
+/*
+ * Very simple example of query parsing.
+ * The query may have multiple filters separated by '&'.
+ * It is upto the entity handler to parse the query for the individual filters,
+ * VALIDATE them and respond as it sees fit.
+
+ * This function only returns false if the query is exactly "power<X" and
+ * current power is greater than X. If X cannot be parsed for an int,
+ * true is returned.
+ */
+bool checkIfQueryForPowerPassed(char * query)
+{
+ if (query && strncmp(query, "power<", strlen("power<")) == 0)
+ {
+ char * pointerToOperator = strstr(query, "<");
+
+ if (pointerToOperator)
+ {
+ int powerRequested = atoi(pointerToOperator + 1);
+ if (Light.power > powerRequested)
+ {
+ OC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
+ , powerRequested);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/*
+ * Application should validate and process these as desired.
+ */
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
+{
+ OC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
+ OC_LOG(INFO, TAG, PCF("Not processing query"));
+ return OC_EH_OK;
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload, uint16_t maxPayloadSize)
{
OCEntityHandlerResult ehResult;
- char *getResp = constructJsonResponse(ehRequest);
+ bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
- if (maxPayloadSize > strlen ((char *)getResp))
+ // Empty payload if the query has no match.
+ if (queryPassed)
{
- strncpy(payload, getResp, strlen((char *)getResp));
- ehResult = OC_EH_OK;
+ char *getResp = constructJsonResponse(ehRequest);
+ if(!getResp)
+ {
+ OC_LOG(ERROR, TAG, "constructJsonResponse failed");
+ return OC_EH_ERROR;
+ }
+
+ if (maxPayloadSize > strlen (getResp))
+ {
+ strncpy(payload, getResp, strlen(getResp));
+ ehResult = OC_EH_OK;
+ }
+ else
+ {
+ OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
+ maxPayloadSize);
+ ehResult = OC_EH_ERROR;
+ }
+
+ free(getResp);
}
else
{
- OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
- maxPayloadSize);
- ehResult = OC_EH_ERROR;
+ ehResult = OC_EH_OK;
}
- free(getResp);
-
return ehResult;
}
-OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload, uint16_t maxPayloadSize)
{
OCEntityHandlerResult ehResult;
char *putResp = constructJsonResponse(ehRequest);
+ if(!putResp)
+ {
+ OC_LOG(ERROR, TAG, "Failed to construct Json response");
+ return OC_EH_ERROR;
+ }
+
if (maxPayloadSize > strlen ((char *)putResp))
{
strncpy(payload, putResp, strlen((char *)putResp));
return ehResult;
}
-OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, OCEntityHandlerResponse *response, char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+ OCEntityHandlerResponse *response, char *payload, uint16_t maxPayloadSize)
{
OCEntityHandlerResult ehResult = OC_EH_OK;
char *respPLPost_light = NULL;
return ehResult;
}
-OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest, char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload, uint16_t maxPayloadSize)
{
if(ehRequest == NULL)
{
return ehResult;
}
-OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest, char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest,
+ char *payload, uint16_t maxPayloadSize)
{
OC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
}
else
{
- OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
+ OC_LOG_V (ERROR, TAG, "Response buffer: %d bytes is too small",
maxPayloadSize);
}
- return OC_EH_RESOURCE_DELETED;
+ return OC_EH_RESOURCE_NOT_FOUND;
}
void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
OC_LOG (ERROR, TAG, "Invalid request pointer");
return OC_EH_ERROR;
}
-
// Initialize certain response fields
response.numSendVendorSpecificHeaderOptions = 0;
- memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof response.sendVendorSpecificHeaderOptions);
memset(response.resourceUri, 0, sizeof response.resourceUri);
- if (flag & OC_INIT_FLAG)
- {
- OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
- }
+
if (flag & OC_REQUEST_FLAG)
{
OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
- if (entityHandlerRequest->resource == NULL) {
+
+ if (entityHandlerRequest->resource == NULL)
+ {
OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
- ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
+ ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest,
+ payload, sizeof(payload) - 1);
}
else if (OC_REST_GET == entityHandlerRequest->method)
{
else
{
OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
- entityHandlerRequest->method);
+ entityHandlerRequest->method);
ehResult = OC_EH_ERROR;
}
-
- // If the result isn't an error or forbidden, send response
+ // If the result isn't an error or forbidden, send response
if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
{
// Format the response. Note this requires some info about the request
response.requestHandle = entityHandlerRequest->requestHandle;
response.resourceHandle = entityHandlerRequest->resource;
response.ehResult = ehResult;
- response.payload = (unsigned char *)payload;
+ response.payload = payload;
response.payloadSize = strlen(payload);
// Indicate that response is NOT in a persistent buffer
response.persistentBufferFlag = 0;
// Initialize certain response fields
response.numSendVendorSpecificHeaderOptions = 0;
- memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.sendVendorSpecificHeaderOptions,
+ 0, sizeof response.sendVendorSpecificHeaderOptions);
memset(response.resourceUri, 0, sizeof response.resourceUri);
- if (flag & OC_INIT_FLAG)
- {
- OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
- }
if (flag & OC_REQUEST_FLAG)
{
OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+
if (OC_REST_GET == entityHandlerRequest->method)
{
OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
else
{
OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
- entityHandlerRequest->method);
+ entityHandlerRequest->method);
+ ehResult = OC_EH_ERROR;
}
-
// If the result isn't an error or forbidden, send response
if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
{
response.requestHandle = entityHandlerRequest->requestHandle;
response.resourceHandle = entityHandlerRequest->resource;
response.ehResult = ehResult;
- response.payload = (unsigned char *)payload;
+ response.payload = payload;
response.payloadSize = strlen(payload);
// Indicate that response is NOT in a persistent buffer
response.persistentBufferFlag = 0;
{
OC_LOG (INFO, TAG, "Received vendor specific options");
uint8_t i = 0;
- OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
+ OCHeaderOption * rcvdOptions =
+ entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
{
if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
{
OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
((OCHeaderOption)rcvdOptions[i]).optionID );
+
OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
- ((OCHeaderOption)rcvdOptions[i]).optionLength);
+ MAX_HEADER_OPTION_DATA_LENGTH);
}
}
OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
}
/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
-void handleSigInt(int signum) {
- if (signum == SIGINT) {
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
gQuitFlag = 1;
}
}
while (!gQuitFlag)
{
- sleep(10);
+ sleep(3);
Light.power += 5;
if (gLightUnderObservation)
{
cJSON *format;
cJSON_AddStringToObject(json,"href",gResourceUri);
cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
- cJSON_AddStringToObject(format, "state", (char *) (Light.state ? "on":"off"));
+ cJSON_AddBoolToObject(format, "state", Light.state);
cJSON_AddNumberToObject(format, "power", Light.power);
char * obsResp = cJSON_Print(json);
cJSON_Delete(json);
result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
- (unsigned char *)obsResp, OC_NA_QOS);
+ obsResp, OC_NA_QOS);
free(obsResp);
}
else if (gObserveNotifyType == 0)
#ifdef WITH_PRESENCE
if(stopPresenceCount > 0)
{
- OC_LOG_V(INFO, TAG, "================ presence count %d", stopPresenceCount);
+ OC_LOG_V(INFO, TAG, "================ Counting down to stop presence %d", stopPresenceCount);
}
if(!stopPresenceCount--)
{
return NULL;
}
+#ifdef WITH_PRESENCE
void *presenceNotificationGenerator(void *param)
{
sleep(5);
sleep(1);
res = OCCreateResource(&presenceNotificationHandles[i],
presenceNotificationResources.at(i).c_str(),
- "oc.mi.def",
+ OC_RSRVD_INTERFACE_DEFAULT,
presenceNotificationUris.at(i).c_str(),
OCNOPEntityHandlerCb,
OC_DISCOVERABLE|OC_OBSERVABLE);
getResult(res));
break;
}
+ OC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
+ presenceNotificationUris[i].c_str());
}
sleep(5);
for(int i=0; i<numPresenceResources; i++)
"resource %s.", presenceNotificationResources.at(i).c_str());
break;
}
+ OC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
+ presenceNotificationUris[i].c_str());
}
return NULL;
}
-
-static void PrintUsage()
-{
- OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
- OC_LOG(INFO, TAG, "-o 0 : Notify all observers");
- OC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
-}
-
-int main(int argc, char* argv[])
-{
- uint8_t addr[20] = {0};
- uint8_t* paddr = NULL;
- uint16_t port = OC_WELL_KNOWN_PORT;
- uint8_t ifname[] = "eth0";
- pthread_t threadId;
- pthread_t threadId_presence;
- int opt;
-
- while ((opt = getopt(argc, argv, "o:")) != -1)
- {
- switch(opt)
- {
- case 'o':
- gObserveNotifyType = atoi(optarg);
- break;
- default:
- PrintUsage();
- return -1;
- }
- }
-
- if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
- {
- PrintUsage();
- return -1;
- }
-
- OC_LOG(DEBUG, TAG, "OCServer is starting...");
- /*Get Ip address on defined interface and initialize coap on it with random port number
- * this port number will be used as a source port in all coap communications*/
- if ( OCGetInterfaceAddress(ifname, sizeof(ifname), AF_INET, addr,
- sizeof(addr)) == ERR_SUCCESS)
- {
- OC_LOG_V(INFO, TAG, "Starting ocserver on address %s:%d",addr,port);
- paddr = addr;
- }
-
- if (OCInit((char *) paddr, port, OC_SERVER) != OC_STACK_OK) {
- OC_LOG(ERROR, TAG, "OCStack init error");
- return 0;
- }
-#ifdef WITH_PRESENCE
- if (OCStartPresence(0) != OC_STACK_OK) {
- OC_LOG(ERROR, TAG, "OCStack presence/discovery error");
- return 0;
- }
#endif
- OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
-
- OCStackResult deviceResult = SetDeviceInfo(contentType, dateOfManufacture, deviceName,
- deviceUUID, firmwareVersion, hostName, manufacturerName,
- manufacturerUrl, modelNumber, platformVersion, supportUrl, version);
-
- if (deviceResult != OC_STACK_OK)
- {
- OC_LOG(INFO, TAG, "Device Registration failed!");
- exit (EXIT_FAILURE);
- }
-
- deviceResult = OCSetDeviceInfo(deviceInfo);
-
- if (deviceResult != OC_STACK_OK)
- {
- OC_LOG(INFO, TAG, "Device Registration failed!");
- exit (EXIT_FAILURE);
- }
-
- /*
- * Declare and create the example resource: Light
- */
- createLightResource(gResourceUri, &Light);
-
- // Initialize observations data structure for the resource
- for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
- {
- interestedObservers[i].valid = false;
- }
-
- /*
- * Create a thread for changing the representation of the Light
- */
- pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
-
- /*
- * Create a thread for generating changes that cause presence notifications
- * to be sent to clients
- */
- pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
-
- // Break from loop with Ctrl-C
- OC_LOG(INFO, TAG, "Entering ocserver main loop...");
- DeleteDeviceInfo();
- signal(SIGINT, handleSigInt);
- while (!gQuitFlag) {
- if (OCProcess() != OC_STACK_OK) {
- OC_LOG(ERROR, TAG, "OCStack process error");
- return 0;
- }
-
- sleep(2);
- }
-
- /*
- * Cancel the Light thread and wait for it to terminate
- */
- pthread_cancel(threadId);
- pthread_join(threadId, NULL);
- pthread_cancel(threadId_presence);
- pthread_join(threadId_presence, NULL);
-
- OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
-
- if (OCStop() != OC_STACK_OK) {
- OC_LOG(ERROR, TAG, "OCStack process error");
- }
-
- return 0;
-}
-
int createLightResource (char *uri, LightResource *lightResource)
{
if (!uri)
return 0;
}
-void DeleteDeviceInfo()
+void DeletePlatformInfo()
{
- free(deviceInfo.contentType);
- free(deviceInfo.dateOfManufacture);
- free(deviceInfo.deviceName);
- free(deviceInfo.deviceUUID);
- free(deviceInfo.firmwareVersion);
- free(deviceInfo.hostName);
- free(deviceInfo.manufacturerName);
- free(deviceInfo.manufacturerUrl);
- free(deviceInfo.modelNumber);
- free(deviceInfo.platformVersion);
- free(deviceInfo.supportUrl);
- free(deviceInfo.version);
+ free (platformInfo.platformID);
+ free (platformInfo.manufacturerName);
+ free (platformInfo.manufacturerUrl);
+ free (platformInfo.modelNumber);
+ free (platformInfo.dateOfManufacture);
+ free (platformInfo.platformVersion);
+ free (platformInfo.operatingSystemVersion);
+ free (platformInfo.hardwareVersion);
+ free (platformInfo.firmwareVersion);
+ free (platformInfo.supportUrl);
+ free (platformInfo.systemTime);
}
bool DuplicateString(char** targetString, const char* sourceString)
{
*targetString = (char *) malloc(strlen(sourceString) + 1);
- if(targetString)
+ if(*targetString)
{
strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
return true;
return false;
}
-OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
- const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
- const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
- const char *modelNumber, const char *platformVersion, const char *supportUrl,
- const char *version)
+OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
+ const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
+ const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
+ const char *firmwareVersion, const char* supportUrl, const char* systemTime)
{
bool success = true;
return OC_STACK_INVALID_PARAM;
}
- if(!DuplicateString(&deviceInfo.contentType, contentType))
+ if(!DuplicateString(&platformInfo.platformID, platformID))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture))
+ if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+ if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.deviceUUID, deviceUUID))
+ if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion))
+ if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.hostName, hostName))
+ if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.manufacturerName, manufacturerName))
+ if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl))
+ if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.modelNumber, modelNumber))
+ if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.platformVersion, platformVersion))
+ if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
{
success = false;
}
- if(!DuplicateString(&deviceInfo.supportUrl, supportUrl))
- {
- success = false;
- }
-
- if(!DuplicateString(&deviceInfo.version, version))
+ if(!DuplicateString(&platformInfo.systemTime, systemTime))
{
success = false;
}
return OC_STACK_OK;
}
- DeleteDeviceInfo();
+ DeletePlatformInfo();
return OC_STACK_ERROR;
}
+
+static void PrintUsage()
+{
+ OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
+ OC_LOG(INFO, TAG, "-o 0 : Notify all observers");
+ OC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_t threadId;
+ pthread_t threadId_presence;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "o:")) != -1)
+ {
+ switch(opt)
+ {
+ case 'o':
+ gObserveNotifyType = atoi(optarg);
+ break;
+ default:
+ PrintUsage();
+ return -1;
+ }
+ }
+
+ if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
+ {
+ PrintUsage();
+ return -1;
+ }
+
+ OC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+#ifdef WITH_PRESENCE
+ if (OCStartPresence(0) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack presence/discovery error");
+ return 0;
+ }
+#endif
+
+ OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
+
+ OCStackResult platformRegistrationResult =
+ SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
+ dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
+ firmwareVersion, supportUrl, systemTime);
+
+ if (platformRegistrationResult != OC_STACK_OK)
+ {
+ OC_LOG(INFO, TAG, "Platform info setting failed locally!");
+ exit (EXIT_FAILURE);
+ }
+
+ platformRegistrationResult = OCSetPlatformInfo(platformInfo);
+
+ if (platformRegistrationResult != OC_STACK_OK)
+ {
+ OC_LOG(INFO, TAG, "Platform Registration failed!");
+ exit (EXIT_FAILURE);
+ }
+
+ /*
+ * Declare and create the example resource: Light
+ */
+ createLightResource(gResourceUri, &Light);
+
+ // Initialize observations data structure for the resource
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ interestedObservers[i].valid = false;
+ }
+
+ /*
+ * Create a thread for changing the representation of the Light
+ */
+ pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
+
+ /*
+ * Create a thread for generating changes that cause presence notifications
+ * to be sent to clients
+ */
+
+ #ifdef WITH_PRESENCE
+ pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
+ #endif
+
+ // Break from loop with Ctrl-C
+ OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+ DeletePlatformInfo();
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+
+ sleep(2);
+ }
+
+ /*
+ * Cancel the Light thread and wait for it to terminate
+ */
+ pthread_cancel(threadId);
+ pthread_join(threadId, NULL);
+ pthread_cancel(threadId_presence);
+ pthread_join(threadId_presence, NULL);
+
+ OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ }
+
+ return 0;
+}
\ No newline at end of file