d1b0a5fc42da5c1d4f92c5d64571ae33b9d18024
[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 <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <glib.h>
26 #include <app_common.h>
27 #include <iotcon.h>
28
29 #include "log.h"
30 #include "connectivity.h"
31 #include "webutil.h"
32 #include "controller_util.h"
33
34 #define DEFAULT_RESOURCE_TYPE "org.tizen.door"
35 #define BUFSIZE 1024
36 #define URI_PATH_LEN 64
37 #define URI_PATH "/door/1"
38 #define PATH "path"
39 #define IOTCON_DB_FILENAME "iotcon-test-svr-db-server.dat"
40
41 struct _connectivity_resource {
42         char *path;
43         char *type;
44         connectivity_protocol_e protocol_type;
45         GHashTable *value_hash;
46         union {
47                 struct {
48                         iotcon_resource_h res;
49                         iotcon_observers_h observers;
50                 } iotcon_data;
51                 struct {
52                         /* Nothing */
53                         char *reserve;
54                 } http_data;
55         } conn_data;
56 };
57
58 typedef enum {
59         DATA_VAL_TYPE_BOOL = 0,
60         DATA_VAL_TYPE_INT,
61         DATA_VAL_TYPE_DOUBLE,
62         DATA_VAL_TYPE_STRING
63 } conn_data_val_type_e;
64
65 typedef struct _conn_data_value_s {
66         conn_data_val_type_e type;
67         union {
68                 bool b_val;
69                 int i_val;
70                 double d_val;
71                 char *s_val;
72         };
73 } conn_data_value_s;
74
75 static connectivity_protocol_e ProtocolType = CONNECTIVITY_PROTOCOL_DEFAULT;
76 static int connectivity_iotcon_intialized = 0;
77 static int connectivity_http_intialized = 0;
78
79 static void _print_iotcon_error(int err_no)
80 {
81         switch (err_no) {
82         case IOTCON_ERROR_NOT_SUPPORTED:
83                 _E("IOTCON_ERROR_NOT_SUPPORTED");
84                 break;
85         case IOTCON_ERROR_PERMISSION_DENIED:
86                 _E("IOTCON_ERROR_PERMISSION_DENIED");
87                 break;
88         case IOTCON_ERROR_INVALID_PARAMETER:
89                 _E("IOTCON_ERROR_INVALID_PARAMETER");
90                 break;
91         default:
92                 _E("Error : [%d]", err_no);
93                 break;
94         }
95
96         return;
97 }
98
99 static void _copy_file(const char *in_filename, const char *out_filename)
100 {
101         char buf[BUFSIZE] = { 0, };
102         size_t nread = 0;
103         FILE *in = NULL;
104         FILE *out = NULL;
105
106         ret_if(!in_filename);
107         ret_if(!out_filename);
108
109         in = fopen(in_filename, "r");
110         ret_if(!in);
111
112         out = fopen(out_filename, "w");
113         goto_if(!out, error);
114
115         rewind(in);
116         while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
117                 if (fwrite(buf, 1, nread, out) < nread) {
118                         _E("critical error to copy a file");
119                         break;
120                 }
121         }
122
123         fclose(in);
124         fclose(out);
125
126         return;
127
128 error:
129         fclose(in);
130         return;
131 }
132
133 static bool _query_cb(const char *key, const char *value, void *user_data)
134 {
135         _D("Key : [%s], Value : [%s]", key, value);
136
137         return IOTCON_FUNC_CONTINUE;
138 }
139
140 static int _handle_query(iotcon_request_h request)
141 {
142         iotcon_query_h query = NULL;
143         int ret = -1;
144
145         ret = iotcon_request_get_query(request, &query);
146         retv_if(IOTCON_ERROR_NONE != ret, -1);
147
148         if (query) iotcon_query_foreach(query, _query_cb, NULL);
149
150         return 0;
151 }
152
153 static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info)
154 {
155         iotcon_request_type_e type;
156         int ret = -1;
157
158         ret = iotcon_request_get_request_type(request, &type);
159         retv_if(IOTCON_ERROR_NONE != ret, -1);
160
161         switch (type) {
162         case IOTCON_REQUEST_GET:
163                 _I("Do not support 'get' query");
164                 break;
165         case IOTCON_REQUEST_PUT:
166                 _I("Do not support 'put' query");
167                 break;
168         case IOTCON_REQUEST_POST:
169                 _I("Do not support 'post' query");
170                 break;
171         case IOTCON_REQUEST_DELETE:
172                 _I("Do not support 'delete' query");
173                 break;
174         default:
175                 _E("Cannot reach here");
176                 ret = -1;
177                 break;
178         }
179         retv_if(0 != ret, -1);
180
181         return 0;
182 }
183
184 static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers)
185 {
186         iotcon_observe_type_e observe_type;
187         int ret = -1;
188         int observe_id = -1;
189
190         ret = iotcon_request_get_observe_type(request, &observe_type);
191         retv_if(IOTCON_ERROR_NONE != ret, -1);
192
193         if (IOTCON_OBSERVE_REGISTER == observe_type) {
194                 ret = iotcon_request_get_observe_id(request, &observe_id);
195                 retv_if(IOTCON_ERROR_NONE != ret, -1);
196
197                 _I("Add an observer : %d", observe_id);
198
199                 ret = iotcon_observers_add(observers, observe_id);
200                 retv_if(IOTCON_ERROR_NONE != ret, -1);
201         } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
202                 ret = iotcon_request_get_observe_id(request, &observe_id);
203                 retv_if(IOTCON_ERROR_NONE != ret, -1);
204
205                 _I("Remove an observer : %d", observe_id);
206
207                 ret = iotcon_observers_remove(observers, observe_id);
208                 retv_if(IOTCON_ERROR_NONE != ret, -1);
209         }
210
211         return 0;
212 }
213
214 static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result)
215 {
216         int ret = -1;
217         iotcon_response_h response;
218
219         ret = iotcon_response_create(request, &response);
220         retv_if(IOTCON_ERROR_NONE != ret, -1);
221
222         ret = iotcon_response_set_result(response, result);
223         goto_if(IOTCON_ERROR_NONE != ret, error);
224
225         ret = iotcon_response_set_representation(response, representation);
226         goto_if(IOTCON_ERROR_NONE != ret, error);
227
228         ret = iotcon_response_send(response);
229         goto_if(IOTCON_ERROR_NONE != ret, error);
230
231         iotcon_response_destroy(response);
232
233         return 0;
234
235 error:
236         iotcon_response_destroy(response);
237         return -1;
238 }
239
240 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
241 {
242         connectivity_resource_s *resource_info = user_data;
243         int ret = -1;
244         char *host_address = NULL;
245
246         ret_if(!request);
247
248         ret = iotcon_request_get_host_address(request, &host_address);
249         goto_if(IOTCON_ERROR_NONE != ret, error);
250
251         _D("Host address : %s", host_address);
252
253         ret = _handle_query(request);
254         goto_if(IOTCON_ERROR_NONE != ret, error);
255
256         ret = _handle_request_by_crud_type(request, resource_info);
257         goto_if(0 != ret, error);
258
259         ret = _handle_observer(request, resource_info->conn_data.iotcon_data.observers);
260         goto_if(0 != ret, error);
261
262         return;
263
264 error:
265         _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
266         return;
267 }
268
269 static int __init_iotcon(connectivity_resource_s *resource_info)
270 {
271         int ret = -1;
272         iotcon_resource_types_h resource_types = NULL;
273         iotcon_resource_interfaces_h ifaces = NULL;
274         uint8_t policies = IOTCON_RESOURCE_NO_POLICY;
275         char res_path[PATH_MAX] = {0,};
276         char data_path[PATH_MAX] = {0,};
277         char *prefix = NULL;
278
279         retv_if(!resource_info, -1);
280         retv_if(resource_info->protocol_type != CONNECTIVITY_PROTOCOL_IOTIVITY, -1);
281
282         prefix = app_get_resource_path();
283         retv_if(!prefix, -1);
284         snprintf(res_path, sizeof(res_path)-1, "%s%s", prefix, IOTCON_DB_FILENAME);
285         free(prefix);
286         prefix = NULL;
287
288         prefix = app_get_data_path();
289         retv_if(!prefix, -1);
290         snprintf(data_path, sizeof(data_path)-1, "%s%s", prefix, IOTCON_DB_FILENAME);
291         free(prefix);
292
293         _copy_file(res_path, data_path);
294
295         ret = iotcon_initialize(data_path);
296         retv_if(IOTCON_ERROR_NONE != ret, -1);
297
298         /* TODO : If we have to set device name, naming it more gorgeous one */
299         ret = iotcon_set_device_name(DEFAULT_RESOURCE_TYPE);
300         goto_if(IOTCON_ERROR_NONE != ret, error);
301
302         ret = iotcon_resource_types_create(&resource_types);
303         goto_if(IOTCON_ERROR_NONE != ret, error);
304
305         ret = iotcon_resource_types_add(resource_types, resource_info->type);
306         goto_if(IOTCON_ERROR_NONE != ret, error);
307
308         ret = iotcon_resource_interfaces_create(&ifaces);
309         goto_if(IOTCON_ERROR_NONE != ret, error);
310
311         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT);
312         goto_if(IOTCON_ERROR_NONE != ret, error);
313
314         ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH);
315         goto_if(IOTCON_ERROR_NONE != ret, error);
316
317         policies =
318                 IOTCON_RESOURCE_DISCOVERABLE |
319                 IOTCON_RESOURCE_OBSERVABLE |
320                 IOTCON_RESOURCE_SECURE;
321
322         ret = iotcon_resource_create(URI_PATH,
323                         resource_types,
324                         ifaces,
325                         policies,
326                         _request_resource_handler,
327                         resource_info,
328                         &resource_info->conn_data.iotcon_data.res);
329         goto_if(IOTCON_ERROR_NONE != ret, error);
330
331         ret = iotcon_observers_create(&resource_info->conn_data.iotcon_data.observers);
332         goto_if(IOTCON_ERROR_NONE != ret, error);
333
334         iotcon_resource_types_destroy(resource_types);
335         iotcon_resource_interfaces_destroy(ifaces);
336         connectivity_iotcon_intialized = 1;
337
338         return 0;
339
340 error:
341         if (resource_types) iotcon_resource_types_destroy(resource_types);
342         if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
343         if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res);
344         iotcon_deinitialize();
345         return -1;
346 }
347
348 static int __init_http(connectivity_resource_s *resource_info)
349 {
350         int ret = 0;
351         ret = web_util_noti_init();
352         if (!ret)
353                 connectivity_http_intialized = 1;
354
355         return ret;
356 }
357
358 #ifdef PRINT_DEBUG_DETAIL
359 static bool __print_attributes_cb(iotcon_attributes_h attributes, const char *key, void *user_data)
360 {
361         iotcon_type_e type = IOTCON_TYPE_NONE;
362
363         iotcon_attributes_get_type(attributes, key, &type);
364
365         switch (type) {
366         case IOTCON_TYPE_INT: {
367                 int value = 0;
368                 iotcon_attributes_get_int(attributes, key, &value);
369                 _D("key[%s] - int value [%d]", key, value);
370                 }
371                 break;
372         case IOTCON_TYPE_BOOL: {
373                 bool value = 0;
374                 iotcon_attributes_get_bool(attributes, key, &value);
375                 _D("key[%s] - bool value [%d]", key, value);
376                 }
377                 break;
378         case IOTCON_TYPE_DOUBLE: {
379                 double value = 0;
380                 iotcon_attributes_get_double(attributes, key, &value);
381                 _D("key[%s] - double value [%lf]", key, value);
382                 }
383         break;
384         case IOTCON_TYPE_STR: {
385                 char *value = 0;
386                 iotcon_attributes_get_str(attributes, key, &value);
387                 _D("key[%s] - string value [%s]", key, value);
388                 }
389         break;
390         case IOTCON_TYPE_NONE:
391         case IOTCON_TYPE_BYTE_STR:
392         case IOTCON_TYPE_NULL:
393         case IOTCON_TYPE_LIST:
394         case IOTCON_TYPE_ATTRIBUTES:
395         default:
396                 _W("unhandled key[%s] type[%d]", key, type);
397                 break;
398         }
399
400         return IOTCON_FUNC_CONTINUE;
401 }
402 #endif
403
404 static void __print_attribute(iotcon_attributes_h attributes)
405 {
406 #ifdef PRINT_DEBUG_DETAIL
407         ret_if(!attributes);
408
409         iotcon_attributes_foreach(attributes, __print_attributes_cb, NULL);
410 #endif
411         return;
412 }
413
414 static void _destroy_representation(iotcon_representation_h representation)
415 {
416         ret_if(!representation);
417         iotcon_representation_destroy(representation);
418         return;
419 }
420
421 static iotcon_representation_h _create_representation_with_bool(connectivity_resource_s *resource_info, const char *key, bool value)
422 {
423         iotcon_attributes_h attributes = NULL;
424         iotcon_representation_h representation = NULL;
425         char *uri_path = NULL;
426         int ret = -1;
427
428         ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
429         retv_if(IOTCON_ERROR_NONE != ret, NULL);
430
431         ret = iotcon_representation_create(&representation);
432         retv_if(IOTCON_ERROR_NONE != ret, NULL);
433
434         ret = iotcon_attributes_create(&attributes);
435         goto_if(IOTCON_ERROR_NONE != ret, error);
436
437         ret = iotcon_representation_set_uri_path(representation, uri_path);
438         goto_if(IOTCON_ERROR_NONE != ret, error);
439
440         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
441         goto_if(IOTCON_ERROR_NONE != ret, error);
442
443         ret = iotcon_attributes_add_bool(attributes, key, value);
444         goto_if(IOTCON_ERROR_NONE != ret, error);
445
446         ret = iotcon_representation_set_attributes(representation, attributes);
447         goto_if(IOTCON_ERROR_NONE != ret, error);
448
449         iotcon_attributes_destroy(attributes);
450
451         return representation;
452
453 error:
454         if (attributes) iotcon_attributes_destroy(attributes);
455         if (representation) iotcon_representation_destroy(representation);
456
457         return NULL;
458 }
459
460 static iotcon_representation_h _create_representation_with_int(connectivity_resource_s *resource_info, const char *key, int value)
461 {
462         iotcon_attributes_h attributes = NULL;
463         iotcon_representation_h representation = NULL;
464         char *uri_path = NULL;
465         int ret = -1;
466
467         ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
468         retv_if(IOTCON_ERROR_NONE != ret, NULL);
469
470         ret = iotcon_representation_create(&representation);
471         retv_if(IOTCON_ERROR_NONE != ret, NULL);
472
473         ret = iotcon_attributes_create(&attributes);
474         goto_if(IOTCON_ERROR_NONE != ret, error);
475
476         ret = iotcon_representation_set_uri_path(representation, uri_path);
477         goto_if(IOTCON_ERROR_NONE != ret, error);
478
479         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
480         goto_if(IOTCON_ERROR_NONE != ret, error);
481
482         ret = iotcon_attributes_add_int(attributes, key, value);
483         goto_if(IOTCON_ERROR_NONE != ret, error);
484
485         ret = iotcon_representation_set_attributes(representation, attributes);
486         goto_if(IOTCON_ERROR_NONE != ret, error);
487
488         iotcon_attributes_destroy(attributes);
489
490         return representation;
491
492 error:
493         if (attributes) iotcon_attributes_destroy(attributes);
494         if (representation) iotcon_representation_destroy(representation);
495
496         return NULL;
497 }
498
499 static iotcon_representation_h _create_representation_with_double(connectivity_resource_s *resource_info, const char *key, double value)
500 {
501         iotcon_attributes_h attributes = NULL;
502         iotcon_representation_h representation = NULL;
503         char *uri_path = NULL;
504         int ret = -1;
505
506         ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
507         retv_if(IOTCON_ERROR_NONE != ret, NULL);
508
509         ret = iotcon_representation_create(&representation);
510         retv_if(IOTCON_ERROR_NONE != ret, NULL);
511
512         ret = iotcon_attributes_create(&attributes);
513         goto_if(IOTCON_ERROR_NONE != ret, error);
514
515         ret = iotcon_representation_set_uri_path(representation, uri_path);
516         goto_if(IOTCON_ERROR_NONE != ret, error);
517
518         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
519         goto_if(IOTCON_ERROR_NONE != ret, error);
520
521         ret = iotcon_attributes_add_double(attributes, key, value);
522         goto_if(IOTCON_ERROR_NONE != ret, error);
523
524         ret = iotcon_representation_set_attributes(representation, attributes);
525         goto_if(IOTCON_ERROR_NONE != ret, error);
526
527         iotcon_attributes_destroy(attributes);
528
529         return representation;
530
531 error:
532         if (attributes) iotcon_attributes_destroy(attributes);
533         if (representation) iotcon_representation_destroy(representation);
534
535         return NULL;
536 }
537
538 static iotcon_representation_h _create_representation_with_string(connectivity_resource_s *resource_info, const char *key, const char *value)
539 {
540         iotcon_attributes_h attributes = NULL;
541         iotcon_representation_h representation = NULL;
542         char *uri_path = NULL;
543         int ret = -1;
544
545         ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
546         retv_if(IOTCON_ERROR_NONE != ret, NULL);
547
548         ret = iotcon_representation_create(&representation);
549         retv_if(IOTCON_ERROR_NONE != ret, NULL);
550
551         ret = iotcon_attributes_create(&attributes);
552         goto_if(IOTCON_ERROR_NONE != ret, error);
553
554         ret = iotcon_representation_set_uri_path(representation, uri_path);
555         goto_if(IOTCON_ERROR_NONE != ret, error);
556
557         ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
558         goto_if(IOTCON_ERROR_NONE != ret, error);
559
560         ret = iotcon_attributes_add_str(attributes, key, (char *)value);
561         goto_if(IOTCON_ERROR_NONE != ret, error);
562
563         ret = iotcon_representation_set_attributes(representation, attributes);
564         goto_if(IOTCON_ERROR_NONE != ret, error);
565
566         iotcon_attributes_destroy(attributes);
567
568         return representation;
569
570 error:
571         if (attributes) iotcon_attributes_destroy(attributes);
572         if (representation) iotcon_representation_destroy(representation);
573
574         return NULL;
575 }
576
577 static inline void __noti_by_http(void)
578 {
579         char *json_data = NULL;
580
581         json_data = web_util_get_json_string();
582         if (json_data) {
583                 const char *url = NULL;
584                 controller_util_get_address(&url);
585                 if (url)
586                         web_util_noti_post(url, json_data);
587                 else
588                         _E("fail to get url");
589                 free(json_data);
590         } else
591                 _E("fail to get json_data");
592
593         return;
594 }
595
596 int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
597 {
598         int ret = -1;
599
600         retv_if(!resource_info, -1);
601         retv_if(!key, -1);
602
603         _D("Notify key[%s], value[%d]", key, value);
604
605         switch (resource_info->protocol_type) {
606         case CONNECTIVITY_PROTOCOL_IOTIVITY:
607                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
608                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
609                 {
610                         iotcon_representation_h representation;
611                         representation = _create_representation_with_bool(resource_info, key, value);
612                         retv_if(!representation, -1);
613                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
614                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
615                         if (IOTCON_ERROR_NONE != ret) {
616                                 _W("There are some troubles for notifying value[%d]", ret);
617                                 _print_iotcon_error(ret);
618                                 return -1;
619                         }
620                         _destroy_representation(representation);
621                 }
622                 break;
623         case CONNECTIVITY_PROTOCOL_HTTP:
624                 ret = web_util_json_init();
625                 retv_if(ret, -1);
626
627                 ret = web_util_json_begin();
628                 retv_if(ret, -1);
629
630                 web_util_json_add_string("SensorPiID", resource_info->path);
631                 web_util_json_add_string("SensorPiType", resource_info->type);
632                 web_util_json_add_boolean(key, value);
633                 web_util_json_end();
634
635                 __noti_by_http();
636
637                 web_util_json_fini();
638                 break;
639         default:
640                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
641                 return -1;
642                 break;
643         }
644
645         return 0;
646 }
647
648 int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
649 {
650         int ret = -1;
651
652         retv_if(!resource_info, -1);
653         retv_if(!key, -1);
654
655         _D("Notify key[%s], value[%d]", key, value);
656
657         switch (resource_info->protocol_type) {
658         case CONNECTIVITY_PROTOCOL_IOTIVITY:
659                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
660                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
661                 {
662                         iotcon_representation_h representation;
663                         representation = _create_representation_with_int(resource_info, key, value);
664                         retv_if(!representation, -1);
665                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
666                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
667                         if (IOTCON_ERROR_NONE != ret) {
668                                 _W("There are some troubles for notifying value[%d]", ret);
669                                 _print_iotcon_error(ret);
670                                 return -1;
671                         }
672                         _destroy_representation(representation);
673                 }
674                 break;
675         case CONNECTIVITY_PROTOCOL_HTTP:
676                 ret = web_util_json_init();
677                 retv_if(ret, -1);
678
679                 ret = web_util_json_begin();
680                 retv_if(ret, -1);
681
682                 web_util_json_add_string("SensorPiID", resource_info->path);
683                 web_util_json_add_string("SensorPiType", resource_info->type);
684                 web_util_json_add_int(key, value);
685                 web_util_json_end();
686
687                 __noti_by_http();
688
689                 web_util_json_fini();
690                 break;
691         default:
692                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
693                 return -1;
694                 break;
695         }
696         return 0;
697 }
698
699 int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
700 {
701         int ret = -1;
702
703         retv_if(!resource_info, -1);
704         retv_if(!key, -1);
705
706         _D("Notify key[%s], value[%lf]", key, value);
707
708         switch (resource_info->protocol_type) {
709         case CONNECTIVITY_PROTOCOL_IOTIVITY:
710                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
711                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
712                 {
713                         iotcon_representation_h representation;
714                         representation = _create_representation_with_double(resource_info, key, value);
715                         retv_if(!representation, -1);
716                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
717                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
718                         if (IOTCON_ERROR_NONE != ret) {
719                                 _W("There are some troubles for notifying value[%d]", ret);
720                                 _print_iotcon_error(ret);
721                                 return -1;
722                         }
723                         _destroy_representation(representation);
724                 }
725                 break;
726         case CONNECTIVITY_PROTOCOL_HTTP:
727                 ret = web_util_json_init();
728                 retv_if(ret, -1);
729
730                 ret = web_util_json_begin();
731                 retv_if(ret, -1);
732
733                 web_util_json_add_string("SensorPiID", resource_info->path);
734                 web_util_json_add_string("SensorPiType", resource_info->type);
735                 web_util_json_add_double(key, value);
736                 web_util_json_end();
737
738                 __noti_by_http();
739
740                 web_util_json_fini();
741                 break;
742         default:
743                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
744                 return -1;
745                 break;
746         }
747         return 0;
748 }
749
750 int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, const char *value)
751 {
752         int ret = -1;
753
754         retv_if(!resource_info, -1);
755         retv_if(!key, -1);
756         retv_if(!value, -1);
757
758         _D("Notify key[%s], value[%s]", key, value);
759
760         switch (resource_info->protocol_type) {
761         case CONNECTIVITY_PROTOCOL_IOTIVITY:
762                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
763                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
764                 {
765                         iotcon_representation_h representation;
766                         representation = _create_representation_with_string(resource_info, key, value);
767                         retv_if(!representation, -1);
768                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
769                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
770                         if (IOTCON_ERROR_NONE != ret) {
771                                 _W("There are some troubles for notifying value[%d]", ret);
772                                 _print_iotcon_error(ret);
773                                 return -1;
774                         }
775                         _destroy_representation(representation);
776                 }
777                 break;
778         case CONNECTIVITY_PROTOCOL_HTTP:
779                 ret = web_util_json_init();
780                 retv_if(ret, -1);
781
782                 ret = web_util_json_begin();
783                 retv_if(ret, -1);
784
785                 web_util_json_add_string("SensorPiID", resource_info->path);
786                 web_util_json_add_string("SensorPiType", resource_info->type);
787                 web_util_json_add_string(key, value);
788                 web_util_json_end();
789
790                 __noti_by_http();
791
792                 web_util_json_fini();
793                 break;
794         default:
795                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
796                 return -1;
797                 break;
798         }
799         return 0;
800 }
801
802 static void __hash_key_free(gpointer data)
803 {
804         free(data);
805         return;
806 }
807
808 static void __hash_value_free(gpointer data)
809 {
810         conn_data_value_s *value = data;
811         if (value && (value->type == DATA_VAL_TYPE_STRING))
812                 free(value->s_val);
813         free(value);
814
815         return;
816 }
817
818 static int __add_value_to_hash(connectivity_resource_s *resource_info, const char *key, conn_data_value_s *value)
819 {
820         retv_if(!resource_info, -1);
821         retv_if(!key, -1);
822         retv_if(!value, -1);
823
824         if (!resource_info->value_hash) {
825                 resource_info->value_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
826                                                                                 __hash_key_free, __hash_value_free);
827                 retv_if(!resource_info->value_hash, -1);
828         }
829
830         g_hash_table_insert(resource_info->value_hash, strdup(key), value);
831
832         return 0;
833 }
834
835 int connectivity_attributes_add_bool(connectivity_resource_s *resource_info, const char *key, bool value)
836 {
837         int ret = 0;
838         conn_data_value_s *data_value = NULL;
839
840         retv_if(!resource_info, -1);
841         retv_if(!key, -1);
842
843         _D("adding key[%s] - value[%d]", key, value);
844
845         data_value = malloc(sizeof(conn_data_value_s));
846         retv_if(!data_value, -1);
847
848         data_value->type = DATA_VAL_TYPE_BOOL;
849         data_value->b_val = value;
850
851         ret = __add_value_to_hash(resource_info, key, data_value);
852         if (ret) {
853                 free(data_value);
854                 return -1;
855         }
856
857         return 0;
858 }
859
860 int connectivity_attributes_add_int(connectivity_resource_s *resource_info, const char *key, int value)
861 {
862         int ret = 0;
863         conn_data_value_s *data_value = NULL;
864
865         retv_if(!resource_info, -1);
866         retv_if(!key, -1);
867
868         _D("adding key[%s] - value[%d]", key, value);
869
870         data_value = malloc(sizeof(conn_data_value_s));
871         retv_if(!data_value, -1);
872
873         data_value->type = DATA_VAL_TYPE_INT;
874         data_value->i_val = value;
875
876         ret = __add_value_to_hash(resource_info, key, data_value);
877         if (ret) {
878                 free(data_value);
879                 return -1;
880         }
881
882         return 0;
883 }
884
885 int connectivity_attributes_add_double(connectivity_resource_s *resource_info, const char *key, double value)
886 {
887         int ret = 0;
888         conn_data_value_s *data_value = NULL;
889
890         retv_if(!resource_info, -1);
891         retv_if(!key, -1);
892
893         _D("adding key[%s] - value[%lf]", key, value);
894
895         data_value = malloc(sizeof(conn_data_value_s));
896         retv_if(!data_value, -1);
897
898         data_value->type = DATA_VAL_TYPE_DOUBLE;
899         data_value->d_val = value;
900
901         ret = __add_value_to_hash(resource_info, key, data_value);
902         if (ret) {
903                 free(data_value);
904                 return -1;
905         }
906
907         return 0;
908 }
909
910 int connectivity_attributes_add_string(connectivity_resource_s *resource_info, const char *key, const char *value)
911 {
912         int ret = 0;
913         conn_data_value_s *data_value = NULL;
914
915         retv_if(!resource_info, -1);
916         retv_if(!key, -1);
917         retv_if(!value, -1);
918
919         _D("adding key[%s] - value[%s]", key, value);
920
921         data_value = malloc(sizeof(conn_data_value_s));
922         retv_if(!data_value, -1);
923
924         data_value->type = DATA_VAL_TYPE_STRING;
925         data_value->s_val = strdup(value);
926
927         ret = __add_value_to_hash(resource_info, key, data_value);
928         if (ret) {
929                 free(data_value->s_val);
930                 free(data_value);
931                 return -1;
932         }
933
934         return 0;
935 }
936
937 int connectivity_attributes_remove_value_by_key(connectivity_resource_s *resource_info, const char *key)
938 {
939         retv_if(!resource_info, -1);
940         retv_if(!key, -1);
941
942         if (resource_info->value_hash)
943                 g_hash_table_remove(resource_info->value_hash, key);
944
945         if (g_hash_table_size(resource_info->value_hash) == 0) {
946                 g_hash_table_unref(resource_info->value_hash);
947                 resource_info->value_hash = NULL;
948         }
949
950         return 0;
951 }
952
953 int connectivity_attributes_remove_all(connectivity_resource_s *resource_info)
954 {
955         retv_if(!resource_info, -1);
956
957         if (resource_info->value_hash) {
958                 g_hash_table_destroy(resource_info->value_hash);
959                 resource_info->value_hash = NULL;
960         }
961
962         return 0;
963 }
964
965 static void __json_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
966 {
967         char *name = key;
968         conn_data_value_s *data = value;
969         int ret = 0;
970
971         ret_if(!name);
972         ret_if(!data);
973
974         switch (data->type) {
975         case DATA_VAL_TYPE_BOOL:
976                 ret = web_util_json_add_boolean(name, data->b_val);
977                 if (IOTCON_ERROR_NONE != ret)
978                         _E("failed to add key[%s], value[%d]", name, data->b_val);
979                 break;
980         case DATA_VAL_TYPE_INT:
981                 ret = web_util_json_add_int(name, data->i_val);
982                 if (IOTCON_ERROR_NONE != ret)
983                         _E("failed to add key[%s], value[%d]", name, data->i_val);
984                 break;
985         case DATA_VAL_TYPE_DOUBLE:
986                 ret = web_util_json_add_double(name, data->d_val);
987                 if (IOTCON_ERROR_NONE != ret)
988                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
989                 break;
990         case DATA_VAL_TYPE_STRING:
991                 ret = web_util_json_add_string(name, data->s_val);
992                 if (IOTCON_ERROR_NONE != ret)
993                         _E("failed to add key[%s], value[%s]", name, data->s_val);
994                 break;
995         default:
996                 _E("Unknown data type [%d]", data->type);
997                 break;
998         }
999
1000         return;
1001 }
1002
1003 static void __attr_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
1004 {
1005         char *name = key;
1006         conn_data_value_s *data = value;
1007         iotcon_attributes_h attr = user_data;
1008         int ret = 0;
1009
1010         ret_if(!name);
1011         ret_if(!data);
1012         ret_if(!attr);
1013
1014         switch (data->type) {
1015         case DATA_VAL_TYPE_BOOL:
1016                 ret = iotcon_attributes_add_bool(attr, name, data->b_val);
1017                 if (IOTCON_ERROR_NONE != ret)
1018                         _E("failed to add key[%s], value[%d]", name, data->b_val);
1019                 break;
1020         case DATA_VAL_TYPE_INT:
1021                 ret = iotcon_attributes_add_int(attr, name, data->i_val);
1022                 if (IOTCON_ERROR_NONE != ret)
1023                         _E("failed to add key[%s], value[%d]", name, data->i_val);
1024                 break;
1025         case DATA_VAL_TYPE_DOUBLE:
1026                 ret = iotcon_attributes_add_double(attr, name, data->d_val);
1027                 if (IOTCON_ERROR_NONE != ret)
1028                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
1029                 break;
1030         case DATA_VAL_TYPE_STRING:
1031                 ret = iotcon_attributes_add_str(attr, name, data->s_val);
1032                 if (IOTCON_ERROR_NONE != ret)
1033                         _E("failed to add key[%s], value[%s]", name, data->s_val);
1034                 break;
1035         default:
1036                 _E("Unknown data type [%d]", data->type);
1037                 break;
1038         }
1039
1040         return;
1041 }
1042
1043 static int __create_attributes(connectivity_resource_s *resource_info, iotcon_attributes_h *attributes)
1044 {
1045         int ret = 0;
1046         iotcon_attributes_h attr = NULL;
1047
1048         ret = iotcon_attributes_create(&attr);
1049         if (IOTCON_ERROR_NONE != ret) {
1050                 _print_iotcon_error(ret);
1051                 return -1;
1052         }
1053
1054         ret = iotcon_attributes_add_str(attr, PATH, resource_info->path);
1055         if (IOTCON_ERROR_NONE != ret) {
1056                 _print_iotcon_error(ret);
1057                 iotcon_attributes_destroy(attr);
1058                 return -1;
1059         }
1060         if (resource_info->value_hash)
1061                 g_hash_table_foreach(resource_info->value_hash, __attr_add_data_iter_cb, attr);
1062
1063         *attributes = attr;
1064
1065         return 0;
1066 }
1067
1068 int connectivity_attributes_notify_all(connectivity_resource_s *resource_info)
1069 {
1070         int ret = 0;
1071
1072         retv_if(!resource_info, -1);
1073
1074         if (resource_info->value_hash == NULL) {
1075                 _W("You have nothing to notify now");
1076                 return 0;
1077         }
1078
1079
1080         switch (resource_info->protocol_type) {
1081         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1082                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
1083                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
1084                 {
1085                         char *uri_path = NULL;
1086                         iotcon_representation_h representation = NULL;
1087                         iotcon_attributes_h attributes = NULL;
1088                         int iotcon_ret = 0;
1089
1090                         iotcon_ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
1091                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1092
1093                         iotcon_ret = iotcon_representation_create(&representation);
1094                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1095
1096                         iotcon_ret = iotcon_representation_set_uri_path(representation, uri_path);
1097                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1098                                 _print_iotcon_error(iotcon_ret);
1099                                 ret = -1;
1100                         }
1101
1102                         iotcon_ret = __create_attributes(resource_info, &attributes);
1103                         if (iotcon_ret) {
1104                                 _E("failed to create attributes");
1105                                 ret = -1;
1106                         }
1107                         __print_attribute(attributes);
1108
1109                         iotcon_ret = iotcon_representation_set_attributes(representation, attributes);
1110                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1111                                 _print_iotcon_error(iotcon_ret);
1112                                 ret = -1;
1113                         }
1114
1115                         iotcon_ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, representation,
1116                                         resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
1117                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1118                                 _print_iotcon_error(iotcon_ret);
1119                                 ret = -1;
1120                         }
1121
1122                         iotcon_representation_destroy(representation);
1123                         iotcon_attributes_destroy(attributes);
1124                 }
1125                 break;
1126         case CONNECTIVITY_PROTOCOL_HTTP:
1127                 ret = web_util_json_init();
1128                 retv_if(ret, -1);
1129
1130                 ret = web_util_json_begin();
1131                 retv_if(ret, -1);
1132
1133                 web_util_json_add_string("SensorPiID", resource_info->path);
1134                 web_util_json_add_string("SensorPiType", resource_info->type);
1135                 g_hash_table_foreach(resource_info->value_hash, __json_add_data_iter_cb, NULL);
1136                 web_util_json_end();
1137
1138                 __noti_by_http();
1139
1140                 web_util_json_fini();
1141                 break;
1142         default:
1143                 break;
1144         }
1145
1146         g_hash_table_destroy(resource_info->value_hash);
1147         resource_info->value_hash = NULL;
1148
1149         return ret;
1150 }
1151
1152 void connectivity_unset_resource(connectivity_resource_s *resource_info)
1153 {
1154         ret_if(!resource_info);
1155
1156         switch (resource_info->protocol_type) {
1157         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1158                 if (resource_info->conn_data.iotcon_data.observers) iotcon_observers_destroy(resource_info->conn_data.iotcon_data.observers);
1159                 if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res);
1160                 iotcon_deinitialize();
1161                 connectivity_iotcon_intialized = 0;
1162                 break;
1163         case CONNECTIVITY_PROTOCOL_HTTP:
1164                 web_util_noti_fini();
1165                 connectivity_http_intialized = 0;
1166                 break;
1167         default:
1168                 break;
1169         }
1170
1171         if (resource_info->path) free(resource_info->path);
1172         if (resource_info->type) free(resource_info->type);
1173         free(resource_info);
1174
1175         return;
1176 }
1177
1178 int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
1179 {
1180         connectivity_resource_s *resource_info = NULL;
1181         int ret = -1;
1182
1183         retv_if(!path, -1);
1184         retv_if(!type, -1);
1185         retv_if(!out_resource_info, -1);
1186
1187         resource_info = calloc(1, sizeof(connectivity_resource_s));
1188         retv_if(!resource_info, -1);
1189
1190         resource_info->path = strdup(path);
1191         goto_if(!resource_info->path, error);
1192
1193         resource_info->type = strdup(type);
1194         goto_if(!resource_info->type, error);
1195
1196         resource_info->protocol_type = ProtocolType;
1197
1198         _D("Path[%s], Type[%s], protocol_type[%d]" , resource_info->path, resource_info->type, resource_info->protocol_type);
1199
1200         switch (resource_info->protocol_type) {
1201         case CONNECTIVITY_PROTOCOL_DEFAULT:
1202                 _D("default protocol type is iotivity\n \
1203                          To set connectivity use connectivity_set_protocol_type() function");
1204                 resource_info->protocol_type = CONNECTIVITY_PROTOCOL_IOTIVITY;
1205         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1206                 ret = __init_iotcon(resource_info);
1207                 goto_if(ret, error);
1208                 break;
1209         case CONNECTIVITY_PROTOCOL_HTTP:
1210                 ret = __init_http(resource_info);
1211                 goto_if(ret, error);
1212                 break;
1213         default:
1214                 goto error;
1215                 break;
1216         }
1217
1218         *out_resource_info = resource_info;
1219
1220         return 0;
1221
1222 error:
1223         if (resource_info->path) free(resource_info->path);
1224         if (resource_info->type) free(resource_info->type);
1225         if (resource_info) free(resource_info);
1226
1227         return -1;
1228 }
1229
1230 int connectivity_set_protocol(connectivity_protocol_e protocol_type)
1231 {
1232         int ret = 0;
1233         retv_if(protocol_type >= CONNECTIVITY_PROTOCOL_MAX, -1);
1234
1235         switch (protocol_type) {
1236         case CONNECTIVITY_PROTOCOL_DEFAULT:
1237         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1238                 if (connectivity_iotcon_intialized) {
1239                         _E("protocol type[%d] aleady initialized", protocol_type);
1240                         return -1;
1241                 }
1242                 ProtocolType = CONNECTIVITY_PROTOCOL_IOTIVITY;
1243                 break;
1244         case CONNECTIVITY_PROTOCOL_HTTP:
1245                 if (connectivity_http_intialized) {
1246                         _E("protocol type[%d] aleady initialized", protocol_type);
1247                         return -1;
1248                 }
1249                 ProtocolType = CONNECTIVITY_PROTOCOL_HTTP;
1250                 break;
1251         default:
1252                 _E("unknown protocol type[%d]", protocol_type);
1253                 return -1;
1254                 break;
1255         }
1256
1257         return ret;
1258 }