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