fix typos in conf file
[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(out);
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         conn_data_value_s *data_value = NULL;
838
839         retv_if(!resource_info, -1);
840         retv_if(!key, -1);
841
842         _D("adding key[%s] - value[%d]", key, value);
843
844         data_value = malloc(sizeof(conn_data_value_s));
845         retv_if(!data_value, -1);
846
847         data_value->type = DATA_VAL_TYPE_BOOL;
848         data_value->b_val = value;
849
850         return __add_value_to_hash(resource_info, key, data_value);
851 }
852
853 int connectivity_attributes_add_int(connectivity_resource_s *resource_info, const char *key, int value)
854 {
855         conn_data_value_s *data_value = NULL;
856
857         retv_if(!resource_info, -1);
858         retv_if(!key, -1);
859
860         _D("adding key[%s] - value[%d]", key, value);
861
862         data_value = malloc(sizeof(conn_data_value_s));
863         retv_if(!data_value, -1);
864
865         data_value->type = DATA_VAL_TYPE_INT;
866         data_value->i_val = value;
867
868         return __add_value_to_hash(resource_info, key, data_value);
869 }
870
871 int connectivity_attributes_add_double(connectivity_resource_s *resource_info, const char *key, double value)
872 {
873         conn_data_value_s *data_value = NULL;
874
875         retv_if(!resource_info, -1);
876         retv_if(!key, -1);
877
878         _D("adding key[%s] - value[%lf]", key, value);
879
880         data_value = malloc(sizeof(conn_data_value_s));
881         retv_if(!data_value, -1);
882
883         data_value->type = DATA_VAL_TYPE_DOUBLE;
884         data_value->d_val = value;
885
886         return __add_value_to_hash(resource_info, key, data_value);
887 }
888
889 int connectivity_attributes_add_string(connectivity_resource_s *resource_info, const char *key, const char *value)
890 {
891         conn_data_value_s *data_value = NULL;
892
893         retv_if(!resource_info, -1);
894         retv_if(!key, -1);
895         retv_if(!value, -1);
896
897         _D("adding key[%s] - value[%s]", key, value);
898
899         data_value = malloc(sizeof(conn_data_value_s));
900         retv_if(!data_value, -1);
901
902         data_value->type = DATA_VAL_TYPE_STRING;
903         data_value->s_val = strdup(value);
904
905         return __add_value_to_hash(resource_info, key, data_value);
906 }
907
908 static void __json_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
909 {
910         char *name = key;
911         conn_data_value_s *data = value;
912         int ret = 0;
913
914         ret_if(name);
915         ret_if(data);
916
917         switch (data->type) {
918         case DATA_VAL_TYPE_BOOL:
919                 ret = web_util_json_add_boolean(name, data->b_val);
920                 if (IOTCON_ERROR_NONE != ret)
921                         _E("failed to add key[%s], value[%d]", name, data->b_val);
922                 break;
923         case DATA_VAL_TYPE_INT:
924                 ret = web_util_json_add_int(name, data->i_val);
925                 if (IOTCON_ERROR_NONE != ret)
926                         _E("failed to add key[%s], value[%d]", name, data->i_val);
927                 break;
928         case DATA_VAL_TYPE_DOUBLE:
929                 ret = web_util_json_add_double(name, data->d_val);
930                 if (IOTCON_ERROR_NONE != ret)
931                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
932                 break;
933         case DATA_VAL_TYPE_STRING:
934                 ret = web_util_json_add_string(name, data->s_val);
935                 if (IOTCON_ERROR_NONE != ret)
936                         _E("failed to add key[%s], value[%s]", name, data->s_val);
937                 break;
938         default:
939                 _E("Unknown data type [%d]", data->type);
940                 break;
941         }
942
943         return;
944 }
945
946 static void __attr_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
947 {
948         char *name = key;
949         conn_data_value_s *data = value;
950         iotcon_attributes_h attr = user_data;
951         int ret = 0;
952
953         ret_if(name);
954         ret_if(data);
955         ret_if(attr);
956
957         switch (data->type) {
958         case DATA_VAL_TYPE_BOOL:
959                 ret = iotcon_attributes_add_bool(attr, name, data->b_val);
960                 if (IOTCON_ERROR_NONE != ret)
961                         _E("failed to add key[%s], value[%d]", name, data->b_val);
962                 break;
963         case DATA_VAL_TYPE_INT:
964                 ret = iotcon_attributes_add_int(attr, name, data->i_val);
965                 if (IOTCON_ERROR_NONE != ret)
966                         _E("failed to add key[%s], value[%d]", name, data->i_val);
967                 break;
968         case DATA_VAL_TYPE_DOUBLE:
969                 ret = iotcon_attributes_add_double(attr, name, data->d_val);
970                 if (IOTCON_ERROR_NONE != ret)
971                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
972                 break;
973         case DATA_VAL_TYPE_STRING:
974                 ret = iotcon_attributes_add_str(attr, name, data->s_val);
975                 if (IOTCON_ERROR_NONE != ret)
976                         _E("failed to add key[%s], value[%s]", name, data->s_val);
977                 break;
978         default:
979                 _E("Unknown data type [%d]", data->type);
980                 break;
981         }
982
983         return;
984 }
985
986 static int __create_attributes(connectivity_resource_s *resource_info, iotcon_attributes_h *attributes)
987 {
988         int ret = 0;
989         iotcon_attributes_h attr = NULL;
990
991         ret = iotcon_attributes_create(&attr);
992         if (IOTCON_ERROR_NONE != ret) {
993                 _print_iotcon_error(ret);
994                 return -1;
995         }
996
997         ret = iotcon_attributes_add_str(attr, PATH, resource_info->path);
998         if (IOTCON_ERROR_NONE != ret) {
999                 _print_iotcon_error(ret);
1000                 iotcon_attributes_destroy(attr);
1001                 return -1;
1002         }
1003         if (resource_info->value_hash)
1004                 g_hash_table_foreach(resource_info->value_hash, __attr_add_data_iter_cb, attr);
1005
1006         *attributes = attr;
1007
1008         return 0;
1009 }
1010
1011 int connectivity_attributes_notify_all(connectivity_resource_s *resource_info)
1012 {
1013         int ret = 0;
1014
1015         retv_if(!resource_info, -1);
1016         retv_if(!resource_info->value_hash, -1);
1017
1018         switch (resource_info->protocol_type) {
1019         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1020                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
1021                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
1022                 {
1023                         char *uri_path = NULL;
1024                         iotcon_representation_h representation = NULL;
1025                         iotcon_attributes_h attributes = NULL;
1026                         int iotcon_ret = 0;
1027
1028                         iotcon_ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
1029                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1030
1031                         iotcon_ret = iotcon_representation_create(&representation);
1032                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1033
1034                         iotcon_ret = iotcon_representation_set_uri_path(representation, uri_path);
1035                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1036                                 _print_iotcon_error(iotcon_ret);
1037                                 ret = -1;
1038                         }
1039
1040                         iotcon_ret = __create_attributes(resource_info, &attributes);
1041                         if (iotcon_ret) {
1042                                 _E("failed to create attributes");
1043                                 ret = -1;
1044                         }
1045                         __print_attribute(attributes);
1046
1047                         iotcon_ret = iotcon_representation_set_attributes(representation, attributes);
1048                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1049                                 _print_iotcon_error(iotcon_ret);
1050                                 ret = -1;
1051                         }
1052
1053                         iotcon_ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, representation,
1054                                         resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
1055                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1056                                 _print_iotcon_error(iotcon_ret);
1057                                 ret = -1;
1058                         }
1059
1060                         iotcon_representation_destroy(representation);
1061                         iotcon_attributes_destroy(attributes);
1062                 }
1063                 break;
1064         case CONNECTIVITY_PROTOCOL_HTTP:
1065                 /* TODO */
1066                 ret = web_util_json_init();
1067                 retv_if(ret, -1);
1068
1069                 ret = web_util_json_begin();
1070                 retv_if(ret, -1);
1071
1072                 web_util_json_add_string("SensorPiID", resource_info->path);
1073                 web_util_json_add_string("SensorPiType", resource_info->type);
1074                 g_hash_table_foreach(resource_info->value_hash, __json_add_data_iter_cb, NULL);
1075                 web_util_json_end();
1076
1077                 __noti_by_http();
1078
1079                 web_util_json_fini();
1080                 break;
1081         default:
1082                 break;
1083         }
1084
1085         g_hash_table_destroy(resource_info->value_hash);
1086         resource_info->value_hash = NULL;
1087
1088         return ret;
1089 }
1090
1091 void connectivity_unset_resource(connectivity_resource_s *resource_info)
1092 {
1093         ret_if(!resource_info);
1094
1095         switch (resource_info->protocol_type) {
1096         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1097                 if (resource_info->conn_data.iotcon_data.observers) iotcon_observers_destroy(resource_info->conn_data.iotcon_data.observers);
1098                 if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res);
1099                 iotcon_deinitialize();
1100                 connectivity_iotcon_intialized = 0;
1101                 break;
1102         case CONNECTIVITY_PROTOCOL_HTTP:
1103                 web_util_noti_fini();
1104                 connectivity_http_intialized = 0;
1105                 break;
1106         default:
1107                 break;
1108         }
1109
1110         if (resource_info->path) free(resource_info->path);
1111         if (resource_info->type) free(resource_info->type);
1112         free(resource_info);
1113
1114         return;
1115 }
1116
1117 int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
1118 {
1119         connectivity_resource_s *resource_info = NULL;
1120         int ret = -1;
1121
1122         retv_if(!path, -1);
1123         retv_if(!type, -1);
1124         retv_if(!out_resource_info, -1);
1125
1126         resource_info = calloc(1, sizeof(connectivity_resource_s));
1127         retv_if(!resource_info, -1);
1128
1129         resource_info->path = strdup(path);
1130         goto_if(!resource_info->path, error);
1131
1132         resource_info->type = strdup(type);
1133         goto_if(!resource_info->type, error);
1134
1135         resource_info->protocol_type = ProtocolType;
1136
1137         _D("Path[%s], Type[%s], protocol_type[%d]" , resource_info->path, resource_info->type, resource_info->protocol_type);
1138
1139         switch (resource_info->protocol_type) {
1140         case CONNECTIVITY_PROTOCOL_DEFAULT:
1141                 _D("default protocol type is iotivity\n \
1142                          To set connectivity use connectivity_set_protocol_type() function");
1143                 resource_info->protocol_type = CONNECTIVITY_PROTOCOL_IOTIVITY;
1144         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1145                 ret = __init_iotcon(resource_info);
1146                 goto_if(ret, error);
1147                 break;
1148         case CONNECTIVITY_PROTOCOL_HTTP:
1149                 ret = __init_http(resource_info);
1150                 goto_if(ret, error);
1151                 break;
1152         default:
1153                 goto error;
1154                 break;
1155         }
1156
1157         *out_resource_info = resource_info;
1158
1159         return 0;
1160
1161 error:
1162         if (resource_info->path) free(resource_info->path);
1163         if (resource_info->type) free(resource_info->type);
1164         if (resource_info) free(resource_info);
1165
1166         return -1;
1167 }
1168
1169 int connectivity_set_protocol(connectivity_protocol_e protocol_type)
1170 {
1171         int ret = 0;
1172         retv_if(protocol_type >= CONNECTIVITY_PROTOCOL_MAX, -1);
1173
1174         switch (protocol_type) {
1175         case CONNECTIVITY_PROTOCOL_DEFAULT:
1176         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1177                 if (connectivity_iotcon_intialized) {
1178                         _E("protocol type[%d] aleady initialized", protocol_type);
1179                         return -1;
1180                 }
1181                 ProtocolType = CONNECTIVITY_PROTOCOL_IOTIVITY;
1182                 break;
1183         case CONNECTIVITY_PROTOCOL_HTTP:
1184                 if (connectivity_http_intialized) {
1185                         _E("protocol type[%d] aleady initialized", protocol_type);
1186                         return -1;
1187                 }
1188                 ProtocolType = CONNECTIVITY_PROTOCOL_HTTP;
1189                 break;
1190         default:
1191                 _E("unknown protocol type[%d]", protocol_type);
1192                 return -1;
1193                 break;
1194         }
1195
1196         return ret;
1197 }