X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fstack%2Fsamples%2Flinux%2FSimpleClientServer%2Focserverslow.cpp;h=2e45cbce2b602d402c0d7fb8bc3f271d6af3a93a;hb=c315c87e07c4080ecd0ef488e7a1047bc3c509b2;hp=2c42f6fbd13cd15def4d192b5424085b8a6a77fb;hpb=04b065bb9da82a3a737a0bffca4c329eb5e524ab;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp index 2c42f6f..2e45cbc 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp @@ -18,28 +18,46 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include "iotivity_config.h" #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif +#ifdef HAVE_WINDOWS_H +#include +#endif #include +#ifdef HAVE_PTHREAD_H #include +#endif +#ifdef HAVE_SYS_TIME_H #include +#endif +#include #include #include "ocstack.h" #include "oic_malloc.h" +#include "oic_string.h" #include "logger.h" +#if defined (__TIZENRT__) +#include +#else #include "cJSON.h" +#endif #include "ocserverslow.h" +#include "ocpayload.h" +#include "payload_logging.h" volatile sig_atomic_t gQuitFlag = 0; static std::list 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("/a/led"); @@ -47,94 +65,81 @@ char *gResourceUri= (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("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("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 (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 (getResp); response.numSendVendorSpecificHeaderOptions = 0; memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions); @@ -145,88 +150,97 @@ void ProcessGetRequest (OCEntityHandlerRequest *ehRequest) // 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 = + OIC_LOG(INFO, TAG, "Copying received request for slow response"); + + OCEntityHandlerRequest *copyOfRequest = (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest)); - if (request) + + if (copyOfRequest) { // Do shallow copy - memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest)); - // Do deep copy of query - request->query = - (char * )OICMalloc(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 * )OICMalloc( - 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) { - OICFree(request->query); - OICFree(request); - request = NULL; + OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure"); + OICFree(copyOfRequest); + return NULL; } } - else + + if (entityHandlerRequest->payload) { - OICFree(request); - request = NULL; + copyOfRequest->payload = reinterpret_cast + (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* callbackParam) +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); + 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; @@ -235,14 +249,14 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag, } 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; } } @@ -262,12 +276,14 @@ void handleSigInt(int signum) // 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; } @@ -276,17 +292,22 @@ void AlarmHandler(int sig) 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 OICFree(entityHandlerRequest->query); - OICFree(entityHandlerRequest->reqJSONPayload); + OCPayloadDestroy(entityHandlerRequest->payload); OICFree(entityHandlerRequest); // If there are more requests in list, re-arm the alarm signal @@ -297,40 +318,39 @@ void AlarmHandler(int sig) } } -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()) @@ -338,7 +358,7 @@ int main(int argc, char* argv[]) for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter) { OICFree((*iter)->query); - OICFree((*iter)->reqJSONPayload); + OCPayloadDestroy((*iter)->payload); OICFree(*iter); } gRequestList.clear(); @@ -346,7 +366,7 @@ int main(int argc, char* argv[]) if (OCStop() != OC_STACK_OK) { - OC_LOG(ERROR, TAG, "OCStack process error"); + OIC_LOG(ERROR, TAG, "OCStack process error"); } return 0; @@ -356,7 +376,7 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, { if (!uri) { - OC_LOG(ERROR, TAG, "Resource URI cannot be NULL"); + OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL"); return -1; } @@ -369,7 +389,7 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, 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; }