Add the scan timeout in bluetooth capi
[platform/core/connectivity/bluetooth-frwk.git] / capi / bluetooth.c
1 /*
2 * Bluetooth-Frwk-NG
3 *
4 * Copyright (c) 2013-2014 Intel Corporation.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *              http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #include <stdbool.h>
21 #include <string.h>
22 #include <gio/gio.h>
23 #include <dbus/dbus.h>
24 #include <gio/gunixfdlist.h>
25
26 #include "common.h"
27 #include "bluez.h"
28 #include "bluetooth-service.h"
29
30 #include "bluetooth.h"
31
32 #define ERROR_INTERFACE "org.tizen.comms.Error"
33 #define SPP_PROFILE_PATH "/bluetooth/profile/spp"
34
35 #define DEVICE_SERVICE_CLASS_DISCOVERABLE_MODE  0x002000
36
37 #define BT_STOP_DISCOVERY_TIMEOUT (1000*15)
38
39 #define BT_SPP_BUFFER_MAX 1024
40 #define BLUETOOTH_IDENT_LEN 6
41 #define CONNMAN_DBUS_NAME "net.connman"
42 #define CONNMAN_BLUETOOTH_SERVICE_PREFIX "/net/connman/service/bluetooth_"
43 #define CONNMAN_BLUETOOTH_TECHNOLOGY_PATH "/net/connman/technology/bluetooth"
44 #define CONNMAN_BLUETOTOH_TECHNOLOGY_INTERFACE "net.connman.Technology"
45
46 #define BLUEZ_AGENT_SERVICE "org.bluezlib.agent"
47 #define AGENT_INTERFACE "org.bluez.Agent1"
48 #define AGENT_OBJECT_PATH "/org/bluezlib/agent"
49
50 static bool initialized;
51 static bool bt_service_init;
52
53 static guint bluetooth_agent_id;
54 static guint profile_id;
55 static GDBusConnection *conn;
56
57 static bluez_adapter_t *default_adapter;
58
59 static guint event_id;
60
61 static void profile_connect_callback(bluez_device_t *device,
62                                         enum device_profile_state state);
63
64 static void profile_disconnect_callback(bluez_device_t *device,
65                                         enum device_profile_state state);
66
67 static int request_name_on_dbus(const char *name);
68 static void release_name_on_dbus(const char *name);
69
70 struct device_connect_cb_node {
71         bt_device_gatt_state_changed_cb cb;
72         void *user_data;
73 };
74
75 struct device_disconnect_cb_node {
76         bt_device_gatt_state_changed_cb cb;
77         void *user_data;
78 };
79
80 struct device_created_cb_node {
81         bt_adapter_device_discovery_state_changed_cb cb;
82         void *user_data;
83 };
84
85 struct adapter_discovering_cb_node {
86         bt_adapter_device_discovery_state_changed_cb cb;
87         void *user_data;
88 };
89
90 struct adapter_visibility_duration_cb_node {
91         bt_adapter_visibility_duration_changed_cb cb;
92         void *user_data;
93 };
94
95 struct adapter_visibility_mode_cb_node {
96         bt_adapter_visibility_mode_changed_cb cb;
97         void *user_data;
98 };
99
100 struct device_destroy_unpaired_cb_node {
101         bt_adapter_device_discovery_state_changed_cb cb;
102         void *user_data;
103 };
104
105 struct adapter_state_cb_node {
106         bt_adapter_state_changed_cb cb;
107         void *user_data;
108 };
109
110 struct device_bond_cb_node {
111         bt_device_bond_created_cb cb;
112         void *user_data;
113 };
114
115 struct device_destroy_paired_cb_node {
116         bt_device_bond_destroyed_cb cb;
117         void *user_data;
118 };
119
120 struct device_auth_cb_node {
121         bt_device_authorization_changed_cb cb;
122         void *user_data;
123 };
124
125 struct adapter_name_cb_node {
126         bt_adapter_name_changed_cb cb;
127         void *user_data;
128 };
129
130 struct device_connected_state_cb_node {
131         bt_device_connection_state_changed_cb cb;
132         void *user_data;
133 };
134
135 struct device_service_search_cb_node {
136         bt_device_service_searched_cb cb;
137         void *user_data;
138 };
139
140 struct spp_connection_requested_cb_node {
141         bt_spp_connection_requested_cb cb;
142         void *user_data;
143 };
144
145 struct spp_data_received_cb_node {
146         bt_spp_data_received_cb cb;
147         void *user_data;
148 };
149
150 struct avrcp_repeat_mode_changed_node {
151         bt_avrcp_repeat_mode_changed_cb cb;
152         void *user_data;
153 };
154
155 struct avrcp_set_shuffle_mode_changed_node {
156         bt_avrcp_shuffle_mode_changed_cb cb;
157         void *user_data;
158 };
159
160 struct avrcp_target_connection_state_changed_node {
161         bt_avrcp_target_connection_state_changed_cb cb;
162         void *user_data;
163 };
164
165 struct audio_connection_state_changed_cb_node {
166         bt_audio_connection_state_changed_cb cb;
167         void *user_data;
168 };
169
170 struct panu_connection_state_changed_cb_node {
171         bt_panu_connection_state_changed_cb cb;
172         void *user_data;
173 };
174
175 struct hdp_connection_changed_cb_node {
176         bt_hdp_connected_cb conn_cb;
177         bt_hdp_disconnected_cb disconn_cb;
178         void *user_data;
179 };
180
181 struct hdp_set_data_received_cb_node {
182         bt_hdp_data_received_cb cb;
183         void *user_data;
184 };
185
186 struct socket_connection_requested_cb_node {
187         bt_socket_connection_requested_cb cb;
188         void *user_data;
189 };
190
191 struct socket_connection_state_changed_cb_node {
192         bt_socket_connection_state_changed_cb cb;
193         void *user_data;
194 };
195
196 struct hid_host_connection_state_changed_cb_node {
197         bt_hid_host_connection_state_changed_cb cb;
198         void *user_data;
199 };
200
201 struct nap_connection_state_changed_cb_node {
202         bt_nap_connection_state_changed_cb cb;
203         void *user_data;
204 };
205
206 static struct device_connect_cb_node *device_connect_node;
207 static struct device_disconnect_cb_node *device_disconnect_node;
208 static struct avrcp_repeat_mode_changed_node *avrcp_repeat_node;
209 static struct avrcp_set_shuffle_mode_changed_node *avrcp_shuffle_node;
210 static struct adapter_name_cb_node *adapter_name_node;
211 static struct device_created_cb_node *device_created_node;
212 static struct adapter_state_cb_node *adapter_state_node;
213 static struct adapter_discovering_cb_node *adapter_discovering_node;
214 static struct adapter_visibility_duration_cb_node
215                                         *adapter_visibility_duration_node;
216 static struct adapter_visibility_mode_cb_node *adapter_visibility_mode_node;
217 static struct device_destroy_unpaired_cb_node *unpaired_device_removed_node;
218 static struct device_bond_cb_node *device_bond_node;
219 static struct device_auth_cb_node *device_auth_node;
220 static struct device_destroy_paired_cb_node *paired_device_removed_node;
221 static struct device_connected_state_cb_node *device_connected_state_node;
222 static struct device_service_search_cb_node *device_service_search_node;
223 static struct spp_connection_requested_cb_node *spp_connection_requested_node;
224 static struct spp_data_received_cb_node *spp_data_received_node;
225 static struct avrcp_target_connection_state_changed_node
226                                         *avrcp_target_state_node;
227 static struct audio_connection_state_changed_cb_node *audio_state_node;
228 static struct panu_connection_state_changed_cb_node *panu_state_node;
229 static struct hdp_connection_changed_cb_node *hdp_state_node;
230 static struct hdp_set_data_received_cb_node *hdp_set_data_received_node;
231
232 static struct socket_connection_requested_cb_node
233                                         *socket_connection_requested_node;
234 static struct socket_connection_state_changed_cb_node
235                                         *socket_connection_state_node;
236 static struct hid_host_connection_state_changed_cb_node *hid_host_state_node;
237 static struct nap_connection_state_changed_cb_node
238                                 *nap_connection_state_changed_node;
239
240 static gboolean generic_device_removed_set;
241
242 static void divide_device_class(bt_class_s *bt_class, unsigned int class)
243 {
244         bt_class->major_device_class =
245                         (unsigned short)(class & 0x00001F00) >> 8;
246         bt_class->minor_device_class =
247                         (unsigned short)((class & 0x000000FC));
248         bt_class->major_service_class_mask =
249                         (unsigned long)((class & 0x00FF0000));
250
251         if (class & 0x002000) {
252                 bt_class->major_service_class_mask |=
253                         DEVICE_SERVICE_CLASS_DISCOVERABLE_MODE;
254         }
255 }
256
257 static bt_adapter_device_discovery_info_s *get_discovery_device_info(
258                                                 bluez_device_t *device)
259 {
260         guint len;
261         signed short rssi;
262         int paired;
263         char *alias, *address;
264         char **uuids;
265         unsigned int class;
266         bt_adapter_device_discovery_info_s *device_info;
267
268         if (device == NULL)
269                 return NULL;
270
271         device_info = g_new0(bt_adapter_device_discovery_info_s, 1);
272         if (device_info == NULL) {
273                 ERROR("no memory.");
274                 return NULL;
275         }
276
277         address = bluez_device_get_property_address(device);
278         alias = bluez_device_get_property_alias(device);
279         uuids = bluez_device_get_property_uuids(device);
280         bluez_device_get_property_class(device, &class);
281         bluez_device_get_property_rssi(device, &rssi);
282         bluez_device_get_property_paired(device, &paired);
283
284         len = g_strv_length(uuids);
285
286         device_info->service_count = len;
287         device_info->remote_address = address;
288         device_info->remote_name = alias;
289         device_info->rssi = rssi;
290         device_info->is_bonded = paired;
291         device_info->service_uuid = uuids;
292
293         divide_device_class(&device_info->bt_class, class);
294
295         return device_info;
296 }
297
298 static void free_discovery_device_info(
299                 bt_adapter_device_discovery_info_s *discovery_device_info)
300 {
301         int i;
302
303         if (discovery_device_info == NULL)
304                 return ;
305
306         g_free(discovery_device_info->remote_address);
307         g_free(discovery_device_info->remote_name);
308
309         for (i = 0; i < discovery_device_info->service_count; ++i)
310                 g_free(discovery_device_info->service_uuid[i]);
311
312         g_free(discovery_device_info->service_uuid);
313         g_free(discovery_device_info);
314 }
315
316 static bt_device_info_s *get_device_info(bluez_device_t *device)
317 {
318         guint len;
319         int paired, connected, trusted;
320         char *alias, *address;
321         char **uuids;
322         unsigned int class;
323         bt_device_info_s *device_info;
324
325         if (device == NULL) {
326                 ERROR("device is NULL");
327                 return NULL;
328         }
329
330         device_info = g_new0(bt_device_info_s, 1);
331         if (device_info == NULL) {
332                 ERROR("no memory");
333                 return NULL;
334         }
335
336         address = bluez_device_get_property_address(device);
337         alias = bluez_device_get_property_alias(device);
338         uuids = bluez_device_get_property_uuids(device);
339         bluez_device_get_property_class(device, &class);
340         bluez_device_get_property_paired(device, &paired);
341         bluez_device_get_property_connected(device, &connected);
342         bluez_device_get_property_trusted(device, &trusted);
343
344         len = g_strv_length(uuids);
345
346         device_info->service_count = len;
347         device_info->remote_address = address;
348         device_info->remote_name = alias;
349         device_info->is_bonded = paired;
350         device_info->is_connected = connected;
351         device_info->is_authorized = trusted;
352         device_info->service_uuid = uuids;
353
354         divide_device_class(&device_info->bt_class, class);
355
356         return device_info;
357 }
358
359 static void free_device_info(bt_device_info_s *device_info)
360 {
361         gsize i;
362
363         if (device_info == NULL)
364                 return;
365
366         g_free(device_info->remote_address);
367         g_free(device_info->remote_name);
368         for (i = 0; i < device_info->service_count; ++i)
369                 g_free(device_info->service_uuid[i]);
370
371         g_free(device_info->service_uuid);
372         g_free(device_info);
373 }
374
375 void adapter_powered_changed(bluez_adapter_t *adater,
376                                         gboolean powered,
377                                         void *user_data)
378 {
379         struct adapter_state_cb_node *data =
380                         (struct adapter_state_cb_node *)user_data;
381
382         DBG("Powered: %d", powered);
383
384         if (powered == true)
385                 data->cb(BT_ERROR_NONE, BT_ADAPTER_ENABLED, data->user_data);
386         else
387                 data->cb(BT_ERROR_NONE, BT_ADAPTER_DISABLED, data->user_data);
388 }
389
390 static void bluez_paired_device_removed(bluez_device_t *device,
391                                                 void *user_data)
392 {
393         int paired;
394         char *device_addr;
395         char *address;
396         struct device_destroy_paired_cb_node *data = user_data;
397
398         DBG("");
399
400         if (data == NULL)
401                 return;
402
403         address = bluez_device_get_property_address(device);
404         bluez_device_get_property_paired(device, &paired);
405
406         device_addr = address;
407
408         /* CAPI function bt_device_bond_destroyed_cb
409          * parameter 2 is char *, not the const char *
410          * so device_addr should free by user
411          */
412         if (data->cb)
413                 data->cb(BT_SUCCESS, device_addr, data->user_data);
414 }
415
416 static void bluez_unpaired_device_removed(bluez_device_t *device,
417                                                         void *user_data)
418 {
419         bt_adapter_device_discovery_info_s *discovery_device_info;
420         struct device_destroy_unpaired_cb_node *node = user_data;
421
422         if (node == NULL)
423                 return;
424
425         discovery_device_info = get_discovery_device_info(device);
426
427         if (node->cb)
428                 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_REMOVED,
429                                 discovery_device_info, node->user_data);
430
431         free_discovery_device_info(discovery_device_info);
432 }
433
434 static void handle_generic_device_removed(bluez_device_t *device, void *user_data)
435 {
436         int paired;
437
438         if (device == NULL)
439                 return;
440
441         bluez_device_get_property_paired(device, &paired);
442         if (paired == false)
443                 bluez_unpaired_device_removed(device, unpaired_device_removed_node);
444         else
445                 bluez_paired_device_removed(device, paired_device_removed_node);
446 }
447
448 static void set_device_removed_generic_callback(bluez_adapter_t *adapter)
449 {
450         bluez_adapter_set_device_removed_cb(adapter,
451                                 handle_generic_device_removed, NULL);
452
453         generic_device_removed_set = TRUE;
454 }
455
456 static bt_avrcp_repeat_mode_e loopstatus_to_enum(const gchar *repeat)
457 {
458         DBG("repeat = %s", repeat);
459
460         if (g_strcmp0(repeat, "None") == 0)
461                 return BT_AVRCP_REPEAT_MODE_OFF;
462         else if (g_strcmp0(repeat, "Track") == 0)
463                 return BT_AVRCP_REPEAT_MODE_SINGLE_TRACK;
464         else if (g_strcmp0(repeat, "Playlist") == 0)
465                 return BT_AVRCP_REPEAT_MODE_ALL_TRACK;
466         return 0x00;
467 }
468
469 static void bluez_avrcp_repeat_changed(const gchar *repeat,
470                                         void *user_data)
471 {
472         bt_avrcp_repeat_mode_e repeat_mode;
473         struct avrcp_repeat_mode_changed_node *data = user_data;
474
475         repeat_mode = loopstatus_to_enum(repeat);
476
477         if (data->cb)
478                 data->cb(repeat_mode, data->user_data);
479 }
480
481 static bt_avrcp_repeat_mode_e shuffle_to_enum(gboolean shuffle)
482 {
483         if (shuffle) {
484                 DBG("shuffle is true");
485                 return BT_AVRCP_SHUFFLE_MODE_ALL_TRACK;
486         } else {
487                 DBG("shuffle is false");
488                 return BT_AVRCP_SHUFFLE_MODE_OFF;
489         }
490 }
491
492 static void bluez_avrcp_shuffle_changed(gboolean shuffle,
493                                         void *user_data)
494 {
495         bt_avrcp_shuffle_mode_e shuffle_mode;
496         struct avrcp_set_shuffle_mode_changed_node *data =
497                                                 user_data;
498
499         shuffle_mode = shuffle_to_enum(shuffle);
500
501         if (data->cb)
502                 data->cb(shuffle_mode, data->user_data);
503 }
504
505 static void bluez_nap_connection_changed(bool connected,
506                                 const char *remote_address,
507                                 const char *interface_name,
508                                 void *user_data)
509 {
510         struct nap_connection_state_changed_cb_node *data =
511                                                 user_data;
512
513         if (data->cb)
514                 data->cb(connected, remote_address,
515                         interface_name, data->user_data);
516 }
517
518 static void bluez_set_data_received_changed(
519                                 unsigned int channel,
520                                 const char *data,
521                                 unsigned int size,
522                                 void *user_data)
523 {
524         struct hdp_set_data_received_cb_node *data_node =
525                                                 user_data;
526
527         if (data_node->cb)
528                 data_node->cb(channel, data, size,
529                                 data_node->user_data);
530 }
531
532
533 static void bluez_hdp_state_changed(int result,
534                                 const char *remote_address,
535                                 const char *app_id,
536                                 bt_hdp_channel_type_e type,
537                                 unsigned int channel,
538                                 void *user_data)
539 {
540         struct hdp_connection_changed_cb_node *data =
541                                                 user_data;
542
543         if (app_id != NULL) {
544                 if (data->conn_cb)
545                         data->conn_cb(result, remote_address,
546                                         app_id, type, channel,
547                                         data->user_data);
548                 else if (data->disconn_cb)
549                         data->disconn_cb(result, remote_address,
550                                         channel, data->user_data);
551         }
552 }
553
554 static void bluez_avrcp_target_state_changed(const char *remote_address,
555                                         gboolean connected,
556                                         void *user_data)
557 {
558         struct avrcp_target_connection_state_changed_node *data =
559                                                         user_data;
560
561         DBG("");
562
563         if (data->cb)
564                 (data->cb)(connected, remote_address,
565                                                 data->user_data);
566 }
567
568 static void bluez_audio_state_changed(int result,
569                                         gboolean connected,
570                                         const char *remote_address,
571                                         bt_audio_profile_type_e type,
572                                         void *user_data)
573 {
574         struct audio_connection_state_changed_cb_node *data =
575                                                         user_data;
576
577         DBG("");
578
579         if (data->cb)
580                 (data->cb)(result, connected, remote_address, type,
581                                                 data->user_data);
582 }
583
584 static void device_paired_changed(bluez_device_t *device,
585                                         int paired,
586                                         void *user_data)
587 {
588         bt_device_info_s *device_bond_info;
589         struct device_bond_cb_node *data = user_data;
590
591         DBG("");
592
593         device_bond_info = get_device_info(device);
594
595         data->cb(BT_SUCCESS, device_bond_info, data->user_data);
596
597         free_device_info(device_bond_info);
598 }
599
600 static void device_connected_changed(bluez_device_t *device,
601                                         int connected, void *user_data)
602 {
603         struct device_connected_state_cb_node *node = user_data;
604         char *device_address;
605
606         DBG("");
607
608         device_address = bluez_device_get_property_address(device);
609
610         node->cb(connected, device_address, node->user_data);
611
612         g_free(device_address);
613 }
614
615 static void device_auth_changed(bluez_device_t *device,
616                                         int trusted, void *user_data)
617 {
618         struct device_auth_cb_node *node = user_data;
619         bt_device_authorization_e authorization;
620         char *device_address;
621
622         DBG("");
623
624         authorization = trusted ? BT_DEVICE_UNAUTHORIZED:
625                                 BT_DEVICE_AUTHORIZED;
626
627         device_address = bluez_device_get_property_address(device);
628
629         node->cb(authorization, device_address, node->user_data);
630
631         g_free(device_address);
632 }
633
634 static void device_panu_connected_changed(bluez_device_t *device,
635                                         int connected, void *user_data)
636 {
637         struct panu_connection_state_changed_cb_node *node = user_data;
638         char *device_address;
639
640         DBG("");
641
642         device_address = bluez_device_get_property_address(device);
643
644         node->cb(BT_SUCCESS, connected, device_address,
645                         BT_PANU_SERVICE_TYPE_NAP, node->user_data);
646
647         g_free(device_address);
648 }
649
650 static void device_hid_connected_changed(bluez_device_t *device,
651                                         int connected, void *user_data)
652 {
653         struct hid_host_connection_state_changed_cb_node *node = user_data;
654         char *device_address;
655
656         DBG("");
657
658         device_address = bluez_device_get_property_address(device);
659
660         node->cb(BT_SUCCESS, connected, device_address, node->user_data);
661
662         g_free(device_address);
663 }
664
665 static unsigned int dev_property_callback_flags;
666
667 enum bluez_device_property_callback_flag {
668         DEV_PROP_FLAG_PAIR = 0x01,
669         DEV_PROP_FLAG_CONNECT = 0x02,
670         DEV_PROP_FLAG_AUTH = 0x04,
671         DEV_PROP_FLAG_PANU_CONNECT = 0x08,
672         DEV_PROP_FLAG_HDP_CONNECT = 0x10,
673         DEV_PROP_FLAG_HDP_DATA = 0x20,
674         DEV_PROP_FLAG_HID_CONNECT = 0x40
675 };
676
677 static void set_device_property_changed_callback(bluez_device_t *device)
678 {
679         DBG("");
680
681         if (dev_property_callback_flags & DEV_PROP_FLAG_PAIR)
682                 bluez_device_set_paired_changed_cb(device,
683                                         device_paired_changed,
684                                         device_bond_node);
685
686         if (dev_property_callback_flags & DEV_PROP_FLAG_CONNECT)
687                 bluez_device_set_connected_changed_cb(device,
688                                         device_connected_changed,
689                                         device_connected_state_node);
690
691         if (dev_property_callback_flags & DEV_PROP_FLAG_AUTH)
692                 bluez_device_set_trusted_changed_cb(device,
693                                         device_auth_changed,
694                                         device_auth_node);
695
696         if (dev_property_callback_flags & DEV_PROP_FLAG_PANU_CONNECT)
697                 bluez_device_network_set_connected_changed_cb(device,
698                                         device_panu_connected_changed,
699                                         panu_state_node);
700
701         if (dev_property_callback_flags & DEV_PROP_FLAG_HDP_CONNECT)
702                 bluez_set_hdp_state_changed_cb(device,
703                                         bluez_hdp_state_changed,
704                                         hdp_state_node);
705
706         if (dev_property_callback_flags & DEV_PROP_FLAG_HDP_DATA)
707                 bluez_set_data_received_changed_cb(device,
708                                         bluez_set_data_received_changed,
709                                         hdp_set_data_received_node);
710
711         if (dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT)
712                 bluez_device_input_set_connected_changed_cb(device,
713                                         device_hid_connected_changed,
714                                         hid_host_state_node);
715
716 }
717
718 static void unset_device_property_changed_callback(bluez_device_t *device)
719 {
720         DBG("");
721
722         if (!(dev_property_callback_flags & DEV_PROP_FLAG_PAIR))
723                 bluez_device_unset_paired_changed_cb(device);
724
725         if (!(dev_property_callback_flags & DEV_PROP_FLAG_CONNECT))
726                 bluez_device_unset_connected_changed_cb(device);
727
728         if (!(dev_property_callback_flags & DEV_PROP_FLAG_AUTH))
729                 bluez_device_unset_trusted_changed_cb(device);
730
731         if (!(dev_property_callback_flags & DEV_PROP_FLAG_PANU_CONNECT))
732                 bluez_device_network_unset_connected_changed_cb(device);
733
734         if (!(dev_property_callback_flags & DEV_PROP_FLAG_HDP_CONNECT))
735                 bluez_unset_hdp_state_changed_cb(device);
736
737         if (!(dev_property_callback_flags & DEV_PROP_FLAG_HDP_DATA))
738                 bluez_unset_data_received_changed_cb(device);
739
740         if (!(dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT))
741                 bluez_device_input_unset_connected_changed_cb(device);
742 }
743
744 static void foreach_device_property_callback(GList *list, unsigned int flag)
745 {
746         bluez_device_t *device;
747         GList *iter, *next;
748
749         DBG("");
750
751         for (iter = g_list_first(list); iter; iter = next) {
752                 next = g_list_next(iter);
753
754                 device = iter->data;
755
756                 if (dev_property_callback_flags & flag)
757                         set_device_property_changed_callback(device);
758                 else
759                         unset_device_property_changed_callback(device);
760         }
761 }
762
763 static void bluez_device_created(bluez_device_t *device, void *user_data)
764 {
765         bt_adapter_device_discovery_info_s *discovery_device_info;
766         struct device_created_cb_node *node = user_data;
767
768         DBG("");
769         discovery_device_info = get_discovery_device_info(device);
770
771         DBG("name: %s, uuid: %p, uuid_count: %d", discovery_device_info->remote_name,
772                                                 discovery_device_info->service_uuid,
773                                                 discovery_device_info->service_count);
774
775         if (node && node->cb)
776                 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_FOUND,
777                                 discovery_device_info, node->user_data);
778
779         set_device_property_changed_callback(device);
780
781         free_discovery_device_info(discovery_device_info);
782 }
783
784 static void bluez_adapter_discovering_changed(bluez_adapter_t *adapter,
785                                                 int discovering,
786                                                 void *user_data)
787 {
788         bt_adapter_device_discovery_state_e state;
789         struct adapter_discovering_cb_node *node = user_data;
790         bt_adapter_device_discovery_info_s *discovery_device_info;
791         GList *device_list, *list, *next;
792         bluez_device_t *device;
793
794         DBG("");
795
796         state = discovering ? BT_ADAPTER_DEVICE_DISCOVERY_STARTED :
797                                 BT_ADAPTER_DEVICE_DISCOVERY_FINISHED;
798
799         if (!node || !node->cb)
800                 return;
801
802         node->cb(BT_SUCCESS, state, NULL, node->user_data);
803
804         /*
805          * BlueZ 5.x may contain some discovering device a short time.
806          * When UI start discovery, the last discovering device may
807          * not dispear, also notify tham.
808          */
809         if (state != BT_ADAPTER_DEVICE_DISCOVERY_STARTED)
810                 return;
811
812         device_list = bluez_adapter_get_devices(default_adapter);
813         for (list = g_list_first(device_list); list; list = next) {
814                 next = g_list_next(list);
815
816                 device = list->data;
817
818                 discovery_device_info = get_discovery_device_info(device);
819
820                 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_FOUND,
821                                 discovery_device_info, node->user_data);
822
823                 set_device_property_changed_callback(device);
824
825                 free_discovery_device_info(discovery_device_info);
826         }
827 }
828
829 void adapter_name_changed(bluez_adapter_t *adapter,
830                                 const gchar *name,
831                                 void *user_data)
832 {
833         struct adapter_name_cb_node *data =
834                         (struct adapter_name_cb_node *)user_data;
835         gchar *adapter_name = g_strdup(name);
836
837         data->cb(adapter_name, data->user_data);
838
839         g_free(adapter_name);
840 }
841
842 static void discoverable_timeout_changed(bluez_adapter_t *adapter,
843                                         guint32 timeout, void *user_data)
844 {
845         struct adapter_visibility_duration_cb_node *node = user_data;
846
847         node->cb(timeout, node->user_data);
848 }
849
850 static void adapter_discoverable_changed(bluez_adapter_t *adapter,
851                                 gboolean discoverable, void *user_data)
852 {
853         struct adapter_visibility_mode_cb_node *node = user_data;
854         bt_adapter_visibility_mode_e discoverable_mode;
855         unsigned int discoverable_timeout;
856
857         if (!discoverable){
858                 discoverable_mode =
859                         BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
860                 goto done;
861         }
862
863         discoverable_timeout = comms_manager_get_bt_adapter_visibale_time();
864         if (discoverable_timeout == -1) {
865                 node->cb(BT_ERROR_OPERATION_FAILED, 0, node->user_data);
866                 return;
867         }
868
869         discoverable_mode = (discoverable_timeout == 0) ?
870                         BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE :
871                         BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
872
873 done:
874         node->cb(BT_SUCCESS, discoverable_mode, node->user_data);
875 }
876
877 static void bluez_device_connect_changed(bluez_device_t *device,
878                                         enum device_state state,
879                                         gpointer user_data)
880 {
881         struct device_connect_cb_node *data = user_data;
882
883         switch (state) {
884         case DEVICE_CONNECT_SUCCESS:
885                 DBG("Connect device: %s", "DEVICE_CONNECT_SUCCESS");
886                 break;
887         case DEVICE_NOT_READY:
888                 DBG("Connect device: %s", "DEVICE_NOT_READY");
889                 break;
890         case DEVICE_ALREADY_CONNECTED:
891                 DBG("Connect device: %s", "DEVICE_ALREADY_CONNECTED");
892                 break;
893         case DEVICE_CONNECT_FAILED:
894                 DBG("Connect device: %s", "DEVICE_CONNECT_FAILED");
895                 break;
896         case DEVICE_CONNECT_INPROGRESS:
897                 DBG("Connect device: %s", "DEVICE_CONNECT_INPROGRESS");
898                 break;
899         default:
900                 ERROR("Unknown error code");
901                 break;
902         }
903
904         if (data->cb)
905                 data->cb(state, data->user_data);
906
907 }
908
909 static void bluez_device_disconnect_changed(bluez_device_t *device,
910                                         enum device_state state,
911                                         gpointer user_data)
912 {
913         struct device_disconnect_cb_node *data = user_data;
914
915         switch (state) {
916         case DEVICE_DISCONNECT_SUCCESS:
917                 DBG("Disconnect device: %s", "DEVICE_DISCONNECT_SUCCESS");
918                 break;
919         case DEVICE_NOT_CONNECTED:
920                 DBG("Disconnect device: %s", "DEVICE_NOT_CONNECTED");
921                 break;
922         default:
923                 ERROR("Unknown error code");
924                 break;
925         }
926
927         if (data->cb)
928                 data->cb(state, data->user_data);
929 }
930
931 static void _bt_update_bluetooth_callbacks(void)
932 {
933         DBG("default_adpater: %p", default_adapter);
934
935         if (default_adapter == NULL)
936                 return;
937
938         if (adapter_state_node)
939                 bluez_adapter_set_powered_changed_cb(default_adapter,
940                                         adapter_powered_changed,
941                                         adapter_state_node);
942
943         if (adapter_name_node)
944                 bluez_adapter_set_alias_changed_cb(default_adapter,
945                                         adapter_name_changed,
946                                         adapter_name_node);
947
948         if (device_created_node)
949                 bluez_adapter_set_device_created_cb(default_adapter,
950                                         bluez_device_created,
951                                         device_created_node);
952
953         if (adapter_discovering_node)
954                 bluez_adapter_set_device_discovering_cb(default_adapter,
955                                         bluez_adapter_discovering_changed,
956                                         adapter_discovering_node);
957
958         if (adapter_visibility_duration_node)
959                 bluez_adapter_set_discoverable_timeout_changed_cb(
960                                         default_adapter,
961                                         discoverable_timeout_changed,
962                                         adapter_visibility_duration_node);
963
964         if (adapter_visibility_mode_node)
965                 bluez_adapter_set_discoverable_changed_cb(default_adapter,
966                                         adapter_discoverable_changed,
967                                         adapter_visibility_mode_node);
968
969         if (generic_device_removed_set == FALSE)
970                 set_device_removed_generic_callback(default_adapter);
971
972         if (audio_state_node)
973                 bluez_set_audio_state_cb(
974                                         bluez_audio_state_changed,
975                                         audio_state_node);
976
977         if (avrcp_target_state_node)
978                 bluez_set_avrcp_target_cb(
979                                         bluez_avrcp_target_state_changed,
980                                         avrcp_target_state_node);
981
982         if (device_connect_node)
983                 bluez_set_device_connect_changed_cb(
984                                         bluez_device_connect_changed,
985                                         device_connect_node);
986
987         if (device_disconnect_node)
988                 bluez_set_device_disconnect_changed_cb(
989                                         bluez_device_disconnect_changed,
990                                         device_disconnect_node);
991
992         if (nap_connection_state_changed_node)
993                 bluez_set_nap_connection_state_cb(
994                                 bluez_nap_connection_changed,
995                                 nap_connection_state_changed_node);
996 }
997
998 static void setup_bluez_lib(void)
999 {
1000         gboolean powered;
1001         int err;
1002
1003         DBG("");
1004
1005         err = bluez_lib_init();
1006         if (err) {
1007                 ERROR("Bluz-lib init error");
1008                 return;
1009         }
1010
1011         default_adapter = bluez_adapter_get_adapter(DEFAULT_ADAPTER_NAME);
1012         if (default_adapter == NULL) {
1013                 ERROR("Can't find adapter %s", DEFAULT_ADAPTER_NAME);
1014                 bluez_lib_deinit();
1015                 return;
1016         }
1017
1018         _bt_update_bluetooth_callbacks();
1019
1020         initialized = true;
1021
1022         DBG("Set bluetooth powered state");
1023         if (adapter_state_node == NULL)
1024                 return;
1025
1026         bluez_adapter_get_property_powered(default_adapter, &powered);
1027         if (powered)
1028                 adapter_powered_changed(default_adapter, powered,
1029                                                 adapter_state_node);
1030
1031         DBG("");
1032 }
1033 static void destroy_bluez_lib(void)
1034 {
1035         bluez_lib_deinit();
1036
1037         default_adapter = NULL;
1038
1039         initialized = false;
1040 }
1041
1042 void _bt_service_bt_in_service_watch(uint in_service, void *user_data)
1043 {
1044         DBG("%d", in_service);
1045 }
1046
1047 int bt_initialize(void)
1048 {
1049         if (bt_service_init)
1050                 return BT_SUCCESS;
1051
1052         comms_lib_init();
1053
1054         comms_manager_set_bt_in_service_watch(
1055                                 _bt_service_bt_in_service_watch, NULL);
1056
1057         bt_service_init = TRUE;
1058
1059         setup_bluez_lib();
1060
1061         return BT_SUCCESS;
1062 }
1063
1064 int bt_deinitialize(void)
1065 {
1066         if (bt_service_init == false)
1067                 return BT_SUCCESS;
1068
1069         destroy_bluez_lib();
1070
1071         comms_manager_remove_bt_in_service_watch();
1072
1073         bt_service_init = FALSE;
1074
1075         return BT_SUCCESS;
1076 }
1077
1078 int bt_adapter_enable(void)
1079 {
1080         DBG("");
1081
1082         if (bt_service_init == false)
1083                 return BT_ERROR_NOT_INITIALIZED;
1084
1085         comms_manager_enable_bluetooth();
1086
1087         return BT_SUCCESS;
1088 }
1089
1090 int bt_adapter_disable(void)
1091 {
1092         DBG("");
1093
1094         if (bt_service_init == false)
1095                 return BT_ERROR_NOT_INITIALIZED;
1096
1097         comms_manager_disable_bluetooth();
1098
1099         return BT_SUCCESS;
1100 }
1101
1102 int bt_adapter_get_state(bt_adapter_state_e *adapter_state)
1103 {
1104         int powered;
1105
1106         DBG("");
1107
1108         if (initialized == false)
1109                 return BT_ERROR_NOT_INITIALIZED;
1110
1111         if (default_adapter == NULL)
1112                 return BT_ERROR_ADAPTER_NOT_FOUND;
1113
1114         if (adapter_state == NULL)
1115                 return BT_ERROR_INVALID_PARAMETER;
1116
1117         bluez_adapter_get_property_powered(default_adapter, &powered);
1118         if (powered == true)
1119                 *adapter_state = BT_ADAPTER_ENABLED;
1120         else
1121                 *adapter_state = BT_ADAPTER_DISABLED;
1122
1123         return BT_SUCCESS;
1124 }
1125
1126 int bt_adapter_get_address(char **local_address)
1127 {
1128         char *address;
1129
1130         DBG("");
1131
1132         if (initialized == false)
1133                 return BT_ERROR_NOT_INITIALIZED;
1134
1135         if (default_adapter == NULL)
1136                 return BT_ERROR_ADAPTER_NOT_FOUND;
1137
1138         if (local_address == NULL)
1139                 return BT_ERROR_INVALID_PARAMETER;
1140
1141         address = bluez_adapter_get_property_address(default_adapter);
1142         if (address == NULL)
1143                 return BT_ERROR_OPERATION_FAILED;
1144
1145         *local_address = address;
1146
1147         return BT_SUCCESS;
1148 }
1149
1150 int bt_adapter_get_name(char **local_name)
1151 {
1152         char *name;
1153
1154         DBG("");
1155
1156         if (initialized == false)
1157                 return BT_ERROR_NOT_INITIALIZED;
1158
1159         if (default_adapter == NULL)
1160                 return BT_ERROR_ADAPTER_NOT_FOUND;
1161
1162         if (local_name == NULL)
1163                 return BT_ERROR_INVALID_PARAMETER;
1164
1165         name = bluez_adapter_get_property_alias(default_adapter);
1166         if (name == NULL)
1167                 return BT_ERROR_OPERATION_FAILED;
1168
1169         *local_name = name;
1170
1171         return BT_SUCCESS;
1172 }
1173
1174 int bt_adapter_set_name(const char *local_name)
1175 {
1176         DBG("");
1177
1178         if (initialized == false)
1179                 return BT_ERROR_NOT_INITIALIZED;
1180
1181         if (default_adapter == NULL)
1182                 return BT_ERROR_ADAPTER_NOT_FOUND;
1183
1184         if (local_name == NULL)
1185                 return BT_ERROR_INVALID_PARAMETER;
1186
1187         bluez_adapter_set_alias(default_adapter, local_name);
1188
1189         return BT_SUCCESS;
1190 }
1191
1192 int bt_adapter_set_name_changed_cb(bt_adapter_name_changed_cb callback,
1193                                         void *user_data)
1194 {
1195         struct adapter_name_cb_node *node_data;
1196
1197         if (callback == NULL)
1198                 return BT_ERROR_INVALID_PARAMETER;
1199
1200         if (adapter_name_node) {
1201                 DBG("Powered state changed callback already set.");
1202                 return BT_ERROR_ALREADY_DONE;
1203         }
1204
1205         node_data = g_new0(struct adapter_name_cb_node, 1);
1206         if (node_data == NULL) {
1207                 ERROR("no memory");
1208                 return BT_ERROR_OUT_OF_MEMORY;
1209         }
1210
1211         node_data->cb = callback;
1212         node_data->user_data = user_data;
1213
1214         adapter_name_node = node_data;
1215
1216         _bt_update_bluetooth_callbacks();
1217
1218         return BT_SUCCESS;
1219 }
1220
1221 int bt_adapter_unset_name_changed_cb(void)
1222 {
1223         DBG("");
1224
1225         if (initialized == false)
1226                 return BT_ERROR_NOT_INITIALIZED;
1227
1228         if (default_adapter == NULL)
1229                 return BT_ERROR_ADAPTER_NOT_FOUND;
1230
1231         if (!adapter_name_node)
1232                 return BT_SUCCESS;
1233
1234         bluez_adapter_unset_alias_changed_cb(default_adapter);
1235
1236         g_free(adapter_name_node);
1237         adapter_name_node = NULL;
1238
1239         return BT_SUCCESS;
1240 }
1241
1242 int bt_adapter_get_visibility(bt_adapter_visibility_mode_e *mode,
1243                                 int *duration)
1244 {
1245         int discoverable;
1246         unsigned int timeout;
1247         int err;
1248
1249         DBG("");
1250
1251         if (initialized == false)
1252                 return BT_ERROR_NOT_INITIALIZED;
1253
1254         if (default_adapter == NULL)
1255                 return BT_ERROR_ADAPTER_NOT_FOUND;
1256
1257         if (mode == NULL)
1258                 return BT_ERROR_INVALID_PARAMETER;
1259
1260         err = bluez_adapter_get_property_discoverable(default_adapter,
1261                                                         &discoverable);
1262         if (err)
1263                 return BT_ERROR_OPERATION_FAILED;
1264
1265         timeout = comms_manager_get_bt_adapter_visibale_time();
1266         if (timeout == -1)
1267                 return BT_ERROR_OPERATION_FAILED;
1268
1269         if (duration)
1270                 *duration = 0;
1271
1272         if (!discoverable){
1273                 *mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
1274                 return BT_SUCCESS;
1275         }
1276
1277         *mode = (timeout == 0) ?
1278                         BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE :
1279                         BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
1280
1281         if (*mode == BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE)
1282                 *duration = timeout;
1283
1284         return BT_SUCCESS;
1285 }
1286
1287 int bt_adapter_set_visibility(bt_adapter_visibility_mode_e discoverable_mode,
1288                                 int duration)
1289 {
1290         int discoverable;
1291
1292         DBG("");
1293
1294         if (initialized == false)
1295                 return BT_ERROR_NOT_INITIALIZED;
1296
1297         if (default_adapter == NULL)
1298                 return BT_ERROR_ADAPTER_NOT_FOUND;
1299
1300         switch (discoverable_mode) {
1301         case BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE:
1302                 discoverable = false;
1303                 duration = 0;
1304                 break;
1305         case BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE:
1306                 discoverable = true;
1307                 break;
1308         case BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE:
1309                 discoverable = true;
1310                 duration = 0;
1311                 break;
1312         default:
1313                 return BT_ERROR_INVALID_PARAMETER;
1314         }
1315
1316         bluez_adapter_set_discoverable(default_adapter, discoverable);
1317
1318         bluez_adapter_set_discoverable_timeout(default_adapter, duration);
1319
1320         return BT_SUCCESS;
1321 }
1322
1323 static gboolean bt_stop_discovery_timeout_cb(gpointer user_data)
1324 {
1325         event_id = 0;
1326
1327         bt_adapter_stop_device_discovery();
1328
1329         return FALSE;
1330 }
1331
1332 static void bt_stop_discovery_timeout(void)
1333 {
1334         if (event_id > 0)
1335                 return;
1336
1337         event_id = g_timeout_add(BT_STOP_DISCOVERY_TIMEOUT,
1338                 (GSourceFunc)bt_stop_discovery_timeout_cb, NULL);
1339 }
1340
1341 int bt_adapter_start_device_discovery(void)
1342 {
1343         DBG("");
1344
1345         if (initialized == false)
1346                 return BT_ERROR_NOT_INITIALIZED;
1347
1348         if (default_adapter == NULL)
1349                 return BT_ERROR_ADAPTER_NOT_FOUND;
1350
1351         bluez_adapter_start_discovery(default_adapter);
1352
1353         bt_stop_discovery_timeout();
1354
1355         return BT_SUCCESS;
1356 }
1357
1358 int bt_adapter_stop_device_discovery(void)
1359 {
1360         DBG("");
1361
1362         if (initialized == false)
1363                 return BT_ERROR_NOT_INITIALIZED;
1364
1365         if (default_adapter == NULL)
1366                 return BT_ERROR_ADAPTER_NOT_FOUND;
1367
1368         bluez_adapter_stop_discovery(default_adapter);
1369
1370         return BT_SUCCESS;
1371 }
1372
1373 int bt_adapter_is_discovering(bool *is_discovering)
1374 {
1375         int discovering;
1376
1377         DBG("");
1378
1379         if (initialized == false)
1380                 return BT_ERROR_NOT_INITIALIZED;
1381
1382         if (default_adapter == NULL)
1383                 return BT_ERROR_ADAPTER_NOT_FOUND;
1384
1385         if (is_discovering == NULL)
1386                 return BT_ERROR_INVALID_PARAMETER;
1387
1388         bluez_adapter_get_property_discovering(default_adapter, &discovering);
1389
1390         *is_discovering = discovering;
1391
1392         return BT_SUCCESS;
1393 }
1394
1395 int bt_adapter_is_service_used(const char *service_uuid, bool *used)
1396 {
1397         guint length, index;
1398         char **uuids;
1399
1400         DBG("");
1401
1402         if (initialized == false)
1403                 return BT_ERROR_NOT_INITIALIZED;
1404
1405         if (default_adapter == NULL)
1406                 return BT_ERROR_ADAPTER_NOT_FOUND;
1407
1408         if (used == NULL)
1409                 return BT_ERROR_INVALID_PARAMETER;
1410
1411         uuids = bluez_adapter_get_property_uuids(default_adapter);
1412         length = g_strv_length(uuids);
1413
1414         *used = false;
1415         for (index = 0; index < length; ++index) {
1416                 if (strcasecmp(uuids[index], service_uuid) == 0) {
1417                         *used = true;
1418                         break;
1419                 }
1420         }
1421
1422         g_strfreev(uuids);
1423
1424         return BT_SUCCESS;
1425 }
1426
1427 int bt_adapter_set_device_discovery_state_changed_cb(
1428                         bt_adapter_device_discovery_state_changed_cb callback,
1429                         void *user_data)
1430 {
1431         struct device_created_cb_node *created_node;
1432         struct adapter_discovering_cb_node *discovering_node;
1433         struct device_destroy_unpaired_cb_node *removed_node;
1434
1435         DBG("");
1436
1437         if (callback == NULL)
1438                 return BT_ERROR_INVALID_PARAMETER;
1439
1440         if (device_created_node) {
1441                 DBG("Discovery state changed callback already set.");
1442                 return BT_ERROR_ALREADY_DONE;
1443         }
1444
1445         created_node = g_new0(struct device_created_cb_node, 1);
1446         if (created_node == NULL) {
1447                 ERROR("no memory.");
1448                 return BT_ERROR_OUT_OF_MEMORY;
1449         }
1450
1451         created_node->cb = callback;
1452         created_node->user_data = user_data;
1453
1454         device_created_node = created_node;
1455
1456         if (adapter_discovering_node) {
1457                 DBG("Device discovering changed callback already set.");
1458                 return BT_ERROR_ALREADY_DONE;
1459         }
1460
1461         discovering_node = g_new0(struct adapter_discovering_cb_node, 1);
1462         if (discovering_node == NULL) {
1463                 ERROR("no memory.");
1464                 return BT_ERROR_OUT_OF_MEMORY;
1465         }
1466
1467         discovering_node->cb = callback;
1468         discovering_node->user_data = user_data;
1469
1470         adapter_discovering_node = discovering_node;
1471
1472         if (unpaired_device_removed_node) {
1473                 DBG("Device removed changed callback already set");
1474                 return BT_ERROR_ALREADY_DONE;
1475         }
1476
1477         removed_node = g_new0(struct device_destroy_unpaired_cb_node, 1);
1478         if (removed_node == NULL) {
1479                 ERROR("no memory");
1480                 return BT_ERROR_OUT_OF_MEMORY;
1481         }
1482
1483         removed_node->cb = callback;
1484         removed_node->user_data = user_data;
1485
1486         unpaired_device_removed_node = removed_node;
1487
1488         _bt_update_bluetooth_callbacks();
1489
1490         return BT_SUCCESS;
1491 }
1492
1493 int bt_adapter_set_state_changed_cb(bt_adapter_state_changed_cb callback,
1494                                         void *user_data)
1495 {
1496         struct adapter_state_cb_node *node_data;
1497
1498         DBG("");
1499
1500         if (callback == NULL)
1501                 return BT_ERROR_INVALID_PARAMETER;
1502
1503         if (adapter_state_node) {
1504                 DBG("Powered state changed callback already set.");
1505                 return BT_ERROR_ALREADY_DONE;
1506         }
1507
1508         node_data = g_new0(struct adapter_state_cb_node, 1);
1509         if (node_data == NULL) {
1510                 ERROR("no memory");
1511                 return BT_ERROR_OUT_OF_MEMORY;
1512         }
1513
1514         node_data->cb = callback;
1515         node_data->user_data = user_data;
1516
1517         adapter_state_node = node_data;
1518
1519         _bt_update_bluetooth_callbacks();
1520
1521         return BT_SUCCESS;
1522 }
1523
1524 int bt_adapter_set_visibility_duration_changed_cb(
1525                         bt_adapter_visibility_duration_changed_cb callback,
1526                         void *user_data)
1527 {
1528         struct adapter_visibility_duration_cb_node *node_data;
1529
1530         DBG("");
1531
1532         if (callback == NULL)
1533                 return BT_ERROR_INVALID_PARAMETER;
1534
1535         if (adapter_visibility_duration_node) {
1536                 DBG("duration changed callback already set.");
1537                 return BT_ERROR_ALREADY_DONE;
1538         }
1539
1540         node_data = g_new0(struct adapter_visibility_duration_cb_node, 1);
1541         if (node_data == NULL) {
1542                 ERROR("no memory");
1543                 return BT_ERROR_OUT_OF_MEMORY;
1544         }
1545
1546         node_data->cb = callback;
1547         node_data->user_data = user_data;
1548
1549         adapter_visibility_duration_node = node_data;
1550
1551         _bt_update_bluetooth_callbacks();
1552         return BT_SUCCESS;
1553 }
1554
1555 int bt_adapter_set_visibility_mode_changed_cb(
1556                         bt_adapter_visibility_mode_changed_cb callback,
1557                         void *user_data)
1558 {
1559         struct adapter_visibility_mode_cb_node *node_data;
1560
1561         DBG("");
1562
1563         if (callback == NULL)
1564                 return BT_ERROR_INVALID_PARAMETER;
1565
1566         if (adapter_visibility_mode_node) {
1567                 DBG("visibility mode changed callback already set.");
1568                 return BT_ERROR_ALREADY_DONE;
1569         }
1570
1571         node_data = g_new0(struct adapter_visibility_mode_cb_node, 1);
1572         if (node_data == NULL) {
1573                 ERROR("no memory");
1574                 return BT_ERROR_OUT_OF_MEMORY;
1575         }
1576
1577         node_data->cb = callback;
1578         node_data->user_data = user_data;
1579
1580         adapter_visibility_mode_node = node_data;
1581
1582         _bt_update_bluetooth_callbacks();
1583
1584         return BT_SUCCESS;
1585 }
1586
1587 int bt_adapter_unset_state_changed_cb(void)
1588 {
1589         DBG("");
1590
1591         if (initialized == false)
1592                 return BT_ERROR_NOT_INITIALIZED;
1593
1594         if (default_adapter == NULL)
1595                 return BT_ERROR_ADAPTER_NOT_FOUND;
1596
1597         if (!adapter_state_node)
1598                 return BT_SUCCESS;
1599
1600         bluez_adapter_unset_powered_changed_cb(default_adapter);
1601
1602         g_free(adapter_state_node);
1603         adapter_state_node = NULL;
1604
1605         return BT_SUCCESS;
1606 }
1607
1608 int bt_adapter_unset_device_discovery_state_changed_cb(void)
1609 {
1610         DBG("");
1611
1612         if (initialized == false)
1613                 return BT_ERROR_NOT_INITIALIZED;
1614
1615         if (default_adapter == NULL)
1616                 return BT_ERROR_ADAPTER_NOT_FOUND;
1617
1618         if (device_created_node) {
1619                 bluez_adapter_unset_device_created_cb(default_adapter);
1620
1621                 g_free(device_created_node);
1622                 device_created_node = NULL;
1623         }
1624
1625         if (adapter_discovering_node) {
1626                 bluez_adapter_unset_device_discovering_cb(default_adapter);
1627
1628                 g_free(adapter_discovering_node);
1629                 adapter_discovering_node = NULL;
1630         }
1631
1632         if (unpaired_device_removed_node) {
1633                 g_free(unpaired_device_removed_node);
1634                 unpaired_device_removed_node = NULL;
1635         }
1636
1637         if (paired_device_removed_node == NULL &&
1638                         generic_device_removed_set == TRUE) {
1639                 bluez_adapter_unset_device_removed_cb(default_adapter);
1640
1641                 generic_device_removed_set = FALSE;
1642         }
1643
1644         return BT_SUCCESS;
1645 }
1646
1647 int bt_adapter_unset_visibility_duration_changed_cb(void)
1648 {
1649         DBG("");
1650
1651         if (initialized == false)
1652                 return BT_ERROR_NOT_INITIALIZED;
1653
1654         if (default_adapter == NULL)
1655                 return BT_ERROR_ADAPTER_NOT_FOUND;
1656
1657         if (!adapter_visibility_duration_node)
1658                 return BT_SUCCESS;
1659
1660         bluez_adapter_unset_discoverable_timeout_changed_cb(default_adapter);
1661
1662         g_free(adapter_visibility_duration_node);
1663         adapter_visibility_duration_node = NULL;
1664
1665         return BT_SUCCESS;
1666 }
1667
1668 int bt_adapter_unset_visibility_mode_changed_cb(void)
1669 {
1670         DBG("");
1671
1672         if (initialized == false)
1673                 return BT_ERROR_NOT_INITIALIZED;
1674
1675         if (default_adapter == NULL)
1676                 return BT_ERROR_ADAPTER_NOT_FOUND;
1677
1678         if (!adapter_visibility_mode_node)
1679                 return BT_SUCCESS;
1680
1681         bluez_adapter_unset_discoverable_changed_cb(default_adapter);
1682
1683         g_free(adapter_visibility_mode_node);
1684         adapter_visibility_mode_node = NULL;
1685
1686         return BT_SUCCESS;
1687 }
1688
1689 int bt_adapter_reset(void)
1690 {
1691         DBG("Not implement");
1692
1693         return BT_SUCCESS;
1694 }
1695
1696 int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb callback,
1697                                         void *user_data)
1698 {
1699         int paired;
1700         bluez_device_t *device;
1701         bt_device_info_s *device_bond_info;
1702         GList *list, *iter;
1703         GList *next = NULL;
1704
1705         DBG("");
1706
1707         if (initialized == false)
1708                 return BT_ERROR_NOT_INITIALIZED;
1709
1710         if (default_adapter == NULL)
1711                 return BT_ERROR_ADAPTER_NOT_FOUND;
1712
1713         if (callback == NULL)
1714                 return BT_ERROR_INVALID_PARAMETER;
1715
1716         list = bluez_adapter_get_devices(default_adapter);
1717         for (iter = g_list_first(list); iter; iter = next) {
1718                 device = iter->data;
1719
1720                 next = g_list_next(iter);
1721
1722                 if (device == NULL)
1723                         continue;
1724
1725                 bluez_device_get_property_paired(device, &paired);
1726                 if (paired == false)
1727                         continue;
1728
1729                 device_bond_info = get_device_info(device);
1730                 DBG("device name: %s", device_bond_info->remote_name);
1731
1732                 callback(device_bond_info, user_data);
1733
1734                 free_device_info(device_bond_info);
1735         }
1736
1737         g_list_free(list);
1738
1739         return BT_SUCCESS;
1740 }
1741
1742 int bt_adapter_get_bonded_device_info(const char *remote_address,
1743                                         bt_device_info_s **device_info)
1744 {
1745         bluez_device_t *device;
1746         int paired;
1747
1748         DBG("");
1749
1750         if (initialized == false)
1751                 return BT_ERROR_NOT_INITIALIZED;
1752
1753         if (default_adapter == NULL)
1754                 return BT_ERROR_ADAPTER_NOT_FOUND;
1755
1756         if (!remote_address || !device_info)
1757                 return BT_ERROR_INVALID_PARAMETER;
1758
1759         device = bluez_adapter_get_device_by_address(default_adapter,
1760                                                         remote_address);
1761         if (device == NULL)
1762                 return BT_ERROR_OPERATION_FAILED;
1763
1764         bluez_device_get_property_paired(device, &paired);
1765         if (paired == false)
1766                 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
1767
1768         *device_info = get_device_info(device);
1769
1770         return BT_SUCCESS;
1771 }
1772
1773 int bt_adapter_free_device_info(bt_device_info_s *device_info)
1774 {
1775         if (!device_info)
1776                 return BT_ERROR_INVALID_PARAMETER;
1777
1778         free_device_info(device_info);
1779
1780         return BT_SUCCESS;
1781 }
1782
1783 /* Device Function */
1784
1785 static void bt_device_paired_cb(enum bluez_error_type error,
1786                                        void *user_data)
1787 {
1788         bt_error_e capi_error = BT_SUCCESS;
1789         char *remote_address = user_data;
1790         bt_device_info_s *device_info;
1791         bluez_device_t *device;
1792
1793         device = bluez_adapter_get_device_by_address(default_adapter,
1794                                                        remote_address);
1795         if (!device) {
1796                 ERROR("no %s device", remote_address);
1797                 return;
1798         }
1799
1800         if (!device_bond_node)
1801                 return;
1802
1803         /* Pair a device success, will report through DISCOVERY EVENT */
1804         if (error == ERROR_NONE)
1805                 return;
1806
1807         switch (error) {
1808         case ERROR_INVALID_ARGUMENTS:
1809                 capi_error = BT_ERROR_INVALID_PARAMETER;
1810                 break;
1811         case ERROR_FAILED:
1812                 capi_error = BT_ERROR_OPERATION_FAILED;
1813                 break;
1814         case ERROR_AUTH_CANCELED:
1815         case ERROR_AUTH_FAILED:
1816                 capi_error = BT_ERROR_AUTH_FAILED;
1817                 break;
1818         case ERROR_AUTH_REJECT:
1819                 capi_error = BT_ERROR_AUTH_REJECTED;
1820                 break;
1821         case ERROR_AUTH_TIMEOUT:
1822                 capi_error = BT_ERROR_TIMED_OUT;
1823                 break;
1824         case ERROR_AUTH_ATTEMPT_FAILED:
1825                 capi_error = BT_ERROR_AUTH_FAILED;
1826                 break;
1827         default:
1828                 WARN("Unknown error type with device pair");
1829         }
1830
1831         device_info = get_device_info(device);
1832
1833         device_bond_node->cb(capi_error, device_info,
1834                                 device_bond_node->user_data);
1835
1836         free_device_info(device_info);
1837 }
1838
1839 int bt_device_create_bond(const char *remote_address)
1840 {
1841         comms_bluetooth_device_pair(remote_address,
1842                                 bt_device_paired_cb, strdup(remote_address));
1843
1844         return BT_SUCCESS;
1845 }
1846
1847 int bt_device_cancel_bonding(void)
1848 {
1849         enum bluez_error_type error_type;
1850         int powered;
1851
1852         DBG("");
1853
1854         if (initialized == false)
1855                 return BT_ERROR_NOT_INITIALIZED;
1856
1857         if (default_adapter == NULL)
1858                 return BT_ERROR_ADAPTER_NOT_FOUND;
1859
1860         bluez_adapter_get_property_powered(default_adapter, &powered);
1861         if (powered == FALSE)
1862                 return BT_ERROR_NOT_ENABLED;
1863
1864         error_type = comms_bluetooth_device_cancel_pairing_sync();
1865         if (error_type == ERROR_NONE)
1866                 return BT_SUCCESS;
1867         else if (error_type == ERROR_DOES_NOT_EXIST)
1868                 return BT_ERROR_NOT_IN_PROGRESS;
1869         else
1870                 return BT_ERROR_OPERATION_FAILED;
1871 }
1872
1873 int bt_device_destroy_bond(const char *remote_address)
1874 {
1875         bluez_device_t *device;
1876
1877         DBG("");
1878
1879         if (initialized == false)
1880                 return BT_ERROR_NOT_INITIALIZED;
1881
1882         if (default_adapter == NULL)
1883                 return BT_ERROR_ADAPTER_NOT_FOUND;
1884
1885         device = bluez_adapter_get_device_by_address(default_adapter,
1886                                                         remote_address);
1887         if (device == NULL)
1888                 return BT_ERROR_OPERATION_FAILED;
1889
1890         bluez_adapter_remove_device(default_adapter, device);
1891
1892         return BT_SUCCESS;
1893 }
1894
1895 int bt_device_set_alias(const char *remote_address, const char *alias)
1896 {
1897         bluez_device_t *device;
1898
1899         DBG("");
1900
1901         if (initialized == false)
1902                 return BT_ERROR_NOT_INITIALIZED;
1903
1904         if (default_adapter == NULL)
1905                 return BT_ERROR_ADAPTER_NOT_FOUND;
1906
1907         if (!remote_address || !alias)
1908                 return BT_ERROR_INVALID_PARAMETER;
1909
1910         device = bluez_adapter_get_device_by_address(default_adapter,
1911                                                         remote_address);
1912         if (device == NULL)
1913                 return BT_ERROR_OPERATION_FAILED;
1914
1915         bluez_device_set_alias(device, alias);
1916
1917         return BT_SUCCESS;
1918 }
1919
1920 int bt_device_set_authorization(const char *remote_address,
1921                                 bt_device_authorization_e authorization_state)
1922 {
1923         int trusted;
1924         bluez_device_t *device;
1925
1926         DBG("");
1927
1928         if (initialized == false)
1929                 return BT_ERROR_NOT_INITIALIZED;
1930
1931         if (default_adapter == NULL)
1932                 return BT_ERROR_ADAPTER_NOT_FOUND;
1933
1934         if (!remote_address)
1935                 return BT_ERROR_INVALID_PARAMETER;
1936
1937         device = bluez_adapter_get_device_by_address(default_adapter,
1938                                                         remote_address);
1939         if (device == NULL)
1940                 return BT_ERROR_OPERATION_FAILED;
1941
1942         trusted = (authorization_state == BT_DEVICE_AUTHORIZED) ?
1943                                                 false : true;
1944
1945         bluez_device_set_trusted(device, trusted);
1946
1947         return BT_SUCCESS;
1948 }
1949
1950 static bt_device_sdp_info_s *get_device_sdp_info(bluez_device_t *device)
1951 {
1952         bt_device_sdp_info_s *sdp_info;
1953         char *address;
1954         char **uuids;
1955         guint len;
1956
1957         sdp_info = g_new0(bt_device_sdp_info_s, 1);
1958         if (sdp_info == NULL) {
1959                 ERROR("no memeory");
1960                 return NULL;
1961         }
1962
1963         address = bluez_device_get_property_address(device);
1964         uuids = bluez_device_get_property_uuids(device);
1965
1966         len = g_strv_length(uuids);
1967
1968         sdp_info->remote_address = address;
1969         sdp_info->service_uuid = uuids;
1970         sdp_info->service_count = len;
1971
1972         return sdp_info;
1973 }
1974
1975 static void free_device_sdp_info(bt_device_sdp_info_s *sdp_info)
1976 {
1977         gsize i;
1978
1979         if (sdp_info == NULL)
1980                 return;
1981
1982         g_free(sdp_info->remote_address);
1983         for (i = 0; i < sdp_info->service_count; ++i)
1984                 g_free(sdp_info->service_uuid[i]);
1985
1986         g_free(sdp_info->service_uuid);
1987         g_free(sdp_info);
1988 }
1989
1990 int bt_device_start_service_search(const char *remote_address)
1991 {
1992         bluez_device_t *device = NULL;
1993         bt_device_sdp_info_s *sdp_info;
1994         int powered, paired;
1995         char *address;
1996         GList *list, *iter, *next;
1997
1998         if (initialized == false)
1999                 return BT_ERROR_NOT_INITIALIZED;
2000
2001         if (default_adapter == NULL)
2002                 return BT_ERROR_ADAPTER_NOT_FOUND;
2003
2004         if (!remote_address)
2005                 return BT_ERROR_INVALID_PARAMETER;
2006
2007         bluez_adapter_get_property_powered(default_adapter, &powered);
2008         if (powered == FALSE)
2009                 return BT_ERROR_NOT_ENABLED;
2010
2011         if (!device_service_search_node)
2012                 return BT_SUCCESS;
2013
2014         list = bluez_adapter_get_devices(default_adapter);
2015         for (iter = g_list_first(list); iter; iter = next) {
2016                 bluez_device_t *dev;
2017                 dev = iter->data;
2018
2019                 next = g_list_next(iter);
2020
2021                 if (dev == NULL)
2022                         continue;
2023
2024                 address = bluez_device_get_property_address(dev);
2025                 if (!g_strcmp0(remote_address, address)) {
2026                         device = dev;
2027                         g_free(address);
2028                         break;
2029                 }
2030
2031                 g_free(address);
2032         }
2033
2034         g_list_free(list);
2035
2036         if (device == NULL)
2037                 return BT_ERROR_SERVICE_SEARCH_FAILED;
2038
2039         bluez_device_get_property_paired(device, &paired);
2040         if (paired == FALSE)
2041                 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
2042
2043         sdp_info = get_device_sdp_info(device);
2044
2045         device_service_search_node->cb(BT_SUCCESS, sdp_info,
2046                                 device_service_search_node->user_data);
2047
2048         free_device_sdp_info(sdp_info);
2049
2050         return BT_SUCCESS;
2051 }
2052
2053 int bt_device_cancel_service_search(void)
2054 {
2055         /*
2056          * BlueZ 5.x don't support cancel device service search
2057          * So only return SUCCESS.
2058          */
2059
2060         return BT_SUCCESS;
2061 }
2062
2063 int bt_device_set_bond_created_cb(bt_device_bond_created_cb callback,
2064                                                         void *user_data)
2065 {
2066         struct device_bond_cb_node *node;
2067         GList *list;
2068
2069         DBG("");
2070
2071         if (callback == NULL)
2072                 return BT_ERROR_INVALID_PARAMETER;
2073
2074         if (device_bond_node) {
2075                 DBG("Device bond callback already set.");
2076                 return BT_SUCCESS;
2077         }
2078
2079         node = g_new0(struct device_bond_cb_node, 1);
2080         if (node == NULL) {
2081                 ERROR("no memeroy");
2082                 return BT_ERROR_OPERATION_FAILED;
2083         }
2084
2085         node->cb = callback;
2086         node->user_data = user_data;
2087
2088         device_bond_node = node;
2089
2090         dev_property_callback_flags |= DEV_PROP_FLAG_PAIR;
2091
2092         if (!default_adapter)
2093                 return BT_SUCCESS;
2094
2095         list = bluez_adapter_get_devices(default_adapter);
2096         foreach_device_property_callback(list, DEV_PROP_FLAG_PAIR);
2097
2098         return BT_SUCCESS;
2099 }
2100
2101 int bt_device_unset_bond_created_cb(void)
2102 {
2103         GList *list;
2104         DBG("");
2105
2106         if (initialized == false)
2107                 return BT_ERROR_NOT_INITIALIZED;
2108
2109         if (default_adapter == NULL)
2110                 return BT_ERROR_ADAPTER_NOT_FOUND;
2111
2112         if (!device_bond_node)
2113                 return BT_SUCCESS;
2114
2115         dev_property_callback_flags &= ~DEV_PROP_FLAG_PAIR;
2116
2117         list = bluez_adapter_get_devices(default_adapter);
2118         foreach_device_property_callback(list, DEV_PROP_FLAG_PAIR);
2119
2120         g_free(device_bond_node);
2121         device_bond_node = NULL;
2122
2123         return BT_SUCCESS;
2124 }
2125
2126 int bt_device_set_bond_destroyed_cb(bt_device_bond_destroyed_cb callback,
2127                                                         void *user_data)
2128 {
2129         struct device_destroy_paired_cb_node *node;
2130
2131         DBG("");
2132
2133         if (callback == NULL)
2134                 return BT_ERROR_INVALID_PARAMETER;
2135
2136         if (paired_device_removed_node) {
2137                 DBG("Device bonded-destroy callback already set");
2138                 return BT_ERROR_ALREADY_DONE;
2139         }
2140
2141         node = g_new0(struct device_destroy_paired_cb_node, 1);
2142         if (node == NULL) {
2143                 ERROR("no memeroy");
2144                 return BT_ERROR_OUT_OF_MEMORY;
2145         }
2146
2147         node->cb = callback;
2148         node->user_data = user_data;
2149
2150         paired_device_removed_node = node;
2151
2152         _bt_update_bluetooth_callbacks();
2153
2154         return BT_SUCCESS;
2155 }
2156
2157 int bt_device_unset_bond_destroyed_cb(void)
2158 {
2159         DBG("");
2160
2161         if (initialized == false)
2162                 return BT_ERROR_NOT_INITIALIZED;
2163
2164         if (default_adapter == NULL)
2165                 return BT_ERROR_ADAPTER_NOT_FOUND;
2166
2167         if (paired_device_removed_node) {
2168                 g_free(paired_device_removed_node);
2169                 paired_device_removed_node = NULL;
2170         }
2171
2172         if (unpaired_device_removed_node == NULL &&
2173                         generic_device_removed_set == TRUE) {
2174                 bluez_adapter_unset_device_removed_cb(default_adapter);
2175
2176                 generic_device_removed_set = FALSE;
2177         }
2178
2179         return BT_SUCCESS;
2180 }
2181
2182 int bt_device_set_authorization_changed_cb(
2183                         bt_device_authorization_changed_cb callback,
2184                                                 void *user_data)
2185 {
2186         struct device_auth_cb_node *node;
2187         GList *list;
2188
2189         DBG("");
2190
2191         if (callback == NULL)
2192                 return BT_ERROR_INVALID_PARAMETER;
2193
2194         if (device_auth_node) {
2195                 DBG("Device bond callback already set.");
2196                 return BT_SUCCESS;
2197         }
2198
2199         node = g_new0(struct device_auth_cb_node, 1);
2200         if (node == NULL) {
2201                 ERROR("no memeroy");
2202                 return BT_ERROR_OPERATION_FAILED;
2203         }
2204
2205         node->cb = callback;
2206         node->user_data = user_data;
2207
2208         device_auth_node = node;
2209
2210         dev_property_callback_flags |= DEV_PROP_FLAG_AUTH;
2211
2212         if (!default_adapter)
2213                 return BT_SUCCESS;
2214
2215         list = bluez_adapter_get_devices(default_adapter);
2216         foreach_device_property_callback(list, DEV_PROP_FLAG_AUTH);
2217
2218         return BT_SUCCESS;
2219 }
2220
2221 int bt_device_unset_authorization_changed_cb(void)
2222 {
2223         GList *list;
2224         DBG("");
2225
2226         if (initialized == false)
2227                 return BT_ERROR_NOT_INITIALIZED;
2228
2229         if (default_adapter == NULL)
2230                 return BT_ERROR_ADAPTER_NOT_FOUND;
2231
2232         if (!device_auth_node)
2233                 return BT_SUCCESS;
2234
2235         dev_property_callback_flags &= ~DEV_PROP_FLAG_AUTH;
2236
2237         list = bluez_adapter_get_devices(default_adapter);
2238         foreach_device_property_callback(list, DEV_PROP_FLAG_AUTH);
2239
2240         g_free(device_auth_node);
2241         device_auth_node = NULL;
2242
2243         return BT_SUCCESS;
2244 }
2245
2246 int bt_device_set_service_searched_cb(bt_device_service_searched_cb callback,
2247                                                         void *user_data)
2248 {
2249         struct device_service_search_cb_node *node;
2250
2251         DBG("");
2252
2253         if (callback == NULL)
2254                 return BT_ERROR_INVALID_PARAMETER;
2255
2256         if (device_service_search_node) {
2257                 DBG("Device service serach callback already set.");
2258                 return BT_SUCCESS;
2259         }
2260
2261         node = g_new0(struct device_service_search_cb_node, 1);
2262         if (node == NULL) {
2263                 ERROR("no memeroy");
2264                 return BT_ERROR_OUT_OF_MEMORY;
2265         }
2266
2267         node->cb = callback;
2268         node->user_data = user_data;
2269
2270         device_service_search_node = node;
2271
2272         return BT_SUCCESS;
2273 }
2274
2275 int bt_device_unset_service_searched_cb(void)
2276 {
2277         DBG("");
2278
2279         if (initialized == false)
2280                 return BT_ERROR_NOT_INITIALIZED;
2281
2282         if (!device_service_search_node)
2283                 return BT_SUCCESS;
2284
2285         g_free(device_service_search_node);
2286         device_service_search_node = NULL;
2287
2288         return BT_SUCCESS;
2289 }
2290
2291 int bt_device_set_connection_state_changed_cb(
2292                                 bt_device_connection_state_changed_cb callback,
2293                                 void *user_data)
2294 {
2295         struct device_connected_state_cb_node *node_data;
2296         GList *list;
2297
2298         DBG("");
2299
2300         if (callback == NULL)
2301                 return BT_ERROR_INVALID_PARAMETER;
2302
2303         if (device_connected_state_node) {
2304                 DBG("Device connected state changed callback already set.");
2305                 return BT_ERROR_ALREADY_DONE;
2306         }
2307
2308         node_data = g_new0(struct device_connected_state_cb_node, 1);
2309         if (node_data == NULL) {
2310                 ERROR("no memory");
2311                 return BT_ERROR_OUT_OF_MEMORY;
2312         }
2313
2314         node_data->cb = callback;
2315         node_data->user_data = user_data;
2316
2317         device_connected_state_node = node_data;
2318
2319         dev_property_callback_flags |= DEV_PROP_FLAG_CONNECT;
2320
2321         if (!default_adapter)
2322                 return BT_SUCCESS;
2323
2324         list = bluez_adapter_get_devices(default_adapter);
2325         foreach_device_property_callback(list, DEV_PROP_FLAG_CONNECT);
2326
2327         return BT_SUCCESS;
2328 }
2329
2330 int bt_device_unset_connection_state_changed_cb(void)
2331 {
2332         GList *list;
2333         DBG("");
2334
2335         if (initialized == false)
2336                 return BT_ERROR_NOT_INITIALIZED;
2337
2338         if (default_adapter == NULL)
2339                 return BT_ERROR_ADAPTER_NOT_FOUND;
2340
2341         if (!device_connected_state_node)
2342                 return BT_SUCCESS;
2343
2344         dev_property_callback_flags &= ~DEV_PROP_FLAG_CONNECT;
2345
2346         list = bluez_adapter_get_devices(default_adapter);
2347         foreach_device_property_callback(list, DEV_PROP_FLAG_CONNECT);
2348
2349         g_free(device_connected_state_node);
2350         device_connected_state_node = NULL;
2351
2352         return BT_SUCCESS;
2353 }
2354
2355 /* Audio Function */
2356
2357 int bt_audio_initialize(void)
2358 {
2359         DBG("Not implement");
2360
2361         return BT_SUCCESS;
2362 }
2363
2364 int bt_audio_deinitialize(void)
2365 {
2366         DBG("Not implement");
2367
2368         return BT_SUCCESS;
2369 }
2370
2371 int bt_audio_connect(const char *remote_address,
2372                                 bt_audio_profile_type_e type)
2373 {
2374         bluez_device_t *device;
2375         char *uuid = NULL;
2376
2377         DBG("");
2378
2379         if (initialized == false)
2380                 return BT_ERROR_NOT_INITIALIZED;
2381
2382         if (default_adapter == NULL)
2383                 return BT_ERROR_ADAPTER_NOT_FOUND;
2384
2385         switch (type) {
2386         case BT_AUDIO_PROFILE_TYPE_HSP_HFP:
2387                 uuid = BT_HFP_HS_UUID;
2388                 break;
2389         case BT_AUDIO_PROFILE_TYPE_A2DP:
2390                 uuid = BT_A2DP_SINK_UUID;
2391                 break;
2392         case BT_AUDIO_PROFILE_TYPE_ALL:
2393                 uuid = BT_GENERIC_AUDIO_UUID;
2394                 break;
2395         default:
2396                 DBG("Unknown role");
2397                 return BT_ERROR_INVALID_PARAMETER;
2398         }
2399
2400         device = bluez_adapter_get_device_by_address(default_adapter,
2401                                                         remote_address);
2402         if (device == NULL)
2403                 return BT_ERROR_OPERATION_FAILED;
2404
2405         bluez_device_connect_profile(device, uuid,
2406                                 profile_connect_callback);
2407
2408         return BT_SUCCESS;
2409 }
2410
2411 int bt_audio_disconnect(const char *remote_address,
2412                                 bt_audio_profile_type_e type)
2413 {
2414         bluez_device_t *device;
2415         char *uuid = NULL;
2416
2417         DBG("");
2418
2419         if (initialized == false)
2420                 return BT_ERROR_NOT_INITIALIZED;
2421
2422         if (default_adapter == NULL)
2423                 return BT_ERROR_ADAPTER_NOT_FOUND;
2424
2425         switch (type) {
2426         case BT_AUDIO_PROFILE_TYPE_HSP_HFP:
2427                 uuid = BT_HFP_HS_UUID;
2428                 break;
2429         case BT_AUDIO_PROFILE_TYPE_A2DP:
2430                 uuid = BT_A2DP_SINK_UUID;
2431                 break;
2432         case BT_AUDIO_PROFILE_TYPE_ALL:
2433                 uuid = BT_GENERIC_AUDIO_UUID;
2434                 break;
2435         default:
2436                 DBG("Unknown role");
2437                 return BT_ERROR_INVALID_PARAMETER;
2438         }
2439
2440         device = bluez_adapter_get_device_by_address(default_adapter,
2441                                                         remote_address);
2442         if (device == NULL)
2443                 return BT_ERROR_OPERATION_FAILED;
2444
2445         bluez_device_disconnect_profile(device, uuid,
2446                                 profile_disconnect_callback);
2447
2448         return BT_SUCCESS;
2449 }
2450
2451 int bt_audio_set_connection_state_changed_cb(
2452                         bt_audio_connection_state_changed_cb callback,
2453                         void *user_data)
2454 {
2455         struct audio_connection_state_changed_cb_node *node_data = NULL;
2456
2457         if (callback == NULL)
2458                 return BT_ERROR_INVALID_PARAMETER;
2459
2460         if (audio_state_node) {
2461                 DBG("audio state callback already set.");
2462                 return BT_ERROR_ALREADY_DONE;
2463         }
2464
2465         node_data = g_new0(struct audio_connection_state_changed_cb_node, 1);
2466         if (node_data == NULL) {
2467                 ERROR("no memory");
2468                 return BT_ERROR_OUT_OF_MEMORY;
2469         }
2470
2471         node_data->cb = callback;
2472         node_data->user_data = user_data;
2473
2474         audio_state_node = node_data;
2475
2476         _bt_update_bluetooth_callbacks();
2477
2478         return BT_SUCCESS;
2479 }
2480
2481 int bt_audio_unset_connection_state_changed_cb(void)
2482 {
2483         DBG("");
2484
2485         if (initialized == false)
2486                 return BT_ERROR_NOT_INITIALIZED;
2487
2488         if (!audio_state_node)
2489                 return BT_SUCCESS;
2490
2491         bluez_unset_audio_state_cb();
2492
2493         g_free(audio_state_node);
2494         audio_state_node = NULL;
2495
2496         return BT_SUCCESS;
2497 }
2498
2499 static gboolean media_handle_set_property(GDBusConnection *connection,
2500                                 const gchar *sender,
2501                                 const gchar *object_path,
2502                                 const gchar *interface_name,
2503                                 const gchar *property_name,
2504                                 GVariant *value,
2505                                 GError **error,
2506                                 gpointer user_data)
2507 {
2508         DBG("property_name = %s", property_name);
2509
2510         if (g_strcmp0(property_name, "LoopStatus") == 0) {
2511                 const gchar *loopstatus = g_variant_get_string(value, NULL);
2512                 DBG("loopstatus = %s", loopstatus);
2513
2514                 if (avrcp_repeat_node)
2515                         bluez_avrcp_repeat_changed(loopstatus,
2516                                                         avrcp_repeat_node);
2517         } else if (g_strcmp0(property_name, "Shuffle") == 0) {
2518                 gboolean shuffle_mode = g_variant_get_boolean(value);
2519                 if (shuffle_mode == TRUE)
2520                         DBG("shuffle_mode TRUE");
2521                 else
2522                         DBG("shuffle_mode FALSE");
2523
2524                 if (avrcp_shuffle_node)
2525                         bluez_avrcp_shuffle_changed(shuffle_mode,
2526                                                         avrcp_shuffle_node);
2527         }
2528
2529         return *error == NULL;
2530 }
2531
2532 static const gchar media_xml[] =
2533 "<node>"
2534 "  <interface name='org.mpris.MediaPlayer2.Player'>"
2535 "    <property type='b' name='Shuffle' access='readwrite'/>"
2536 "    <property type='s' name='LoopStatus' access='readwrite'/>"
2537 "  </interface>"
2538 "</node>";
2539
2540 static const GDBusInterfaceVTable media_handle = {
2541         NULL,
2542         NULL,
2543         media_handle_set_property
2544 };
2545
2546 static GDBusNodeInfo *media_data;
2547 static int bluetooth_media_agent_id;
2548
2549 static int destory_media_agent(void)
2550 {
2551         if (bluetooth_media_agent_id > 0) {
2552                 comms_bluetooth_unregister_media_agent(AGENT_OBJECT_PATH,
2553                                                         NULL, NULL);
2554
2555                 g_dbus_connection_unregister_object(conn,
2556                                                 bluetooth_media_agent_id);
2557
2558                 bluetooth_media_agent_id = 0;
2559
2560                 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
2561         }
2562
2563         return 0;
2564 }
2565
2566 static int create_media_agent(void)
2567 {
2568         int ret;
2569
2570         if (bluetooth_media_agent_id)
2571                 return BT_ERROR_ALREADY_DONE;
2572
2573         media_data =
2574                 g_dbus_node_info_new_for_xml(media_xml, NULL);
2575
2576         ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
2577         if (ret != 0)
2578                 return -1;
2579
2580         DBG("%s requested success", BLUEZ_AGENT_SERVICE);
2581
2582         bluetooth_media_agent_id = g_dbus_connection_register_object(
2583                                                 conn,
2584                                                 AGENT_OBJECT_PATH,
2585                                                 media_data->
2586                                                         interfaces[0],
2587                                                 &media_handle,
2588                                                 NULL,
2589                                                 NULL,
2590                                                 NULL);
2591
2592         if (bluetooth_media_agent_id == 0)
2593                 return BT_ERROR_OPERATION_FAILED;
2594
2595         ret = comms_bluetooth_register_media_agent_sync(AGENT_OBJECT_PATH,
2596                                                                 NULL);
2597
2598         DBG("ret = %d", ret);
2599
2600         if (ret != BT_SUCCESS) {
2601                 destory_media_agent();
2602                 return BT_ERROR_OPERATION_FAILED;
2603         }
2604
2605         return BT_SUCCESS;
2606 }
2607
2608 int bt_avrcp_target_initialize(
2609                         bt_avrcp_target_connection_state_changed_cb callback,
2610                         void *user_data)
2611 {
2612         struct avrcp_target_connection_state_changed_node *node_data = NULL;
2613         int ret;
2614
2615         DBG("default_adpater: %p", default_adapter);
2616
2617         if (default_adapter == NULL)
2618                 return BT_ERROR_ADAPTER_NOT_FOUND;
2619
2620         if (callback == NULL)
2621                 return BT_ERROR_INVALID_PARAMETER;
2622
2623         if (avrcp_target_state_node) {
2624                 DBG("avrcp target callback already set.");
2625                 return BT_ERROR_ALREADY_DONE;
2626         }
2627
2628         ret = create_media_agent();
2629
2630         if (ret != BT_SUCCESS)
2631                 return ret;
2632
2633         node_data =
2634                 g_new0(struct avrcp_target_connection_state_changed_node, 1);
2635         if (node_data == NULL) {
2636                 ERROR("no memory");
2637                 return BT_ERROR_OUT_OF_MEMORY;
2638         }
2639
2640         node_data->cb = callback;
2641         node_data->user_data = user_data;
2642
2643         avrcp_target_state_node = node_data;
2644
2645         _bt_update_bluetooth_callbacks();
2646
2647         return BT_SUCCESS;
2648 }
2649
2650 int bt_avrcp_target_deinitialize(void)
2651 {
2652         DBG("");
2653
2654         if (initialized == false)
2655                 return BT_ERROR_NOT_INITIALIZED;
2656
2657         if (!avrcp_target_state_node)
2658                 return BT_SUCCESS;
2659
2660         bluez_unset_avrcp_target_cb();
2661
2662         g_free(avrcp_target_state_node);
2663         avrcp_target_state_node = NULL;
2664
2665         destory_media_agent();
2666
2667         return BT_SUCCESS;
2668 }
2669
2670 int bt_avrcp_set_repeat_mode_changed_cb(
2671                 bt_avrcp_repeat_mode_changed_cb callback,
2672                 void *user_data)
2673 {
2674         static struct avrcp_repeat_mode_changed_node *node_data;
2675
2676         DBG("default_adpater: %p", default_adapter);
2677
2678         if (default_adapter == NULL)
2679                 return BT_ERROR_ADAPTER_NOT_FOUND;
2680
2681         if (callback == NULL)
2682                 return BT_ERROR_INVALID_PARAMETER;
2683
2684         if (avrcp_repeat_node) {
2685                 DBG("repeat mode callback already set.");
2686                 return BT_ERROR_ALREADY_DONE;
2687         }
2688
2689         node_data = g_new0(struct avrcp_repeat_mode_changed_node, 1);
2690         if (node_data == NULL) {
2691                 ERROR("no memory");
2692                 return BT_ERROR_OUT_OF_MEMORY;
2693         }
2694
2695         node_data->cb = callback;
2696         node_data->user_data = user_data;
2697
2698         avrcp_repeat_node = node_data;
2699
2700         return BT_SUCCESS;
2701 }
2702
2703 int bt_avrcp_unset_repeat_mode_changed_cb(void)
2704 {
2705         DBG("");
2706
2707         if (initialized == false)
2708                 return BT_ERROR_NOT_INITIALIZED;
2709
2710         if (!avrcp_repeat_node)
2711                 return BT_SUCCESS;
2712
2713         g_free(avrcp_repeat_node);
2714         avrcp_repeat_node = NULL;
2715
2716         return BT_SUCCESS;
2717 }
2718
2719 int bt_avrcp_set_shuffle_mode_changed_cb(
2720                 bt_avrcp_shuffle_mode_changed_cb callback,
2721                 void *user_data)
2722 {
2723         struct avrcp_set_shuffle_mode_changed_node *node_data = NULL;
2724
2725         DBG("default_adpater: %p", default_adapter);
2726
2727         if (default_adapter == NULL)
2728                 return BT_ERROR_ADAPTER_NOT_FOUND;
2729
2730         if (callback == NULL)
2731                 return BT_ERROR_INVALID_PARAMETER;
2732
2733         if (avrcp_shuffle_node) {
2734                 DBG("repeat mode callback already set.");
2735                 return BT_ERROR_ALREADY_DONE;
2736         }
2737
2738         node_data = g_new0(struct avrcp_set_shuffle_mode_changed_node, 1);
2739         if (node_data == NULL) {
2740                 ERROR("no memory");
2741                 return BT_ERROR_OUT_OF_MEMORY;
2742         }
2743
2744         node_data->cb = callback;
2745         node_data->user_data = user_data;
2746
2747         avrcp_shuffle_node = node_data;
2748
2749         return BT_SUCCESS;
2750 }
2751
2752 int bt_avrcp_unset_shuffle_mode_changed_cb(void)
2753 {
2754         DBG("");
2755
2756         if (initialized == false)
2757                 return BT_ERROR_NOT_INITIALIZED;
2758
2759         if (!avrcp_shuffle_node)
2760                 return BT_SUCCESS;
2761
2762         g_free(avrcp_shuffle_node);
2763         avrcp_shuffle_node = NULL;
2764
2765         return BT_SUCCESS;
2766 }
2767
2768 int bt_avrcp_target_notify_repeat_mode(bt_avrcp_repeat_mode_e mode)
2769 {
2770         DBG("");
2771
2772         if (default_adapter == NULL) {
2773                 DBG("no adapter");
2774                 return BT_ERROR_ADAPTER_NOT_FOUND;
2775         }
2776
2777         return comms_bluetooth_avrcp_change_property(LOOPSTATUS,
2778                                         mode, NULL, NULL);
2779 }
2780
2781 int bt_avrcp_target_notify_shuffle_mode(bt_avrcp_shuffle_mode_e mode)
2782 {
2783         DBG("");
2784
2785         if (default_adapter == NULL) {
2786                 DBG("no adapter");
2787                 return BT_ERROR_ADAPTER_NOT_FOUND;
2788         }
2789
2790         return comms_bluetooth_avrcp_change_property(SHUFFLE, mode,
2791                                         NULL, NULL);
2792 }
2793
2794 int bt_avrcp_target_notify_player_state(bt_avrcp_player_state_e state)
2795 {
2796         DBG("");
2797
2798         if (default_adapter == NULL) {
2799                 DBG("no adapter");
2800                 return BT_ERROR_ADAPTER_NOT_FOUND;
2801         }
2802
2803         return comms_bluetooth_avrcp_change_property(PLAYBACKSTATUS,
2804                                         state, NULL, NULL);
2805 }
2806
2807 int bt_avrcp_target_notify_position(unsigned int position)
2808 {
2809         DBG("");
2810
2811         if (default_adapter == NULL) {
2812                 DBG("no adapter");
2813                 return BT_ERROR_ADAPTER_NOT_FOUND;
2814         }
2815
2816         return comms_bluetooth_avrcp_change_property(POSITION,
2817                                 position, NULL, NULL);
2818 }
2819
2820 int bt_avrcp_target_notify_track(const char *title, const char *artist,
2821                 const char *album, const char *genre, unsigned int track_num,
2822                 unsigned int total_tracks, unsigned int duration)
2823 {
2824         GVariantBuilder *builder;
2825         GVariant *val;
2826
2827         DBG("");
2828
2829         if (default_adapter == NULL) {
2830                 DBG("no adapter");
2831                 return BT_ERROR_ADAPTER_NOT_FOUND;
2832         }
2833
2834         builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2835
2836         val = g_variant_new("s", title);
2837         g_variant_builder_add(builder, "{sv}", "xesam:title", val);
2838
2839         val = g_variant_new("s", artist);
2840         g_variant_builder_add(builder, "{sv}", "xesam:artist", val);
2841
2842         val = g_variant_new("s", genre);
2843         g_variant_builder_add(builder, "{sv}", "xesam:genre", val);
2844
2845         val = g_variant_new("s", album);
2846         g_variant_builder_add(builder, "{sv}", "xesam:album", val);
2847
2848         val = g_variant_new("i", track_num);
2849         g_variant_builder_add(builder, "{sv}", "xesam:trackNumber", val);
2850
2851         val = g_variant_new("x", duration);
2852         g_variant_builder_add(builder, "{sv}", "mpris:length", val);
2853
2854         return comms_bluetooth_avrcp_change_track((void *)builder,
2855                                                         NULL, NULL);
2856 }
2857
2858 int bt_avrcp_target_notify_equalizer_state(bt_avrcp_equalizer_state_e state)
2859 {
2860         /*bluez-5.X doesn't provide the property*/
2861         return BT_SUCCESS;
2862 }
2863
2864 int bt_avrcp_target_notify_scan_mode(bt_avrcp_scan_mode_e mode)
2865 {
2866         /*bluez-5.X doesn't provide the property*/
2867         return BT_SUCCESS;
2868 }
2869
2870 int bt_avrcp_set_equalizer_state_changed_cb(
2871                                 bt_avrcp_equalizer_state_changed_cb callback,
2872                                 void *user_data)
2873 {
2874         /*bluez-5.X doesn't provide the property*/
2875         return BT_SUCCESS;
2876 }
2877
2878 int bt_avrcp_unset_equalizer_state_changed_cb(void)
2879 {
2880         /*bluez-5.X doesn't provide the property*/
2881         return BT_SUCCESS;
2882 }
2883
2884 int bt_avrcp_set_scan_mode_changed_cb(bt_avrcp_scan_mode_changed_cb callback,
2885                                 void *user_data)
2886 {
2887         /*bluez-5.X doesn't provide the property*/
2888         return BT_SUCCESS;
2889 }
2890
2891 int bt_avrcp_unset_scan_mode_changed_cb(void)
2892 {
2893          /*bluez-5.X doesn't provide the property*/
2894         return BT_SUCCESS;
2895 }
2896
2897 /* Hid function */
2898 int bt_hid_host_initialize(
2899                 bt_hid_host_connection_state_changed_cb connection_cb,
2900                 void *user_data)
2901 {
2902         struct hid_host_connection_state_changed_cb_node *node_data;
2903         GList *list;
2904
2905         DBG("");
2906
2907         if (connection_cb == NULL)
2908                 return BT_ERROR_INVALID_PARAMETER;
2909
2910         if (hid_host_state_node) {
2911                 DBG("hid host connected state changed callback already set.");
2912                 return BT_ERROR_ALREADY_DONE;
2913         }
2914
2915         node_data = g_new0(struct hid_host_connection_state_changed_cb_node, 1);
2916         if (node_data == NULL) {
2917                 ERROR("no memory");
2918                 return BT_ERROR_OUT_OF_MEMORY;
2919         }
2920
2921         node_data->cb = connection_cb;
2922         node_data->user_data = user_data;
2923
2924         hid_host_state_node = node_data;
2925
2926         dev_property_callback_flags |= DEV_PROP_FLAG_HID_CONNECT;
2927
2928         if (!default_adapter)
2929                 return BT_SUCCESS;
2930
2931         list = bluez_adapter_get_devices(default_adapter);
2932         foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
2933
2934         g_list_free(list);
2935
2936         return BT_SUCCESS;
2937 }
2938
2939 int bt_hid_host_deinitialize(void)
2940 {
2941         GList *list;
2942         DBG("");
2943
2944         if (initialized == false)
2945                 return BT_ERROR_NOT_INITIALIZED;
2946
2947         if (default_adapter == NULL)
2948                 return BT_ERROR_ADAPTER_NOT_FOUND;
2949
2950         if (!hid_host_state_node)
2951                 return BT_SUCCESS;
2952
2953         dev_property_callback_flags &= ~DEV_PROP_FLAG_HID_CONNECT;
2954
2955         list = bluez_adapter_get_devices(default_adapter);
2956         foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
2957
2958         g_free(hid_host_state_node);
2959         hid_host_state_node = NULL;
2960
2961         return BT_SUCCESS;
2962 }
2963
2964 static void profile_connect_callback(bluez_device_t *device,
2965                                         enum device_profile_state state)
2966 {
2967         switch (state) {
2968         case PROFILE_CONNECT_SUCCESS:
2969                 DBG("Connect profile: %s", "PROFILE_CONNECT_SUCCESS");
2970                 break;
2971         case PROFILE_NOT_EXIST:
2972                 DBG("Connect profile: %s", "PROFILE_NOT_EXIST");
2973                 break;
2974         case PROFILE_ALREADY_CONNECTED:
2975                 DBG("Connect profile: %s", "PROFILE_ALREADY_CONNECTED");
2976                 break;
2977         case PROFILE_CONNECT_FAILED:
2978                 DBG("Connect profile: %s", "PROFILE_CONNECT_FAILED");
2979                 break;
2980         default:
2981                 ERROR("Unknown error code");
2982                 break;
2983         }
2984 }
2985
2986 int bt_hid_host_connect(const char *remote_address)
2987 {
2988         bluez_device_t *device;
2989
2990         DBG("");
2991
2992         if (initialized == false)
2993                 return BT_ERROR_NOT_INITIALIZED;
2994
2995         if (default_adapter == NULL)
2996                 return BT_ERROR_ADAPTER_NOT_FOUND;
2997
2998         device = bluez_adapter_get_device_by_address(default_adapter,
2999                                                         remote_address);
3000         if (device == NULL)
3001                 return BT_ERROR_OPERATION_FAILED;
3002
3003         bluez_device_connect_profile(device, BT_HID_UUID,
3004                                 profile_connect_callback);
3005
3006         return BT_SUCCESS;
3007 }
3008
3009 static void profile_disconnect_callback(bluez_device_t *device,
3010                                         enum device_profile_state state)
3011 {
3012         switch (state) {
3013         case PROFILE_DISCONNECT_SUCCESS:
3014                 DBG("Connect profile: %s", "PROFILE_DISCONNECT_SUCCESS");
3015                 break;
3016         case PROFILE_NOT_EXIST:
3017                 DBG("Connect profile: %s", "PROFILE_NOT_EXIST");
3018                 break;
3019         case PROFILE_NOT_CONNECTED:
3020                 DBG("Connect profile: %s", "PROFILE_NOT_CONNECTED");
3021                 break;
3022         case PROFILE_NOT_SUPPORTED:
3023                 DBG("Connect profile: %s", "PROFILE_NOT_SUPPORTED");
3024                 break;
3025         case PROFILE_DISCONNECT_FAILED:
3026                 DBG("Connect profile: %s", "PROFILE_DISCONNECT_FAILED");
3027                 break;
3028         default:
3029                 ERROR("Unknown error code");
3030                 break;
3031         }
3032 }
3033
3034 int bt_hid_host_disconnect(const char *remote_address)
3035 {
3036         bluez_device_t *device;
3037
3038         DBG("");
3039
3040         if (initialized == false)
3041                 return BT_ERROR_NOT_INITIALIZED;
3042
3043         if (default_adapter == NULL)
3044                 return BT_ERROR_ADAPTER_NOT_FOUND;
3045
3046         device = bluez_adapter_get_device_by_address(default_adapter,
3047                                                         remote_address);
3048         if (device == NULL)
3049                 return BT_ERROR_OPERATION_FAILED;
3050
3051         bluez_device_disconnect_profile(device, BT_HID_UUID,
3052                                 profile_disconnect_callback);
3053
3054         return BT_SUCCESS;
3055 }
3056
3057 struct spp_context {
3058         int fd;
3059         gchar *remote_address;
3060         gchar *uuid;
3061         gchar *spp_path;
3062         GIOChannel *channel;
3063         bt_spp_new_connection_cb new_connection;
3064         void *new_connection_data;
3065
3066         int max_pending;
3067         void *requestion;
3068         gboolean is_accept;
3069         bt_socket_role_e role;
3070 };
3071
3072 GList *spp_ctx_list;
3073
3074 static GDBusNodeInfo *profile_xml_data;
3075
3076 static struct spp_context *create_spp_context(void)
3077 {
3078         struct spp_context *spp_ctx, *spp_last;
3079         GList *list;
3080
3081         spp_ctx = g_try_new0(struct spp_context, 1);
3082         if (spp_ctx == NULL) {
3083                 DBG("no memroy");
3084                 return NULL;
3085         }
3086
3087         if (g_list_length(spp_ctx_list) != 0) {
3088                 list = g_list_last(spp_ctx_list);
3089                 spp_last = list->data;
3090                 spp_ctx->fd = spp_last->fd + 1;
3091         } else
3092                 spp_ctx->fd = 1;
3093
3094         return spp_ctx;
3095 }
3096
3097 static void free_spp_context(struct spp_context *spp_ctx)
3098 {
3099         if (spp_ctx == NULL)
3100                 return;
3101
3102         if (spp_ctx->uuid)
3103                 g_free(spp_ctx->uuid);
3104
3105         if (spp_ctx->spp_path)
3106                 g_free(spp_ctx->spp_path);
3107
3108         if (spp_ctx->remote_address)
3109                 g_free(spp_ctx->remote_address);
3110
3111         g_free(spp_ctx);
3112 }
3113
3114 static struct spp_context *find_spp_context_from_uuid(const char *uuid)
3115 {
3116         struct spp_context *spp_ctx;
3117         GList *list, *next;
3118
3119         for (list = g_list_first(spp_ctx_list); list; list = next) {
3120                 next = g_list_next(list);
3121
3122                 spp_ctx = list->data;
3123
3124                 if (spp_ctx && !g_strcmp0(spp_ctx->uuid, uuid))
3125                         return spp_ctx;
3126         }
3127
3128         return NULL;
3129 }
3130
3131 static struct spp_context *find_spp_context_from_socketfd(int socket_fd)
3132 {
3133         struct spp_context *spp_ctx;
3134         GList *list, *next;
3135
3136         for (list = g_list_first(spp_ctx_list); list; list = next) {
3137                 next = g_list_next(list);
3138
3139                 spp_ctx = list->data;
3140
3141                 if (spp_ctx && (spp_ctx->fd == socket_fd))
3142                         return spp_ctx;
3143         }
3144
3145         return NULL;
3146 }
3147
3148 static struct spp_context *find_spp_context_from_fd(int fd)
3149 {
3150         struct spp_context *spp_ctx;
3151         GList *list, *next;
3152         int spp_fd;
3153
3154         for (list = g_list_first(spp_ctx_list); list; list = next) {
3155                 next = g_list_next(list);
3156
3157                 spp_ctx = list->data;
3158
3159                 spp_fd = g_io_channel_unix_get_fd(spp_ctx->channel);
3160
3161                 if (spp_ctx && spp_fd == fd)
3162                         return spp_ctx;
3163         }
3164
3165         return NULL;
3166 }
3167
3168 /* Agent Function */
3169
3170 static bt_agent *this_agent;
3171
3172 static GDBusNodeInfo *introspection_data;
3173
3174 static const gchar introspection_xml[] =
3175         "<node>"
3176         "  <interface name='org.bluez.Agent1'>"
3177         "    <method name='Release'>"
3178         "    </method>"
3179         "    <method name='RequestPinCode'>"
3180         "      <arg type='o' name='device' direction='in'/>"
3181         "      <arg type='s' direction='out'/>"
3182         "    </method>"
3183         "    <method name='DisplayPinCode'>"
3184         "      <arg type='o' name='device' direction='in'/>"
3185         "      <arg type='s' name='pincode' direction='in'/>"
3186         "    </method>"
3187         "    <method name='RequestPasskey'>"
3188         "      <arg type='o' name='device' direction='in'/>"
3189         "      <arg type='u' direction='out'/>"
3190         "    </method>"
3191         "    <method name='RequestConfirmation'>"
3192         "      <arg type='o' name='device' direction='in'/>"
3193         "      <arg type='u' name='passkey' direction='in'/>"
3194         "    </method>"
3195         "    <method name='RequestAuthorization'>"
3196         "      <arg type='o' name='device' direction='in'/>"
3197         "    </method>"
3198         "    <method name='AuthorizeService'>"
3199         "      <arg type='o' name='device' direction='in'/>"
3200         "      <arg type='s' name='uuid' direction='in'/>"
3201         "      <arg type='h' name='fd' direction='in'/>"
3202         "    </method>"
3203         "    <method name='Cancel'>"
3204         "    </method>"
3205         "  </interface>"
3206         "</node>";
3207
3208 static void handle_release(GDBusMethodInvocation *invocation)
3209 {
3210         DBG("");
3211
3212         g_dbus_method_invocation_return_value(invocation, NULL);
3213 }
3214
3215 static void handle_display_pincode(const gchar *device_path,
3216                                         const char *pincode,
3217                                         GDBusMethodInvocation *invocation)
3218 {
3219         gchar *device_name;
3220         bluez_device_t *device;
3221
3222         DBG("");
3223
3224         if (default_adapter == NULL) {
3225                 ERROR("No default adapter");
3226                 return;
3227         }
3228
3229         device = bluez_adapter_get_device_by_path(default_adapter,
3230                                                         device_path);
3231         if (device == NULL) {
3232                 ERROR("Can't find device %s", device_path);
3233                 return;
3234         }
3235
3236         device_name = bluez_device_get_property_alias(device);
3237
3238         if (this_agent && this_agent->display_pincode)
3239                 this_agent->display_pincode(device_name, pincode, invocation);
3240
3241         g_dbus_method_invocation_return_value(invocation, NULL);
3242 }
3243
3244 static void request_pincode_handler(const gchar *device_path,
3245                                         GDBusMethodInvocation *invocation)
3246 {
3247         gchar *device_name;
3248         bluez_device_t *device;
3249
3250         DBG("");
3251
3252         if (default_adapter == NULL) {
3253                 ERROR("No default adapter");
3254                 return;
3255         }
3256
3257         device = bluez_adapter_get_device_by_path(default_adapter,
3258                                                         device_path);
3259         if (device == NULL) {
3260                 ERROR("Can't find device %s", device_path);
3261                 return;
3262         }
3263
3264         device_name = bluez_device_get_property_alias(device);
3265
3266         if (this_agent && this_agent->request_pincode)
3267                 this_agent->request_pincode(device_name, invocation);
3268 }
3269
3270 static void request_passkey_handler(const gchar *device_path,
3271                                         GDBusMethodInvocation *invocation)
3272 {
3273         gchar *device_name;
3274         bluez_device_t *device;
3275
3276         DBG("");
3277
3278         if (default_adapter == NULL) {
3279                 ERROR("No default adapter");
3280                 return;
3281         }
3282
3283         device = bluez_adapter_get_device_by_path(default_adapter,
3284                                                         device_path);
3285         if (device == NULL) {
3286                 ERROR("Can't find device %s", device_path);
3287                 return;
3288         }
3289
3290         device_name = bluez_device_get_property_alias(device);
3291
3292         if (this_agent && this_agent->request_passkey)
3293                 this_agent->request_passkey(device_name, invocation);
3294 }
3295
3296 static void request_confirmation_handler(const gchar *device_path,
3297                                         guint32 passkey,
3298                                         GDBusMethodInvocation *invocation)
3299 {
3300         gchar *device_name;
3301         bluez_device_t *device;
3302
3303         DBG("");
3304
3305         if (default_adapter == NULL) {
3306                 ERROR("No default adapter");
3307                 return;
3308         }
3309
3310         device = bluez_adapter_get_device_by_path(default_adapter,
3311                                                         device_path);
3312         if (device == NULL) {
3313                 ERROR("Can't find device %s", device_path);
3314                 return;
3315         }
3316
3317         device_name = bluez_device_get_property_alias(device);
3318
3319         if (this_agent && this_agent->request_confirm)
3320                 this_agent->request_confirm(device_name, passkey, invocation);
3321 }
3322
3323 static void handle_spp_authorize_request(bluez_device_t *device,
3324                                         struct spp_context *spp_ctx,
3325                                         GDBusMethodInvocation *invocation)
3326 {
3327         char *device_name, *device_address;
3328         GDBusMessage *msg;
3329         GUnixFDList *fd_list;
3330         gint fd;
3331
3332         if (spp_ctx->max_pending == 0) {
3333                 bt_spp_reject(invocation);
3334                 return;
3335         }
3336
3337         msg = g_dbus_method_invocation_get_message(invocation);
3338
3339         fd_list = g_dbus_message_get_unix_fd_list(msg);
3340
3341         fd = g_unix_fd_list_get(fd_list, (gint)0, NULL);
3342
3343         spp_ctx->channel = g_io_channel_unix_new(fd);
3344
3345         device_name = bluez_device_get_property_alias(device);
3346         device_address = bluez_device_get_property_address(device);
3347
3348         /* New API handler */
3349         if (spp_connection_requested_node)
3350                 spp_connection_requested_node->cb(
3351                                 spp_ctx->uuid, device_name, invocation,
3352                                 spp_connection_requested_node->user_data);
3353
3354         /* Old API handler */
3355         if (spp_ctx->max_pending <=0) {
3356                 bt_spp_reject(invocation);
3357                 goto done;
3358         }
3359
3360         if (spp_ctx->is_accept) {
3361                 bt_spp_accept(invocation);
3362                 goto done;
3363         }
3364
3365         spp_ctx->requestion = invocation;
3366         spp_ctx->role = BT_SOCKET_SERVER;
3367         spp_ctx->remote_address = g_strdup(device_address);
3368
3369         if (socket_connection_requested_node)
3370                 socket_connection_requested_node->cb(
3371                                 spp_ctx->fd, (const char *)device_address,
3372                                 socket_connection_requested_node->user_data);
3373
3374 done:
3375         if (device_name)
3376                 g_free(device_name);
3377
3378         if (device_address)
3379                 g_free(device_address);
3380 }
3381
3382 static void request_authorize_service_handler(const gchar *device_path,
3383                                         const gchar *uuid,
3384                                         GDBusMethodInvocation *invocation)
3385 {
3386         struct spp_context *spp_ctx;
3387         gchar *device_name;
3388         bluez_device_t *device;
3389
3390         DBG("");
3391
3392         if (default_adapter == NULL) {
3393                 ERROR("No default adapter");
3394                 return;
3395         }
3396
3397         device = bluez_adapter_get_device_by_path(default_adapter,
3398                                                         device_path);
3399         if (device == NULL) {
3400                 ERROR("Can't find device %s", device_path);
3401                 return;
3402         }
3403
3404         spp_ctx = find_spp_context_from_uuid(uuid);
3405         if (spp_ctx != NULL) {
3406                 handle_spp_authorize_request(device, spp_ctx, invocation);
3407                 return;
3408         }
3409
3410         /* Other profile Authorize request */
3411         if (!this_agent || !this_agent->authorize_service)
3412                 return;
3413
3414         device_name = bluez_device_get_property_alias(device);
3415
3416         this_agent->authorize_service(device_name, uuid, invocation);
3417
3418         g_free(device_name);
3419 }
3420
3421 static void request_authorization_handler(const gchar *device_path,
3422                                         GDBusMethodInvocation *invocation)
3423 {
3424         if (!this_agent)
3425                 return;
3426
3427         if (!this_agent->cancel)
3428                 return;
3429
3430         g_dbus_method_invocation_return_value(invocation, NULL);
3431 }
3432
3433 static void cancel_handler(GDBusMethodInvocation *invocation)
3434 {
3435         if (!this_agent)
3436                 return;
3437
3438         if (!this_agent->cancel)
3439                 return;
3440
3441         this_agent->cancel();
3442
3443         g_dbus_method_invocation_return_value(invocation, NULL);
3444 }
3445
3446 static void handle_method_call(GDBusConnection *connection,
3447                                 const gchar *sender,
3448                                 const gchar *object_path,
3449                                 const gchar *interface_name,
3450                                 const gchar *method_name,
3451                                 GVariant *parameters,
3452                                 GDBusMethodInvocation *invocation,
3453                                 gpointer user_data)
3454 {
3455         if (g_strcmp0(method_name, "Release") == 0) {
3456                 handle_release(invocation);
3457
3458                 return;
3459         }
3460
3461         if (g_strcmp0(method_name, "DisplayPinCode") == 0) {
3462                 gchar *device_path = NULL, *pincode =  NULL;
3463                 g_variant_get(parameters, "(os)", &device_path, &pincode);
3464
3465                 handle_display_pincode(device_path, pincode, invocation);
3466
3467                 g_free(device_path);
3468                 g_free(pincode);
3469
3470                 return;
3471         }
3472
3473         if (g_strcmp0(method_name, "RequestPinCode") == 0) {
3474                 gchar *device_path = NULL;
3475                 g_variant_get(parameters, "(o)", &device_path);
3476
3477                 request_pincode_handler(device_path, invocation);
3478
3479                 g_free(device_path);
3480
3481                 return;
3482         }
3483
3484         if (g_strcmp0(method_name, "RequestPasskey") == 0) {
3485                 gchar *device_path = NULL;
3486                 g_variant_get(parameters, "(o)", &device_path);
3487
3488                 request_passkey_handler(device_path, invocation);
3489
3490                 g_free(device_path);
3491
3492                 return;
3493         }
3494
3495         if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
3496                 gchar *device_path = NULL;
3497                 guint32 passkey = 0;
3498                 g_variant_get(parameters, "(ou)", &device_path, &passkey);
3499
3500                 request_confirmation_handler(device_path, passkey, invocation);
3501
3502                 g_free(device_path);
3503
3504                 return;
3505         }
3506
3507         if (g_strcmp0(method_name, "AuthorizeService") == 0) {
3508                 gchar *device_path, *uuid;
3509                 gint32 fd_index;
3510
3511                 g_variant_get(parameters, "(osh)", &device_path,
3512                                                 &uuid, &fd_index);
3513
3514                 request_authorize_service_handler(device_path,
3515                                                 uuid, invocation);
3516
3517                 g_free(device_path);
3518                 g_free(uuid);
3519
3520                 return;
3521         }
3522
3523         if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
3524                 gchar *device_path;
3525                 g_variant_get(parameters, "(o)", &device_path);
3526
3527                 request_authorization_handler(device_path, invocation);
3528
3529                 g_free(device_path);
3530
3531                 return;
3532         }
3533
3534         if (g_strcmp0(method_name, "Cancel") == 0) {
3535                 cancel_handler(invocation);
3536
3537                 return;
3538         }
3539 }
3540
3541 static const GDBusInterfaceVTable interface_handle = {
3542         handle_method_call,
3543         NULL,
3544         NULL
3545 };
3546
3547
3548 static void release_dbus_connection(void)
3549 {
3550         g_object_unref(conn);
3551         conn = NULL;
3552 }
3553
3554 static void release_name_on_dbus(const char *name)
3555 {
3556         GVariant *ret;
3557         guint32 request_name_reply;
3558         GError *error = NULL;
3559
3560         if (bluetooth_agent_id || profile_id)
3561                 return;
3562
3563         ret = g_dbus_connection_call_sync(conn,
3564                                         "org.freedesktop.DBus",
3565                                         "/org/freedesktop/DBus",
3566                                         "org.freedesktop.DBus",
3567                                         "ReleaseName",
3568                                         g_variant_new("(s)", name),
3569                                         G_VARIANT_TYPE("(u)"),
3570                                         G_DBUS_CALL_FLAGS_NONE,
3571                                         -1, NULL, &error);
3572         if (ret == NULL) {
3573                 WARN("%s", error->message);
3574                 return;
3575         }
3576
3577         g_variant_get(ret, "(u)", &request_name_reply);
3578         g_variant_unref(ret);
3579
3580         if (request_name_reply != 1) {
3581                 WARN("Unexpected reply");
3582                 return;
3583         }
3584
3585         release_dbus_connection();
3586
3587         return;
3588 }
3589
3590 static GDBusConnection *get_system_dbus_connect(void)
3591 {
3592         GError *error = NULL;
3593
3594         if (conn)
3595                 return conn;
3596
3597         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
3598         if (conn == NULL) {
3599                 DBG("%s", error->message);
3600
3601                 g_error_free(error);
3602         }
3603
3604         return conn;
3605 }
3606
3607 static int request_name_on_dbus(const char *name)
3608 {
3609         GDBusConnection *connection;
3610         GVariant *ret;
3611         guint32 request_name_reply;
3612         GError *error = NULL;
3613
3614         if (bluetooth_agent_id || profile_id)
3615                 return 0;
3616
3617         connection = get_system_dbus_connect();
3618         if (connection == NULL)
3619                 return -1;
3620
3621         ret = g_dbus_connection_call_sync(connection,
3622                                         "org.freedesktop.DBus",
3623                                         "/org/freedesktop/DBus",
3624                                         "org.freedesktop.DBus",
3625                                         "RequestName",
3626                                         g_variant_new("(su)",
3627                                                 name,
3628                                                 G_BUS_NAME_OWNER_FLAGS_NONE),
3629                                         G_VARIANT_TYPE("(u)"),
3630                                         G_DBUS_CALL_FLAGS_NONE,
3631                                         -1, NULL, &error);
3632         if (ret == NULL) {
3633                 WARN("%s", error->message);
3634                 g_error_free(error);
3635
3636                 goto failed;
3637         }
3638
3639         g_variant_get(ret, "(u)", &request_name_reply);
3640         g_variant_unref(ret);
3641
3642         /* RequestName will return the uint32 value:
3643          * 1: DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
3644          * 2: BUS_REQUEST_NAME_REPLY_IN_QUEUE
3645          * 3: DBUS_REQUEST_NAME_REPLY_EXISTS
3646          * 4: DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
3647          * Also see dbus doc
3648          */
3649         if (request_name_reply != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
3650                 DBG("Lost name");
3651
3652                 release_name_on_dbus(name);
3653
3654                 goto failed;
3655         }
3656
3657         return 0;
3658
3659 failed:
3660         g_object_unref(connection);
3661
3662         return -1;
3663 }
3664
3665 static int destory_agent(void)
3666 {
3667         if (bluetooth_agent_id > 0) {
3668                 comms_bluetooth_unregister_pairing_agent(AGENT_OBJECT_PATH,
3669                                                                 NULL, NULL);
3670
3671                 g_dbus_connection_unregister_object(conn, bluetooth_agent_id);
3672
3673                 bluetooth_agent_id = 0;
3674
3675                 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
3676         }
3677
3678         return 0;
3679 }
3680
3681 static int create_agent(void)
3682 {
3683         int ret;
3684
3685         if (bluetooth_agent_id)
3686                 return BT_ERROR_ALREADY_DONE;
3687
3688         introspection_data =
3689                 g_dbus_node_info_new_for_xml(introspection_xml, NULL);
3690
3691         ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
3692         if (ret != 0)
3693                 return -1;
3694
3695         DBG("%s requested success", BLUEZ_AGENT_SERVICE);
3696
3697         bluetooth_agent_id = g_dbus_connection_register_object(conn,
3698                                         AGENT_OBJECT_PATH,
3699                                         introspection_data->interfaces[0],
3700                                         &interface_handle, NULL, NULL, NULL);
3701         if (bluetooth_agent_id == 0)
3702                 return -1;
3703
3704         ret = comms_bluetooth_register_pairing_agent_sync(
3705                                         AGENT_OBJECT_PATH, NULL);
3706         if (ret != BT_SUCCESS)
3707                 return BT_ERROR_OPERATION_FAILED;
3708
3709         return 0;
3710 }
3711
3712 int bt_agent_register(bt_agent *agent)
3713 {
3714         int ret;
3715
3716         if (initialized == false)
3717                 return BT_ERROR_NOT_INITIALIZED;
3718
3719         if (agent == NULL)
3720                 return BT_ERROR_INVALID_PARAMETER;
3721
3722         if (bluetooth_agent_id > 0)
3723                 return BT_ERROR_ALREADY_DONE;
3724
3725         if (this_agent != NULL)
3726                 return BT_ERROR_ALREADY_DONE;
3727
3728         ret = create_agent();
3729         if (ret != BT_SUCCESS)
3730                 return ret;
3731
3732         this_agent = agent;
3733
3734         return BT_SUCCESS;
3735 }
3736
3737 int bt_agent_unregister(void)
3738 {
3739         if (initialized == false)
3740                 return BT_ERROR_NOT_INITIALIZED;
3741
3742         destory_agent();
3743
3744         this_agent = NULL;
3745
3746         return BT_SUCCESS;
3747 }
3748
3749 static void bt_agent_simple_accept(GDBusMethodInvocation *invocation)
3750 {
3751         g_dbus_method_invocation_return_value(invocation, NULL);
3752 }
3753
3754 static void bt_agent_simple_reject(GDBusMethodInvocation *invocation)
3755 {
3756         g_dbus_method_invocation_return_dbus_error(invocation,
3757                         ERROR_INTERFACE ".Rejected",
3758                         "RejectedByUser");
3759 }
3760
3761 void bt_agent_confirm_accept(bt_req_t *requestion)
3762 {
3763         GDBusMethodInvocation *invocation = requestion;
3764
3765         bt_agent_simple_accept(invocation);
3766 }
3767
3768 void bt_agent_confirm_reject(bt_req_t *requestion)
3769 {
3770         GDBusMethodInvocation *invocation = requestion;
3771
3772         bt_agent_simple_reject(invocation);
3773 }
3774
3775 void bt_agent_pincode_reply(const char *pin_code, bt_req_t *requestion)
3776 {
3777         GDBusMethodInvocation *invocation = requestion;
3778
3779         g_dbus_method_invocation_return_value(invocation,
3780                                         g_variant_new("(s)", pin_code));
3781 }
3782
3783 void bt_agent_pincode_cancel(bt_req_t *requestion)
3784 {
3785         GDBusMethodInvocation *invocation = requestion;
3786
3787         g_dbus_method_invocation_return_dbus_error(invocation,
3788                         ERROR_INTERFACE ".Canceled",
3789                         "CanceledByUser");
3790 }
3791
3792 static const gchar profile_xml[] =
3793         "<node>"
3794         "  <interface name='org.bluez.Profile1'>"
3795         "    <method name='Release'>"
3796         "    </method>"
3797         "    <method name='NewConnection'>"
3798         "      <arg type='o' name='device' direction='in'/>"
3799         "      <arg type='h' name='fd' direction='in'/>"
3800         "      <arg type='a{sv}' name='opts' direction='in'/>"
3801         "    </method>"
3802         "    <method name='RequestDisconnection'>"
3803         "      <arg type='o' name='device' direction='in'/>"
3804         "    </method>"
3805         "  </interface>"
3806         "</node>";
3807
3808 static gboolean received_data(GIOChannel *channel, GIOCondition con,
3809                                                         gpointer user_data)
3810 {
3811         bt_spp_received_data spp_data;
3812         struct spp_context *spp_ctx;
3813         GIOStatus status;
3814         gsize rbytes = 0;
3815
3816         spp_ctx = user_data;
3817         if (spp_ctx == NULL) {
3818                 WARN("no spp find");
3819                 return FALSE;
3820         }
3821
3822         if (!spp_data_received_node)
3823                 goto done;
3824
3825         spp_data.socket_fd = g_io_channel_unix_get_fd(channel);
3826         spp_data.data = g_try_new0(gchar, BT_SPP_BUFFER_MAX);
3827
3828         status = g_io_channel_read_chars(channel, spp_data.data,
3829                                 BT_SPP_BUFFER_MAX - 1, &rbytes, NULL);
3830         if (status == G_IO_STATUS_ERROR) {
3831                 DBG("read channel error");
3832                 return FALSE;
3833         }
3834
3835         spp_data.data_size = rbytes;
3836
3837         if (spp_data_received_node->cb)
3838                 spp_data_received_node->cb(&spp_data,
3839                                 spp_data_received_node->user_data);
3840
3841         g_free(spp_data.data);
3842
3843 done:
3844         return TRUE;
3845 }
3846
3847 static void notify_connection_state(gchar *device_path,
3848                                 bt_socket_connection_state_e state,
3849                                 struct spp_context *spp_ctx)
3850 {
3851         bluez_device_t *device;
3852         gchar *device_name, *address;
3853         int fd;
3854
3855         device = bluez_adapter_get_device_by_path(default_adapter,
3856                                                 device_path);
3857         if (device == NULL) {
3858                 ERROR("Can't find device %s", device_path);
3859                 return;
3860         }
3861
3862         device_name = bluez_device_get_property_alias(device);
3863         address = bluez_device_get_property_address(device);
3864
3865         fd = g_io_channel_unix_get_fd(spp_ctx->channel);
3866
3867         if (spp_ctx->new_connection)
3868                 spp_ctx->new_connection(spp_ctx->uuid, device_name,
3869                                         fd, spp_ctx->new_connection_data);
3870
3871         if (socket_connection_state_node) {
3872                 bt_socket_connection_s connection;
3873
3874                 connection.socket_fd = fd;
3875                 connection.remote_address = address;
3876                 connection.service_uuid = spp_ctx->uuid;
3877                 connection.local_role = spp_ctx->role;
3878
3879                 socket_connection_state_node->cb(
3880                                 BT_SUCCESS, state, &connection,
3881                                 socket_connection_state_node->user_data);
3882         }
3883
3884         g_free(device_name);
3885         g_free(address);
3886 }
3887
3888 static void handle_new_connection(gchar *device_path, gint fd,
3889                                         GDBusMethodInvocation *invocation,
3890                                         void *user_data)
3891 {
3892         struct spp_context *spp_ctx;
3893         GIOChannel *channel;
3894
3895         spp_ctx = user_data;
3896         if (spp_ctx == NULL) {
3897                 DBG("no spp context");
3898                 return;
3899         }
3900
3901         if (!(spp_ctx->channel)) {
3902                 channel = g_io_channel_unix_new(fd);
3903                 if (channel == NULL) {
3904                         ERROR("Create connection channel error");
3905                         g_dbus_method_invocation_return_value(invocation, NULL);
3906                         goto done;
3907                 }
3908
3909                 spp_ctx->channel = channel;
3910         } else
3911                 channel = spp_ctx->channel;
3912
3913         g_io_channel_set_close_on_unref(channel, TRUE);
3914         g_io_channel_set_encoding(channel, NULL, NULL);
3915         g_io_channel_set_buffered(channel, FALSE);
3916
3917         g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
3918                                                 received_data, user_data);
3919
3920 done:
3921         notify_connection_state(device_path, BT_SOCKET_CONNECTED, spp_ctx);
3922
3923         g_dbus_method_invocation_return_value(invocation, NULL);
3924 }
3925
3926 static void handle_request_disconnection(gchar *device_path,
3927                                         GDBusMethodInvocation *invocation,
3928                                         void *user_data)
3929 {
3930         struct spp_context *spp_ctx = user_data;
3931
3932         DBG("device path %s", device_path);
3933
3934         g_io_channel_unref(spp_ctx->channel);
3935         spp_ctx->channel = NULL;
3936
3937         notify_connection_state(device_path, BT_SOCKET_DISCONNECTED, spp_ctx);
3938
3939         g_dbus_method_invocation_return_value(invocation, NULL);
3940 }
3941
3942 static void handle_profile_method_call(GDBusConnection *connection,
3943                                         const gchar *sender,
3944                                         const gchar *object_path,
3945                                         const gchar *interface_name,
3946                                         const gchar *method_name,
3947                                         GVariant *parameters,
3948                                         GDBusMethodInvocation *invocation,
3949                                         gpointer user_data)
3950 {
3951         if (g_strcmp0(method_name, "Release") == 0)
3952                 handle_release(invocation);
3953         else if (g_strcmp0(method_name, "NewConnection") == 0) {
3954                 GDBusMessage *msg;
3955                 GUnixFDList *fd_list;
3956                 GVariantIter *opts;
3957                 gchar *device_path;
3958                 gint32 fd_index;
3959                 gint fd;
3960
3961                 g_variant_get(parameters, "(oha{sv})",
3962                                         &device_path, &fd_index, &opts);
3963
3964                 msg = g_dbus_method_invocation_get_message(invocation);
3965
3966                 fd_list = g_dbus_message_get_unix_fd_list(msg);
3967
3968                 fd = g_unix_fd_list_get(fd_list, fd_index, NULL);
3969
3970                 handle_new_connection(device_path, fd, invocation, user_data);
3971
3972                 g_free(device_path);
3973                 g_variant_iter_free(opts);
3974         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
3975                 gchar *device_path;
3976
3977                 g_variant_get(parameters, "(o)", &device_path);
3978
3979                 handle_request_disconnection(device_path,
3980                                         invocation, user_data);
3981
3982                 g_free(device_path);
3983         } else
3984                 DBG("Unknown method name %s", method_name);
3985 }
3986
3987 static const GDBusInterfaceVTable profile_interface = {
3988         handle_profile_method_call,
3989         NULL,
3990         NULL
3991 };
3992
3993 static int register_profile_agent(const gchar *path,
3994                                 struct spp_context *spp_ctx)
3995 {
3996         int ret;
3997
3998         if (profile_id > 0)
3999                 return BT_SUCCESS;
4000
4001         ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
4002         if (ret != 0)
4003                 goto failed;
4004
4005         profile_xml_data = g_dbus_node_info_new_for_xml(profile_xml, NULL);
4006
4007         profile_id = g_dbus_connection_register_object(conn, spp_ctx->spp_path,
4008                                         profile_xml_data->interfaces[0],
4009                                         &profile_interface,
4010                                         spp_ctx, NULL, NULL);
4011
4012         if (profile_id == 0)
4013                 goto failed;
4014
4015         return BT_SUCCESS;
4016
4017 failed:
4018         return BT_ERROR_OPERATION_FAILED;
4019 }
4020
4021 static void unregister_profile_agent(void)
4022 {
4023         g_dbus_connection_unregister_object(conn, profile_id);
4024
4025         g_dbus_node_info_unref(profile_xml_data);
4026
4027         profile_id = 0;
4028 }
4029
4030 gchar *generate_object_path_from_uuid(const gchar *prefix, const gchar *uuid)
4031 {
4032         gchar *path, *iter;
4033
4034         path = g_strdup_printf("%s/%s", prefix, uuid);
4035
4036         iter = path;
4037
4038         while (*iter) {
4039                 if (*iter == '-')
4040                         *iter = '_';
4041
4042                 iter++;
4043         }
4044
4045         return path;
4046 }
4047
4048 int bt_spp_create_rfcomm(const char *uuid,
4049                         bt_spp_new_connection_cb new_connection_cb,
4050                         void *user_data)
4051 {
4052         enum bluez_error_type err_type;
4053         struct spp_context *spp_ctx;
4054         GVariantBuilder *opts;
4055         gchar *path;
4056         int ret;
4057
4058         if (uuid == NULL)
4059                 return BT_ERROR_INVALID_PARAMETER;
4060
4061         spp_ctx = create_spp_context();
4062         if (spp_ctx == NULL)
4063                 return BT_ERROR_OUT_OF_MEMORY;
4064
4065         path = generate_object_path_from_uuid(SPP_PROFILE_PATH, uuid);
4066
4067         spp_ctx->spp_path = path;
4068         spp_ctx->uuid = g_strdup(uuid);
4069         spp_ctx->new_connection = new_connection_cb;
4070         spp_ctx->new_connection_data = user_data;
4071
4072         ret = register_profile_agent(path, spp_ctx);
4073         if (ret != BT_SUCCESS) {
4074                 free_spp_context(spp_ctx);
4075                 return ret;
4076         }
4077
4078         opts = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
4079         g_variant_builder_add(opts, "{sv}", "Name",
4080                                         g_variant_new("s", "spp"));
4081         g_variant_builder_add(opts, "{sv}", "Version",
4082                                         g_variant_new("q", 1));
4083
4084         err_type = bluez_profile_register_profile_sync(path, uuid, opts);
4085
4086         if (err_type == ERROR_INVALID_ARGUMENTS) {
4087                 unregister_profile_agent();
4088
4089                 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
4090
4091                 free_spp_context(spp_ctx);
4092
4093                 return BT_ERROR_OPERATION_FAILED;
4094         }
4095
4096         spp_ctx_list = g_list_append(spp_ctx_list, spp_ctx);
4097
4098         return BT_SUCCESS;
4099 }
4100
4101 int bt_spp_destroy_rfcomm(const char *uuid)
4102 {
4103         struct spp_context *spp_ctx;
4104
4105         if (uuid == NULL)
4106                 return BT_ERROR_INVALID_PARAMETER;
4107
4108         spp_ctx = find_spp_context_from_uuid(uuid);
4109         if (spp_ctx == NULL) {
4110                 WARN("no specified uuid");
4111                 return BT_ERROR_OPERATION_FAILED;
4112         }
4113
4114         bluez_profile_unregister_profile(spp_ctx->spp_path, NULL, NULL);
4115
4116         unregister_profile_agent();
4117
4118         release_name_on_dbus(BLUEZ_AGENT_SERVICE);
4119
4120         spp_ctx_list = g_list_remove(spp_ctx_list, spp_ctx);
4121
4122         g_io_channel_shutdown(spp_ctx->channel, TRUE, NULL);
4123
4124         g_io_channel_unref(spp_ctx->channel);
4125
4126         free_spp_context(spp_ctx);
4127
4128         return BT_SUCCESS;
4129 }
4130
4131 int bt_spp_connect_rfcomm(const char *remote_address,
4132                                         const char *service_uuid)
4133 {
4134         bluez_device_t *device;
4135
4136         DBG("");
4137
4138         if (!remote_address || !service_uuid)
4139                 return BT_ERROR_INVALID_PARAMETER;
4140
4141         if (initialized == false)
4142                 return BT_ERROR_NOT_INITIALIZED;
4143
4144         if (default_adapter == NULL)
4145                 return BT_ERROR_ADAPTER_NOT_FOUND;
4146
4147         device = bluez_adapter_get_device_by_address(default_adapter,
4148                                                         remote_address);
4149         if (device == NULL)
4150                 return BT_ERROR_OPERATION_FAILED;
4151
4152         bluez_device_connect_profile(device, service_uuid,
4153                                         profile_connect_callback);
4154
4155         return BT_SUCCESS;
4156 }
4157
4158 int bt_spp_disconnect_rfcomm(const char *remote_address,
4159                                         const char *service_uuid)
4160 {
4161         bluez_device_t *device;
4162
4163         DBG("");
4164
4165         if (!remote_address || !service_uuid)
4166                 return BT_ERROR_INVALID_PARAMETER;
4167
4168         if (initialized == false)
4169                 return BT_ERROR_NOT_INITIALIZED;
4170
4171         if (default_adapter == NULL)
4172                 return BT_ERROR_ADAPTER_NOT_FOUND;
4173
4174         device = bluez_adapter_get_device_by_address(default_adapter,
4175                                                         remote_address);
4176         if (device == NULL)
4177                 return BT_ERROR_OPERATION_FAILED;
4178
4179         bluez_device_disconnect_profile(device, service_uuid,
4180                                         profile_disconnect_callback);
4181
4182         return BT_SUCCESS;
4183 }
4184
4185 int bt_spp_accept(bt_req_t *requestion)
4186 {
4187         GDBusMethodInvocation *invocation = requestion;
4188
4189         bt_agent_simple_accept(invocation);
4190
4191         return BT_SUCCESS;
4192 }
4193
4194 int bt_spp_reject(bt_req_t *requestion)
4195 {
4196         GDBusMethodInvocation *invocation = requestion;
4197
4198         bt_agent_simple_reject(invocation);
4199
4200         return BT_SUCCESS;
4201 }
4202
4203 int bt_spp_set_connection_requested_cb(bt_spp_connection_requested_cb callback,
4204                                         void *user_data)
4205 {
4206         struct spp_connection_requested_cb_node *node_data;
4207
4208         if (callback == NULL)
4209                 return BT_ERROR_INVALID_PARAMETER;
4210
4211         if (spp_connection_requested_node) {
4212                 DBG("spp connection requested callback already set.");
4213                 return BT_ERROR_ALREADY_DONE;
4214         }
4215
4216         node_data = g_new0(struct spp_connection_requested_cb_node, 1);
4217         if (node_data == NULL) {
4218                 ERROR("no memory");
4219                 return BT_ERROR_OUT_OF_MEMORY;
4220         }
4221
4222         node_data->cb = callback;
4223         node_data->user_data = user_data;
4224
4225         spp_connection_requested_node = node_data;
4226
4227         return BT_SUCCESS;
4228 }
4229
4230 int bt_spp_unset_connection_requested_cb(void)
4231 {
4232         DBG("");
4233
4234         if (initialized == false)
4235                 return BT_ERROR_NOT_INITIALIZED;
4236
4237         if (default_adapter == NULL)
4238                 return BT_ERROR_ADAPTER_NOT_FOUND;
4239
4240         if (!spp_connection_requested_node)
4241                 return BT_SUCCESS;
4242
4243         g_free(spp_connection_requested_node);
4244         spp_connection_requested_node = NULL;
4245
4246         return BT_SUCCESS;
4247 }
4248
4249 int bt_spp_send_data(int fd, const char *data, int length)
4250 {
4251         struct spp_context *spp_ctx;
4252         gsize written = 0, count = 0;
4253         GIOStatus status;
4254
4255         if (fd < 0)
4256                 return BT_ERROR_INVALID_PARAMETER;
4257
4258         spp_ctx = find_spp_context_from_fd(fd);
4259         if (spp_ctx == NULL) {
4260                 WARN("no specified fd");
4261                 return BT_ERROR_OPERATION_FAILED;
4262         }
4263
4264         do {
4265                 status = g_io_channel_write_chars(spp_ctx->channel, data,
4266                                                 length, &count, NULL);
4267
4268                 written += count;
4269
4270         } while (status != G_IO_STATUS_ERROR && written < length);
4271
4272         if (status == G_IO_STATUS_ERROR)
4273                 return BT_ERROR_OPERATION_FAILED;
4274
4275         return BT_SUCCESS;
4276 }
4277
4278 int bt_spp_set_data_received_cb(bt_spp_data_received_cb callback,
4279                                                 void *user_data)
4280 {
4281         struct spp_data_received_cb_node *node_data;
4282
4283         if (initialized == false)
4284                 return BT_ERROR_NOT_INITIALIZED;
4285
4286         if (callback == NULL)
4287                 return BT_ERROR_INVALID_PARAMETER;
4288
4289         if (spp_data_received_node) {
4290                 DBG("SPP data received callback already set.");
4291                 return BT_ERROR_ALREADY_DONE;
4292         }
4293
4294         node_data = g_new0(struct spp_data_received_cb_node, 1);
4295         if (node_data == NULL) {
4296                 ERROR("no memory");
4297                 return BT_ERROR_OUT_OF_MEMORY;
4298         }
4299
4300         node_data->cb = callback;
4301         node_data->user_data = user_data;
4302
4303         spp_data_received_node = node_data;
4304
4305         return BT_SUCCESS;
4306 }
4307
4308 int bt_spp_unset_data_received_cb(void)
4309 {
4310         DBG("");
4311
4312         if (initialized == false)
4313                 return BT_ERROR_NOT_INITIALIZED;
4314
4315         if (!spp_data_received_node)
4316                 return BT_SUCCESS;
4317
4318         g_free(spp_data_received_node);
4319         spp_data_received_node = NULL;
4320
4321         return BT_SUCCESS;
4322 }
4323
4324 int bt_socket_create_rfcomm(const char *service_uuid, int *socket_fd)
4325 {
4326         struct spp_context *spp_ctx;
4327         int ret;
4328
4329         if (!service_uuid || !socket_fd)
4330                 return BT_ERROR_INVALID_PARAMETER;
4331
4332         ret = bt_spp_create_rfcomm(service_uuid, NULL, NULL);
4333         if (ret != BT_SUCCESS)
4334                 return ret;
4335
4336         spp_ctx = find_spp_context_from_uuid(service_uuid);
4337         if (spp_ctx == NULL)
4338                 return BT_ERROR_OPERATION_FAILED;
4339
4340         *socket_fd = spp_ctx->fd;
4341
4342         return BT_SUCCESS;
4343 }
4344
4345 int bt_socket_destroy_rfcomm(int socket_fd)
4346 {
4347         struct spp_context *spp_ctx;
4348
4349         spp_ctx = find_spp_context_from_socketfd(socket_fd);
4350         if (!spp_ctx)
4351                 return BT_ERROR_OPERATION_FAILED;
4352
4353         return bt_spp_destroy_rfcomm(spp_ctx->uuid);
4354 }
4355
4356 int bt_socket_connect_rfcomm(const char *remote_address,
4357                                 const char *service_uuid)
4358 {
4359         struct spp_context *spp_ctx;
4360         int ret;
4361
4362         if (!remote_address || !service_uuid)
4363                 return BT_ERROR_INVALID_PARAMETER;
4364
4365         spp_ctx = find_spp_context_from_uuid(service_uuid);
4366         if (spp_ctx)
4367                 goto done;
4368
4369         /* BlueZ 5.x should create_rfcomm using a specify UUID,
4370          * then it can connect remote device.
4371          */
4372         ret = bt_spp_create_rfcomm(service_uuid, NULL, NULL);
4373         if (ret != BT_SUCCESS)
4374                 return ret;
4375
4376         spp_ctx = find_spp_context_from_uuid(service_uuid);
4377         if (!spp_ctx)
4378                 return BT_ERROR_OPERATION_FAILED;
4379
4380 done:
4381         if (!spp_ctx->remote_address) {
4382                 spp_ctx->remote_address = g_strdup(remote_address);
4383                 spp_ctx->role = BT_SOCKET_CLIENT;
4384         }
4385
4386         return bt_spp_connect_rfcomm(remote_address, service_uuid);
4387 }
4388
4389 int bt_socket_disconnect_rfcomm(int socket_fd)
4390 {
4391         struct spp_context *spp_ctx;
4392
4393         spp_ctx = find_spp_context_from_fd(socket_fd);
4394         if (!spp_ctx)
4395                 return BT_ERROR_OPERATION_FAILED;
4396
4397         return bt_spp_disconnect_rfcomm(spp_ctx->remote_address,
4398                                         spp_ctx->uuid);
4399 }
4400
4401 int bt_socket_listen(int socket_fd, int max_pending_connections)
4402 {
4403         struct spp_context *spp_ctx;
4404
4405         spp_ctx = find_spp_context_from_socketfd(socket_fd);
4406         if (spp_ctx == NULL)
4407                 return BT_ERROR_OPERATION_FAILED;
4408
4409         if (max_pending_connections > 0)
4410                 spp_ctx->max_pending = max_pending_connections;
4411         else
4412                 spp_ctx->max_pending = -1;
4413
4414         return BT_SUCCESS;
4415 }
4416
4417 int bt_socket_listen_and_accept_rfcomm(int socket_fd,
4418                                 int max_pending_connections)
4419 {
4420         struct spp_context *spp_ctx;
4421
4422         spp_ctx = find_spp_context_from_socketfd(socket_fd);
4423         if (spp_ctx == NULL)
4424                 return BT_ERROR_OPERATION_FAILED;
4425
4426         if (max_pending_connections > 0)
4427                 spp_ctx->max_pending = max_pending_connections;
4428         else
4429                 spp_ctx->max_pending = -1;
4430
4431         spp_ctx->is_accept = true;
4432
4433         return BT_SUCCESS;
4434 }
4435
4436 int bt_socket_accept(int requested_socket_fd, int *connected_socket_fd)
4437 {
4438         struct spp_context *spp_ctx;
4439
4440         if (connected_socket_fd == NULL)
4441                 return BT_ERROR_INVALID_PARAMETER;
4442
4443         spp_ctx = find_spp_context_from_socketfd(requested_socket_fd);
4444         if (spp_ctx == NULL)
4445                 return BT_ERROR_OPERATION_FAILED;
4446
4447         bt_spp_accept(spp_ctx->requestion);
4448
4449         if (spp_ctx->max_pending > 0)
4450                 spp_ctx->max_pending--;
4451
4452         /* BlueZ 5.x GAP.
4453          * Note: this connected_socket_fd maybe invalid, because
4454          * connected_socket_fd should return by connection_state_changed,
4455          */
4456         if (spp_ctx->channel == NULL)
4457                 *connected_socket_fd = -1;
4458         else
4459                 *connected_socket_fd =
4460                                 g_io_channel_unix_get_fd(spp_ctx->channel);
4461
4462         return BT_SUCCESS;
4463 }
4464
4465 int bt_socket_reject(int socket_fd)
4466 {
4467         struct spp_context *spp_ctx;
4468
4469         spp_ctx = find_spp_context_from_socketfd(socket_fd);
4470         if (spp_ctx == NULL)
4471                 return BT_ERROR_OPERATION_FAILED;
4472
4473         bt_spp_reject(spp_ctx->requestion);
4474
4475         if (spp_ctx->max_pending >= 0)
4476                 spp_ctx->max_pending++;
4477
4478         return BT_SUCCESS;
4479 }
4480
4481 int bt_socket_send_data(int socket_fd, const char *data, int length)
4482 {
4483         return bt_spp_send_data(socket_fd, data, length);
4484 }
4485
4486 int bt_socket_set_data_received_cb(bt_socket_data_received_cb callback,
4487                                                         void *user_data)
4488 {
4489         return bt_spp_set_data_received_cb(
4490                                 (bt_spp_data_received_cb)callback, user_data);
4491 }
4492
4493 int bt_socket_set_connection_requested_cb(
4494                                 bt_socket_connection_requested_cb callback,
4495                                 void *user_data)
4496 {
4497         struct socket_connection_requested_cb_node *node_data;
4498
4499         if (initialized == false)
4500                 return BT_ERROR_NOT_INITIALIZED;
4501
4502         if (callback == NULL)
4503                 return BT_ERROR_INVALID_PARAMETER;
4504
4505         if (spp_connection_requested_node) {
4506                 DBG("socket connection requested callback already set.");
4507                 return BT_ERROR_ALREADY_DONE;
4508         }
4509
4510         node_data = g_new0(struct socket_connection_requested_cb_node, 1);
4511         if (node_data == NULL) {
4512                 ERROR("no memory");
4513                 return BT_ERROR_OUT_OF_MEMORY;
4514         }
4515
4516         node_data->cb = callback;
4517         node_data->user_data = user_data;
4518
4519         socket_connection_requested_node = node_data;
4520
4521         return BT_SUCCESS;
4522 }
4523
4524 int bt_socket_set_connection_state_changed_cb(
4525                         bt_socket_connection_state_changed_cb callback,
4526                         void *user_data)
4527 {
4528         struct socket_connection_state_changed_cb_node *node_data;
4529
4530         if (initialized == false)
4531                 return BT_ERROR_NOT_INITIALIZED;
4532
4533         if (callback == NULL)
4534                 return BT_ERROR_INVALID_PARAMETER;
4535
4536         if (socket_connection_state_node) {
4537                 DBG("socket connection state changed callback already set.");
4538                 return BT_ERROR_ALREADY_DONE;
4539         }
4540
4541         node_data = g_new0(struct socket_connection_state_changed_cb_node, 1);
4542         if (node_data == NULL) {
4543                 ERROR("no memory");
4544                 return BT_ERROR_OUT_OF_MEMORY;
4545         }
4546
4547         node_data->cb = callback;
4548         node_data->user_data = user_data;
4549
4550         socket_connection_state_node = node_data;
4551
4552         return BT_SUCCESS;
4553
4554         return BT_SUCCESS;
4555 }
4556
4557 int bt_socket_unset_connection_requested_cb(void)
4558 {
4559         if (initialized == false)
4560                 return BT_ERROR_NOT_INITIALIZED;
4561
4562         if (!socket_connection_requested_node)
4563                 return BT_SUCCESS;
4564
4565         g_free(socket_connection_requested_node);
4566         socket_connection_requested_node = NULL;
4567
4568         return BT_SUCCESS;
4569 }
4570
4571 int bt_socket_unset_data_received_cb(void)
4572 {
4573         return bt_spp_unset_data_received_cb();
4574 }
4575
4576 int bt_socket_unset_connection_state_changed_cb(void)
4577 {
4578         if (initialized == false)
4579                 return BT_ERROR_NOT_INITIALIZED;
4580
4581         if (!socket_connection_state_node)
4582                 return BT_SUCCESS;
4583
4584         g_free(socket_connection_state_node);
4585         socket_connection_state_node = NULL;
4586
4587         return BT_SUCCESS;
4588 }
4589
4590 static void address2ident(const char *name, char *ident)
4591 {
4592         unsigned int index;
4593
4594         for (index = 0; index < BLUETOOTH_IDENT_LEN; ++index) {
4595                 ident[index * 2] = name[index * 3];
4596                 ident[index * 2 + 1] = name[index * 3 + 1];
4597         }
4598
4599         ident[BLUETOOTH_IDENT_LEN * 2] = '\0';
4600 }
4601
4602 char *get_connman_service_path(const char *adapter_name,
4603                                 const char *remote_name)
4604 {
4605         char adapter_ident[BLUETOOTH_IDENT_LEN * 2 + 1] = { 0 };
4606         char remote_ident[BLUETOOTH_IDENT_LEN * 2 + 1] = { 0 };
4607         unsigned int len;
4608         char *path;
4609
4610         len = strlen(CONNMAN_BLUETOOTH_SERVICE_PREFIX) +
4611                         BLUETOOTH_IDENT_LEN * 4 + 2;
4612
4613         path = calloc(len, sizeof(char));
4614         if (path == NULL)
4615                 return NULL;
4616
4617         address2ident(adapter_name, adapter_ident);
4618         address2ident(remote_name, remote_ident);
4619
4620         sprintf(path, "%s%s%s%s", CONNMAN_BLUETOOTH_SERVICE_PREFIX,
4621                                 adapter_ident, "_", remote_ident);
4622
4623         return path;
4624 }
4625
4626 int bt_panu_connect(const char *remote_address, bt_panu_service_type_e type)
4627 {
4628         GDBusConnection *connection;
4629         bt_device_info_s *device_bond_info;
4630         char *path, *adapter_address;
4631         bluez_device_t *device;
4632         bool is_bonded;
4633         GError *error = NULL;
4634         int ret;
4635
4636         DBG("");
4637
4638         if (initialized == false)
4639                 return BT_ERROR_NOT_INITIALIZED;
4640
4641         if (default_adapter == NULL)
4642                 return BT_ERROR_ADAPTER_NOT_FOUND;
4643
4644         if (!remote_address)
4645                 return BT_ERROR_INVALID_PARAMETER;
4646
4647         device = bluez_adapter_get_device_by_address(default_adapter,
4648                                                         remote_address);
4649
4650         if (device == NULL)
4651                 return BT_ERROR_OPERATION_FAILED;
4652
4653         device_bond_info = get_device_info(device);
4654         is_bonded = device_bond_info->is_bonded;
4655         free_device_info(device_bond_info);
4656
4657         if (is_bonded == FALSE)
4658                 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
4659
4660         adapter_address = bluez_adapter_get_property_address(default_adapter);
4661         if (adapter_address == NULL)
4662                 return BT_ERROR_OPERATION_FAILED;
4663
4664         path = get_connman_service_path(adapter_address, remote_address);
4665         if (path == NULL) {
4666                 free(adapter_address);
4667                 return BT_ERROR_OPERATION_FAILED;
4668         }
4669
4670         DBG("path %s", path);
4671
4672         connection = get_system_dbus_connect();
4673         if (connection == NULL) {
4674                 ret = BT_ERROR_OPERATION_FAILED;
4675                 goto done;
4676         }
4677
4678         g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME, path,
4679                                         "net.connman.Service", "Connect",
4680                                         NULL, NULL, 0, -1, NULL, &error);
4681
4682         if (error) {
4683                 DBG("error %s", error->message);
4684                 g_error_free(error);
4685                 ret = BT_ERROR_OPERATION_FAILED;
4686
4687                 goto done;
4688         }
4689
4690         ret = BT_SUCCESS;
4691
4692 done:
4693         free(path);
4694         free(adapter_address);
4695
4696         return ret;
4697 }
4698
4699 int bt_panu_disconnect(const char *remote_address)
4700 {
4701         GDBusConnection *connection;
4702         char *path, *adapter_address;
4703         bluez_device_t *device;
4704         int connected, ret;
4705         GError *error = NULL;
4706
4707         DBG("");
4708
4709         if (initialized == false)
4710                 return BT_ERROR_NOT_INITIALIZED;
4711
4712         if (default_adapter == NULL)
4713                 return BT_ERROR_ADAPTER_NOT_FOUND;
4714
4715         if (!remote_address)
4716                 return BT_ERROR_INVALID_PARAMETER;
4717
4718         device = bluez_adapter_get_device_by_address(default_adapter,
4719                                                         remote_address);
4720
4721         if (device == NULL)
4722                 return BT_ERROR_OPERATION_FAILED;
4723
4724         bluez_device_network_get_property_connected(device, &connected);
4725         if (connected == FALSE)
4726                 return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
4727
4728         adapter_address = bluez_adapter_get_property_address(default_adapter);
4729         if (adapter_address == NULL)
4730                 return BT_ERROR_OPERATION_FAILED;
4731
4732         path = get_connman_service_path(adapter_address, remote_address);
4733         if (path == NULL) {
4734                 free(adapter_address);
4735                 return BT_ERROR_OPERATION_FAILED;
4736         }
4737
4738         DBG("path %s", path);
4739
4740         connection = get_system_dbus_connect();
4741         if (connection == NULL) {
4742                 ret = BT_ERROR_OPERATION_FAILED;
4743                 goto done;
4744         }
4745
4746         g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME, path,
4747                                         "net.connman.Service", "Disconnect",
4748                                         NULL, NULL, 0, -1, NULL, &error);
4749
4750         if (error) {
4751                 DBG("error %s", error->message);
4752                 g_error_free(error);
4753                 ret = BT_ERROR_OPERATION_FAILED;
4754
4755                 goto done;
4756         }
4757
4758         ret = BT_SUCCESS;
4759
4760 done:
4761         free(path);
4762         free(adapter_address);
4763
4764         return ret;
4765 }
4766
4767 int bt_panu_set_connection_state_changed_cb(
4768                                 bt_panu_connection_state_changed_cb callback,
4769                                 void *user_data)
4770 {
4771         struct panu_connection_state_changed_cb_node *node_data;
4772         GList *list;
4773
4774         DBG("");
4775
4776         if (callback == NULL)
4777                 return BT_ERROR_INVALID_PARAMETER;
4778
4779         if (panu_state_node) {
4780                 DBG("network connected state changed callback already set.");
4781                 return BT_ERROR_ALREADY_DONE;
4782         }
4783
4784         node_data = g_new0(struct panu_connection_state_changed_cb_node, 1);
4785         if (node_data == NULL) {
4786                 ERROR("no memory");
4787                 return BT_ERROR_OUT_OF_MEMORY;
4788         }
4789
4790         node_data->cb = callback;
4791         node_data->user_data = user_data;
4792
4793         panu_state_node = node_data;
4794
4795         dev_property_callback_flags |= DEV_PROP_FLAG_PANU_CONNECT;
4796
4797         if (!default_adapter)
4798                 return BT_SUCCESS;
4799
4800         list = bluez_adapter_get_devices(default_adapter);
4801         foreach_device_property_callback(list, DEV_PROP_FLAG_PANU_CONNECT);
4802
4803         g_list_free(list);
4804
4805         return BT_SUCCESS;
4806 }
4807
4808 int bt_panu_unset_connection_state_changed_cb(void)
4809 {
4810         GList *list;
4811         DBG("");
4812
4813         if (initialized == false)
4814                 return BT_ERROR_NOT_INITIALIZED;
4815
4816         if (default_adapter == NULL)
4817                 return BT_ERROR_ADAPTER_NOT_FOUND;
4818
4819         if (!panu_state_node)
4820                 return BT_SUCCESS;
4821
4822         dev_property_callback_flags &= ~DEV_PROP_FLAG_PANU_CONNECT;
4823
4824         list = bluez_adapter_get_devices(default_adapter);
4825         foreach_device_property_callback(list, DEV_PROP_FLAG_PANU_CONNECT);
4826
4827         g_free(panu_state_node);
4828         panu_state_node = NULL;
4829
4830         return BT_SUCCESS;
4831 }
4832
4833 static int connman_set_tethering(bool tethering)
4834 {
4835         GDBusConnection *connection;
4836         GVariant *tethering_val;
4837         GError *error = NULL;
4838
4839         if (initialized == false)
4840                 return BT_ERROR_NOT_INITIALIZED;
4841
4842         if (default_adapter == NULL)
4843                 return BT_ERROR_ADAPTER_NOT_FOUND;
4844
4845         connection = get_system_dbus_connect();
4846         if (connection == NULL)
4847                 return BT_ERROR_OPERATION_FAILED;
4848
4849         tethering_val = g_variant_new("b", tethering);
4850
4851         g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME,
4852                                 CONNMAN_BLUETOOTH_TECHNOLOGY_PATH,
4853                                 CONNMAN_BLUETOTOH_TECHNOLOGY_INTERFACE,
4854                                 "SetProperty",
4855                                 g_variant_new("(sv)",
4856                                         "Tethering", tethering_val),
4857                                 NULL, 0, -1, NULL, &error);
4858
4859         if (error) {
4860                 DBG("error %s", error->message);
4861                 g_error_free(error);
4862                 return BT_ERROR_OPERATION_FAILED;
4863         }
4864
4865         return BT_SUCCESS;
4866 }
4867
4868 int bt_nap_activate(void)
4869 {
4870         return connman_set_tethering(true);
4871 }
4872
4873 int bt_nap_deactivate(void)
4874 {
4875         return connman_set_tethering(false);
4876 }
4877
4878 int bt_hdp_register_sink_app(unsigned short data_type, char **app_id)
4879 {
4880         int result = BT_ERROR_NONE;
4881
4882         DBG("");
4883
4884         if (initialized == false)
4885                 return BT_ERROR_NOT_INITIALIZED;
4886
4887         if (default_adapter == NULL)
4888                 return BT_ERROR_ADAPTER_NOT_FOUND;
4889
4890         result = bluetooth_hdp_activate(data_type,
4891                         HDP_ROLE_SINK, HDP_QOS_ANY, app_id);
4892         return result;
4893 }
4894
4895 int bt_hdp_unregister_sink_app(const char *app_id)
4896 {
4897         int result = BT_ERROR_NONE;
4898
4899         DBG("");
4900
4901         if (initialized == false)
4902                 return BT_ERROR_NOT_INITIALIZED;
4903
4904         if (default_adapter == NULL)
4905                 return BT_ERROR_ADAPTER_NOT_FOUND;
4906
4907         result = bluetooth_hdp_deactivate(app_id);
4908
4909         return result;
4910 }
4911
4912 int bt_hdp_send_data(unsigned int channel, const char *data,
4913                                                 unsigned int size)
4914 {
4915         int result = BT_ERROR_NONE;
4916
4917         DBG("");
4918
4919         if (initialized == false)
4920                 return BT_ERROR_NOT_INITIALIZED;
4921
4922         if (default_adapter == NULL)
4923                 return BT_ERROR_ADAPTER_NOT_FOUND;
4924
4925         result = bluetooth_hdp_send_data(channel, data, size);
4926
4927         return result;
4928 }
4929
4930 int bt_hdp_connect_to_source(const char *remote_address,
4931                                                 const char *app_id)
4932 {
4933         int result = BT_ERROR_NONE;
4934         bluetooth_device_address_t addr_hex = { {0,} };
4935
4936         DBG("");
4937
4938         if (initialized == false)
4939                 return BT_ERROR_NOT_INITIALIZED;
4940
4941         if (default_adapter == NULL)
4942                 return BT_ERROR_ADAPTER_NOT_FOUND;
4943
4944         if (remote_address == NULL)
4945                 return BT_ERROR_INVALID_PARAMETER;
4946
4947         convert_address_to_hex(&addr_hex, remote_address);
4948
4949         result = bluetooth_hdp_connect(app_id, HDP_QOS_ANY, &addr_hex);
4950
4951         return result;
4952 }
4953
4954 int bt_hdp_disconnect(const char *remote_address, unsigned int channel)
4955 {
4956         int result = BT_ERROR_NONE;
4957         bluetooth_device_address_t addr_hex = { {0,} };
4958
4959         DBG("");
4960
4961         if (initialized == false)
4962                 return BT_ERROR_NOT_INITIALIZED;
4963
4964         if (default_adapter == NULL)
4965                 return BT_ERROR_ADAPTER_NOT_FOUND;
4966
4967         if (remote_address == NULL)
4968                 return BT_ERROR_INVALID_PARAMETER;
4969
4970         convert_address_to_hex(&addr_hex, remote_address);
4971
4972         result = bluetooth_hdp_disconnect(channel, &addr_hex);
4973
4974         return result;
4975 }
4976
4977 int bt_hdp_set_connection_state_changed_cb(bt_hdp_connected_cb connected_cb,
4978                 bt_hdp_disconnected_cb disconnected_cb, void *user_data)
4979 {
4980         struct hdp_connection_changed_cb_node *node_data = NULL;
4981         GList *list;
4982
4983         if (connected_cb == NULL || disconnected_cb == NULL)
4984                 return BT_ERROR_INVALID_PARAMETER;
4985
4986         if (hdp_state_node) {
4987                 DBG("hdp state callback already set.");
4988                 return BT_ERROR_ALREADY_DONE;
4989         }
4990
4991         node_data = g_new0(struct hdp_connection_changed_cb_node, 1);
4992         if (node_data == NULL) {
4993                 ERROR("no memory");
4994                 return BT_ERROR_OUT_OF_MEMORY;
4995         }
4996
4997         node_data->conn_cb = connected_cb;
4998         node_data->disconn_cb = disconnected_cb;
4999         node_data->user_data = user_data;
5000
5001         hdp_state_node = node_data;
5002
5003         dev_property_callback_flags |= DEV_PROP_FLAG_HDP_CONNECT;
5004
5005         if (!default_adapter)
5006                 return BT_SUCCESS;
5007
5008         list = bluez_adapter_get_devices(default_adapter);
5009         foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_CONNECT);
5010
5011         g_list_free(list);
5012
5013         return BT_SUCCESS;
5014 }
5015
5016 int bt_hdp_unset_connection_state_changed_cb(void)
5017 {
5018         GList *list;
5019
5020         DBG("");
5021
5022         if (initialized == false)
5023                 return BT_ERROR_NOT_INITIALIZED;
5024
5025         if (!hdp_state_node)
5026                 return BT_SUCCESS;
5027
5028         dev_property_callback_flags &= ~DEV_PROP_FLAG_HDP_CONNECT;
5029
5030         list = bluez_adapter_get_devices(default_adapter);
5031         foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_CONNECT);
5032
5033         g_free(hdp_state_node);
5034         hdp_state_node = NULL;
5035
5036         return BT_SUCCESS;
5037 }
5038
5039 int bt_hdp_set_data_received_cb(bt_hdp_data_received_cb callback,
5040                                                         void *user_data)
5041 {
5042         struct hdp_set_data_received_cb_node *node_data = NULL;
5043         GList *list;
5044
5045         DBG("");
5046
5047         if (callback == NULL)
5048                 return BT_ERROR_INVALID_PARAMETER;
5049
5050         if (hdp_set_data_received_node) {
5051                 DBG("hdp set data receive dnode callback already set.");
5052                 return BT_ERROR_ALREADY_DONE;
5053         }
5054
5055         node_data = g_new0(struct hdp_set_data_received_cb_node, 1);
5056         if (node_data == NULL) {
5057                 ERROR("no memory");
5058                 return BT_ERROR_OUT_OF_MEMORY;
5059         }
5060
5061         node_data->cb = callback;
5062         node_data->user_data = user_data;
5063
5064         hdp_set_data_received_node = node_data;
5065
5066         dev_property_callback_flags |= DEV_PROP_FLAG_HDP_DATA;
5067
5068         if (!default_adapter)
5069                 return BT_SUCCESS;
5070
5071         list = bluez_adapter_get_devices(default_adapter);
5072         foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_DATA);
5073
5074         g_list_free(list);
5075
5076         return BT_SUCCESS;
5077 }
5078
5079 int bt_hdp_unset_data_received_cb(void)
5080 {
5081         GList *list;
5082
5083         DBG("");
5084
5085         if (initialized == false)
5086                 return BT_ERROR_NOT_INITIALIZED;
5087
5088         if (!hdp_set_data_received_node)
5089                 return BT_SUCCESS;
5090
5091         dev_property_callback_flags &= ~DEV_PROP_FLAG_HDP_DATA;
5092
5093         list = bluez_adapter_get_devices(default_adapter);
5094         foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_DATA);
5095
5096         g_free(hdp_set_data_received_node);
5097         hdp_set_data_received_node = NULL;
5098
5099         return BT_SUCCESS;
5100 }
5101
5102 int bt_device_connect_le(bt_device_gatt_state_changed_cb callback,
5103                         const char *remote_address)
5104 {
5105         bluez_device_t *device;
5106
5107         struct device_connect_cb_node *node_data = NULL;
5108
5109         DBG("");
5110
5111         if (initialized == false)
5112                 return BT_ERROR_NOT_INITIALIZED;
5113
5114         if (default_adapter == NULL)
5115                 return BT_ERROR_ADAPTER_NOT_FOUND;
5116
5117         if (callback == NULL)
5118                 return BT_ERROR_INVALID_PARAMETER;
5119
5120         device = bluez_adapter_get_device_by_address(default_adapter,
5121                                                         remote_address);
5122         if (device == NULL)
5123                 return BT_ERROR_OPERATION_FAILED;
5124
5125         if (device_connect_node) {
5126                 DBG("device disconnect callback already set.");
5127                 return BT_ERROR_ALREADY_DONE;
5128         }
5129
5130         node_data =
5131                 g_new0(struct device_connect_cb_node, 1);
5132         if (node_data == NULL) {
5133                 ERROR("no memory");
5134                 return BT_ERROR_OUT_OF_MEMORY;
5135         }
5136
5137         node_data->cb = callback;
5138         node_data->user_data = NULL;
5139
5140         device_connect_node = node_data;
5141
5142         _bt_update_bluetooth_callbacks();
5143
5144         bluez_device_connect_le(device);
5145
5146         return BT_SUCCESS;
5147 }
5148
5149 int bt_device_disconnect_le(bt_device_gatt_state_changed_cb callback,
5150                         const char *remote_address)
5151 {
5152         bluez_device_t *device;
5153
5154         struct device_disconnect_cb_node *node_data = NULL;
5155
5156         DBG("");
5157
5158         if (initialized == false)
5159                 return BT_ERROR_NOT_INITIALIZED;
5160
5161         if (default_adapter == NULL)
5162                 return BT_ERROR_ADAPTER_NOT_FOUND;
5163
5164         if (callback == NULL)
5165                 return BT_ERROR_INVALID_PARAMETER;
5166
5167         device = bluez_adapter_get_device_by_address(default_adapter,
5168                                                         remote_address);
5169         if (device == NULL)
5170                 return BT_ERROR_OPERATION_FAILED;
5171
5172         if (device_disconnect_node) {
5173                 DBG("device disconnect callback already set.");
5174                 return BT_ERROR_ALREADY_DONE;
5175         }
5176
5177         node_data =
5178                 g_new0(struct device_disconnect_cb_node, 1);
5179         if (node_data == NULL) {
5180                 ERROR("no memory");
5181                 return BT_ERROR_OUT_OF_MEMORY;
5182         }
5183
5184         node_data->cb = callback;
5185         node_data->user_data = NULL;
5186
5187         device_disconnect_node = node_data;
5188
5189         _bt_update_bluetooth_callbacks();
5190
5191         bluez_device_disconnect_le(device);
5192
5193         return BT_SUCCESS;
5194 }
5195
5196 int bt_nap_set_connection_state_changed_cb(
5197                                 bt_nap_connection_state_changed_cb callback,
5198                                 void *user_data)
5199 {
5200         struct nap_connection_state_changed_cb_node *node_data;
5201
5202         DBG("");
5203
5204         if (callback == NULL)
5205                 return BT_ERROR_INVALID_PARAMETER;
5206
5207         if (nap_connection_state_changed_node) {
5208                 DBG("Powered state changed callback already set.");
5209                 return BT_ERROR_ALREADY_DONE;
5210         }
5211
5212         node_data = g_new0(struct nap_connection_state_changed_cb_node, 1);
5213         if (node_data == NULL) {
5214                 ERROR("no memory");
5215                 return BT_ERROR_OUT_OF_MEMORY;
5216         }
5217
5218         node_data->cb = callback;
5219         node_data->user_data = user_data;
5220
5221         nap_connection_state_changed_node = node_data;
5222
5223         _bt_update_bluetooth_callbacks();
5224
5225         return BT_SUCCESS;
5226 }
5227
5228 int bt_nap_unset_connection_state_changed_cb(void)
5229 {
5230         DBG("");
5231
5232         if (initialized == false)
5233                 return BT_ERROR_NOT_INITIALIZED;
5234
5235         if (default_adapter == NULL)
5236                 return BT_ERROR_ADAPTER_NOT_FOUND;
5237
5238         if (!adapter_name_node)
5239                 return BT_SUCCESS;
5240
5241         bluez_unset_nap_connection_state_cb();
5242
5243         g_free(nap_connection_state_changed_node);
5244         nap_connection_state_changed_node = NULL;
5245
5246         return BT_SUCCESS;
5247 }
5248
5249 static gboolean spp_is_device_connected(const char *address)
5250 {
5251         struct spp_context *spp_ctx;
5252         GList *list, *next;
5253
5254         DBG("");
5255
5256         for (list = g_list_first(spp_ctx_list); list; list = next) {
5257                 next = g_list_next(list);
5258
5259                 spp_ctx = list->data;
5260                 if (spp_ctx)
5261                         if (spp_ctx->channel &&
5262                                 g_strcmp0(spp_ctx->remote_address,
5263                                                 address) == 0)
5264                                 return true;
5265         }
5266
5267         return false;
5268 }
5269
5270 int bt_device_foreach_connected_profiles(
5271                         const char *remote_address,
5272                         bt_device_connected_profile callback,
5273                         void *user_data)
5274 {
5275         bluez_device_t *device;
5276         bt_device_info_s *device_info;
5277         gboolean rfcomm_connected;
5278         gboolean is_type;
5279         gboolean hid_connected = false;
5280
5281         DBG("");
5282
5283         if (initialized == false)
5284                 return BT_ERROR_NOT_INITIALIZED;
5285
5286         if (default_adapter == NULL)
5287                 return BT_ERROR_ADAPTER_NOT_FOUND;
5288
5289         if (!remote_address || !callback)
5290                 return BT_ERROR_INVALID_PARAMETER;
5291
5292         device = bluez_adapter_get_device_by_address(default_adapter,
5293                                                         remote_address);
5294         if (device == NULL)
5295                 return BT_ERROR_OPERATION_FAILED;
5296
5297         device_info = get_device_info(device);
5298
5299         if (device_info->is_connected == false)
5300                 return  BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
5301
5302         rfcomm_connected = spp_is_device_connected(remote_address);
5303         if (rfcomm_connected)
5304                 callback(BT_PROFILE_RFCOMM, user_data);
5305
5306         is_type = bluez_get_media_type(remote_address);
5307
5308         /*not check hfp and hsp connected, hfp is not ready*/
5309         /*todo hfp and hsp checking*/
5310
5311         if (is_type)
5312                 callback(BT_PROFILE_A2DP, user_data);
5313
5314         if (!(bluez_device_input_get_property_connected(device,
5315                                         &hid_connected))) {
5316                 if (hid_connected)
5317                         callback(BT_PROFILE_HID, user_data);
5318         }
5319
5320         free_device_info(device_info);
5321
5322         return BT_SUCCESS;
5323 }