50f651f80237d9a94c64016fe965c4f38801b75c
[apps/native/position-finder-server.git] / src / connectivity.c
1 /*
2  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 <glib.h>
24 #include <Eina.h>
25
26 #include <iotcon.h>
27
28 #include "log.h"
29 #include "connectivity.h"
30
31 #define ULTRASONIC_RESOURCE_1_URI "/door/1"
32 #define ULTRASONIC_RESOURCE_2_URI "/door/2"
33 #define ULTRASONIC_RESOURCE_TYPE "org.tizen.door"
34
35 static bool _resource_created;
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_attribute(iotcon_resource_h res, 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 int _handle_get_request(iotcon_resource_h res, iotcon_request_h request)
107 {
108         iotcon_representation_h representation;
109         int ret = -1;
110         int value = 1;
111
112         /* FIXME : We need to check the value of sensors */
113         representation = _create_representation_with_attribute(res, (bool)value);
114         retv_if(!representation, -1);
115
116         ret = _send_response(request, representation, IOTCON_RESPONSE_OK);
117         goto_if(0 != ret, error);
118
119         _destroy_representation(representation);
120
121         return 0;
122
123 error:
124         _destroy_representation(representation);
125         return -1;
126 }
127
128 static int _get_value_from_representation(iotcon_representation_h representation, bool *value)
129 {
130         iotcon_attributes_h attributes;
131         int ret = -1;
132
133         ret = iotcon_representation_get_attributes(representation, &attributes);
134         retv_if(IOTCON_ERROR_NONE != ret, -1);
135
136         ret = iotcon_attributes_get_bool(attributes, "opened", value);
137         retv_if(IOTCON_ERROR_NONE != ret, -1);
138
139         return 0;
140 }
141
142 static int _set_value_into_thing(iotcon_representation_h representation, bool value)
143 {
144         /* FIXME : We need to set the value into the thing */
145         return 0;
146 }
147
148 static int _handle_put_request(connectivity_resource_s *resource_info, iotcon_request_h request)
149 {
150         iotcon_representation_h req_repr, resp_repr;
151         int ret = -1;
152         bool value = false;
153
154         _D("PUT request");
155
156         ret = iotcon_request_get_representation(request, &req_repr);
157         retv_if(IOTCON_ERROR_NONE != ret, -1);
158
159         ret = _get_value_from_representation(req_repr, &value);
160         retv_if(0 != ret, -1);
161
162         ret = _set_value_into_thing(req_repr, value);
163         retv_if(0 != ret, -1);
164
165         resp_repr = _create_representation_with_attribute(resource_info->res, (bool)value);
166         retv_if(NULL == resp_repr, -1);
167
168         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_OK);
169         goto_if(0 != ret, error);
170
171         ret = iotcon_resource_notify(resource_info->res, resp_repr, resource_info->observers, IOTCON_QOS_HIGH);
172         goto_if(IOTCON_ERROR_NONE != ret, error);
173
174         _destroy_representation(resp_repr);
175
176         return 0;
177
178 error:
179         _destroy_representation(resp_repr);
180         return -1;
181 }
182
183 int connectivity_notify(connectivity_resource_s *resource_info, int value)
184 {
185         iotcon_representation_h representation;
186         int ret = -1;
187
188         retv_if(!resource_info, -1);
189         retv_if(!resource_info->observers, -1);
190
191         _D("Notify the value[%d]", value);
192
193         representation = _create_representation_with_attribute(resource_info->res, (bool)value);
194         retv_if(!representation, -1);
195
196         ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_HIGH);
197         retv_if(IOTCON_ERROR_NONE != ret, -1);
198
199         _destroy_representation(representation);
200
201         return 0;
202 }
203
204 static int _handle_post_request(connectivity_resource_s *resource_info, iotcon_request_h request)
205 {
206         iotcon_attributes_h resp_attributes = NULL;
207         iotcon_representation_h resp_repr = NULL;
208         connectivity_resource_s *new_resource_info = NULL;
209         int ret = -1;
210
211         _D("POST request");
212
213         if (_resource_created) {
214                 _E("Resource(%s) is already created", ULTRASONIC_RESOURCE_2_URI);
215                 return -1;
216         }
217
218         new_resource_info = calloc(1, sizeof(connectivity_resource_s));
219         retv_if(!new_resource_info, -1);
220
221         ret = connectivity_set_resource(ULTRASONIC_RESOURCE_2_URI, ULTRASONIC_RESOURCE_TYPE, &new_resource_info);
222         retv_if(0 != ret, -1);
223
224         _resource_created = true;
225
226         ret = iotcon_representation_create(&resp_repr);
227         retv_if(IOTCON_ERROR_NONE != ret, -1);
228
229         ret = iotcon_attributes_create(&resp_attributes);
230         goto_if(IOTCON_ERROR_NONE != ret, error);
231
232         ret = iotcon_attributes_add_str(resp_attributes, "createduripath", ULTRASONIC_RESOURCE_2_URI);
233         goto_if(IOTCON_ERROR_NONE != ret, error);
234
235         ret = iotcon_representation_set_attributes(resp_repr, resp_attributes);
236         goto_if(IOTCON_ERROR_NONE != ret, error);
237
238         iotcon_attributes_destroy(resp_attributes);
239
240         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_RESOURCE_CREATED);
241         goto_if(0 != ret, error);
242
243         iotcon_representation_destroy(resp_repr);
244
245         return 0;
246
247 error:
248         if (resp_attributes) iotcon_attributes_destroy(resp_attributes);
249         iotcon_representation_destroy(resp_repr);
250         return -1;
251 }
252
253 static int _handle_delete_request(iotcon_resource_h resource, iotcon_request_h request)
254 {
255         int ret = -1;
256
257         _D("DELETE request");
258
259         ret = iotcon_resource_destroy(resource);
260         retv_if(IOTCON_ERROR_NONE != ret, -1);
261
262         ret = _send_response(request, NULL, IOTCON_RESPONSE_RESOURCE_DELETED);
263         retv_if(0 != ret, -1);
264
265         return 0;
266 }
267
268 static bool _query_cb(const char *key, const char *value, void *user_data)
269 {
270         _D("Key : [%s], Value : [%s]", key, value);
271
272         return IOTCON_FUNC_CONTINUE;
273 }
274
275 static int _handle_query(iotcon_request_h request)
276 {
277         iotcon_query_h query = NULL;
278         int ret = -1;
279
280         ret = iotcon_request_get_query(request, &query);
281         retv_if(IOTCON_ERROR_NONE != ret, -1);
282
283         if (query) iotcon_query_foreach(query, _query_cb, NULL);
284
285         return 0;
286 }
287
288 static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info)
289 {
290         iotcon_request_type_e type;
291         int ret = -1;
292
293         ret = iotcon_request_get_request_type(request, &type);
294         retv_if(IOTCON_ERROR_NONE != ret, -1);
295
296         switch (type) {
297         case IOTCON_REQUEST_GET:
298                 ret = _handle_get_request(resource_info->res, request);
299                 break;
300         case IOTCON_REQUEST_PUT:
301                 ret = _handle_put_request(resource_info, request);
302                 break;
303         case IOTCON_REQUEST_POST:
304                 ret = _handle_post_request(resource_info, request);
305                 break;
306         case IOTCON_REQUEST_DELETE:
307                 ret = _handle_delete_request(resource_info->res, request);
308                 break;
309         default:
310                 _E("Cannot reach here");
311                 ret = -1;
312                 break;
313         }
314         retv_if(0 != ret, -1);
315
316         return 0;
317 }
318
319 static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers)
320 {
321         iotcon_observe_type_e observe_type;
322         int ret = -1;
323         int observe_id = -1;
324
325         ret = iotcon_request_get_observe_type(request, &observe_type);
326         retv_if(IOTCON_ERROR_NONE != ret, -1);
327
328         if (IOTCON_OBSERVE_REGISTER == observe_type) {
329                 ret = iotcon_request_get_observe_id(request, &observe_id);
330                 retv_if(IOTCON_ERROR_NONE != ret, -1);
331
332                 ret = iotcon_observers_add(observers, observe_id);
333                 retv_if(IOTCON_ERROR_NONE != ret, -1);
334         } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
335                 ret = iotcon_request_get_observe_id(request, &observe_id);
336                 retv_if(IOTCON_ERROR_NONE != ret, -1);
337
338                 ret = iotcon_observers_remove(observers, observe_id);
339                 retv_if(IOTCON_ERROR_NONE != ret, -1);
340         }
341
342         return 0;
343 }
344
345 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
346 {
347         connectivity_resource_s *resource_info = user_data;
348         int ret = -1;
349         char *host_address = NULL;
350
351         ret_if(!request);
352
353         ret = iotcon_request_get_host_address(request, &host_address);
354         goto_if(IOTCON_ERROR_NONE != ret, error);
355
356         _D("Host address : %s", host_address);
357
358         ret = _handle_query(request);
359         goto_if(IOTCON_ERROR_NONE != ret, error);
360
361         ret = _handle_request_by_crud_type(request, resource_info);
362         goto_if(0 != ret, error);
363
364         ret = _handle_observer(request, resource_info->observers);
365         goto_if(0 != ret, error);
366
367         return;
368
369 error:
370         _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
371 }
372
373 int connectivity_init(void)
374 {
375         int ret = -1;
376
377         ret = iotcon_initialize("/home/owner/apps_rw/org.tizen.position-finder-server/data/iotcon-test-svr-db-server.dat");
378         retv_if(IOTCON_ERROR_NONE != ret, -1);
379
380         ret = iotcon_set_device_name(ULTRASONIC_RESOURCE_TYPE);
381         goto_if(IOTCON_ERROR_NONE != ret, error);
382
383         ret = iotcon_start_presence(10);
384         goto_if(IOTCON_ERROR_NONE != ret, error);
385
386         return 0;
387
388 error:
389         iotcon_deinitialize();
390         return -1;
391 }
392
393 int connectivity_fini(void)
394 {
395         iotcon_deinitialize();
396         return 0;
397 }
398
399 void connectivity_unset_resource(connectivity_resource_s *resource_info)
400 {
401         ret_if(!resource_info);
402         if (resource_info->observers) iotcon_observers_destroy(resource_info->observers);
403         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
404         free(resource_info);
405 }
406
407 int connectivity_set_resource(const char *uri_path, const char *type, connectivity_resource_s **out_resource_info)
408 {
409         iotcon_resource_types_h resource_types = NULL;
410         iotcon_resource_interfaces_h ifaces = NULL;
411         connectivity_resource_s *resource_info = NULL;
412         uint8_t policies;
413         int ret = -1;
414
415         resource_info = calloc(1, sizeof(connectivity_resource_s));
416         retv_if(!resource_info, -1);
417         *out_resource_info = resource_info;
418
419         ret = iotcon_resource_types_create(&resource_types);
420         goto_if(IOTCON_ERROR_NONE != ret, error);
421
422         ret = iotcon_resource_types_add(resource_types, type);
423         goto_if(IOTCON_ERROR_NONE != ret, error);
424
425         ret = iotcon_resource_interfaces_create(&ifaces);
426         goto_if(IOTCON_ERROR_NONE != ret, error);
427
428         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT);
429         goto_if(IOTCON_ERROR_NONE != ret, error);
430
431         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH);
432         goto_if(IOTCON_ERROR_NONE != ret, error);
433
434         policies =
435                 IOTCON_RESOURCE_DISCOVERABLE |
436                 IOTCON_RESOURCE_OBSERVABLE |
437                 IOTCON_RESOURCE_SECURE;
438
439         ret = iotcon_resource_create(uri_path,
440                         resource_types,
441                         ifaces,
442                         policies,
443                         _request_resource_handler,
444                         resource_info,
445                         &resource_info->res);
446         goto_if(IOTCON_ERROR_NONE != ret, error);
447
448         ret = iotcon_observers_create(&resource_info->observers);
449         goto_if(IOTCON_ERROR_NONE != ret, error);
450
451         iotcon_resource_types_destroy(resource_types);
452         iotcon_resource_interfaces_destroy(ifaces);
453
454         return 0;
455
456 error:
457         if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
458         if (resource_types) iotcon_resource_types_destroy(resource_types);
459         if (resource_info->res) iotcon_resource_destroy(resource_info->res);
460         if (resource_info) free(resource_info);
461
462         return -1;
463 }