Copy CBOR file from res dir to data dir for protecting crash
[apps/native/position-finder-server.git] / src / connectivity.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Contact: Jin Yoon <jinny.yoon@samsung.com>
5  *          Geunsun Lee <gs86.lee@samsung.com>
6  *          Eunyoung Lee <ey928.lee@samsung.com>
7  *          Junkyu Han <junkyu.han@samsung.com>
8  *
9  * Licensed under the Flora License, Version 1.1 (the License);
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://floralicense.org/license/
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an AS IS BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <glib.h>
26 #include <Eina.h>
27
28 #include <iotcon.h>
29
30 #include "log.h"
31 #include "connectivity.h"
32
33 #define ULTRASONIC_RESOURCE_1_URI "/door/1"
34 #define ULTRASONIC_RESOURCE_2_URI "/door/2"
35 #define ULTRASONIC_RESOURCE_TYPE "org.tizen.door"
36 #define BUFSIZE 1024
37 #define CBOR_FILE_IN_RES "/home/owner/apps_rw/org.tizen.position-finder-server/res/iotcon-test-svr-db-server.dat"
38 #define CBOR_FILE_IN_DATA "/home/owner/apps_rw/org.tizen.position-finder-server/data/iotcon-test-svr-db-server.dat"
39
40 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
41
42 static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result)
43 {
44         int ret = -1;
45         iotcon_response_h response;
46
47         ret = iotcon_response_create(request, &response);
48         retv_if(IOTCON_ERROR_NONE != ret, -1);
49
50         ret = iotcon_response_set_result(response, result);
51         goto_if(IOTCON_ERROR_NONE != ret, error);
52
53         ret = iotcon_response_set_representation(response, representation);
54         goto_if(IOTCON_ERROR_NONE != ret, error);
55
56         ret = iotcon_response_send(response);
57         goto_if(IOTCON_ERROR_NONE != ret, error);
58
59         iotcon_response_destroy(response);
60
61         return 0;
62
63 error:
64         iotcon_response_destroy(response);
65         return -1;
66 }
67
68 static void _destroy_representation(iotcon_representation_h representation)
69 {
70         ret_if(!representation);
71         iotcon_representation_destroy(representation);
72 }
73
74 static iotcon_representation_h _create_representation_with_bool(iotcon_resource_h res, const char *key, bool value)
75 {
76         iotcon_attributes_h attributes = NULL;
77         iotcon_representation_h representation = NULL;
78         char *uri_path = NULL;
79         int ret = -1;
80
81         ret = iotcon_resource_get_uri_path(res, &uri_path);
82         retv_if(IOTCON_ERROR_NONE != ret, NULL);
83
84         ret = iotcon_representation_create(&representation);
85         retv_if(IOTCON_ERROR_NONE != ret, NULL);
86
87         ret = iotcon_attributes_create(&attributes);
88         goto_if(IOTCON_ERROR_NONE != ret, error);
89
90         ret = iotcon_representation_set_uri_path(representation, uri_path);
91         goto_if(IOTCON_ERROR_NONE != ret, error);
92
93         ret = iotcon_attributes_add_bool(attributes, "opened", value);
94         goto_if(IOTCON_ERROR_NONE != ret, error);
95
96         ret = iotcon_representation_set_attributes(representation, attributes);
97         goto_if(IOTCON_ERROR_NONE != ret, error);
98
99         iotcon_attributes_destroy(attributes);
100
101         return representation;
102
103 error:
104         if (attributes) iotcon_attributes_destroy(attributes);
105         if (representation) iotcon_representation_destroy(representation);
106
107         return NULL;
108 }
109
110 static iotcon_representation_h _create_representation_with_int(iotcon_resource_h res, const char *key, int value)
111 {
112         iotcon_attributes_h attributes = NULL;
113         iotcon_representation_h representation = NULL;
114         char *uri_path = NULL;
115         int ret = -1;
116
117         ret = iotcon_resource_get_uri_path(res, &uri_path);
118         retv_if(IOTCON_ERROR_NONE != ret, NULL);
119
120         ret = iotcon_representation_create(&representation);
121         retv_if(IOTCON_ERROR_NONE != ret, NULL);
122
123         ret = iotcon_attributes_create(&attributes);
124         goto_if(IOTCON_ERROR_NONE != ret, error);
125
126         ret = iotcon_representation_set_uri_path(representation, uri_path);
127         goto_if(IOTCON_ERROR_NONE != ret, error);
128
129         ret = iotcon_attributes_add_int(attributes, "opened", value);
130         goto_if(IOTCON_ERROR_NONE != ret, error);
131
132         ret = iotcon_representation_set_attributes(representation, attributes);
133         goto_if(IOTCON_ERROR_NONE != ret, error);
134
135         iotcon_attributes_destroy(attributes);
136
137         return representation;
138
139 error:
140         if (attributes) iotcon_attributes_destroy(attributes);
141         if (representation) iotcon_representation_destroy(representation);
142
143         return NULL;
144 }
145
146 static iotcon_representation_h _create_representation_with_double(iotcon_resource_h res, const char *key, double value)
147 {
148         iotcon_attributes_h attributes = NULL;
149         iotcon_representation_h representation = NULL;
150         char *uri_path = NULL;
151         int ret = -1;
152
153         ret = iotcon_resource_get_uri_path(res, &uri_path);
154         retv_if(IOTCON_ERROR_NONE != ret, NULL);
155
156         ret = iotcon_representation_create(&representation);
157         retv_if(IOTCON_ERROR_NONE != ret, NULL);
158
159         ret = iotcon_attributes_create(&attributes);
160         goto_if(IOTCON_ERROR_NONE != ret, error);
161
162         ret = iotcon_representation_set_uri_path(representation, uri_path);
163         goto_if(IOTCON_ERROR_NONE != ret, error);
164
165         ret = iotcon_attributes_add_double(attributes, "opened", value);
166         goto_if(IOTCON_ERROR_NONE != ret, error);
167
168         ret = iotcon_representation_set_attributes(representation, attributes);
169         goto_if(IOTCON_ERROR_NONE != ret, error);
170
171         iotcon_attributes_destroy(attributes);
172
173         return representation;
174
175 error:
176         if (attributes) iotcon_attributes_destroy(attributes);
177         if (representation) iotcon_representation_destroy(representation);
178
179         return NULL;
180 }
181
182 int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
183 {
184         iotcon_representation_h representation;
185         int ret = -1;
186
187         retv_if(!resource_info, -1);
188         retv_if(!resource_info->observers, -1);
189
190         _D("Notify the value[%d]", value);
191
192         representation = _create_representation_with_bool(resource_info->res, key, value);
193         retv_if(!representation, -1);
194
195         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_HIGH);
196         retv_if(IOTCON_ERROR_NONE != ret, -1);
197
198         _destroy_representation(representation);
199
200         return 0;
201 }
202
203 int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
204 {
205         iotcon_representation_h representation;
206         int ret = -1;
207
208         retv_if(!resource_info, -1);
209         retv_if(!resource_info->observers, -1);
210
211         _D("Notify the value[%d]", value);
212
213         representation = _create_representation_with_int(resource_info->res, key, value);
214         retv_if(!representation, -1);
215
216         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_HIGH);
217         retv_if(IOTCON_ERROR_NONE != ret, -1);
218
219         _destroy_representation(representation);
220
221         return 0;
222 }
223
224 int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
225 {
226         iotcon_representation_h representation;
227         int ret = -1;
228
229         retv_if(!resource_info, -1);
230         retv_if(!resource_info->observers, -1);
231
232         _D("Notify the value[%f]", value);
233
234         representation = _create_representation_with_double(resource_info->res, key, value);
235         retv_if(!representation, -1);
236
237         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_HIGH);
238         retv_if(IOTCON_ERROR_NONE != ret, -1);
239
240         _destroy_representation(representation);
241
242         return 0;
243 }
244
245 static bool _query_cb(const char *key, const char *value, void *user_data)
246 {
247         _D("Key : [%s], Value : [%s]", key, value);
248
249         return IOTCON_FUNC_CONTINUE;
250 }
251
252 static int _handle_query(iotcon_request_h request)
253 {
254         iotcon_query_h query = NULL;
255         int ret = -1;
256
257         ret = iotcon_request_get_query(request, &query);
258         retv_if(IOTCON_ERROR_NONE != ret, -1);
259
260         if (query) iotcon_query_foreach(query, _query_cb, NULL);
261
262         return 0;
263 }
264
265 static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info)
266 {
267         iotcon_request_type_e type;
268         int ret = -1;
269
270         ret = iotcon_request_get_request_type(request, &type);
271         retv_if(IOTCON_ERROR_NONE != ret, -1);
272
273         switch (type) {
274         case IOTCON_REQUEST_GET:
275                 _I("Do not support 'get' query");
276                 break;
277         case IOTCON_REQUEST_PUT:
278                 _I("Do not support 'put' query");
279                 break;
280         case IOTCON_REQUEST_POST:
281                 _I("Do not support 'post' query");
282                 break;
283         case IOTCON_REQUEST_DELETE:
284                 _I("Do not support 'delete' query");
285                 break;
286         default:
287                 _E("Cannot reach here");
288                 ret = -1;
289                 break;
290         }
291         retv_if(0 != ret, -1);
292
293         return 0;
294 }
295
296 static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers)
297 {
298         iotcon_observe_type_e observe_type;
299         int ret = -1;
300         int observe_id = -1;
301
302         ret = iotcon_request_get_observe_type(request, &observe_type);
303         retv_if(IOTCON_ERROR_NONE != ret, -1);
304
305         if (IOTCON_OBSERVE_REGISTER == observe_type) {
306                 ret = iotcon_request_get_observe_id(request, &observe_id);
307                 retv_if(IOTCON_ERROR_NONE != ret, -1);
308
309                 _I("Add an observer : %d", observe_id);
310
311                 ret = iotcon_observers_add(observers, observe_id);
312                 retv_if(IOTCON_ERROR_NONE != ret, -1);
313         } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
314                 ret = iotcon_request_get_observe_id(request, &observe_id);
315                 retv_if(IOTCON_ERROR_NONE != ret, -1);
316
317                 _I("Remove an observer : %d", observe_id);
318
319                 ret = iotcon_observers_remove(observers, observe_id);
320                 retv_if(IOTCON_ERROR_NONE != ret, -1);
321         }
322
323         return 0;
324 }
325
326 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
327 {
328         connectivity_resource_s *resource_info = user_data;
329         int ret = -1;
330         char *host_address = NULL;
331
332         ret_if(!request);
333
334         ret = iotcon_request_get_host_address(request, &host_address);
335         goto_if(IOTCON_ERROR_NONE != ret, error);
336
337         _D("Host address : %s", host_address);
338
339         ret = _handle_query(request);
340         goto_if(IOTCON_ERROR_NONE != ret, error);
341
342         ret = _handle_request_by_crud_type(request, resource_info);
343         goto_if(0 != ret, error);
344
345         ret = _handle_observer(request, resource_info->observers);
346         goto_if(0 != ret, error);
347
348         return;
349
350 error:
351         _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
352 }
353
354 static void _copy_file(const char *in_filename, const char *out_filename)
355 {
356         char buf[BUFSIZE] = { 0, };
357         size_t nread = 0;
358         FILE *in = NULL;
359         FILE *out = NULL;
360
361         ret_if(!in_filename);
362         ret_if(!out_filename);
363
364         in = fopen(in_filename, "r");
365         ret_if(!in);
366
367         out = fopen(out_filename, "w");
368         goto_if(!out, error);
369
370         rewind(in);
371         while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
372                 if (fwrite (buf, 1, nread, out) < nread) {
373                         _E("critical error to copy a file");
374                         break;
375                 }
376         }
377
378         fclose(in);
379         fclose(out);
380
381         return;
382
383 error:
384         fclose(out);
385 }
386
387 int connectivity_init(void)
388 {
389         int ret = -1;
390
391         _copy_file(CBOR_FILE_IN_RES, CBOR_FILE_IN_DATA);
392
393         ret = iotcon_initialize(CBOR_FILE_IN_DATA);
394         retv_if(IOTCON_ERROR_NONE != ret, -1);
395
396         ret = iotcon_set_device_name(ULTRASONIC_RESOURCE_TYPE);
397         goto_if(IOTCON_ERROR_NONE != ret, error);
398
399         return 0;
400
401 error:
402         iotcon_deinitialize();
403         return -1;
404 }
405
406 int connectivity_fini(void)
407 {
408         iotcon_deinitialize();
409         return 0;
410 }
411
412 void connectivity_unset_resource(connectivity_resource_s *resource_info)
413 {
414         ret_if(!resource_info);
415         if (resource_info->observers) iotcon_observers_destroy(resource_info->observers);
416         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
417         free(resource_info);
418 }
419
420 int connectivity_set_resource(const char *uri_path, const char *type, connectivity_resource_s **out_resource_info)
421 {
422         iotcon_resource_types_h resource_types = NULL;
423         iotcon_resource_interfaces_h ifaces = NULL;
424         connectivity_resource_s *resource_info = NULL;
425         uint8_t policies;
426         int ret = -1;
427
428         resource_info = calloc(1, sizeof(connectivity_resource_s));
429         retv_if(!resource_info, -1);
430         *out_resource_info = resource_info;
431
432         ret = iotcon_resource_types_create(&resource_types);
433         goto_if(IOTCON_ERROR_NONE != ret, error);
434
435         ret = iotcon_resource_types_add(resource_types, type);
436         goto_if(IOTCON_ERROR_NONE != ret, error);
437
438         ret = iotcon_resource_interfaces_create(&ifaces);
439         goto_if(IOTCON_ERROR_NONE != ret, error);
440
441         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT);
442         goto_if(IOTCON_ERROR_NONE != ret, error);
443
444         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH);
445         goto_if(IOTCON_ERROR_NONE != ret, error);
446
447         policies =
448                 IOTCON_RESOURCE_DISCOVERABLE |
449                 IOTCON_RESOURCE_OBSERVABLE |
450                 IOTCON_RESOURCE_SECURE;
451
452         ret = iotcon_resource_create(uri_path,
453                         resource_types,
454                         ifaces,
455                         policies,
456                         _request_resource_handler,
457                         resource_info,
458                         &resource_info->res);
459         goto_if(IOTCON_ERROR_NONE != ret, error);
460
461         ret = iotcon_observers_create(&resource_info->observers);
462         goto_if(IOTCON_ERROR_NONE != ret, error);
463
464         iotcon_resource_types_destroy(resource_types);
465         iotcon_resource_interfaces_destroy(ifaces);
466
467         return 0;
468
469 error:
470         if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
471         if (resource_types) iotcon_resource_types_destroy(resource_types);
472         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
473         if (resource_info) free(resource_info);
474
475         return -1;
476 }