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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "iotivity_config.h"
35 #ifdef HAVE_SYS_TIME_H
38 #include <boost/config.hpp>
41 #include "oic_malloc.h"
42 #include "oic_string.h"
44 #if defined (__TIZENRT__)
45 #include <apps/netutils/cJSON.h>
49 #include "ocserverslow.h"
50 #include "ocpayload.h"
51 #include "payload_logging.h"
53 volatile sig_atomic_t gQuitFlag = 0;
55 static std::list<OCEntityHandlerRequest *> gRequestList;
56 BOOST_STATIC_CONSTEXPR unsigned int SLOW_RESPONSE_DELAY_SEC = 5;
58 static LEDResource LED;
60 BOOST_STATIC_CONSTEXPR unsigned int SAMPLE_MAX_NUM_POST_INSTANCE = 2;
61 static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
63 //char *gResourceUri= const_cast<char *>("/a/led");
64 char *gResourceUri= (char *)"/a/led";
66 //This function takes the request as an input and returns the response
68 OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
70 LEDResource *currLEDResource = &LED;
72 OIC_LOG(INFO, TAG, "Entering constructResponse");
74 if (ehRequest->resource == gLedInstance[0].handle)
76 OIC_LOG(INFO, TAG, "handle 0");
77 currLEDResource = &gLedInstance[0];
78 gResourceUri = const_cast<char *>("a/led/0");
80 else if (ehRequest->resource == gLedInstance[1].handle)
82 OIC_LOG(INFO, TAG, "handle 1");
83 currLEDResource = &gLedInstance[1];
84 gResourceUri = const_cast<char *>("a/led/1");
87 if(OC_REST_PUT == ehRequest->method)
89 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
91 OIC_LOG(ERROR, TAG, ("Incoming payload not a representation"));
95 OCRepPayload *putPayload = reinterpret_cast<OCRepPayload*> (ehRequest->payload);
100 if (OCRepPayloadGetPropBool(putPayload, "state", &state))
102 currLEDResource->state = state;
104 if (OCRepPayloadGetPropInt (putPayload, "power", &power))
106 currLEDResource->power = power;
110 OCRepPayload *response = OCRepPayloadCreate();
114 OIC_LOG_V(ERROR, TAG, "Memory allocation for response payload failed.");
117 OCRepPayloadSetUri (response, gResourceUri);
118 OCRepPayloadSetPropBool(response, "state", currLEDResource->state);
119 OCRepPayloadSetPropInt(response, "power", currLEDResource->power);
124 void ProcessGetPutRequest (OCEntityHandlerRequest *ehRequest)
126 OIC_LOG(INFO, TAG, "Entering ProcessGetPutRequest");
128 OCRepPayload *getResp = constructResponse(ehRequest);
132 OIC_LOG(ERROR, TAG, "Failed to construct response");
136 OCEntityHandlerResponse response;
138 // Format the response. Note this requires some info about the request
139 response.requestHandle = ehRequest->requestHandle;
140 response.resourceHandle = ehRequest->resource;
141 response.ehResult = OC_EH_OK;
142 response.payload = reinterpret_cast<OCPayload*> (getResp);
143 response.numSendVendorSpecificHeaderOptions = 0;
144 memset(response.sendVendorSpecificHeaderOptions,
145 0, sizeof response.sendVendorSpecificHeaderOptions);
146 memset(response.resourceUri, 0, sizeof(response.resourceUri));
147 // Indicate that response is NOT in a persistent buffer
148 response.persistentBufferFlag = 0;
151 if (OCDoResponse(&response) != OC_STACK_OK)
153 OIC_LOG(ERROR, TAG, "Error sending response");
156 OCRepPayloadDestroy(getResp);
159 OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
161 OIC_LOG(INFO, TAG, "Copying received request for slow response");
163 OCEntityHandlerRequest *copyOfRequest =
164 (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
169 memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
172 if (copyOfRequest->query)
174 copyOfRequest->query = OICStrdup(entityHandlerRequest->query);
175 if(!copyOfRequest->query)
177 OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
178 OICFree(copyOfRequest);
183 if (entityHandlerRequest->payload)
185 copyOfRequest->payload = reinterpret_cast<OCPayload*>
186 (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
189 // Ignore vendor specific header options for example
190 copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
191 copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
196 OIC_LOG(INFO, TAG, "Copied client request");
200 OIC_LOG(ERROR, TAG, "Error copying client request");
202 return copyOfRequest;
205 #if !defined(SIGALRM)
206 void AlarmHandler(int sig);
207 int WINAPI AlarmThread(void *seconds)
209 sleep((unsigned int)seconds);
214 void alarm(unsigned int seconds)
216 CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AlarmThread, (void*)seconds, 0, NULL);
220 OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
221 OCEntityHandlerRequest *entityHandlerRequest, void* /*callbackParam*/)
223 OCEntityHandlerResult result = OC_EH_ERROR;
224 OCEntityHandlerRequest *request = NULL;
226 OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
228 if (flag & OC_REQUEST_FLAG)
230 OIC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
231 if (entityHandlerRequest)
233 OIC_LOG_V (INFO, TAG, "request query %s from client",
234 entityHandlerRequest->query);
235 OIC_LOG_PAYLOAD (INFO, entityHandlerRequest->payload);
237 // Make deep copy of received request and queue it for slow processing
238 request = CopyRequest(entityHandlerRequest);
243 OIC_LOG(INFO, TAG, "Scheduling slow response for received request");
244 gRequestList.push_back(request);
245 // Indicate to the stack that this is a slow response
247 // Start the slow response alarm
248 alarm(SLOW_RESPONSE_DELAY_SEC);
252 OIC_LOG(ERROR, TAG, "Error queuing request for slow response");
253 // Indicate to the stack that this is a slow response
254 result = OC_EH_ERROR;
259 OIC_LOG(ERROR, TAG, "Invalid request");
260 result = OC_EH_ERROR;
266 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
267 void handleSigInt(int signum)
269 if (signum == SIGINT)
275 // SIGINT alarm handler: alarm set by entity handler. Does
276 // slow response when fired
277 void AlarmHandler(int sig)
283 OIC_LOG (INFO, TAG, "Server starting slow response");
284 if (gRequestList.empty())
286 OIC_LOG (INFO, TAG, "No requests to service");
290 // Get the request from the list
291 OCEntityHandlerRequest *entityHandlerRequest = gRequestList.front();
292 gRequestList.pop_front();
293 if (entityHandlerRequest->method == OC_REST_GET)
295 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
296 ProcessGetPutRequest (entityHandlerRequest);
298 else if (entityHandlerRequest->method == OC_REST_PUT)
300 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
301 ProcessGetPutRequest (entityHandlerRequest);
305 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
306 entityHandlerRequest->method);
309 OICFree(entityHandlerRequest->query);
310 OCPayloadDestroy(entityHandlerRequest->payload);
311 OICFree(entityHandlerRequest);
313 // If there are more requests in list, re-arm the alarm signal
314 if (gRequestList.empty())
316 alarm(SLOW_RESPONSE_DELAY_SEC);
321 int main(int /*argc*/, char** /*argv[]*/)
323 OIC_LOG(DEBUG, TAG, "OCServer is starting...");
325 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
327 OIC_LOG(ERROR, TAG, "OCStack init error");
331 // Declare and create the example resource: LED
332 createLEDResource(gResourceUri, &LED, false, 42);
335 // Initialize slow response alarm
336 signal(SIGALRM, AlarmHandler);
339 // Break from loop with Ctrl-C
340 OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
341 signal(SIGINT, handleSigInt);
345 if (OCProcess() != OC_STACK_OK)
347 OIC_LOG(ERROR, TAG, "OCStack process error");
353 OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
356 if (!gRequestList.empty())
358 for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
360 OICFree((*iter)->query);
361 OCPayloadDestroy((*iter)->payload);
364 gRequestList.clear();
367 if (OCStop() != OC_STACK_OK)
369 OIC_LOG(ERROR, TAG, "OCStack process error");
375 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
379 OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
383 ledResource->state = resourceState;
384 ledResource->power= resourcePower;
385 OCStackResult res = OCCreateResource(&(ledResource->handle),
387 OC_RSRVD_INTERFACE_DEFAULT,
391 OC_DISCOVERABLE|OC_OBSERVABLE);
392 OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));