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