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