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