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