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