3 * neard - Near Field Communication manager
5 * Copyright (C) 2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #define BLUEZ_SERVICE "org.bluez"
35 #define MANAGER_INTF BLUEZ_SERVICE ".Manager"
36 #define ADAPTER_INTF BLUEZ_SERVICE ".Adapter"
37 #define OOB_INTF BLUEZ_SERVICE ".OutOfBand"
38 #define DEFAULT_ADAPTER "DefaultAdapter"
39 #define ADAPTER_REMOVED "AdapterRemoved"
40 #define DEFAULT_ADAPTER_CHANGED "DefaultAdapterChanged"
41 #define MANAGER_PATH "/"
42 #define OOB_AGENT "/org/neard/agent/neard_oob"
44 #define BT_NOINPUTOUTPUT "NoInputNoOutput"
45 #define BT_DISPLAY_YESNO "DisplayYesNo"
48 #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
49 #define EIR_NAME_SHORT 0x08 /* shortened local name */
50 #define EIR_NAME_COMPLETE 0x09 /* complete local name */
52 /* Specific OOB EIRs */
53 #define EIR_CLASS_OF_DEVICE 0x0D /* class of device */
54 #define EIR_SP_HASH 0x0E /* simple pairing hash C */
55 #define EIR_SP_RANDOMIZER 0x0F /* simple pairing randomizer R */
57 #define EIR_DEVICE_ID 0x10 /* device ID */
58 #define EIR_SECURITY_MGR_FLAGS 0x11 /* security manager flags */
60 #define EIR_SIZE_LEN 1
61 #define EIR_HEADER_LEN (EIR_SIZE_LEN + 1)
62 #define BT_ADDRESS_SIZE 6
64 #define OOB_SP_SIZE 16
66 struct near_oob_data {
69 char *bd_addr; /* oob mandatory */
72 char *bt_name; /* short or long name */
74 int class_of_device; /* Class of device */
77 near_bool_t discoverable;
81 uint8_t *spair_hash; /* OOB hash Key */
82 uint8_t *spair_randomizer; /* OOB randomizer key */
83 uint8_t authentication[OOB_SP_SIZE]; /* On BT 2.0 */
84 uint8_t security_manager_oob_flags; /* see BT Core 4.0 */
87 static DBusConnection *bt_conn;
88 static struct near_oob_data bt_def_oob_data;
90 static int bt_do_pairing(struct near_oob_data *oob);
92 static void __bt_eir_free(struct near_oob_data *oob)
96 if (oob->def_adapter != NULL) {
97 g_free(oob->def_adapter);
98 oob->def_adapter = NULL;
101 if (oob->bd_addr != NULL) {
102 g_free(oob->bd_addr);
106 if (oob->bt_name != NULL) {
107 g_free(oob->bt_name);
111 if (oob->spair_hash != NULL) {
112 g_free(oob->spair_hash);
113 oob->spair_hash = NULL;
116 if (oob->spair_randomizer != NULL) {
117 g_free(oob->spair_randomizer);
118 oob->spair_randomizer = NULL;
124 static void bt_eir_free(struct near_oob_data *oob)
131 /* D-Bus helper functions */
132 static int bt_generic_call(DBusConnection *conn,
133 struct near_oob_data *oob, /* user data */
134 const char *dest, /* method call */
136 const char *interface,
138 DBusPendingCallNotifyFunction bt_cb, /* callback */
139 int type, ...) /* params */
142 DBusPendingCall *pending;
148 msg = dbus_message_new_method_call(dest, path, interface, method);
151 near_error("Unable to allocate new D-Bus %s message", method);
155 va_start(args, type);
157 if (!dbus_message_append_args_valist(msg, type, args)) {
164 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
165 near_error("Sending %s failed", method);
170 if (pending == NULL) {
171 near_error("D-Bus connection not available");
176 /* Prepare for notification */
177 dbus_pending_call_set_notify(pending, bt_cb, oob, NULL);
181 dbus_message_unref(msg);
185 static void bt_create_paired_device_cb(DBusPendingCall *pending,
190 struct near_oob_data *oob = user_data;
194 reply = dbus_pending_call_steal_reply(pending);
198 dbus_error_init(&error);
200 if (dbus_set_error_from_message(&error, reply)) {
201 near_error("%s", error.message);
202 dbus_error_free(&error);
206 near_info("Pairing done successfully !");
209 /* task completed - clean memory*/
212 dbus_message_unref(reply);
213 dbus_pending_call_unref(pending);
218 static int bt_create_paired_device(DBusConnection *conn,
219 struct near_oob_data *oob,
220 const char *capabilities)
222 const char *agent_path = OOB_AGENT;
224 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
225 oob->def_adapter, ADAPTER_INTF, "CreatePairedDevice",
226 bt_create_paired_device_cb,
228 DBUS_TYPE_STRING, &oob->bd_addr,
229 DBUS_TYPE_OBJECT_PATH, &agent_path,
230 DBUS_TYPE_STRING, &capabilities,
235 static void bt_oob_add_remote_data_cb(DBusPendingCall *pending, void *user_data)
239 struct near_oob_data *oob = user_data;
243 reply = dbus_pending_call_steal_reply(pending);
247 dbus_error_init(&error);
249 if (dbus_set_error_from_message(&error, reply))
252 near_info("OOB data added");
254 dbus_message_unref(reply);
255 dbus_pending_call_unref(pending);
257 /* Jump to the next: Pairing !!!*/
258 DBG("Try to pair devices...");
259 bt_create_paired_device(bt_conn, oob, BT_DISPLAY_YESNO);
263 near_error("%s", error.message);
264 dbus_error_free(&error);
268 dbus_message_unref(reply);
269 dbus_pending_call_unref(pending);
274 static int bt_oob_add_remote_data(DBusConnection *conn,
275 struct near_oob_data *oob)
277 int16_t hash_len = 16;
278 int16_t rdm_len = 16;
280 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
281 oob->def_adapter, OOB_INTF, "AddRemoteData",
282 bt_oob_add_remote_data_cb,
284 DBUS_TYPE_STRING, &oob->bd_addr,
286 DBUS_TYPE_BYTE, &oob->spair_hash, hash_len,
288 DBUS_TYPE_BYTE, &oob->spair_randomizer, rdm_len,
292 /* Pairing: JustWorks or OOB */
293 static int bt_do_pairing(struct near_oob_data *oob)
297 DBG("%s", oob->bd_addr);
299 /* Is this a *real* oob pairing or a "JustWork" */
300 if ((oob->spair_hash) && (oob->spair_randomizer))
301 err = bt_oob_add_remote_data(bt_conn, oob);
303 err = bt_create_paired_device(bt_conn, oob,
307 near_error("Pairing failed. Err[%d]", err);
314 static int extract_properties(DBusMessage *reply,
315 struct near_oob_data *oob)
321 DBusMessageIter array, dict;
323 if (dbus_message_iter_init(reply, &array) == FALSE)
326 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
329 dbus_message_iter_recurse(&array, &dict);
331 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
332 DBusMessageIter entry, value;
335 dbus_message_iter_recurse(&dict, &entry);
336 dbus_message_iter_get_basic(&entry, &key);
338 dbus_message_iter_next(&entry);
339 dbus_message_iter_recurse(&entry, &value);
341 if (g_str_equal(key, "Address") == TRUE) {
342 dbus_message_iter_get_basic(&value, &data);
344 /* Now, fill the local struct */
345 oob->bd_addr = g_try_malloc0(BT_ADDRESS_SIZE);
346 if (oob->bd_addr == NULL)
349 /* Address is like: "ff:ee:dd:cc:bb:aa" */
350 for (i = 5, j = 0 ; i >= 0; i--, j += 3)
351 oob->bd_addr[i] = strtol(data + j, NULL, 16);
352 DBG("local address: %s", data);
354 } else if (g_str_equal(key, "Name") == TRUE) {
355 dbus_message_iter_get_basic(&value, &data);
356 oob->bt_name = g_strdup(data);
357 if (oob->bt_name != NULL) {
358 oob->bt_name_len = strlen(oob->bt_name);
359 DBG("local name: %s", oob->bt_name);
362 } else if (g_str_equal(key, "Class") == TRUE) {
363 dbus_message_iter_get_basic(&value, &idata);
364 oob->class_of_device = idata;
366 } else if (g_str_equal(key, "Powered") == TRUE) {
367 dbus_message_iter_get_basic(&value, &idata);
368 oob->powered = idata;
370 } else if (g_str_equal(key, "Discoverable") == TRUE) {
371 dbus_message_iter_get_basic(&value, &idata);
372 oob->discoverable = idata;
374 } else if (g_str_equal(key, "Pairable") == TRUE) {
375 dbus_message_iter_get_basic(&value, &idata);
376 oob->pairable = idata;
378 } else if (g_str_equal(key, "UUIDs") == TRUE) {
379 oob->uuids_len = sizeof(value);
380 oob->uuids = g_try_malloc0(oob->uuids_len);
381 if (oob->uuids == NULL)
383 memcpy(oob->uuids, &value, oob->uuids_len);
386 dbus_message_iter_next(&dict);
392 static int bt_parse_properties(DBusMessage *reply, void *user_data)
394 struct near_oob_data *bt_props = user_data;
399 g_free(bt_props->bd_addr);
400 g_free(bt_props->bt_name);
402 /* Grab properties from dbus */
403 if (extract_properties(reply, bt_props) < 0)
409 g_free(bt_props->bd_addr);
410 bt_props->bd_addr = NULL;
412 g_free(bt_props->bt_name);
413 bt_props->bt_name = NULL;
419 /* Get default local adapter properties */
420 static void bt_get_properties_cb(DBusPendingCall *pending, void *user_data)
422 struct near_oob_data *bt_props = user_data;
429 reply = dbus_pending_call_steal_reply(pending);
433 dbus_error_init(&error);
435 if (dbus_set_error_from_message(&error, reply))
438 err = bt_parse_properties(reply, bt_props);
440 near_error("Problem parsing local properties %d", err);
442 DBG("Get Properties complete: %s", bt_props->def_adapter);
445 dbus_message_unref(reply);
446 dbus_pending_call_unref(pending);
450 near_error("%s", error.message);
451 dbus_error_free(&error);
453 dbus_message_unref(reply);
454 dbus_pending_call_unref(pending);
459 static void bt_get_default_adapter_cb(DBusPendingCall *pending, void *user_data)
461 struct near_oob_data *bt_props = user_data;
468 reply = dbus_pending_call_steal_reply(pending);
472 dbus_error_init(&error);
474 if (dbus_set_error_from_message(&error, reply))
477 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH,
478 &path, DBUS_TYPE_INVALID) == FALSE)
481 /* Save the default adapter */
482 bt_props->def_adapter = g_strdup(path);
483 DBG("Using default adapter %s", bt_props->def_adapter);
486 dbus_message_unref(reply);
487 dbus_pending_call_unref(pending);
489 /* Jump on getAdapterProperties */
490 bt_generic_call(bt_conn, bt_props,
492 bt_props->def_adapter,
493 ADAPTER_INTF, "GetProperties",
494 bt_get_properties_cb,
499 near_error("%s", error.message);
500 dbus_error_free(&error);
502 dbus_message_unref(reply);
503 dbus_pending_call_unref(pending);
508 static int bt_refresh_adapter_props(DBusConnection *conn, void *user_data)
510 DBG("%p %p", conn, user_data);
512 return bt_generic_call(conn, user_data,
514 MANAGER_PATH, MANAGER_INTF,
516 bt_get_default_adapter_cb,
520 /* Parse and fill the bluetooth oob information block */
521 static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
522 struct near_oob_data *oob)
527 DBG("total len: %u", eir_data_len);
529 while (len < eir_data_len - 1) {
530 uint8_t eir_len = eir_data[0]; /* EIR field length */
531 uint8_t eir_code; /* EIR field type*/
532 uint8_t data_len; /* EIR data length */
535 /* check for early termination */
541 /* Do not continue EIR Data parsing if got incorrect length */
542 if (len > eir_data_len)
545 data_len = eir_len - 1;
547 eir_code = eir_data[1]; /* EIR code */
550 DBG("type 0x%.2X data_len %u", eir_code, data_len);
554 case EIR_NAME_COMPLETE:
555 oob->bt_name = g_try_malloc0(data_len + 1); /* eos */
557 oob->bt_name_len = data_len;
558 memcpy(oob->bt_name, data, oob->bt_name_len);
559 oob->bt_name[data_len] = 0; /* end str*/
563 case EIR_CLASS_OF_DEVICE:
564 tmp = g_strdup_printf("%02X%02X%02X",
565 *data, *(data + 1), *(data + 2));
567 oob->class_of_device = strtol(tmp, NULL, 16);
572 oob->spair_hash = g_try_malloc0(OOB_SP_SIZE);
574 memcpy(oob->spair_hash, data, OOB_SP_SIZE);
577 case EIR_SP_RANDOMIZER:
578 oob->spair_randomizer = g_try_malloc0(OOB_SP_SIZE);
579 if (oob->spair_randomizer)
580 memcpy(oob->spair_randomizer,
584 case EIR_SECURITY_MGR_FLAGS:
585 oob->security_manager_oob_flags = *data;
588 case EIR_UUID128_ALL:
589 /* TODO: Process uuids128
593 default: /* ignore and skip */
594 near_error("Unknown EIR x%02x (len: %d)", eir_code,
599 eir_data += eir_len + 1;
604 * Because of some "old" implementation, "version" will help
605 * to determine the record data structure.
606 * Some specifications are proprietary (eg. "short mode")
607 * and are not fully documented.
609 int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
612 struct near_oob_data *oob;
613 uint16_t bt_oob_data_size;
614 uint8_t *ptr = bt_data;
620 oob = g_try_malloc0(sizeof(struct near_oob_data));
622 if (version == BT_MIME_V2_1) {
623 /* Total OOB data size (including size bytes)*/
624 bt_oob_data_size = *((uint16_t *)(bt_data));
625 bt_oob_data_size -= 2 ; /* remove oob datas size len */
627 /* First item: BD_ADDR (mandatory) */
629 oob->bd_addr = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
630 ptr[5], ptr[4], ptr[3], ptr[2], ptr[1], ptr[0]);
632 /* Skip to the next element (optional) */
633 ptr += BT_ADDRESS_SIZE;
634 bt_oob_data_size -= BT_ADDRESS_SIZE ;
636 if (bt_oob_data_size)
637 bt_parse_eir(ptr, bt_oob_data_size, oob);
638 } else if (version == BT_MIME_V2_0) {
639 marker = *ptr++; /* could be '$' */
641 oob->bd_addr = g_strdup_printf(
642 "%02X:%02X:%02X:%02X:%02X:%02X",
643 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
644 ptr = ptr + BT_ADDRESS_SIZE;
646 /* Class of device */
647 tmp = g_strdup_printf("%02X%02X%02X",
648 *ptr, *(ptr + 1), *(ptr + 2));
650 oob->class_of_device = strtol(tmp, NULL, 16);
655 /* "Short mode" seems to use a 4 bytes code
656 * instead of 16 bytes...
658 if (marker == '$') { /* Short NFC */
659 memcpy(oob->authentication, ptr, 4);
662 memcpy(oob->authentication, ptr, 16);
666 /* get the device name */
667 oob->bt_name_len = *ptr++;
668 oob->bt_name = g_try_malloc0(oob->bt_name_len+1);
670 memcpy(oob->bt_name, ptr, oob->bt_name_len);
671 oob->bt_name[oob->bt_name_len+1] = 0;
673 ptr = ptr + oob->bt_name_len;
681 /* check and get the default adapter */
682 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
683 if (oob->bt_name == NULL) {
684 near_error("bt_get_default_adapter failed");
689 return bt_do_pairing(oob);
692 int __near_bluetooth_pair(void *data)
694 struct near_oob_data *oob = data;
696 /* check and get the default adapter */
697 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
698 if (oob->bt_name == NULL) {
699 near_error("bt_get_default_adapter failed: %d", -EIO);
704 return bt_do_pairing(oob);
707 /* This function is synchronous as oob datas change on each session */
708 static int bt_sync_oob_readlocaldata(DBusConnection *conn, char *adapter_path,
710 char *spair_randomizer)
712 DBusMessage *message, *reply;
714 int hash_len, rndm_len;
716 message = dbus_message_new_method_call(BLUEZ_SERVICE, adapter_path,
717 OOB_INTF, "ReadLocalData");
721 dbus_error_init(&error);
723 reply = dbus_connection_send_with_reply_and_block(conn,
724 message, -1, &error);
726 dbus_message_unref(message);
729 if (dbus_error_is_set(&error) == TRUE) {
730 near_error("%s", error.message);
731 dbus_error_free(&error);
733 near_error("Failed to set property");
738 if (dbus_message_get_args(reply, NULL,
739 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, spair_hash, &hash_len,
740 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
741 spair_randomizer, &rndm_len,
742 DBUS_TYPE_INVALID) == FALSE)
745 if ((hash_len != OOB_SP_SIZE) || (rndm_len != OOB_SP_SIZE)) {
746 DBG("no OOB data found !");
750 dbus_message_unref(reply);
751 DBG("OOB data found");
755 dbus_message_unref(reply);
760 * External API to get bt properties
761 * Prepare a "real" oob datas block
763 uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
765 uint8_t *bt_oob_block = NULL;
766 uint16_t bt_oob_block_size = 0;
770 char hash[OOB_SP_SIZE];
771 char random[OOB_SP_SIZE];
773 /* Check adapter datas */
774 if (bt_def_oob_data.def_adapter == NULL) {
775 near_error("No bt adapter info");
779 /* Prepare the BT block */
780 max_block_size = sizeof(uint16_t) + /* stored oob size */
782 EIR_HEADER_LEN + bt_def_oob_data.bt_name_len +
783 EIR_HEADER_LEN + COD_SIZE + /* class */
784 EIR_HEADER_LEN + OOB_SP_SIZE + /* oob hash */
785 EIR_HEADER_LEN + OOB_SP_SIZE; /* oob random */
788 bt_oob_block_size = sizeof(uint16_t) /* stored oob size */
789 + BT_ADDRESS_SIZE; /* device address */
791 bt_oob_block = g_try_malloc0(max_block_size);
792 if (bt_oob_block == NULL)
794 offset = sizeof(uint16_t); /* Skip size...will be filled later */
796 /* Now prepare data frame */
797 memcpy(bt_oob_block + offset, bt_def_oob_data.bd_addr, BT_ADDRESS_SIZE);
798 offset += BT_ADDRESS_SIZE;
801 if (bt_def_oob_data.bt_name != NULL) {
802 bt_oob_block_size += (bt_def_oob_data.bt_name_len +
805 bt_oob_block[offset++] = bt_def_oob_data.bt_name_len +
807 bt_oob_block[offset++] = EIR_NAME_COMPLETE; /* EIR data type */
808 memcpy(bt_oob_block + offset, bt_def_oob_data.bt_name,
809 bt_def_oob_data.bt_name_len);
810 offset += bt_def_oob_data.bt_name_len;
814 bt_oob_block_size += COD_SIZE + EIR_HEADER_LEN;
816 bt_oob_block[offset++] = COD_SIZE + EIR_SIZE_LEN;
817 bt_oob_block[offset++] = EIR_CLASS_OF_DEVICE;
819 memcpy(bt_oob_block + offset,
820 (uint8_t *)&bt_def_oob_data.class_of_device, COD_SIZE);
823 /* The following data are generated dynamically
824 * so we have to read the local oob data
826 if (bt_sync_oob_readlocaldata(bt_conn, bt_def_oob_data.def_adapter,
827 hash, random) == OOB_SP_SIZE) {
828 bt_oob_block_size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
832 bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
833 bt_oob_block[offset++] = EIR_SP_HASH;
834 memcpy(bt_oob_block + offset, hash, OOB_SP_SIZE);
835 offset += OOB_SP_SIZE;
838 if (random != NULL) {
839 bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
840 bt_oob_block[offset++] = EIR_SP_RANDOMIZER;
841 memcpy(bt_oob_block + offset, random, OOB_SP_SIZE);
842 offset += OOB_SP_SIZE;
846 *(uint16_t *)bt_oob_block = bt_oob_block_size ;
847 *bt_data_len = bt_oob_block_size;
852 g_free(bt_oob_block);
856 static void bt_connect(DBusConnection *conn, void *user_data)
859 DBG("connection %p with %p", conn, user_data);
860 if (bt_refresh_adapter_props(conn, user_data) < 0)
861 near_error("bt_get_default_adapter failed");
866 static void bt_disconnect(DBusConnection *conn, void *user_data)
870 __bt_eir_free(user_data);
873 /* BT adapter removed handler */
874 static gboolean bt_adapter_removed(DBusConnection *conn,
875 DBusMessage *message,
878 DBusMessageIter iter;
879 struct near_oob_data *bt_props = user_data;
880 const char *adapter_path;
884 if (bt_props->def_adapter == NULL)
887 if (dbus_message_iter_init(message, &iter) == FALSE)
890 dbus_message_iter_get_basic(&iter, &adapter_path);
892 if (g_strcmp0(adapter_path, bt_props->def_adapter) == 0) {
893 near_info("Remove the default adapter [%s]", adapter_path);
895 __bt_eir_free(bt_props);
896 bt_props->def_adapter = NULL;
902 /* BT default adapter changed handler */
903 static gboolean bt_default_adapter_changed(DBusConnection *conn,
904 DBusMessage *message,
907 struct near_oob_data *bt_props = user_data;
908 DBusMessageIter iter;
909 const char *adapter_path;
913 if (dbus_message_iter_init(message, &iter) == FALSE)
916 dbus_message_iter_get_basic(&iter, &adapter_path);
917 DBG("New default adapter [%s]", adapter_path);
919 /* Disable the old one */
920 __bt_eir_free(bt_props);
921 bt_props->def_adapter = NULL;
924 bt_refresh_adapter_props(conn, user_data);
929 static void bt_dbus_disconnect_cb(DBusConnection *conn, void *user_data)
931 near_error("D-Bus disconnect (BT)");
936 static guint removed_watch;
937 static guint adapter_watch;
939 static int bt_prepare_handlers(DBusConnection *conn)
946 watch = g_dbus_add_service_watch(conn, BLUEZ_SERVICE,
949 &bt_def_oob_data, NULL);
951 removed_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
954 &bt_def_oob_data, NULL);
957 adapter_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
958 DEFAULT_ADAPTER_CHANGED,
959 bt_default_adapter_changed,
960 &bt_def_oob_data, NULL);
962 if (watch == 0 || removed_watch == 0 || adapter_watch == 0) {
963 near_error("Bluez event handlers failed to register.");
964 g_dbus_remove_watch(conn, watch);
965 g_dbus_remove_watch(conn, removed_watch);
966 g_dbus_remove_watch(conn, adapter_watch);
974 /* Bluetooth exiting function */
975 void __near_bluetooth_cleanup(void)
982 g_dbus_remove_watch(bt_conn, watch);
983 g_dbus_remove_watch(bt_conn, removed_watch);
984 g_dbus_remove_watch(bt_conn, adapter_watch);
986 dbus_connection_unref(bt_conn);
988 __bt_eir_free(&bt_def_oob_data);
994 * Bluetooth initialization function.
995 * Allocate bt local settings storage
996 * and setup event handlers
998 int __near_bluetooth_init(void)
1004 dbus_error_init(&err);
1006 /* save the dbus connection */
1007 bt_conn = near_dbus_get_connection();
1008 if (bt_conn == NULL) {
1009 if (dbus_error_is_set(&err) == TRUE) {
1010 near_error("%s", err.message);
1011 dbus_error_free(&err);
1013 near_error("Can't register with system bus\n");
1017 /* dbus disconnect callback */
1018 g_dbus_set_disconnect_function(bt_conn, bt_dbus_disconnect_cb,
1021 /* Set bluez event handlers */
1022 return bt_prepare_handlers(bt_conn);