//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include "iotivity_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
#include <signal.h>
+#ifdef HAVE_PTHREAD_H
#include <pthread.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
+#include <boost/config.hpp>
#include <list>
#include "ocstack.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
#include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
#include "cJSON.h"
+#endif
#include "ocserverslow.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
volatile sig_atomic_t gQuitFlag = 0;
static std::list<OCEntityHandlerRequest *> gRequestList;
-static constexpr unsigned int SLOW_RESPONSE_DELAY_SEC = 5;
+BOOST_STATIC_CONSTEXPR unsigned int SLOW_RESPONSE_DELAY_SEC = 5;
static LEDResource LED;
-static constexpr unsigned int SAMPLE_MAX_NUM_POST_INSTANCE = 2;
+BOOST_STATIC_CONSTEXPR unsigned int SAMPLE_MAX_NUM_POST_INSTANCE = 2;
static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
//char *gResourceUri= const_cast<char *>("/a/led");
//This function takes the request as an input and returns the response
//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
{
- cJSON *json = cJSON_CreateObject();
-
- if(!json)
- {
- OC_LOG(ERROR, TAG, "CreateObject result in null for json");
- return NULL;
- }
-
- cJSON *format;
- char *jsonResponse;
LEDResource *currLEDResource = &LED;
- OC_LOG(INFO, TAG, "Entering constructJsonResponse");
+ OIC_LOG(INFO, TAG, "Entering constructResponse");
if (ehRequest->resource == gLedInstance[0].handle)
{
- OC_LOG(INFO, TAG, "handle 0");
+ OIC_LOG(INFO, TAG, "handle 0");
currLEDResource = &gLedInstance[0];
gResourceUri = const_cast<char *>("a/led/0");
}
else if (ehRequest->resource == gLedInstance[1].handle)
{
- OC_LOG(INFO, TAG, "handle 1");
+ OIC_LOG(INFO, TAG, "handle 1");
currLEDResource = &gLedInstance[1];
gResourceUri = const_cast<char *>("a/led/1");
}
if(OC_REST_PUT == ehRequest->method)
{
- cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
-
- if(!putJson)
+ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
{
- OC_LOG(ERROR, TAG, "CreateObject result in null for putJson");
- cJSON_Delete(json);
- return NULL;
+ OIC_LOG(ERROR, TAG, ("Incoming payload not a representation"));
+ return nullptr;
}
- currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring ,
- "on") ? true:false);
- currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
- cJSON_Delete(putJson);
+ OCRepPayload *putPayload = reinterpret_cast<OCRepPayload*> (ehRequest->payload);
+
+ int64_t power;
+ bool state;
+
+ if (OCRepPayloadGetPropBool(putPayload, "state", &state))
+ {
+ currLEDResource->state = state;
+ }
+ if (OCRepPayloadGetPropInt (putPayload, "power", &power))
+ {
+ currLEDResource->power = power;
+ }
}
- cJSON_AddStringToObject(json,"href",gResourceUri);
- format = cJSON_CreateObject();
+ OCRepPayload *response = OCRepPayloadCreate();
- if(!format)
+ if (!response)
{
- OC_LOG(ERROR, TAG, "CreateObject result in null for format");
- cJSON_Delete(json);
- return NULL;
+ OIC_LOG_V(ERROR, TAG, "Memory allocation for response payload failed.");
}
- cJSON_AddItemToObject(json, "rep", format);
- cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
- cJSON_AddNumberToObject(format, "power", currLEDResource->power);
-
- OC_LOG(INFO, TAG, "Before constructJsonResponse print");
- jsonResponse = cJSON_Print(json);
- OC_LOG(INFO, TAG, "Before constructJsonResponse delete");
- cJSON_Delete(json);
+ OCRepPayloadSetUri (response, gResourceUri);
+ OCRepPayloadSetPropBool(response, "state", currLEDResource->state);
+ OCRepPayloadSetPropInt(response, "power", currLEDResource->power);
- OC_LOG(INFO, TAG, "Before constructJsonResponse return");
- return jsonResponse;
+ return response;
}
-void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
+void ProcessGetPutRequest (OCEntityHandlerRequest *ehRequest)
{
- OC_LOG(INFO, TAG, "Entering ProcessGetRequest");
- char *getResp = constructJsonResponse(ehRequest);
+ OIC_LOG(INFO, TAG, "Entering ProcessGetPutRequest");
+
+ OCRepPayload *getResp = constructResponse(ehRequest);
if(!getResp)
{
- OC_LOG(ERROR, TAG, "Failed to constructJsonResponse");
+ OIC_LOG(ERROR, TAG, "Failed to construct response");
return;
}
- OC_LOG(INFO, TAG, "After constructJsonResponse");
+
OCEntityHandlerResponse response;
// Format the response. Note this requires some info about the request
response.requestHandle = ehRequest->requestHandle;
response.resourceHandle = ehRequest->resource;
response.ehResult = OC_EH_OK;
- response.payload = getResp;
- response.payloadSize = strlen(getResp) + 1;
+ response.payload = reinterpret_cast<OCPayload*> (getResp);
response.numSendVendorSpecificHeaderOptions = 0;
memset(response.sendVendorSpecificHeaderOptions,
0, sizeof response.sendVendorSpecificHeaderOptions);
// Send the response
if (OCDoResponse(&response) != OC_STACK_OK)
{
- OC_LOG(ERROR, TAG, "Error sending response");
+ OIC_LOG(ERROR, TAG, "Error sending response");
}
- free(getResp);
+ OCRepPayloadDestroy(getResp);
}
OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
{
- OC_LOG(INFO, TAG, "Copying received request for slow response");
- OCEntityHandlerRequest *request =
- (OCEntityHandlerRequest *)OCMalloc(sizeof(OCEntityHandlerRequest));
- if (request)
+ OIC_LOG(INFO, TAG, "Copying received request for slow response");
+
+ OCEntityHandlerRequest *copyOfRequest =
+ (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
+
+ if (copyOfRequest)
{
// Do shallow copy
- memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
- // Do deep copy of query
- request->query =
- (char * )OCMalloc(strlen((const char *)entityHandlerRequest->query) + 1);
- if (request->query)
- {
- strcpy((char *)request->query, (const char *)entityHandlerRequest->query);
+ memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
- // Copy the request payload
- request->reqJSONPayload = (char * )OCMalloc(
- strlen((const char *)entityHandlerRequest->reqJSONPayload) + 1);
- if (request->reqJSONPayload)
- {
- strcpy((char *)request->reqJSONPayload,
- (const char *)entityHandlerRequest->reqJSONPayload);
- // Ignore vendor specific header options for example
- request->numRcvdVendorSpecificHeaderOptions = 0;
- request->rcvdVendorSpecificHeaderOptions = NULL;
- }
- else
+ if (copyOfRequest->query)
+ {
+ copyOfRequest->query = OICStrdup(entityHandlerRequest->query);
+ if(!copyOfRequest->query)
{
- OCFree(request->query);
- OCFree(request);
- request = NULL;
+ OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
+ OICFree(copyOfRequest);
+ return NULL;
}
}
- else
+
+ if (entityHandlerRequest->payload)
{
- OCFree(request);
- request = NULL;
+ copyOfRequest->payload = reinterpret_cast<OCPayload*>
+ (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
}
+
+ // Ignore vendor specific header options for example
+ copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+ copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
}
- if (request)
+ if (copyOfRequest)
{
- OC_LOG(INFO, TAG, "Copied client request");
+ OIC_LOG(INFO, TAG, "Copied client request");
}
else
{
- OC_LOG(ERROR, TAG, "Error copying client request");
+ OIC_LOG(ERROR, TAG, "Error copying client request");
}
- return request;
+ return copyOfRequest;
+}
+
+#if !defined(SIGALRM)
+void AlarmHandler(int sig);
+int WINAPI AlarmThread(void *seconds)
+{
+ sleep((unsigned int)seconds);
+ AlarmHandler(0);
+ return 0;
}
-OCEntityHandlerResult
-OCEntityHandlerCb (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest *entityHandlerRequest)
+void alarm(unsigned int seconds)
+{
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AlarmThread, (void*)seconds, 0, NULL);
+}
+#endif
+
+OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, void* /*callbackParam*/)
{
OCEntityHandlerResult result = OC_EH_ERROR;
OCEntityHandlerRequest *request = NULL;
- OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
- if (flag & OC_INIT_FLAG)
- {
- OC_LOG(INFO, TAG, "Flag includes OC_INIT_FLAG");
- result = OC_EH_OK;
- }
+ OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+
if (flag & OC_REQUEST_FLAG)
{
- OC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+ OIC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
if (entityHandlerRequest)
{
- OC_LOG_V (INFO, TAG, "request query %s from client",
+ OIC_LOG_V (INFO, TAG, "request query %s from client",
entityHandlerRequest->query);
- OC_LOG_V (INFO, TAG, "request payload %s from client",
- entityHandlerRequest->reqJSONPayload);
+ OIC_LOG_PAYLOAD (INFO, entityHandlerRequest->payload);
+
// Make deep copy of received request and queue it for slow processing
request = CopyRequest(entityHandlerRequest);
+
if (request)
{
- OC_LOG(INFO, TAG, "Scheduling slow response for received request");
+ OIC_LOG(INFO, TAG, "Scheduling slow response for received request");
gRequestList.push_back(request);
// Indicate to the stack that this is a slow response
result = OC_EH_SLOW;
}
else
{
- OC_LOG(ERROR, TAG, "Error queuing request for slow response");
+ OIC_LOG(ERROR, TAG, "Error queuing request for slow response");
// Indicate to the stack that this is a slow response
result = OC_EH_ERROR;
}
}
else
{
- OC_LOG(ERROR, TAG, "Invalid request");
+ OIC_LOG(ERROR, TAG, "Invalid request");
result = OC_EH_ERROR;
}
}
// slow response when fired
void AlarmHandler(int sig)
{
+#ifdef SIGALRM
if (sig == SIGALRM)
+#endif
{
- OC_LOG (INFO, TAG, "Server starting slow response");
+ OIC_LOG (INFO, TAG, "Server starting slow response");
if (gRequestList.empty())
{
- OC_LOG (INFO, TAG, "No requests to service");
+ OIC_LOG (INFO, TAG, "No requests to service");
return;
}
gRequestList.pop_front();
if (entityHandlerRequest->method == OC_REST_GET)
{
- OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
- ProcessGetRequest (entityHandlerRequest);
+ OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+ ProcessGetPutRequest (entityHandlerRequest);
+ }
+ else if (entityHandlerRequest->method == OC_REST_PUT)
+ {
+ OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+ ProcessGetPutRequest (entityHandlerRequest);
}
else
{
- OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+ OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
entityHandlerRequest->method);
}
// Free the request
- OCFree(entityHandlerRequest->query);
- OCFree(entityHandlerRequest->reqJSONPayload);
- OCFree(entityHandlerRequest);
+ OICFree(entityHandlerRequest->query);
+ OCPayloadDestroy(entityHandlerRequest->payload);
+ OICFree(entityHandlerRequest);
// If there are more requests in list, re-arm the alarm signal
if (gRequestList.empty())
}
}
-int main(int argc, char* argv[])
+int main(int /*argc*/, char** /*argv[]*/)
{
- OC_LOG(DEBUG, TAG, "OCServer is starting...");
+ OIC_LOG(DEBUG, TAG, "OCServer is starting...");
if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
{
- OC_LOG(ERROR, TAG, "OCStack init error");
+ OIC_LOG(ERROR, TAG, "OCStack init error");
return 0;
}
- /*
- * Declare and create the example resource: LED
- */
- createLEDResource(gResourceUri, &LED, false, 0);
+ // Declare and create the example resource: LED
+ createLEDResource(gResourceUri, &LED, false, 42);
+#ifdef SIGALRM
// Initialize slow response alarm
signal(SIGALRM, AlarmHandler);
+#endif
// Break from loop with Ctrl-C
- OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+ OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
signal(SIGINT, handleSigInt);
while (!gQuitFlag)
{
if (OCProcess() != OC_STACK_OK)
{
- OC_LOG(ERROR, TAG, "OCStack process error");
+ OIC_LOG(ERROR, TAG, "OCStack process error");
return 0;
}
-
sleep(2);
}
- OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+ OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
// Free requests
if (!gRequestList.empty())
{
for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
{
- OCFree((*iter)->query);
- OCFree((*iter)->reqJSONPayload);
- OCFree(*iter);
+ OICFree((*iter)->query);
+ OCPayloadDestroy((*iter)->payload);
+ OICFree(*iter);
}
gRequestList.clear();
}
if (OCStop() != OC_STACK_OK)
{
- OC_LOG(ERROR, TAG, "OCStack process error");
+ OIC_LOG(ERROR, TAG, "OCStack process error");
}
return 0;
{
if (!uri)
{
- OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+ OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
return -1;
}
OC_RSRVD_INTERFACE_DEFAULT,
uri,
OCEntityHandlerCb,
+ NULL,
OC_DISCOVERABLE|OC_OBSERVABLE);
- OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+ OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
return 0;
}