replaced OC_LOG with OIC_LOG in security
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / ck_manager / sample / Light_sample.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <iostream>
27 #include <pthread.h>
28 #include "ocstack.h"
29 #include "logger.h"
30 #include "cJSON.h"
31 #include "global.h"
32 #include "cainterface.h"
33 #include "cacommon.h"
34 #include "ocpayload.h"
35
36 #define TAG "DEMO"
37
38 volatile sig_atomic_t gQuitFlag = 0;
39 OCPersistentStorage ps = {0, 0, 0, 0, 0};
40 const char *gResourceUri = (char *)"/a/light";
41
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";
46
47
48 //Structure to represent a light resource  and its attributes
49 typedef struct LIGHTRESOURCE
50 {
51     OCResourceHandle handle;
52     //Attributes
53     int brightness;   // 0-100
54 } LightResource;
55
56 // Structure to represent a light resource  and its attributes
57 static LightResource Light;
58
59 OCRepPayload* getPayload(const char* uri, int64_t brightness)
60 {
61     OCRepPayload* payload = OCRepPayloadCreate();
62     if(!payload)
63     {
64         OIC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
65         return nullptr;
66     }
67
68     OCRepPayloadSetUri(payload, uri);
69     OCRepPayloadSetPropInt(payload, "brightness", brightness);
70
71     return payload;
72 }
73
74 //This function takes the request as an input and returns the response
75 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
76 {
77     if(!ehRequest)
78     {
79         return nullptr;
80     }
81
82     if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
83     {
84         OIC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
85         return nullptr;
86     }
87
88     return getPayload(gResourceUri, Light.brightness);
89 }
90
91 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
92         OCRepPayload **payload)
93 {
94     OCEntityHandlerResult ehResult = OC_EH_ERROR;
95
96     OCRepPayload *getResp = constructResponse(ehRequest);
97
98     if(getResp && payload)
99     {
100         *payload = getResp;
101         ehResult = OC_EH_OK;
102     }
103
104     return ehResult;
105 }
106
107
108 OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
109                                          OCEntityHandlerRequest *entityHandlerRequest,
110                                          void* /*callbackParam*/)
111 {
112     OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
113
114     OCEntityHandlerResult ehResult = OC_EH_ERROR;
115     OCEntityHandlerResponse response;
116
117     // Validate pointer
118     if (!entityHandlerRequest)
119     {
120         OIC_LOG (ERROR, TAG, "Invalid request pointer");
121         return OC_EH_ERROR;
122     }
123
124     OCRepPayload* payload = nullptr;
125
126     if (flag & OC_REQUEST_FLAG)
127     {
128         OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
129         if (entityHandlerRequest)
130         {
131             switch(entityHandlerRequest->method)
132             {
133             case OC_REST_GET:
134             {
135                 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
136                 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
137             }
138             break;
139             default:
140             {
141                 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
142                         entityHandlerRequest->method);
143                 ehResult = OC_EH_ERROR;
144             }
145             break;
146             }
147
148             if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
149             {
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;
160
161                 // Send the response
162                 if (OCDoResponse(&response) != OC_STACK_OK)
163                 {
164                     OIC_LOG(ERROR, TAG, "Error sending response");
165                     ehResult = OC_EH_ERROR;
166                 }
167             }
168         }
169     }
170
171     OCPayloadDestroy(response.payload);
172     return ehResult;
173 }
174
175 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
176 void handleSigInt(int signum)
177 {
178     if (signum == SIGINT)
179     {
180         gQuitFlag = 1;
181     }
182 }
183
184 FILE* server_fopen(const char * /*path*/, const char *mode)
185 {
186     return fopen(CRED_FILE, mode);
187 }
188
189 void SetPersistentHandler(OCPersistentStorage *ps)
190
191 {
192
193     if (ps)
194
195     {
196
197         ps->open =  server_fopen;
198
199         ps->read = fread;
200
201         ps->write = fwrite;
202
203         ps->close = fclose;
204
205         ps->unlink = unlink;
206
207
208         OCRegisterPersistentStorageHandler(ps);
209
210     }
211
212 }
213 /**
214  * GetResult is returned result to string.
215  * @param   result             [IN] stack result
216  * @return  converted OCStackResult as string for debugging
217  */
218 static const char *getResult(OCStackResult result)
219 {
220     switch (result)
221     {
222         case OC_STACK_OK:
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";
256         case OC_STACK_ERROR:
257             return "OC_STACK_ERROR";
258         default:
259             return "UNKNOWN";
260     }
261 }
262
263 /**
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.
268  */
269 int createLightResource (const char *uri, LightResource *lightResource)
270 {
271     if (!uri)
272     {
273         OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
274
275     }
276
277     lightResource->brightness = 0;
278     OCStackResult res = OCCreateResource(&(lightResource->handle),
279                                          "core.light",
280                                          OC_RSRVD_INTERFACE_DEFAULT,
281                                          uri,
282                                          OCEntityHandlerCb,
283                                          NULL,
284                                          OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
285
286     OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
287     return 0;
288 }
289
290
291 int main()
292 {
293     OIC_LOG(DEBUG, TAG, "OCServer is starting...");
294     SetPersistentHandler(&ps);
295     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
296     {
297         OIC_LOG(ERROR, TAG, "OCStack init error");
298         return 0;
299     }
300
301     /*
302      * Declare and create the example resource: Light
303      */
304     createLightResource(gResourceUri, &Light);
305
306     CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
307
308     struct timespec timeout;
309     timeout.tv_sec  = 0;
310     timeout.tv_nsec = 100000000L;
311
312     // Break from loop with Ctrl-C
313     OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
314     signal(SIGINT, handleSigInt);
315     while (!gQuitFlag)
316     {
317         if (OCProcess() != OC_STACK_OK)
318         {
319             OIC_LOG(ERROR, TAG, "OCStack process error");
320             return 0;
321         }
322
323         nanosleep(&timeout, NULL);
324     }
325
326     OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
327
328     if (OCStop() != OC_STACK_OK)
329     {
330         OIC_LOG(ERROR, TAG, "OCStack process error");
331     }
332
333     return 0;
334 }