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 #define get_unaligned(ptr) \
68 struct __attribute__((packed)) { \
70 } *__p = (typeof(__p)) (ptr); \
74 struct near_oob_data {
77 char *bd_addr; /* oob mandatory */
80 char *bt_name; /* short or long name */
82 int class_of_device; /* Class of device */
85 near_bool_t discoverable;
89 uint8_t *spair_hash; /* OOB hash Key */
90 uint8_t *spair_randomizer; /* OOB randomizer key */
91 uint8_t authentication[OOB_SP_SIZE]; /* On BT 2.0 */
92 uint8_t security_manager_oob_flags; /* see BT Core 4.0 */
95 static DBusConnection *bt_conn;
96 static struct near_oob_data bt_def_oob_data;
98 static int bt_do_pairing(struct near_oob_data *oob);
100 static void __bt_eir_free(struct near_oob_data *oob)
104 if (oob->def_adapter != NULL) {
105 g_free(oob->def_adapter);
106 oob->def_adapter = NULL;
109 if (oob->bd_addr != NULL) {
110 g_free(oob->bd_addr);
114 if (oob->bt_name != NULL) {
115 g_free(oob->bt_name);
119 if (oob->spair_hash != NULL) {
120 g_free(oob->spair_hash);
121 oob->spair_hash = NULL;
124 if (oob->spair_randomizer != NULL) {
125 g_free(oob->spair_randomizer);
126 oob->spair_randomizer = NULL;
132 static void bt_eir_free(struct near_oob_data *oob)
139 /* D-Bus helper functions */
140 static int bt_generic_call(DBusConnection *conn,
141 struct near_oob_data *oob, /* user data */
142 const char *dest, /* method call */
144 const char *interface,
146 DBusPendingCallNotifyFunction bt_cb, /* callback */
147 int type, ...) /* params */
150 DBusPendingCall *pending;
156 msg = dbus_message_new_method_call(dest, path, interface, method);
159 near_error("Unable to allocate new D-Bus %s message", method);
163 va_start(args, type);
165 if (!dbus_message_append_args_valist(msg, type, args)) {
172 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
173 near_error("Sending %s failed", method);
178 if (pending == NULL) {
179 near_error("D-Bus connection not available");
184 /* Prepare for notification */
185 dbus_pending_call_set_notify(pending, bt_cb, oob, NULL);
189 dbus_message_unref(msg);
193 static void bt_create_paired_device_cb(DBusPendingCall *pending,
198 struct near_oob_data *oob = user_data;
202 reply = dbus_pending_call_steal_reply(pending);
206 dbus_error_init(&error);
208 if (dbus_set_error_from_message(&error, reply)) {
209 near_error("%s", error.message);
210 dbus_error_free(&error);
214 near_info("Pairing done successfully !");
217 /* task completed - clean memory*/
220 dbus_message_unref(reply);
221 dbus_pending_call_unref(pending);
226 static int bt_create_paired_device(DBusConnection *conn,
227 struct near_oob_data *oob,
228 const char *capabilities)
230 const char *agent_path = OOB_AGENT;
232 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
233 oob->def_adapter, ADAPTER_INTF, "CreatePairedDevice",
234 bt_create_paired_device_cb,
236 DBUS_TYPE_STRING, &oob->bd_addr,
237 DBUS_TYPE_OBJECT_PATH, &agent_path,
238 DBUS_TYPE_STRING, &capabilities,
243 static void bt_oob_add_remote_data_cb(DBusPendingCall *pending, void *user_data)
247 struct near_oob_data *oob = user_data;
251 reply = dbus_pending_call_steal_reply(pending);
255 dbus_error_init(&error);
257 if (dbus_set_error_from_message(&error, reply))
260 near_info("OOB data added");
262 dbus_message_unref(reply);
263 dbus_pending_call_unref(pending);
265 /* Jump to the next: Pairing !!!*/
266 DBG("Try to pair devices...");
267 bt_create_paired_device(bt_conn, oob, BT_DISPLAY_YESNO);
271 near_error("%s", error.message);
272 dbus_error_free(&error);
276 dbus_message_unref(reply);
277 dbus_pending_call_unref(pending);
282 static int bt_oob_add_remote_data(DBusConnection *conn,
283 struct near_oob_data *oob)
285 int16_t hash_len = 16;
286 int16_t rdm_len = 16;
288 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
289 oob->def_adapter, OOB_INTF, "AddRemoteData",
290 bt_oob_add_remote_data_cb,
292 DBUS_TYPE_STRING, &oob->bd_addr,
294 DBUS_TYPE_BYTE, &oob->spair_hash, hash_len,
296 DBUS_TYPE_BYTE, &oob->spair_randomizer, rdm_len,
300 /* Pairing: JustWorks or OOB */
301 static int bt_do_pairing(struct near_oob_data *oob)
305 DBG("%s", oob->bd_addr);
307 /* Is this a *real* oob pairing or a "JustWork" */
308 if ((oob->spair_hash) && (oob->spair_randomizer))
309 err = bt_oob_add_remote_data(bt_conn, oob);
311 err = bt_create_paired_device(bt_conn, oob,
315 near_error("Pairing failed. Err[%d]", err);
322 static int extract_properties(DBusMessage *reply,
323 struct near_oob_data *oob)
329 DBusMessageIter array, dict;
331 if (dbus_message_iter_init(reply, &array) == FALSE)
334 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
337 dbus_message_iter_recurse(&array, &dict);
339 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
340 DBusMessageIter entry, value;
343 dbus_message_iter_recurse(&dict, &entry);
344 dbus_message_iter_get_basic(&entry, &key);
346 dbus_message_iter_next(&entry);
347 dbus_message_iter_recurse(&entry, &value);
349 if (g_str_equal(key, "Address") == TRUE) {
350 dbus_message_iter_get_basic(&value, &data);
352 /* Now, fill the local struct */
353 oob->bd_addr = g_try_malloc0(BT_ADDRESS_SIZE);
354 if (oob->bd_addr == NULL)
357 /* Address is like: "ff:ee:dd:cc:bb:aa" */
358 for (i = 5, j = 0 ; i >= 0; i--, j += 3)
359 oob->bd_addr[i] = strtol(data + j, NULL, 16);
360 DBG("local address: %s", data);
362 } else if (g_str_equal(key, "Name") == TRUE) {
363 dbus_message_iter_get_basic(&value, &data);
364 oob->bt_name = g_strdup(data);
365 if (oob->bt_name != NULL) {
366 oob->bt_name_len = strlen(oob->bt_name);
367 DBG("local name: %s", oob->bt_name);
370 } else if (g_str_equal(key, "Class") == TRUE) {
371 dbus_message_iter_get_basic(&value, &idata);
372 oob->class_of_device = idata;
374 } else if (g_str_equal(key, "Powered") == TRUE) {
375 dbus_message_iter_get_basic(&value, &idata);
376 oob->powered = idata;
378 } else if (g_str_equal(key, "Discoverable") == TRUE) {
379 dbus_message_iter_get_basic(&value, &idata);
380 oob->discoverable = idata;
382 } else if (g_str_equal(key, "Pairable") == TRUE) {
383 dbus_message_iter_get_basic(&value, &idata);
384 oob->pairable = idata;
386 } else if (g_str_equal(key, "UUIDs") == TRUE) {
387 oob->uuids_len = sizeof(value);
388 oob->uuids = g_try_malloc0(oob->uuids_len);
389 if (oob->uuids == NULL)
391 memcpy(oob->uuids, &value, oob->uuids_len);
394 dbus_message_iter_next(&dict);
400 static int bt_parse_properties(DBusMessage *reply, void *user_data)
402 struct near_oob_data *bt_props = user_data;
407 g_free(bt_props->bd_addr);
408 g_free(bt_props->bt_name);
410 /* Grab properties from dbus */
411 if (extract_properties(reply, bt_props) < 0)
417 g_free(bt_props->bd_addr);
418 bt_props->bd_addr = NULL;
420 g_free(bt_props->bt_name);
421 bt_props->bt_name = NULL;
427 /* Get default local adapter properties */
428 static void bt_get_properties_cb(DBusPendingCall *pending, void *user_data)
430 struct near_oob_data *bt_props = user_data;
437 reply = dbus_pending_call_steal_reply(pending);
441 dbus_error_init(&error);
443 if (dbus_set_error_from_message(&error, reply))
446 err = bt_parse_properties(reply, bt_props);
448 near_error("Problem parsing local properties %d", err);
450 DBG("Get Properties complete: %s", bt_props->def_adapter);
453 dbus_message_unref(reply);
454 dbus_pending_call_unref(pending);
458 near_error("%s", error.message);
459 dbus_error_free(&error);
461 dbus_message_unref(reply);
462 dbus_pending_call_unref(pending);
467 static void bt_get_default_adapter_cb(DBusPendingCall *pending, void *user_data)
469 struct near_oob_data *bt_props = user_data;
476 reply = dbus_pending_call_steal_reply(pending);
480 dbus_error_init(&error);
482 if (dbus_set_error_from_message(&error, reply))
485 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH,
486 &path, DBUS_TYPE_INVALID) == FALSE)
489 /* Save the default adapter */
490 bt_props->def_adapter = g_strdup(path);
491 DBG("Using default adapter %s", bt_props->def_adapter);
494 dbus_message_unref(reply);
495 dbus_pending_call_unref(pending);
497 /* Jump on getAdapterProperties */
498 bt_generic_call(bt_conn, bt_props,
500 bt_props->def_adapter,
501 ADAPTER_INTF, "GetProperties",
502 bt_get_properties_cb,
507 near_error("%s", error.message);
508 dbus_error_free(&error);
510 dbus_message_unref(reply);
511 dbus_pending_call_unref(pending);
516 static int bt_refresh_adapter_props(DBusConnection *conn, void *user_data)
518 DBG("%p %p", conn, user_data);
520 return bt_generic_call(conn, user_data,
522 MANAGER_PATH, MANAGER_INTF,
524 bt_get_default_adapter_cb,
528 /* Parse and fill the bluetooth oob information block */
529 static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
530 struct near_oob_data *oob)
535 DBG("total len: %u", eir_data_len);
537 while (len < eir_data_len - 1) {
538 uint8_t eir_len = eir_data[0]; /* EIR field length */
539 uint8_t eir_code; /* EIR field type*/
540 uint8_t data_len; /* EIR data length */
543 /* check for early termination */
549 /* Do not continue EIR Data parsing if got incorrect length */
550 if (len > eir_data_len)
553 data_len = eir_len - 1;
555 eir_code = eir_data[1]; /* EIR code */
558 DBG("type 0x%.2X data_len %u", eir_code, data_len);
562 case EIR_NAME_COMPLETE:
563 oob->bt_name = g_try_malloc0(data_len + 1); /* eos */
565 oob->bt_name_len = data_len;
566 memcpy(oob->bt_name, data, oob->bt_name_len);
567 oob->bt_name[data_len] = 0; /* end str*/
571 case EIR_CLASS_OF_DEVICE:
572 tmp = g_strdup_printf("%02X%02X%02X",
573 *data, *(data + 1), *(data + 2));
575 oob->class_of_device = strtol(tmp, NULL, 16);
580 oob->spair_hash = g_try_malloc0(OOB_SP_SIZE);
582 memcpy(oob->spair_hash, data, OOB_SP_SIZE);
585 case EIR_SP_RANDOMIZER:
586 oob->spair_randomizer = g_try_malloc0(OOB_SP_SIZE);
587 if (oob->spair_randomizer)
588 memcpy(oob->spair_randomizer,
592 case EIR_SECURITY_MGR_FLAGS:
593 oob->security_manager_oob_flags = *data;
596 case EIR_UUID128_ALL:
597 /* TODO: Process uuids128
601 default: /* ignore and skip */
602 near_error("Unknown EIR x%02x (len: %d)", eir_code,
607 eir_data += eir_len + 1;
612 * Because of some "old" implementation, "version" will help
613 * to determine the record data structure.
614 * Some specifications are proprietary (eg. "short mode")
615 * and are not fully documented.
617 int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
620 struct near_oob_data *oob;
621 uint16_t bt_oob_data_size;
622 uint8_t *ptr = bt_data;
628 oob = g_try_malloc0(sizeof(struct near_oob_data));
630 if (version == BT_MIME_V2_1) {
632 * Total OOB data size (including size bytes)
633 * Some implementations (e.g. Android 4.1) stores
634 * the data_size in big endian but NDEF forum spec (BT Secure
635 * Simple Pairing) requires a little endian. At the same time,
636 * the NDEF forum NDEF spec define a payload length as single
637 * byte (and the payload size IS the oob data size).
640 GUINT16_FROM_LE(get_unaligned((uint16_t *) bt_data));
641 if (bt_oob_data_size > 0xFF) /* Big Endian */
642 bt_oob_data_size = GUINT16_FROM_BE(bt_oob_data_size);
644 bt_oob_data_size -= 2 ; /* remove oob datas size len */
646 /* First item: BD_ADDR (mandatory) */
648 oob->bd_addr = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
649 ptr[5], ptr[4], ptr[3], ptr[2], ptr[1], ptr[0]);
651 /* Skip to the next element (optional) */
652 ptr += BT_ADDRESS_SIZE;
653 bt_oob_data_size -= BT_ADDRESS_SIZE ;
655 if (bt_oob_data_size)
656 bt_parse_eir(ptr, bt_oob_data_size, oob);
657 } else if (version == BT_MIME_V2_0) {
658 marker = *ptr++; /* could be '$' */
660 oob->bd_addr = g_strdup_printf(
661 "%02X:%02X:%02X:%02X:%02X:%02X",
662 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
663 ptr = ptr + BT_ADDRESS_SIZE;
665 /* Class of device */
666 tmp = g_strdup_printf("%02X%02X%02X",
667 *ptr, *(ptr + 1), *(ptr + 2));
669 oob->class_of_device = strtol(tmp, NULL, 16);
674 /* "Short mode" seems to use a 4 bytes code
675 * instead of 16 bytes...
677 if (marker == '$') { /* Short NFC */
678 memcpy(oob->authentication, ptr, 4);
681 memcpy(oob->authentication, ptr, 16);
685 /* get the device name */
686 oob->bt_name_len = *ptr++;
687 oob->bt_name = g_try_malloc0(oob->bt_name_len+1);
689 memcpy(oob->bt_name, ptr, oob->bt_name_len);
690 oob->bt_name[oob->bt_name_len+1] = 0;
692 ptr = ptr + oob->bt_name_len;
700 /* check and get the default adapter */
701 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
702 if (oob->def_adapter == NULL) {
703 near_error("bt_get_default_adapter failed");
708 return bt_do_pairing(oob);
711 int __near_bluetooth_pair(void *data)
713 struct near_oob_data *oob = data;
715 /* check and get the default adapter */
716 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
717 if (oob->bt_name == NULL) {
718 near_error("bt_get_default_adapter failed: %d", -EIO);
723 return bt_do_pairing(oob);
726 /* This function is synchronous as oob datas change on each session */
727 static int bt_sync_oob_readlocaldata(DBusConnection *conn, char *adapter_path,
729 char *spair_randomizer)
731 DBusMessage *message, *reply;
733 int hash_len, rndm_len;
735 message = dbus_message_new_method_call(BLUEZ_SERVICE, adapter_path,
736 OOB_INTF, "ReadLocalData");
740 dbus_error_init(&error);
742 reply = dbus_connection_send_with_reply_and_block(conn,
743 message, -1, &error);
745 dbus_message_unref(message);
748 if (dbus_error_is_set(&error) == TRUE) {
749 near_error("%s", error.message);
750 dbus_error_free(&error);
752 near_error("Failed to set property");
757 if (dbus_message_get_args(reply, NULL,
758 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, spair_hash, &hash_len,
759 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
760 spair_randomizer, &rndm_len,
761 DBUS_TYPE_INVALID) == FALSE)
764 if ((hash_len != OOB_SP_SIZE) || (rndm_len != OOB_SP_SIZE)) {
765 DBG("no OOB data found !");
769 dbus_message_unref(reply);
770 DBG("OOB data found");
774 dbus_message_unref(reply);
779 * External API to get bt properties
780 * Prepare a "real" oob datas block
782 uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
784 uint8_t *bt_oob_block = NULL;
785 uint16_t bt_oob_block_size = 0;
789 char hash[OOB_SP_SIZE];
790 char random[OOB_SP_SIZE];
792 /* Check adapter datas */
793 if (bt_def_oob_data.def_adapter == NULL) {
794 near_error("No bt adapter info");
798 /* Prepare the BT block */
799 max_block_size = sizeof(uint16_t) + /* stored oob size */
801 EIR_HEADER_LEN + bt_def_oob_data.bt_name_len +
802 EIR_HEADER_LEN + COD_SIZE + /* class */
803 EIR_HEADER_LEN + OOB_SP_SIZE + /* oob hash */
804 EIR_HEADER_LEN + OOB_SP_SIZE; /* oob random */
807 bt_oob_block_size = sizeof(uint16_t) /* stored oob size */
808 + BT_ADDRESS_SIZE; /* device address */
810 bt_oob_block = g_try_malloc0(max_block_size);
811 if (bt_oob_block == NULL)
813 offset = sizeof(uint16_t); /* Skip size...will be filled later */
815 /* Now prepare data frame */
816 memcpy(bt_oob_block + offset, bt_def_oob_data.bd_addr, BT_ADDRESS_SIZE);
817 offset += BT_ADDRESS_SIZE;
820 if (bt_def_oob_data.bt_name != NULL) {
821 bt_oob_block_size += (bt_def_oob_data.bt_name_len +
824 bt_oob_block[offset++] = bt_def_oob_data.bt_name_len +
826 bt_oob_block[offset++] = EIR_NAME_COMPLETE; /* EIR data type */
827 memcpy(bt_oob_block + offset, bt_def_oob_data.bt_name,
828 bt_def_oob_data.bt_name_len);
829 offset += bt_def_oob_data.bt_name_len;
833 bt_oob_block_size += COD_SIZE + EIR_HEADER_LEN;
835 bt_oob_block[offset++] = COD_SIZE + EIR_SIZE_LEN;
836 bt_oob_block[offset++] = EIR_CLASS_OF_DEVICE;
838 memcpy(bt_oob_block + offset,
839 (uint8_t *)&bt_def_oob_data.class_of_device, COD_SIZE);
842 /* The following data are generated dynamically
843 * so we have to read the local oob data
845 if (bt_sync_oob_readlocaldata(bt_conn, bt_def_oob_data.def_adapter,
846 hash, random) == OOB_SP_SIZE) {
847 bt_oob_block_size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
851 bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
852 bt_oob_block[offset++] = EIR_SP_HASH;
853 memcpy(bt_oob_block + offset, hash, OOB_SP_SIZE);
854 offset += OOB_SP_SIZE;
857 if (random != NULL) {
858 bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
859 bt_oob_block[offset++] = EIR_SP_RANDOMIZER;
860 memcpy(bt_oob_block + offset, random, OOB_SP_SIZE);
861 offset += OOB_SP_SIZE;
865 *(uint16_t *)bt_oob_block = bt_oob_block_size ;
866 *bt_data_len = bt_oob_block_size;
871 g_free(bt_oob_block);
875 static void bt_connect(DBusConnection *conn, void *user_data)
878 DBG("connection %p with %p", conn, user_data);
879 if (bt_refresh_adapter_props(conn, user_data) < 0)
880 near_error("bt_get_default_adapter failed");
885 static void bt_disconnect(DBusConnection *conn, void *user_data)
889 __bt_eir_free(user_data);
892 /* BT adapter removed handler */
893 static gboolean bt_adapter_removed(DBusConnection *conn,
894 DBusMessage *message,
897 DBusMessageIter iter;
898 struct near_oob_data *bt_props = user_data;
899 const char *adapter_path;
903 if (bt_props->def_adapter == NULL)
906 if (dbus_message_iter_init(message, &iter) == FALSE)
909 dbus_message_iter_get_basic(&iter, &adapter_path);
911 if (g_strcmp0(adapter_path, bt_props->def_adapter) == 0) {
912 near_info("Remove the default adapter [%s]", adapter_path);
914 __bt_eir_free(bt_props);
915 bt_props->def_adapter = NULL;
921 /* BT default adapter changed handler */
922 static gboolean bt_default_adapter_changed(DBusConnection *conn,
923 DBusMessage *message,
926 struct near_oob_data *bt_props = user_data;
927 DBusMessageIter iter;
928 const char *adapter_path;
932 if (dbus_message_iter_init(message, &iter) == FALSE)
935 dbus_message_iter_get_basic(&iter, &adapter_path);
936 DBG("New default adapter [%s]", adapter_path);
938 /* Disable the old one */
939 __bt_eir_free(bt_props);
940 bt_props->def_adapter = NULL;
943 bt_refresh_adapter_props(conn, user_data);
948 static void bt_dbus_disconnect_cb(DBusConnection *conn, void *user_data)
950 near_error("D-Bus disconnect (BT)");
955 static guint removed_watch;
956 static guint adapter_watch;
958 static int bt_prepare_handlers(DBusConnection *conn)
965 watch = g_dbus_add_service_watch(conn, BLUEZ_SERVICE,
968 &bt_def_oob_data, NULL);
970 removed_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
973 &bt_def_oob_data, NULL);
976 adapter_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
977 DEFAULT_ADAPTER_CHANGED,
978 bt_default_adapter_changed,
979 &bt_def_oob_data, NULL);
981 if (watch == 0 || removed_watch == 0 || adapter_watch == 0) {
982 near_error("Bluez event handlers failed to register.");
983 g_dbus_remove_watch(conn, watch);
984 g_dbus_remove_watch(conn, removed_watch);
985 g_dbus_remove_watch(conn, adapter_watch);
993 /* Bluetooth exiting function */
994 void __near_bluetooth_cleanup(void)
1001 g_dbus_remove_watch(bt_conn, watch);
1002 g_dbus_remove_watch(bt_conn, removed_watch);
1003 g_dbus_remove_watch(bt_conn, adapter_watch);
1005 dbus_connection_unref(bt_conn);
1007 __bt_eir_free(&bt_def_oob_data);
1013 * Bluetooth initialization function.
1014 * Allocate bt local settings storage
1015 * and setup event handlers
1017 int __near_bluetooth_init(void)
1023 dbus_error_init(&err);
1025 /* save the dbus connection */
1026 bt_conn = near_dbus_get_connection();
1027 if (bt_conn == NULL) {
1028 if (dbus_error_is_set(&err) == TRUE) {
1029 near_error("%s", err.message);
1030 dbus_error_free(&err);
1032 near_error("Can't register with system bus\n");
1036 /* dbus disconnect callback */
1037 g_dbus_set_disconnect_function(bt_conn, bt_dbus_disconnect_cb,
1040 /* Set bluez event handlers */
1041 return bt_prepare_handlers(bt_conn);