b2f0b78c0afcaacf64b4ef14c8cee0d0ede67a73
[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 #include <app_common.h>
28
29 #include "log.h"
30 #include "connectivity.h"
31
32 #define DEVICE_NAME "org.tizen.device"
33 #define BUFSIZE 1024
34 #define URI_PATH_LEN 64
35 #define URI_PATH "/door/1"
36 #define PATH "path"
37
38 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
39
40 static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result)
41 {
42         int ret = -1;
43         iotcon_response_h response;
44
45         ret = iotcon_response_create(request, &response);
46         retv_if(IOTCON_ERROR_NONE != ret, -1);
47
48         ret = iotcon_response_set_result(response, result);
49         goto_if(IOTCON_ERROR_NONE != ret, error);
50
51         ret = iotcon_response_set_representation(response, representation);
52         goto_if(IOTCON_ERROR_NONE != ret, error);
53
54         ret = iotcon_response_send(response);
55         goto_if(IOTCON_ERROR_NONE != ret, error);
56
57         iotcon_response_destroy(response);
58
59         return 0;
60
61 error:
62         iotcon_response_destroy(response);
63         return -1;
64 }
65
66 static void _destroy_representation(iotcon_representation_h representation)
67 {
68         ret_if(!representation);
69         iotcon_representation_destroy(representation);
70 }
71
72 static iotcon_representation_h _create_representation_with_bool(connectivity_resource_s *resource_info, const char *key, bool value)
73 {
74         iotcon_attributes_h attributes = NULL;
75         iotcon_representation_h representation = NULL;
76         char *uri_path = NULL;
77         int ret = -1;
78
79         ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
80         retv_if(IOTCON_ERROR_NONE != ret, NULL);
81
82         ret = iotcon_representation_create(&representation);
83         retv_if(IOTCON_ERROR_NONE != ret, NULL);
84
85         ret = iotcon_attributes_create(&attributes);
86         goto_if(IOTCON_ERROR_NONE != ret, error);
87
88         ret = iotcon_representation_set_uri_path(representation, uri_path);
89         goto_if(IOTCON_ERROR_NONE != ret, error);
90
91         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
92         goto_if(IOTCON_ERROR_NONE != ret, error);
93
94         ret = iotcon_attributes_add_bool(attributes, key, value);
95         goto_if(IOTCON_ERROR_NONE != ret, error);
96
97         ret = iotcon_representation_set_attributes(representation, attributes);
98         goto_if(IOTCON_ERROR_NONE != ret, error);
99
100         iotcon_attributes_destroy(attributes);
101
102         return representation;
103
104 error:
105         if (attributes) iotcon_attributes_destroy(attributes);
106         if (representation) iotcon_representation_destroy(representation);
107
108         return NULL;
109 }
110
111 static iotcon_representation_h _create_representation_with_int(connectivity_resource_s *resource_info, const char *key, int value)
112 {
113         iotcon_attributes_h attributes = NULL;
114         iotcon_representation_h representation = NULL;
115         char *uri_path = NULL;
116         int ret = -1;
117
118         ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
119         retv_if(IOTCON_ERROR_NONE != ret, NULL);
120
121         ret = iotcon_representation_create(&representation);
122         retv_if(IOTCON_ERROR_NONE != ret, NULL);
123
124         ret = iotcon_attributes_create(&attributes);
125         goto_if(IOTCON_ERROR_NONE != ret, error);
126
127         ret = iotcon_representation_set_uri_path(representation, uri_path);
128         goto_if(IOTCON_ERROR_NONE != ret, error);
129
130         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
131         goto_if(IOTCON_ERROR_NONE != ret, error);
132
133         ret = iotcon_attributes_add_int(attributes, key, value);
134         goto_if(IOTCON_ERROR_NONE != ret, error);
135
136         ret = iotcon_representation_set_attributes(representation, attributes);
137         goto_if(IOTCON_ERROR_NONE != ret, error);
138
139         iotcon_attributes_destroy(attributes);
140
141         return representation;
142
143 error:
144         if (attributes) iotcon_attributes_destroy(attributes);
145         if (representation) iotcon_representation_destroy(representation);
146
147         return NULL;
148 }
149
150 static iotcon_representation_h _create_representation_with_double(connectivity_resource_s *resource_info, const char *key, double value)
151 {
152         iotcon_attributes_h attributes = NULL;
153         iotcon_representation_h representation = NULL;
154         char *uri_path = NULL;
155         int ret = -1;
156
157         ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
158         retv_if(IOTCON_ERROR_NONE != ret, NULL);
159
160         ret = iotcon_representation_create(&representation);
161         retv_if(IOTCON_ERROR_NONE != ret, NULL);
162
163         ret = iotcon_attributes_create(&attributes);
164         goto_if(IOTCON_ERROR_NONE != ret, error);
165
166         ret = iotcon_representation_set_uri_path(representation, uri_path);
167         goto_if(IOTCON_ERROR_NONE != ret, error);
168
169         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
170         goto_if(IOTCON_ERROR_NONE != ret, error);
171
172         ret = iotcon_attributes_add_str(attributes, "Hash", "0");
173         goto_if(IOTCON_ERROR_NONE != ret, error);
174
175         ret = iotcon_attributes_add_double(attributes, key, value);
176         goto_if(IOTCON_ERROR_NONE != ret, error);
177
178         ret = iotcon_representation_set_attributes(representation, attributes);
179         goto_if(IOTCON_ERROR_NONE != ret, error);
180
181         iotcon_attributes_destroy(attributes);
182
183         return representation;
184
185 error:
186         if (attributes) iotcon_attributes_destroy(attributes);
187         if (representation) iotcon_representation_destroy(representation);
188
189         return NULL;
190 }
191
192 static iotcon_representation_h _create_representation_with_string(connectivity_resource_s *resource_info, const char *key, char *value)
193 {
194         iotcon_attributes_h attributes = NULL;
195         iotcon_representation_h representation = NULL;
196         char *uri_path = NULL;
197         int ret = -1;
198
199         ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
200         retv_if(IOTCON_ERROR_NONE != ret, NULL);
201
202         ret = iotcon_representation_create(&representation);
203         retv_if(IOTCON_ERROR_NONE != ret, NULL);
204
205         ret = iotcon_attributes_create(&attributes);
206         goto_if(IOTCON_ERROR_NONE != ret, error);
207
208         ret = iotcon_representation_set_uri_path(representation, uri_path);
209         goto_if(IOTCON_ERROR_NONE != ret, error);
210
211         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
212         goto_if(IOTCON_ERROR_NONE != ret, error);
213
214         ret = iotcon_attributes_add_str(attributes, key, value);
215         goto_if(IOTCON_ERROR_NONE != ret, error);
216
217         ret = iotcon_representation_set_attributes(representation, attributes);
218         goto_if(IOTCON_ERROR_NONE != ret, error);
219
220         iotcon_attributes_destroy(attributes);
221
222         return representation;
223
224 error:
225         if (attributes) iotcon_attributes_destroy(attributes);
226         if (representation) iotcon_representation_destroy(representation);
227
228         return NULL;
229 }
230
231 static void _print_iotcon_error(int err_no)
232 {
233         switch (err_no) {
234         case IOTCON_ERROR_NOT_SUPPORTED:
235                 _E("IOTCON_ERROR_NOT_SUPPORTED");
236                 break;
237         case IOTCON_ERROR_PERMISSION_DENIED:
238                 _E("IOTCON_ERROR_PERMISSION_DENIED");
239                 break;
240         case IOTCON_ERROR_INVALID_PARAMETER:
241                 _E("IOTCON_ERROR_INVALID_PARAMETER");
242                 break;
243         default:
244                 _E("Error : [%d]", err_no);
245                 break;
246         }
247 }
248
249 int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
250 {
251         iotcon_representation_h representation;
252         int ret = -1;
253
254         retv_if(!resource_info, -1);
255         retv_if(!resource_info->observers, -1);
256
257         _D("Notify the value[%d]", value);
258
259         representation = _create_representation_with_bool(resource_info, key, value);
260         retv_if(!representation, -1);
261
262         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
263         if (IOTCON_ERROR_NONE != ret) {
264                 _I("There are some troubles for notifying value[%d]", ret);
265                 _print_iotcon_error(ret);
266                 return -1;
267         }
268
269         _destroy_representation(representation);
270
271         return 0;
272 }
273
274 int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
275 {
276         iotcon_representation_h representation;
277         int ret = -1;
278
279         retv_if(!resource_info, -1);
280         retv_if(!resource_info->observers, -1);
281
282         _D("Notify the value[%d]", value);
283
284         representation = _create_representation_with_int(resource_info, key, value);
285         retv_if(!representation, -1);
286
287         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
288         if (IOTCON_ERROR_NONE != ret) {
289                 _I("There are some troubles for notifying value[%d]", ret);
290                 _print_iotcon_error(ret);
291                 return -1;
292         }
293
294         _destroy_representation(representation);
295
296         return 0;
297 }
298
299 int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
300 {
301         iotcon_representation_h representation;
302         int ret = -1;
303
304         retv_if(!resource_info, -1);
305         retv_if(!resource_info->observers, -1);
306
307         _D("Notify the value [%.2lf]", value);
308
309         representation = _create_representation_with_double(resource_info, key, value);
310         retv_if(!representation, -1);
311
312         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
313         if (IOTCON_ERROR_NONE != ret) {
314                 _I("There are some troubles for notifying value[%d]", ret);
315                 _print_iotcon_error(ret);
316                 return -1;
317         }
318
319         _destroy_representation(representation);
320
321         return 0;
322 }
323
324 int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, char *value)
325 {
326         iotcon_representation_h representation;
327         int ret = -1;
328
329         retv_if(!resource_info, -1);
330         retv_if(!resource_info->observers, -1);
331
332         _D("Notify the value [%s]", value);
333
334         representation = _create_representation_with_string(resource_info, key, value);
335         retv_if(!representation, -1);
336
337         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
338         if (IOTCON_ERROR_NONE != ret) {
339                 _I("There are some troubles for notifying value[%d]", ret);
340                 _print_iotcon_error(ret);
341                 return -1;
342         }
343
344         _destroy_representation(representation);
345
346         return 0;
347 }
348
349 static bool _query_cb(const char *key, const char *value, void *user_data)
350 {
351         _D("Key : [%s], Value : [%s]", key, value);
352
353         return IOTCON_FUNC_CONTINUE;
354 }
355
356 static int _handle_query(iotcon_request_h request)
357 {
358         iotcon_query_h query = NULL;
359         int ret = -1;
360
361         ret = iotcon_request_get_query(request, &query);
362         retv_if(IOTCON_ERROR_NONE != ret, -1);
363
364         if (query) iotcon_query_foreach(query, _query_cb, NULL);
365
366         return 0;
367 }
368
369 static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info)
370 {
371         iotcon_request_type_e type;
372         int ret = -1;
373
374         ret = iotcon_request_get_request_type(request, &type);
375         retv_if(IOTCON_ERROR_NONE != ret, -1);
376
377         switch (type) {
378         case IOTCON_REQUEST_GET:
379                 _I("Do not support 'get' query");
380                 break;
381         case IOTCON_REQUEST_PUT:
382                 _I("Do not support 'put' query");
383                 break;
384         case IOTCON_REQUEST_POST:
385                 _I("Do not support 'post' query");
386                 break;
387         case IOTCON_REQUEST_DELETE:
388                 _I("Do not support 'delete' query");
389                 break;
390         default:
391                 _E("Cannot reach here");
392                 ret = -1;
393                 break;
394         }
395         retv_if(0 != ret, -1);
396
397         return 0;
398 }
399
400 static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers)
401 {
402         iotcon_observe_type_e observe_type;
403         int ret = -1;
404         int observe_id = -1;
405
406         ret = iotcon_request_get_observe_type(request, &observe_type);
407         retv_if(IOTCON_ERROR_NONE != ret, -1);
408
409         if (IOTCON_OBSERVE_REGISTER == observe_type) {
410                 ret = iotcon_request_get_observe_id(request, &observe_id);
411                 retv_if(IOTCON_ERROR_NONE != ret, -1);
412
413                 _I("Add an observer : %d", observe_id);
414
415                 ret = iotcon_observers_add(observers, observe_id);
416                 retv_if(IOTCON_ERROR_NONE != ret, -1);
417         } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
418                 ret = iotcon_request_get_observe_id(request, &observe_id);
419                 retv_if(IOTCON_ERROR_NONE != ret, -1);
420
421                 _I("Remove an observer : %d", observe_id);
422
423                 ret = iotcon_observers_remove(observers, observe_id);
424                 retv_if(IOTCON_ERROR_NONE != ret, -1);
425         }
426
427         return 0;
428 }
429
430 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
431 {
432         connectivity_resource_s *resource_info = user_data;
433         int ret = -1;
434         char *host_address = NULL;
435
436         ret_if(!request);
437
438         ret = iotcon_request_get_host_address(request, &host_address);
439         goto_if(IOTCON_ERROR_NONE != ret, error);
440
441         _D("Host address : %s", host_address);
442
443         ret = _handle_query(request);
444         goto_if(IOTCON_ERROR_NONE != ret, error);
445
446         ret = _handle_request_by_crud_type(request, resource_info);
447         goto_if(0 != ret, error);
448
449         ret = _handle_observer(request, resource_info->observers);
450         goto_if(0 != ret, error);
451
452         return;
453
454 error:
455         _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
456 }
457
458 static void _copy_file(const char *in_filename, const char *out_filename)
459 {
460         char buf[BUFSIZE] = { 0, };
461         size_t nread = 0;
462         FILE *in = NULL;
463         FILE *out = NULL;
464
465         ret_if(!in_filename);
466         ret_if(!out_filename);
467
468         in = fopen(in_filename, "r");
469         ret_if(!in);
470
471         out = fopen(out_filename, "w");
472         goto_if(!out, error);
473
474         rewind(in);
475         while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
476                 if (fwrite(buf, 1, nread, out) < nread) {
477                         _E("critical error to copy a file");
478                         break;
479                 }
480         }
481
482         fclose(in);
483         fclose(out);
484
485         return;
486
487 error:
488         fclose(out);
489 }
490
491 int connectivity_init(void)
492 {
493         int ret = -1;
494         char buf[PATH_MAX] = {0,};
495         char data[PATH_MAX] = {0,};
496         char *prefix = NULL;
497
498         prefix = app_get_resource_path();
499         retv_if(!prefix, -1);
500         snprintf(buf, sizeof(buf)-1, "%s%s", prefix, "iotcon-test-svr-db-server.dat");
501         free(prefix);
502         prefix = NULL;
503
504         prefix = app_get_data_path();
505         retv_if(!prefix, -1);
506         snprintf(data, sizeof(data)-1, "%s%s", prefix, "iotcon-test-svr-db-server.dat");
507         free(prefix);
508
509         _copy_file(buf, data);
510
511         ret = iotcon_initialize(data);
512         retv_if(IOTCON_ERROR_NONE != ret, -1);
513
514         ret = iotcon_set_device_name(DEVICE_NAME);
515         goto_if(IOTCON_ERROR_NONE != ret, error);
516
517         return 0;
518
519 error:
520         iotcon_deinitialize();
521         return -1;
522 }
523
524 int connectivity_fini(void)
525 {
526         iotcon_deinitialize();
527         return 0;
528 }
529
530 void connectivity_unset_resource(connectivity_resource_s *resource_info)
531 {
532         ret_if(!resource_info);
533         if (resource_info->observers) iotcon_observers_destroy(resource_info->observers);
534         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
535         if (resource_info->path) free(resource_info->path);
536         free(resource_info);
537 }
538
539 int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
540 {
541         iotcon_resource_types_h resource_types = NULL;
542         iotcon_resource_interfaces_h ifaces = NULL;
543         connectivity_resource_s *resource_info = NULL;
544         uint8_t policies;
545         int ret = -1;
546
547         retv_if(!path, -1);
548         retv_if(!type, -1);
549         retv_if(!out_resource_info, -1);
550
551         resource_info = calloc(1, sizeof(connectivity_resource_s));
552         retv_if(!resource_info, -1);
553
554         resource_info->path = strdup(path);
555         goto_if(!resource_info->path, error);
556
557         _D("Path : [%s]", resource_info->path);
558
559         ret = iotcon_resource_types_create(&resource_types);
560         goto_if(IOTCON_ERROR_NONE != ret, error);
561
562         ret = iotcon_resource_types_add(resource_types, type);
563         goto_if(IOTCON_ERROR_NONE != ret, error);
564
565         ret = iotcon_resource_interfaces_create(&ifaces);
566         goto_if(IOTCON_ERROR_NONE != ret, error);
567
568         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT);
569         goto_if(IOTCON_ERROR_NONE != ret, error);
570
571         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH);
572         goto_if(IOTCON_ERROR_NONE != ret, error);
573
574         policies =
575                 IOTCON_RESOURCE_DISCOVERABLE |
576                 IOTCON_RESOURCE_OBSERVABLE |
577                 IOTCON_RESOURCE_SECURE;
578
579         ret = iotcon_resource_create(URI_PATH,
580                         resource_types,
581                         ifaces,
582                         policies,
583                         _request_resource_handler,
584                         resource_info,
585                         &resource_info->res);
586         goto_if(IOTCON_ERROR_NONE != ret, error);
587
588         ret = iotcon_observers_create(&resource_info->observers);
589         goto_if(IOTCON_ERROR_NONE != ret, error);
590
591         iotcon_resource_types_destroy(resource_types);
592         iotcon_resource_interfaces_destroy(ifaces);
593         *out_resource_info = resource_info;
594
595         return 0;
596
597 error:
598         if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
599         if (resource_types) iotcon_resource_types_destroy(resource_types);
600         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
601         if (resource_info->path) free(resource_info->path);
602         if (resource_info) free(resource_info);
603
604         return -1;
605 }