fix typos in connectivity.c 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 #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         return;
596 }
597
598 int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
599 {
600         int ret = -1;
601
602         retv_if(!resource_info, -1);
603         retv_if(!key, -1);
604
605         _D("Notify key[%s], value[%d]", key, value);
606
607         switch (resource_info->protocol_type) {
608         case CONNECTIVITY_PROTOCOL_IOTIVITY:
609                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
610                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
611                 {
612                         iotcon_representation_h representation;
613                         representation = _create_representation_with_bool(resource_info, key, value);
614                         retv_if(!representation, -1);
615                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
616                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
617                         if (IOTCON_ERROR_NONE != ret) {
618                                 _W("There are some troubles for notifying value[%d]", ret);
619                                 _print_iotcon_error(ret);
620                                 return -1;
621                         }
622                         _destroy_representation(representation);
623                 }
624                 break;
625         case CONNECTIVITY_PROTOCOL_HTTP:
626                 ret = web_util_json_init();
627                 retv_if(ret, -1);
628
629                 ret = web_util_json_begin();
630                 retv_if(ret, -1);
631
632                 web_util_json_add_string("SensorPiID", resource_info->path);
633                 web_util_json_add_string("SensorPiType", resource_info->type);
634                 web_util_json_add_string("SensorPiIP", resource_info->ip);
635                 web_util_json_add_boolean(key, value);
636                 web_util_json_end();
637
638                 __noti_by_http();
639
640                 web_util_json_fini();
641                 break;
642         default:
643                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
644                 return -1;
645                 break;
646         }
647
648         return 0;
649 }
650
651 int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
652 {
653         int ret = -1;
654
655         retv_if(!resource_info, -1);
656         retv_if(!key, -1);
657
658         _D("Notify key[%s], value[%d]", key, value);
659
660         switch (resource_info->protocol_type) {
661         case CONNECTIVITY_PROTOCOL_IOTIVITY:
662                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
663                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
664                 {
665                         iotcon_representation_h representation;
666                         representation = _create_representation_with_int(resource_info, key, value);
667                         retv_if(!representation, -1);
668                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
669                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
670                         if (IOTCON_ERROR_NONE != ret) {
671                                 _W("There are some troubles for notifying value[%d]", ret);
672                                 _print_iotcon_error(ret);
673                                 return -1;
674                         }
675                         _destroy_representation(representation);
676                 }
677                 break;
678         case CONNECTIVITY_PROTOCOL_HTTP:
679                 ret = web_util_json_init();
680                 retv_if(ret, -1);
681
682                 ret = web_util_json_begin();
683                 retv_if(ret, -1);
684
685                 web_util_json_add_string("SensorPiID", resource_info->path);
686                 web_util_json_add_string("SensorPiType", resource_info->type);
687                 web_util_json_add_string("SensorPiIP", resource_info->ip);
688                 web_util_json_add_int(key, value);
689                 web_util_json_end();
690
691                 __noti_by_http();
692
693                 web_util_json_fini();
694                 break;
695         default:
696                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
697                 return -1;
698                 break;
699         }
700         return 0;
701 }
702
703 int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
704 {
705         int ret = -1;
706
707         retv_if(!resource_info, -1);
708         retv_if(!key, -1);
709
710         _D("Notify key[%s], value[%lf]", key, value);
711
712         switch (resource_info->protocol_type) {
713         case CONNECTIVITY_PROTOCOL_IOTIVITY:
714                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
715                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
716                 {
717                         iotcon_representation_h representation;
718                         representation = _create_representation_with_double(resource_info, key, value);
719                         retv_if(!representation, -1);
720                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
721                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
722                         if (IOTCON_ERROR_NONE != ret) {
723                                 _W("There are some troubles for notifying value[%d]", ret);
724                                 _print_iotcon_error(ret);
725                                 return -1;
726                         }
727                         _destroy_representation(representation);
728                 }
729                 break;
730         case CONNECTIVITY_PROTOCOL_HTTP:
731                 ret = web_util_json_init();
732                 retv_if(ret, -1);
733
734                 ret = web_util_json_begin();
735                 retv_if(ret, -1);
736
737                 web_util_json_add_string("SensorPiID", resource_info->path);
738                 web_util_json_add_string("SensorPiType", resource_info->type);
739                 web_util_json_add_string("SensorPiIP", resource_info->ip);
740                 web_util_json_add_double(key, value);
741                 web_util_json_end();
742
743                 __noti_by_http();
744
745                 web_util_json_fini();
746                 break;
747         default:
748                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
749                 return -1;
750                 break;
751         }
752         return 0;
753 }
754
755 int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, const char *value)
756 {
757         int ret = -1;
758
759         retv_if(!resource_info, -1);
760         retv_if(!key, -1);
761         retv_if(!value, -1);
762
763         _D("Notify key[%s], value[%s]", key, value);
764
765         switch (resource_info->protocol_type) {
766         case CONNECTIVITY_PROTOCOL_IOTIVITY:
767                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
768                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
769                 {
770                         iotcon_representation_h representation;
771                         representation = _create_representation_with_string(resource_info, key, value);
772                         retv_if(!representation, -1);
773                         ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res,
774                                         representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
775                         if (IOTCON_ERROR_NONE != ret) {
776                                 _W("There are some troubles for notifying value[%d]", ret);
777                                 _print_iotcon_error(ret);
778                                 return -1;
779                         }
780                         _destroy_representation(representation);
781                 }
782                 break;
783         case CONNECTIVITY_PROTOCOL_HTTP:
784                 ret = web_util_json_init();
785                 retv_if(ret, -1);
786
787                 ret = web_util_json_begin();
788                 retv_if(ret, -1);
789
790                 web_util_json_add_string("SensorPiID", resource_info->path);
791                 web_util_json_add_string("SensorPiType", resource_info->type);
792                 web_util_json_add_string("SensorPiIP", resource_info->ip);
793                 web_util_json_add_string(key, value);
794                 web_util_json_end();
795
796                 __noti_by_http();
797
798                 web_util_json_fini();
799                 break;
800         default:
801                 _E("Unknown protocol type[%d]", resource_info->protocol_type);
802                 return -1;
803                 break;
804         }
805         return 0;
806 }
807
808 static void __hash_key_free(gpointer data)
809 {
810         free(data);
811         return;
812 }
813
814 static void __hash_value_free(gpointer data)
815 {
816         conn_data_value_s *value = data;
817         if (value && (value->type == DATA_VAL_TYPE_STRING))
818                 free(value->s_val);
819         free(value);
820
821         return;
822 }
823
824 static int __add_value_to_hash(connectivity_resource_s *resource_info, const char *key, conn_data_value_s *value)
825 {
826         retv_if(!resource_info, -1);
827         retv_if(!key, -1);
828         retv_if(!value, -1);
829
830         if (!resource_info->value_hash) {
831                 resource_info->value_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
832                                                                                 __hash_key_free, __hash_value_free);
833                 retv_if(!resource_info->value_hash, -1);
834         }
835
836         g_hash_table_insert(resource_info->value_hash, strdup(key), value);
837
838         return 0;
839 }
840
841 int connectivity_attributes_add_bool(connectivity_resource_s *resource_info, const char *key, bool value)
842 {
843         int ret = 0;
844         conn_data_value_s *data_value = NULL;
845
846         retv_if(!resource_info, -1);
847         retv_if(!key, -1);
848
849         _D("adding key[%s] - value[%d]", key, value);
850
851         data_value = malloc(sizeof(conn_data_value_s));
852         retv_if(!data_value, -1);
853
854         data_value->type = DATA_VAL_TYPE_BOOL;
855         data_value->b_val = value;
856
857         ret = __add_value_to_hash(resource_info, key, data_value);
858         if (ret) {
859                 free(data_value);
860                 return -1;
861         }
862
863         return 0;
864 }
865
866 int connectivity_attributes_add_int(connectivity_resource_s *resource_info, const char *key, int value)
867 {
868         int ret = 0;
869         conn_data_value_s *data_value = NULL;
870
871         retv_if(!resource_info, -1);
872         retv_if(!key, -1);
873
874         _D("adding key[%s] - value[%d]", key, value);
875
876         data_value = malloc(sizeof(conn_data_value_s));
877         retv_if(!data_value, -1);
878
879         data_value->type = DATA_VAL_TYPE_INT;
880         data_value->i_val = value;
881
882         ret = __add_value_to_hash(resource_info, key, data_value);
883         if (ret) {
884                 free(data_value);
885                 return -1;
886         }
887
888         return 0;
889 }
890
891 int connectivity_attributes_add_double(connectivity_resource_s *resource_info, const char *key, double value)
892 {
893         int ret = 0;
894         conn_data_value_s *data_value = NULL;
895
896         retv_if(!resource_info, -1);
897         retv_if(!key, -1);
898
899         _D("adding key[%s] - value[%lf]", key, value);
900
901         data_value = malloc(sizeof(conn_data_value_s));
902         retv_if(!data_value, -1);
903
904         data_value->type = DATA_VAL_TYPE_DOUBLE;
905         data_value->d_val = value;
906
907         ret = __add_value_to_hash(resource_info, key, data_value);
908         if (ret) {
909                 free(data_value);
910                 return -1;
911         }
912
913         return 0;
914 }
915
916 int connectivity_attributes_add_string(connectivity_resource_s *resource_info, const char *key, const char *value)
917 {
918         int ret = 0;
919         conn_data_value_s *data_value = NULL;
920
921         retv_if(!resource_info, -1);
922         retv_if(!key, -1);
923         retv_if(!value, -1);
924
925         _D("adding key[%s] - value[%s]", key, value);
926
927         data_value = malloc(sizeof(conn_data_value_s));
928         retv_if(!data_value, -1);
929
930         data_value->type = DATA_VAL_TYPE_STRING;
931         data_value->s_val = strdup(value);
932
933         ret = __add_value_to_hash(resource_info, key, data_value);
934         if (ret) {
935                 free(data_value->s_val);
936                 free(data_value);
937                 return -1;
938         }
939
940         return 0;
941 }
942
943 int connectivity_attributes_remove_value_by_key(connectivity_resource_s *resource_info, const char *key)
944 {
945         retv_if(!resource_info, -1);
946         retv_if(!key, -1);
947
948         if (resource_info->value_hash)
949                 g_hash_table_remove(resource_info->value_hash, key);
950
951         if (g_hash_table_size(resource_info->value_hash) == 0) {
952                 g_hash_table_unref(resource_info->value_hash);
953                 resource_info->value_hash = NULL;
954         }
955
956         return 0;
957 }
958
959 int connectivity_attributes_remove_all(connectivity_resource_s *resource_info)
960 {
961         retv_if(!resource_info, -1);
962
963         if (resource_info->value_hash) {
964                 g_hash_table_destroy(resource_info->value_hash);
965                 resource_info->value_hash = NULL;
966         }
967
968         return 0;
969 }
970
971 static void __json_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
972 {
973         char *name = key;
974         conn_data_value_s *data = value;
975         int ret = 0;
976
977         ret_if(!name);
978         ret_if(!data);
979
980         switch (data->type) {
981         case DATA_VAL_TYPE_BOOL:
982                 ret = web_util_json_add_boolean(name, data->b_val);
983                 if (IOTCON_ERROR_NONE != ret)
984                         _E("failed to add key[%s], value[%d]", name, data->b_val);
985                 break;
986         case DATA_VAL_TYPE_INT:
987                 ret = web_util_json_add_int(name, data->i_val);
988                 if (IOTCON_ERROR_NONE != ret)
989                         _E("failed to add key[%s], value[%d]", name, data->i_val);
990                 break;
991         case DATA_VAL_TYPE_DOUBLE:
992                 ret = web_util_json_add_double(name, data->d_val);
993                 if (IOTCON_ERROR_NONE != ret)
994                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
995                 break;
996         case DATA_VAL_TYPE_STRING:
997                 ret = web_util_json_add_string(name, data->s_val);
998                 if (IOTCON_ERROR_NONE != ret)
999                         _E("failed to add key[%s], value[%s]", name, data->s_val);
1000                 break;
1001         default:
1002                 _E("Unknown data type [%d]", data->type);
1003                 break;
1004         }
1005
1006         return;
1007 }
1008
1009 static void __attr_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data)
1010 {
1011         char *name = key;
1012         conn_data_value_s *data = value;
1013         iotcon_attributes_h attr = user_data;
1014         int ret = 0;
1015
1016         ret_if(!name);
1017         ret_if(!data);
1018         ret_if(!attr);
1019
1020         switch (data->type) {
1021         case DATA_VAL_TYPE_BOOL:
1022                 ret = iotcon_attributes_add_bool(attr, name, data->b_val);
1023                 if (IOTCON_ERROR_NONE != ret)
1024                         _E("failed to add key[%s], value[%d]", name, data->b_val);
1025                 break;
1026         case DATA_VAL_TYPE_INT:
1027                 ret = iotcon_attributes_add_int(attr, name, data->i_val);
1028                 if (IOTCON_ERROR_NONE != ret)
1029                         _E("failed to add key[%s], value[%d]", name, data->i_val);
1030                 break;
1031         case DATA_VAL_TYPE_DOUBLE:
1032                 ret = iotcon_attributes_add_double(attr, name, data->d_val);
1033                 if (IOTCON_ERROR_NONE != ret)
1034                         _E("failed to add key[%s], value[%lf]", name, data->d_val);
1035                 break;
1036         case DATA_VAL_TYPE_STRING:
1037                 ret = iotcon_attributes_add_str(attr, name, data->s_val);
1038                 if (IOTCON_ERROR_NONE != ret)
1039                         _E("failed to add key[%s], value[%s]", name, data->s_val);
1040                 break;
1041         default:
1042                 _E("Unknown data type [%d]", data->type);
1043                 break;
1044         }
1045
1046         return;
1047 }
1048
1049 static int __create_attributes(connectivity_resource_s *resource_info, iotcon_attributes_h *attributes)
1050 {
1051         int ret = 0;
1052         iotcon_attributes_h attr = NULL;
1053
1054         ret = iotcon_attributes_create(&attr);
1055         if (IOTCON_ERROR_NONE != ret) {
1056                 _print_iotcon_error(ret);
1057                 return -1;
1058         }
1059
1060         ret = iotcon_attributes_add_str(attr, PATH, resource_info->path);
1061         if (IOTCON_ERROR_NONE != ret) {
1062                 _print_iotcon_error(ret);
1063                 iotcon_attributes_destroy(attr);
1064                 return -1;
1065         }
1066         if (resource_info->value_hash)
1067                 g_hash_table_foreach(resource_info->value_hash, __attr_add_data_iter_cb, attr);
1068
1069         *attributes = attr;
1070
1071         return 0;
1072 }
1073
1074 int connectivity_attributes_notify_all(connectivity_resource_s *resource_info)
1075 {
1076         int ret = 0;
1077
1078         retv_if(!resource_info, -1);
1079
1080         if (resource_info->value_hash == NULL) {
1081                 _W("You have nothing to notify now");
1082                 return 0;
1083         }
1084
1085
1086         switch (resource_info->protocol_type) {
1087         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1088                 retv_if(!resource_info->conn_data.iotcon_data.res, -1);
1089                 retv_if(!resource_info->conn_data.iotcon_data.observers, -1);
1090                 {
1091                         char *uri_path = NULL;
1092                         iotcon_representation_h representation = NULL;
1093                         iotcon_attributes_h attributes = NULL;
1094                         int iotcon_ret = 0;
1095
1096                         iotcon_ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path);
1097                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1098
1099                         iotcon_ret = iotcon_representation_create(&representation);
1100                         retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1);
1101
1102                         iotcon_ret = iotcon_representation_set_uri_path(representation, uri_path);
1103                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1104                                 _print_iotcon_error(iotcon_ret);
1105                                 ret = -1;
1106                         }
1107
1108                         iotcon_ret = __create_attributes(resource_info, &attributes);
1109                         if (iotcon_ret) {
1110                                 _E("failed to create attributes");
1111                                 ret = -1;
1112                         }
1113                         __print_attribute(attributes);
1114
1115                         iotcon_ret = iotcon_representation_set_attributes(representation, attributes);
1116                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1117                                 _print_iotcon_error(iotcon_ret);
1118                                 ret = -1;
1119                         }
1120
1121                         iotcon_ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, representation,
1122                                         resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW);
1123                         if (IOTCON_ERROR_NONE != iotcon_ret) {
1124                                 _print_iotcon_error(iotcon_ret);
1125                                 ret = -1;
1126                         }
1127
1128                         iotcon_representation_destroy(representation);
1129                         iotcon_attributes_destroy(attributes);
1130                 }
1131                 break;
1132         case CONNECTIVITY_PROTOCOL_HTTP:
1133                 ret = web_util_json_init();
1134                 retv_if(ret, -1);
1135
1136                 ret = web_util_json_begin();
1137                 retv_if(ret, -1);
1138
1139                 web_util_json_add_string("SensorPiID", resource_info->path);
1140                 web_util_json_add_string("SensorPiType", resource_info->type);
1141                 web_util_json_add_string("SensorPiIP", resource_info->ip);
1142                 g_hash_table_foreach(resource_info->value_hash, __json_add_data_iter_cb, NULL);
1143                 web_util_json_end();
1144
1145                 __noti_by_http();
1146
1147                 web_util_json_fini();
1148                 break;
1149         default:
1150                 break;
1151         }
1152
1153         g_hash_table_destroy(resource_info->value_hash);
1154         resource_info->value_hash = NULL;
1155
1156         return ret;
1157 }
1158
1159 void connectivity_unset_resource(connectivity_resource_s *resource_info)
1160 {
1161         ret_if(!resource_info);
1162
1163         switch (resource_info->protocol_type) {
1164         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1165                 if (resource_info->conn_data.iotcon_data.observers) iotcon_observers_destroy(resource_info->conn_data.iotcon_data.observers);
1166                 if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res);
1167                 iotcon_deinitialize();
1168                 connectivity_iotcon_intialized = 0;
1169                 break;
1170         case CONNECTIVITY_PROTOCOL_HTTP:
1171                 web_util_noti_fini();
1172                 connectivity_http_intialized = 0;
1173                 break;
1174         default:
1175                 break;
1176         }
1177
1178         if (resource_info->path) free(resource_info->path);
1179         if (resource_info->type) free(resource_info->type);
1180         if (resource_info->ip) free(resource_info->ip);
1181         free(resource_info);
1182
1183         return;
1184 }
1185
1186 int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
1187 {
1188         connectivity_resource_s *resource_info = NULL;
1189         const char *ip = NULL;
1190         int ret = -1;
1191
1192         retv_if(!path, -1);
1193         retv_if(!type, -1);
1194         retv_if(!out_resource_info, -1);
1195
1196         resource_info = calloc(1, sizeof(connectivity_resource_s));
1197         retv_if(!resource_info, -1);
1198
1199         resource_info->path = strdup(path);
1200         goto_if(!resource_info->path, error);
1201
1202         resource_info->type = strdup(type);
1203         goto_if(!resource_info->type, error);
1204
1205         connection_manager_get_ip(&ip);
1206         resource_info->ip = strdup(ip);
1207         goto_if(!resource_info->ip, error);
1208
1209         resource_info->protocol_type = ProtocolType;
1210
1211         _D("Path[%s], Type[%s], protocol_type[%d]" , resource_info->path, resource_info->type, resource_info->protocol_type);
1212
1213         switch (resource_info->protocol_type) {
1214         case CONNECTIVITY_PROTOCOL_DEFAULT:
1215                 _D("default protocol type is iotivity\n \
1216                          To set connectivity use connectivity_set_protocol_type() function");
1217                 resource_info->protocol_type = CONNECTIVITY_PROTOCOL_IOTIVITY;
1218         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1219                 ret = __init_iotcon(resource_info);
1220                 goto_if(ret, error);
1221                 break;
1222         case CONNECTIVITY_PROTOCOL_HTTP:
1223                 ret = __init_http(resource_info);
1224                 goto_if(ret, error);
1225                 break;
1226         default:
1227                 goto error;
1228                 break;
1229         }
1230
1231         *out_resource_info = resource_info;
1232
1233         return 0;
1234
1235 error:
1236         if (resource_info->path) free(resource_info->path);
1237         if (resource_info->type) free(resource_info->type);
1238         if (resource_info->ip) free(resource_info->ip);
1239         if (resource_info) free(resource_info);
1240
1241         return -1;
1242 }
1243
1244 int connectivity_set_protocol(connectivity_protocol_e protocol_type)
1245 {
1246         int ret = 0;
1247         retv_if(protocol_type >= CONNECTIVITY_PROTOCOL_MAX, -1);
1248
1249         switch (protocol_type) {
1250         case CONNECTIVITY_PROTOCOL_DEFAULT:
1251         case CONNECTIVITY_PROTOCOL_IOTIVITY:
1252                 if (connectivity_iotcon_intialized) {
1253                         _E("protocol type[%d] already initialized", protocol_type);
1254                         return -1;
1255                 }
1256                 ProtocolType = CONNECTIVITY_PROTOCOL_IOTIVITY;
1257                 break;
1258         case CONNECTIVITY_PROTOCOL_HTTP:
1259                 if (connectivity_http_intialized) {
1260                         _E("protocol type[%d] already initialized", protocol_type);
1261                         return -1;
1262                 }
1263                 ProtocolType = CONNECTIVITY_PROTOCOL_HTTP;
1264                 break;
1265         default:
1266                 _E("unknown protocol type[%d]", protocol_type);
1267                 return -1;
1268                 break;
1269         }
1270
1271         return ret;
1272 }