Initial version
[apps/native/position-finder-server.git] / src / connectivity.c
1 /*
2  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <glib.h>
19
20 #include <iotcon.h>
21 #include "log.h"
22
23 #define ULTRASONIC_RESOURCE_1_URI "/door/1"
24 #define ULTRASONIC_RESOURCE_2_URI "/door/2"
25 #define ULTRASONIC_RESOURCE_TYPE "org.tizen.door"
26
27 /* Door Resource */
28 struct _ultrasonic_resource_s {
29         bool attributes;
30         char *uri_path;
31         char *type;
32         uint8_t policies;
33         iotcon_resource_interfaces_h ifaces;
34         iotcon_resource_h handle;
35         iotcon_observers_h observers;
36         iotcon_representation_h repr;
37 };
38 typedef struct _ultrasonic_resource_s ultrasonic_resource_s;
39
40 static bool _resource_created;
41
42 static void _request_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
43
44 static int _set_door_resource(ultrasonic_resource_s *door)
45 {
46         int ret;
47
48         door->attributes = false;
49
50         door->uri_path = strdup(ULTRASONIC_RESOURCE_1_URI);
51         if (NULL == door->uri_path) {
52                 _E("strdup(%s) Fail", ULTRASONIC_RESOURCE_1_URI);
53                 return -1;
54         }
55
56         door->type = strdup(ULTRASONIC_RESOURCE_TYPE);
57         if (NULL == door->type) {
58                 _E("strdup(%s) Fail", ULTRASONIC_RESOURCE_TYPE);
59                 free(door->uri_path);
60                 return -1;
61         }
62
63         ret = iotcon_resource_interfaces_create(&door->ifaces);
64         if (IOTCON_ERROR_NONE != ret) {
65                 _E("iotcon_resource_interfaces_create() Fail(%d)", ret);
66                 free(door->type);
67                 free(door->uri_path);
68                 return -1;
69         }
70
71         ret = iotcon_resource_interfaces_add(door->ifaces, IOTCON_INTERFACE_DEFAULT);
72         if (IOTCON_ERROR_NONE != ret) {
73                 _E("iotcon_resource_interfaces_add() Fail(%d)", ret);
74                 iotcon_resource_interfaces_destroy(door->ifaces);
75                 free(door->type);
76                 free(door->uri_path);
77                 return -1;
78         }
79
80         door->policies = IOTCON_RESOURCE_DISCOVERABLE | IOTCON_RESOURCE_OBSERVABLE
81                 | IOTCON_RESOURCE_SECURE;
82
83         ret = iotcon_observers_create(&door->observers);
84         if (IOTCON_ERROR_NONE != ret) {
85                 _E("iotcon_observers_create() Fail");
86                 iotcon_resource_interfaces_destroy(door->ifaces);
87                 free(door->type);
88                 free(door->uri_path);
89                 return -1;
90         }
91
92         return 0;
93 }
94
95 static void _free_door_resource(ultrasonic_resource_s *door)
96 {
97         iotcon_observers_destroy(door->observers);
98         iotcon_resource_interfaces_destroy(door->ifaces);
99         free(door->type);
100         free(door->uri_path);
101 }
102
103 static void _check_door_attributes(ultrasonic_resource_s door)
104 {
105         if (false == door.attributes)
106                 _D("[Door] closed.");
107         else
108                 _D("[Door] opened.");
109 }
110
111 static iotcon_resource_h _create_door_resource(char *uri_path, char *type,
112                 iotcon_resource_interfaces_h ifaces, uint8_t policies, void *user_data)
113 {
114         int ret;
115         iotcon_resource_h handle;
116         iotcon_resource_types_h resource_types;
117
118         ret = iotcon_resource_types_create(&resource_types);
119         if (IOTCON_ERROR_NONE != ret) {
120                 _E("iotcon_resource_types_create() Fail(%d)", ret);
121                 return NULL;
122         }
123
124         ret = iotcon_resource_types_add(resource_types, type);
125         if (IOTCON_ERROR_NONE != ret) {
126                 _E("iotcon_resource_types_add() Fail(%d)", ret);
127                 iotcon_resource_types_destroy(resource_types);
128                 return NULL;
129         }
130
131         /* register door resource */
132         ret = iotcon_resource_create(uri_path, resource_types, ifaces, policies,
133                         _request_handler, user_data, &handle);
134         if (IOTCON_ERROR_NONE != ret) {
135                 _E("iotcon_resource_create() Fail");
136                 iotcon_resource_types_destroy(resource_types);
137                 return NULL;
138         }
139
140         iotcon_resource_types_destroy(resource_types);
141
142         return handle;
143 }
144
145 static int _send_response(iotcon_request_h request, iotcon_representation_h repr,
146                 iotcon_response_result_e result)
147 {
148         int ret;
149         iotcon_response_h response;
150
151         ret = iotcon_response_create(request, &response);
152         if (IOTCON_ERROR_NONE != ret) {
153                 _E("iotcon_response_create() Fail(%d)", ret);
154                 return -1;
155         }
156
157         ret = iotcon_response_set_result(response, result);
158         if (IOTCON_ERROR_NONE != ret) {
159                 _E("iotcon_response_set_result() Fail(%d)", ret);
160                 iotcon_response_destroy(response);
161                 return -1;
162         }
163
164         ret = iotcon_response_set_representation(response, repr);
165         if (IOTCON_ERROR_NONE != ret) {
166                 _E("iotcon_response_set_representation() Fail(%d)", ret);
167                 iotcon_response_destroy(response);
168                 return -1;
169         }
170
171         /* send Representation to the client */
172         ret = iotcon_response_send(response);
173         if (IOTCON_ERROR_NONE != ret) {
174                 _E("iotcon_response_send() Fail(%d)", ret);
175                 iotcon_response_destroy(response);
176                 return -1;
177         }
178
179         iotcon_response_destroy(response);
180
181         return 0;
182 }
183
184 static iotcon_representation_h _get_door_representation(ultrasonic_resource_s *door)
185 {
186         int ret;
187         iotcon_attributes_h attributes;
188         iotcon_representation_h repr;
189
190         /* create a door Representation */
191         ret = iotcon_representation_create(&repr);
192         if (IOTCON_ERROR_NONE != ret) {
193                 _E("iotcon_representation_create() Fail(%d)", ret);
194                 return NULL;
195         }
196
197         /* create a door attributes */
198         ret = iotcon_attributes_create(&attributes);
199         if (IOTCON_ERROR_NONE != ret) {
200                 _E("iotcon_attributes_create() Fail(%d)", ret);
201                 iotcon_representation_destroy(repr);
202                 return NULL;
203         }
204
205         ret = iotcon_representation_set_uri_path(repr, door->uri_path);
206         if (IOTCON_ERROR_NONE != ret) {
207                 _E("iotcon_representation_set_uri_path() Fail(%d)", ret);
208                 iotcon_attributes_destroy(attributes);
209                 iotcon_representation_destroy(repr);
210                 return NULL;
211         }
212
213         ret = iotcon_attributes_add_bool(attributes, "opened", door->attributes);
214         if (IOTCON_ERROR_NONE != ret) {
215                 _E("iotcon_attributes_add_bool() Fail(%d)", ret);
216                 iotcon_attributes_destroy(attributes);
217                 iotcon_representation_destroy(repr);
218                 return NULL;
219         }
220
221         ret = iotcon_representation_set_attributes(repr, attributes);
222         if (IOTCON_ERROR_NONE != ret) {
223                 _E("iotcon_representation_set_attributes() Fail(%d)", ret);
224                 iotcon_attributes_destroy(attributes);
225                 iotcon_representation_destroy(repr);
226                 return NULL;
227         }
228
229         iotcon_attributes_destroy(attributes);
230
231         return repr;
232 }
233
234 static int _request_handler_get(ultrasonic_resource_s *door, iotcon_request_h request)
235 {
236         int ret;
237         iotcon_representation_h resp_repr;
238         _D("GET request");
239
240         resp_repr = _get_door_representation(door);
241         if (NULL == resp_repr) {
242                 _E("_get_door_representation() Fail");
243                 return -1;
244         }
245
246         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_OK);
247         if (0 != ret) {
248                 _E("_send_response() Fail(%d)", ret);
249                 iotcon_representation_destroy(resp_repr);
250                 return -1;
251         }
252
253         iotcon_representation_destroy(resp_repr);
254
255         return 0;
256 }
257
258 static int _set_door_representation(ultrasonic_resource_s *door,
259                 iotcon_representation_h repr)
260 {
261         int ret;
262         bool bval;
263         iotcon_attributes_h attributes;
264
265         ret = iotcon_representation_get_attributes(repr, &attributes);
266         if (IOTCON_ERROR_NONE != ret) {
267                 _E("iotcon_representation_get_attributes() Fail(%d)", ret);
268                 return -1;
269         }
270
271         ret = iotcon_attributes_get_bool(attributes, "opened", &bval);
272         if (IOTCON_ERROR_NONE != ret) {
273                 _E("iotcon_attributes_get_bool() Fail(%d)", ret);
274                 return -1;
275         }
276
277         door->attributes = bval;
278
279         return 0;
280 }
281
282 static int _request_handler_put(ultrasonic_resource_s *door, iotcon_request_h request)
283 {
284         int ret;
285         iotcon_representation_h req_repr, resp_repr;
286         _D("PUT request");
287
288         ret = iotcon_request_get_representation(request, &req_repr);
289         if (IOTCON_ERROR_NONE != ret) {
290                 _E("iotcon_request_get_representation() Fail(%d)", ret);
291                 return -1;
292         }
293
294         ret = _set_door_representation(door, req_repr);
295         if (0 != ret) {
296                 _E("_set_door_representation() Fail(%d)", ret);
297                 return -1;
298         }
299
300         _check_door_attributes(*door);
301
302         resp_repr = _get_door_representation(door);
303         if (NULL == resp_repr) {
304                 _E("_get_door_representation() Fail");
305                 return -1;
306         }
307
308         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_OK);
309         if (0 != ret) {
310                 _E("_send_response() Fail(%d)", ret);
311                 iotcon_representation_destroy(resp_repr);
312                 return -1;
313         }
314
315         /* notify */
316         ret = iotcon_resource_notify(door->handle, resp_repr, door->observers, IOTCON_QOS_HIGH);
317         if (IOTCON_ERROR_NONE != ret)
318                 _E("iotcon_resource_notify() Fail(%d)", ret);
319
320         iotcon_representation_destroy(resp_repr);
321
322         return 0;
323 }
324
325 static gboolean _door_attributes_changer(gpointer user_data)
326 {
327         int ret;
328         static int i = 0;
329         iotcon_representation_h repr;
330         ultrasonic_resource_s *door = user_data;
331
332         if ((5 == i++) || NULL == door->observers)
333                 return G_SOURCE_REMOVE;
334
335         if (false == door->attributes) {
336                 door->attributes = true;
337                 _D("[Door] closed -> opened");
338         } else {
339                 door->attributes = false;
340                 _D("[Door] opened -> closed");
341         }
342
343         _D("NOTIFY!");
344
345         repr = _get_door_representation(door);
346         if (NULL == repr) {
347                 _E("_get_door_representation() Fail");
348                 return G_SOURCE_REMOVE;
349         }
350
351         ret = iotcon_resource_notify(door->handle, repr, door->observers, IOTCON_QOS_HIGH);
352         if (IOTCON_ERROR_NONE != ret) {
353                 _E("iotcon_resource_notify() Fail(%d)", ret);
354                 iotcon_representation_destroy(repr);
355                 return G_SOURCE_REMOVE;
356         }
357
358         iotcon_representation_destroy(repr);
359         return G_SOURCE_CONTINUE;
360 }
361
362 static int _request_handler_post(ultrasonic_resource_s *door, iotcon_request_h request)
363 {
364         int ret;
365         iotcon_attributes_h resp_attributes;
366         iotcon_representation_h resp_repr = NULL;
367         iotcon_resource_h new_door_handle;
368         _D("POST request");
369
370         if (_resource_created) {
371                 _E("Resource(%s) is already created", ULTRASONIC_RESOURCE_2_URI);
372                 return -1;
373         }
374
375         new_door_handle = _create_door_resource(ULTRASONIC_RESOURCE_2_URI, door->type,
376                         door->ifaces, IOTCON_RESOURCE_SECURE, door);
377         if (NULL == new_door_handle) {
378                 _E("_create_door_resource() Fail");
379                 return -1;
380         }
381         _resource_created = true;
382
383         /* send information that new resource was created */
384         ret = iotcon_representation_create(&resp_repr);
385         if (IOTCON_ERROR_NONE != ret) {
386                 _E("iotcon_representation_create() Fail(%d)", ret);
387                 return -1;
388         }
389
390         ret = iotcon_attributes_create(&resp_attributes);
391         if (IOTCON_ERROR_NONE != ret) {
392                 _E("iotcon_attributes_create() Fail(%d)", ret);
393                 iotcon_representation_destroy(resp_repr);
394                 return -1;
395         }
396
397         ret = iotcon_attributes_add_str(resp_attributes, "createduripath", ULTRASONIC_RESOURCE_2_URI);
398         if (IOTCON_ERROR_NONE != ret) {
399                 _E("iotcon_attributes_add_str() Fail(%d)", ret);
400                 iotcon_attributes_destroy(resp_attributes);
401                 iotcon_representation_destroy(resp_repr);
402                 return -1;
403         }
404
405         ret = iotcon_representation_set_attributes(resp_repr, resp_attributes);
406         if (IOTCON_ERROR_NONE != ret) {
407                 _E("iotcon_representation_set_attributes() Fail(%d)", ret);
408                 iotcon_attributes_destroy(resp_attributes);
409                 iotcon_representation_destroy(resp_repr);
410                 return -1;
411         }
412
413         iotcon_attributes_destroy(resp_attributes);
414
415         ret = _send_response(request, resp_repr, IOTCON_RESPONSE_RESOURCE_CREATED);
416         if (0 != ret) {
417                 _E("_send_response() Fail(%d)", ret);
418                 iotcon_representation_destroy(resp_repr);
419                 return -1;
420         }
421
422         iotcon_representation_destroy(resp_repr);
423
424         return 0;
425 }
426
427 static int _request_handler_delete(iotcon_resource_h resource,
428                 iotcon_request_h request)
429 {
430         int ret;
431         _D("DELETE request");
432
433         ret = iotcon_resource_destroy(resource);
434         if (IOTCON_ERROR_NONE != ret) {
435                 _E("iotcon_resource_destroy() Fail(%d)", ret);
436                 return -1;
437         }
438
439         ret = _send_response(request, NULL, IOTCON_RESPONSE_RESOURCE_DELETED);
440         if (0 != ret) {
441                 _E("_send_response() Fail(%d)", ret);
442                 return -1;
443         }
444
445         return 0;
446 }
447
448 static bool _query_cb(const char *key, const char *value, void *user_data)
449 {
450         _D("key : %s, value : %s", key, value);
451
452         return IOTCON_FUNC_CONTINUE;
453 }
454
455 static void _request_handler(iotcon_resource_h resource, iotcon_request_h request,
456                 void *user_data)
457 {
458         ultrasonic_resource_s *door;
459         iotcon_query_h query;
460         int ret, observe_id;
461         iotcon_request_type_e type;
462         iotcon_observe_type_e observe_type;
463         char *host_address;
464
465         ret_if(NULL == request);
466
467         ret = iotcon_request_get_host_address(request, &host_address);
468         if (IOTCON_ERROR_NONE != ret) {
469                 _E("iotcon_request_get_host_address() Fail(%d)", ret);
470                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
471                 return;
472         }
473         _D("host_address : %s", host_address);
474
475         ret = iotcon_request_get_query(request, &query);
476         if (IOTCON_ERROR_NONE != ret) {
477                 _E("iotcon_request_get_query() Fail(%d)", ret);
478                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
479                 return;
480         }
481         if (query)
482                 iotcon_query_foreach(query, _query_cb, NULL);
483
484         ret = iotcon_request_get_request_type(request, &type);
485         if (IOTCON_ERROR_NONE != ret) {
486                 _E("iotcon_request_get_request_type() Fail(%d)", ret);
487                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
488                 return;
489         }
490
491         door = user_data;
492
493         if (IOTCON_REQUEST_GET == type)
494                 ret = _request_handler_get(door, request);
495
496         else if (IOTCON_REQUEST_PUT == type)
497                 ret = _request_handler_put(door, request);
498
499         else if (IOTCON_REQUEST_POST == type)
500                 ret = _request_handler_post(door, request);
501
502         else if (IOTCON_REQUEST_DELETE == type)
503                 ret = _request_handler_delete(resource, request);
504
505         if (0 != ret) {
506                 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
507                 return;
508         }
509
510         ret = iotcon_request_get_observe_type(request, &observe_type);
511         if (IOTCON_ERROR_NONE != ret) {
512                 _E("iotcon_request_get_observe_type() Fail(%d)", ret);
513                 return;
514         }
515
516         if (IOTCON_OBSERVE_REGISTER == observe_type) {
517                 ret = iotcon_request_get_observe_id(request, &observe_id);
518                 if (IOTCON_ERROR_NONE != ret) {
519                         _E("iotcon_request_get_observe_id() Fail(%d)", ret);
520                         return;
521                 }
522
523                 ret = iotcon_observers_add(door->observers, observe_id);
524                 if (IOTCON_ERROR_NONE != ret) {
525                         _E("iotcon_observers_add() Fail(%d)", ret);
526                         return;
527                 }
528         } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
529                 ret = iotcon_request_get_observe_id(request, &observe_id);
530                 if (IOTCON_ERROR_NONE != ret) {
531                         _E("iotcon_request_get_observe_id() Fail(%d)", ret);
532                         return;
533                 }
534                 ret = iotcon_observers_remove(door->observers, observe_id);
535                 if (IOTCON_ERROR_NONE != ret) {
536                         _E("iotcon_observers_remove() Fail(%d)", ret);
537                         return;
538                 }
539         }
540 }
541
542 static gboolean _presence_timer(gpointer user_data)
543 {
544         static int i = 0;
545         i++;
546         if (i % 2)
547                 iotcon_stop_presence();
548         else
549                 iotcon_start_presence(10);
550
551         if (3 == i)
552                 return G_SOURCE_REMOVE;
553
554         return G_SOURCE_CONTINUE;
555 }
556
557 int main(int argc, char **argv)
558 {
559         int ret;
560         GMainLoop *loop;
561         ultrasonic_resource_s my_door = {0};
562
563         loop = g_main_loop_new(NULL, FALSE);
564
565         /* initialize iotcon */
566         ret = iotcon_initialize("/usr/bin/iotcon-test-svr-db-server.dat");
567         if (IOTCON_ERROR_NONE != ret) {
568                 _E("iotcon_initialize() Fail(%d)", ret);
569                 return -1;
570         }
571
572         /* set device name */
573         ret = iotcon_set_device_name("iotcon-test-basic-server");
574         if (IOTCON_ERROR_NONE != ret) {
575                 _E("iotcon_set_device_name() Fail(%d)", ret);
576                 iotcon_deinitialize();
577                 return -1;
578         }
579
580         /* set local door resource */
581         ret = _set_door_resource(&my_door);
582         if (0 != ret) {
583                 _E("_set_door_resource() Fail");
584                 iotcon_deinitialize();
585                 return -1;
586         }
587
588         /* add resource options */
589         ret = iotcon_resource_interfaces_add(my_door.ifaces, IOTCON_INTERFACE_BATCH);
590         if (IOTCON_ERROR_NONE != ret) {
591                 _E("iotcon_resource_interfaces_add() Fail(%d)", ret);
592                 _free_door_resource(&my_door);
593                 iotcon_deinitialize();
594                 return -1;
595         }
596
597         /* add presence */
598         g_timeout_add_seconds(10, _presence_timer, NULL);
599         iotcon_start_presence(10);
600
601         /* create new door resource */
602         my_door.handle = _create_door_resource(my_door.uri_path, my_door.type, my_door.ifaces,
603                         my_door.policies, &my_door);
604         if (NULL == my_door.handle) {
605                 _E("_create_door_resource() Fail");
606                 _free_door_resource(&my_door);
607                 iotcon_deinitialize();
608                 return -1;
609         }
610
611         _check_door_attributes(my_door);
612
613         /* add observe */
614         g_timeout_add_seconds(5, _door_attributes_changer, &my_door);
615
616         g_main_loop_run(loop);
617         g_main_loop_unref(loop);
618
619         iotcon_resource_destroy(my_door.handle);
620
621         _free_door_resource(&my_door);
622
623         /* deinitialize iotcon */
624         iotcon_deinitialize();
625
626         return 0;
627 }