1 //******************************************************************
3 // Copyright 2015 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
32 #include "cainterface.h"
34 #include "ocpayload.h"
38 volatile sig_atomic_t gQuitFlag = 0;
39 OCPersistentStorage ps = {0, 0, 0, 0, 0};
40 const char *gResourceUri = (char *)"/a/light";
42 //Secure Virtual Resource database for Iotivity Server
43 //It contains Server's Identity and the PSK credentials
44 //of other devices which the server trusts
45 static char CRED_FILE[] = "oic_svr_db_light.json";
48 //Structure to represent a light resource and its attributes
49 typedef struct LIGHTRESOURCE
51 OCResourceHandle handle;
53 int brightness; // 0-100
56 // Structure to represent a light resource and its attributes
57 static LightResource Light;
59 OCRepPayload* getPayload(const char* uri, int64_t brightness)
61 OCRepPayload* payload = OCRepPayloadCreate();
64 OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
68 OCRepPayloadSetUri(payload, uri);
69 OCRepPayloadSetPropInt(payload, "brightness", brightness);
74 //This function takes the request as an input and returns the response
75 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
82 if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
84 OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
88 return getPayload(gResourceUri, Light.brightness);
91 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
92 OCRepPayload **payload)
94 OCEntityHandlerResult ehResult = OC_EH_ERROR;
96 OCRepPayload *getResp = constructResponse(ehRequest);
98 if(getResp && payload)
108 OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
109 OCEntityHandlerRequest *entityHandlerRequest,
110 void* /*callbackParam*/)
112 OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
114 OCEntityHandlerResult ehResult = OC_EH_ERROR;
115 OCEntityHandlerResponse response;
118 if (!entityHandlerRequest)
120 OC_LOG (ERROR, TAG, "Invalid request pointer");
124 OCRepPayload* payload = nullptr;
126 if (flag & OC_REQUEST_FLAG)
128 OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
129 if (entityHandlerRequest)
131 switch(entityHandlerRequest->method)
135 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
136 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
141 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
142 entityHandlerRequest->method);
143 ehResult = OC_EH_ERROR;
148 if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
150 // Format the response. Note this requires some info about the request
151 response.requestHandle = entityHandlerRequest->requestHandle;
152 response.resourceHandle = entityHandlerRequest->resource;
153 response.ehResult = ehResult;
154 response.payload = reinterpret_cast<OCPayload*>(payload);
155 response.numSendVendorSpecificHeaderOptions = 0;
156 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
157 memset(response.resourceUri, 0, sizeof(response.resourceUri));
158 // Indicate that response is NOT in a persistent buffer
159 response.persistentBufferFlag = 0;
162 if (OCDoResponse(&response) != OC_STACK_OK)
164 OC_LOG(ERROR, TAG, "Error sending response");
165 ehResult = OC_EH_ERROR;
171 OCPayloadDestroy(response.payload);
175 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
176 void handleSigInt(int signum)
178 if (signum == SIGINT)
184 FILE* server_fopen(const char * /*path*/, const char *mode)
186 return fopen(CRED_FILE, mode);
189 void SetPersistentHandler(OCPersistentStorage *ps)
197 ps->open = server_fopen;
208 OCRegisterPersistentStorageHandler(ps);
214 * GetResult is returned result to string.
215 * @param result [IN] stack result
216 * @return converted OCStackResult as string for debugging
218 static const char *getResult(OCStackResult result)
223 return "OC_STACK_OK";
224 case OC_STACK_RESOURCE_CREATED:
225 return "OC_STACK_RESOURCE_CREATED";
226 case OC_STACK_RESOURCE_DELETED:
227 return "OC_STACK_RESOURCE_DELETED";
228 case OC_STACK_INVALID_URI:
229 return "OC_STACK_INVALID_URI";
230 case OC_STACK_INVALID_QUERY:
231 return "OC_STACK_INVALID_QUERY";
232 case OC_STACK_INVALID_IP:
233 return "OC_STACK_INVALID_IP";
234 case OC_STACK_INVALID_PORT:
235 return "OC_STACK_INVALID_PORT";
236 case OC_STACK_INVALID_CALLBACK:
237 return "OC_STACK_INVALID_CALLBACK";
238 case OC_STACK_INVALID_METHOD:
239 return "OC_STACK_INVALID_METHOD";
240 case OC_STACK_NO_MEMORY:
241 return "OC_STACK_NO_MEMORY";
242 case OC_STACK_COMM_ERROR:
243 return "OC_STACK_COMM_ERROR";
244 case OC_STACK_INVALID_PARAM:
245 return "OC_STACK_INVALID_PARAM";
246 case OC_STACK_NOTIMPL:
247 return "OC_STACK_NOTIMPL";
248 case OC_STACK_NO_RESOURCE:
249 return "OC_STACK_NO_RESOURCE";
250 case OC_STACK_RESOURCE_ERROR:
251 return "OC_STACK_RESOURCE_ERROR";
252 case OC_STACK_SLOW_RESOURCE:
253 return "OC_STACK_SLOW_RESOURCE";
254 case OC_STACK_NO_OBSERVERS:
255 return "OC_STACK_NO_OBSERVERS";
257 return "OC_STACK_ERROR";
264 * CreateLightResource creates a new light resource by calling the OCCreateResource() method.
265 * @param uri [IN] uri
266 * @param lightResource [IN] info of resource
267 * @return ::OC_STACK_OK on success, some other value upon failure.
269 int createLightResource (const char *uri, LightResource *lightResource)
273 OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
277 lightResource->brightness = 0;
278 OCStackResult res = OCCreateResource(&(lightResource->handle),
280 OC_RSRVD_INTERFACE_DEFAULT,
284 OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
286 OC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
293 OC_LOG(DEBUG, TAG, "OCServer is starting...");
294 SetPersistentHandler(&ps);
295 if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
297 OC_LOG(ERROR, TAG, "OCStack init error");
302 * Declare and create the example resource: Light
304 createLightResource(gResourceUri, &Light);
306 CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
308 struct timespec timeout;
310 timeout.tv_nsec = 100000000L;
312 // Break from loop with Ctrl-C
313 OC_LOG(INFO, TAG, "Entering ocserver main loop...");
314 signal(SIGINT, handleSigInt);
317 if (OCProcess() != OC_STACK_OK)
319 OC_LOG(ERROR, TAG, "OCStack process error");
323 nanosleep(&timeout, NULL);
326 OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
328 if (OCStop() != OC_STACK_OK)
330 OC_LOG(ERROR, TAG, "OCStack process error");