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 ADAPTER_PROPERTY_CHANGED "PropertyChanged"
42 #define MANAGER_PATH "/"
43 #define OOB_AGENT "/org/neard/agent/neard_oob"
45 #define BT_NOINPUTOUTPUT "NoInputNoOutput"
46 #define BT_DISPLAY_YESNO "DisplayYesNo"
48 #define DBUS_MANAGER_INTF "org.freedesktop.DBus.ObjectManager"
49 #define AGENT_REGISTER_TIMEOUT 2
52 #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
53 #define EIR_NAME_SHORT 0x08 /* shortened local name */
54 #define EIR_NAME_COMPLETE 0x09 /* complete local name */
56 /* Specific OOB EIRs */
57 #define EIR_CLASS_OF_DEVICE 0x0D /* class of device */
58 #define EIR_SP_HASH 0x0E /* simple pairing hash C */
59 #define EIR_SP_RANDOMIZER 0x0F /* simple pairing randomizer R */
61 #define EIR_DEVICE_ID 0x10 /* device ID */
62 #define EIR_SECURITY_MGR_FLAGS 0x11 /* security manager flags */
64 #define EIR_SIZE_LEN 1
65 #define EIR_HEADER_LEN (EIR_SIZE_LEN + 1)
66 #define BT_ADDRESS_SIZE 6
68 #define OOB_SP_SIZE 16
69 #define EIR_SIZE_MAX 255
71 struct near_oob_data {
74 char *bd_addr; /* oob mandatory */
77 char *bt_name; /* short or long name */
79 int class_of_device; /* Class of device */
82 near_bool_t discoverable;
86 uint8_t *spair_hash; /* OOB hash Key */
87 uint8_t *spair_randomizer; /* OOB randomizer key */
88 uint8_t authentication[OOB_SP_SIZE]; /* On BT 2.0 */
89 uint8_t security_manager_oob_flags; /* see BT Core 4.0 */
92 static DBusConnection *bt_conn;
93 static struct near_oob_data bt_def_oob_data;
96 static guint removed_watch;
97 static guint adapter_watch;
98 static guint adapter_props_watch;
100 static guint register_bluez_timer;
102 static void __bt_eir_free(struct near_oob_data *oob)
106 if (oob->def_adapter != NULL) {
107 g_free(oob->def_adapter);
108 oob->def_adapter = NULL;
111 if (oob->bd_addr != NULL) {
112 g_free(oob->bd_addr);
116 if (oob->bt_name != NULL) {
117 g_free(oob->bt_name);
121 if (oob->spair_hash != NULL) {
122 g_free(oob->spair_hash);
123 oob->spair_hash = NULL;
126 if (oob->spair_randomizer != NULL) {
127 g_free(oob->spair_randomizer);
128 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 DBG("Successful pairing");
217 /* task completed - clean memory*/
220 dbus_message_unref(reply);
221 dbus_pending_call_unref(pending);
224 static int bt_create_paired_device(DBusConnection *conn,
225 struct near_oob_data *oob,
226 const char *capabilities)
228 const char *agent_path = OOB_AGENT;
230 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
231 oob->def_adapter, ADAPTER_INTF, "CreatePairedDevice",
232 bt_create_paired_device_cb,
234 DBUS_TYPE_STRING, &oob->bd_addr,
235 DBUS_TYPE_OBJECT_PATH, &agent_path,
236 DBUS_TYPE_STRING, &capabilities,
240 static void bt_oob_add_remote_data_cb(DBusPendingCall *pending, void *user_data)
244 struct near_oob_data *oob = user_data;
248 reply = dbus_pending_call_steal_reply(pending);
252 dbus_error_init(&error);
254 if (dbus_set_error_from_message(&error, reply))
257 near_info("OOB data added");
259 dbus_message_unref(reply);
260 dbus_pending_call_unref(pending);
262 /* Jump to the next: Pairing !!!*/
263 DBG("Try to pair devices...");
264 bt_create_paired_device(bt_conn, oob, BT_DISPLAY_YESNO);
268 near_error("%s", error.message);
269 dbus_error_free(&error);
273 dbus_message_unref(reply);
274 dbus_pending_call_unref(pending);
277 static int bt_oob_add_remote_data(DBusConnection *conn,
278 struct near_oob_data *oob)
280 int16_t hash_len = 16;
281 int16_t rdm_len = 16;
283 return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
284 oob->def_adapter, OOB_INTF, "AddRemoteData",
285 bt_oob_add_remote_data_cb,
287 DBUS_TYPE_STRING, &oob->bd_addr,
289 DBUS_TYPE_BYTE, &oob->spair_hash, hash_len,
291 DBUS_TYPE_BYTE, &oob->spair_randomizer, rdm_len,
295 /* Pairing: JustWorks or OOB */
296 static int bt_do_pairing(struct near_oob_data *oob)
300 DBG("%s", oob->bd_addr);
302 /* Is this a *real* oob pairing or a "JustWork" */
303 if ((oob->spair_hash) && (oob->spair_randomizer))
304 err = bt_oob_add_remote_data(bt_conn, oob);
306 err = bt_create_paired_device(bt_conn, oob,
310 near_error("Pairing failed. Err[%d]", err);
317 static int extract_properties(DBusMessage *reply, struct near_oob_data *oob)
323 DBusMessageIter array, dict;
325 if (dbus_message_iter_init(reply, &array) == FALSE)
328 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
331 dbus_message_iter_recurse(&array, &dict);
333 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
334 DBusMessageIter entry, value;
337 dbus_message_iter_recurse(&dict, &entry);
338 dbus_message_iter_get_basic(&entry, &key);
340 dbus_message_iter_next(&entry);
341 dbus_message_iter_recurse(&entry, &value);
343 if (g_str_equal(key, "Address") == TRUE) {
344 dbus_message_iter_get_basic(&value, &data);
346 /* Now, fill the local struct */
347 oob->bd_addr = g_try_malloc0(BT_ADDRESS_SIZE);
348 if (oob->bd_addr == NULL)
351 /* Address is like: "ff:ee:dd:cc:bb:aa" */
352 for (i = 5, j = 0 ; i >= 0; i--, j += 3)
353 oob->bd_addr[i] = strtol(data + j, NULL, 16);
354 DBG("local address: %s", data);
356 } else if (g_str_equal(key, "Name") == TRUE) {
357 dbus_message_iter_get_basic(&value, &data);
358 oob->bt_name = g_strdup(data);
359 if (oob->bt_name != NULL) {
360 oob->bt_name_len = strlen(oob->bt_name);
361 DBG("local name: %s", oob->bt_name);
364 } else if (g_str_equal(key, "Class") == TRUE) {
365 dbus_message_iter_get_basic(&value, &idata);
366 oob->class_of_device = idata;
368 } else if (g_str_equal(key, "Powered") == TRUE) {
369 dbus_message_iter_get_basic(&value, &idata);
370 oob->powered = idata;
372 } else if (g_str_equal(key, "Discoverable") == TRUE) {
373 dbus_message_iter_get_basic(&value, &idata);
374 oob->discoverable = idata;
376 } else if (g_str_equal(key, "Pairable") == TRUE) {
377 dbus_message_iter_get_basic(&value, &idata);
378 oob->pairable = idata;
380 } else if (g_str_equal(key, "UUIDs") == TRUE) {
381 oob->uuids_len = sizeof(value);
382 oob->uuids = g_try_malloc0(oob->uuids_len);
383 if (oob->uuids == NULL)
385 memcpy(oob->uuids, &value, oob->uuids_len);
388 dbus_message_iter_next(&dict);
394 static int bt_parse_properties(DBusMessage *reply, void *user_data)
396 struct near_oob_data *bt_props = user_data;
401 g_free(bt_props->bd_addr);
402 g_free(bt_props->bt_name);
404 /* Grab properties from dbus */
405 if (extract_properties(reply, bt_props) < 0)
411 g_free(bt_props->bd_addr);
412 bt_props->bd_addr = NULL;
414 g_free(bt_props->bt_name);
415 bt_props->bt_name = NULL;
420 static gboolean bt_adapter_property_changed(DBusConnection *conn,
421 DBusMessage *message,
424 DBusMessageIter iter;
426 const char *property;
428 if (dbus_message_iter_init(message, &iter) == FALSE)
431 dbus_message_iter_get_basic(&iter, &property);
432 dbus_message_iter_next(&iter);
434 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
437 dbus_message_iter_recurse(&iter, &var);
439 if (g_str_equal(property, "Name") == TRUE) {
442 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
445 dbus_message_iter_get_basic(&iter, &name);
447 g_free(bt_def_oob_data.bt_name);
448 bt_def_oob_data.bt_name = g_strdup(name);
450 if (bt_def_oob_data.bt_name != NULL)
451 bt_def_oob_data.bt_name_len = strlen(name);
453 bt_def_oob_data.bt_name_len = 0;
455 DBG("%s: %s", property, name);
456 } else if (g_str_equal(property, "Class") == TRUE) {
459 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_UINT32)
462 dbus_message_iter_get_basic(&var, &class);
463 bt_def_oob_data.class_of_device = class;
465 DBG("%s: %x", property, bt_def_oob_data.class_of_device);
466 } else if (g_str_equal(property, "Powered") == TRUE) {
469 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
472 dbus_message_iter_get_basic(&var, &powered);
473 bt_def_oob_data.powered = powered;
475 DBG("%s: %u", property, bt_def_oob_data.powered);
481 /* Get default local adapter properties */
482 static void bt_get_properties_cb(DBusPendingCall *pending, void *user_data)
484 struct near_oob_data *bt_props = user_data;
491 reply = dbus_pending_call_steal_reply(pending);
495 dbus_error_init(&error);
497 if (dbus_set_error_from_message(&error, reply))
500 err = bt_parse_properties(reply, bt_props);
502 near_error("Problem parsing local properties %d", err);
504 DBG("Get Properties complete: %s", bt_props->def_adapter);
506 adapter_props_watch = g_dbus_add_signal_watch(bt_conn, NULL, NULL,
508 ADAPTER_PROPERTY_CHANGED,
509 bt_adapter_property_changed,
513 dbus_message_unref(reply);
514 dbus_pending_call_unref(pending);
518 near_error("%s", error.message);
519 dbus_error_free(&error);
521 dbus_message_unref(reply);
522 dbus_pending_call_unref(pending);
525 static void bt_get_default_adapter_cb(DBusPendingCall *pending, void *user_data)
527 struct near_oob_data *bt_props = user_data;
534 reply = dbus_pending_call_steal_reply(pending);
538 dbus_error_init(&error);
540 if (dbus_set_error_from_message(&error, reply))
543 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH,
544 &path, DBUS_TYPE_INVALID) == FALSE)
547 /* Save the default adapter */
548 bt_props->def_adapter = g_strdup(path);
549 DBG("Using default adapter %s", bt_props->def_adapter);
552 dbus_message_unref(reply);
553 dbus_pending_call_unref(pending);
555 /* Jump on getAdapterProperties */
556 bt_generic_call(bt_conn, bt_props,
558 bt_props->def_adapter,
559 ADAPTER_INTF, "GetProperties",
560 bt_get_properties_cb,
565 near_error("%s", error.message);
566 dbus_error_free(&error);
568 dbus_message_unref(reply);
569 dbus_pending_call_unref(pending);
572 static int bt_refresh_adapter_props(DBusConnection *conn, void *user_data)
574 DBG("%p %p", conn, user_data);
576 return bt_generic_call(conn, user_data,
578 MANAGER_PATH, MANAGER_INTF,
580 bt_get_default_adapter_cb,
584 /* Parse and fill the bluetooth oob information block */
585 static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
586 struct near_oob_data *oob, uint16_t *props)
591 DBG("total len: %u", eir_data_len);
593 while (len < eir_data_len - 1) {
594 uint8_t eir_len = eir_data[0]; /* EIR field length */
595 uint8_t eir_code; /* EIR field type*/
596 uint8_t data_len; /* EIR data length */
599 /* check for early termination */
605 /* Do not continue EIR Data parsing if got incorrect length */
606 if (len > eir_data_len)
609 data_len = eir_len - 1;
611 eir_code = eir_data[1]; /* EIR code */
614 DBG("type 0x%.2X data_len %u", eir_code, data_len);
618 case EIR_NAME_COMPLETE:
619 oob->bt_name = g_try_malloc0(data_len + 1); /* eos */
621 oob->bt_name_len = data_len;
622 memcpy(oob->bt_name, data, oob->bt_name_len);
623 oob->bt_name[data_len] = 0; /* end str*/
627 case EIR_CLASS_OF_DEVICE:
628 tmp = g_strdup_printf("%02X%02X%02X",
629 *data, *(data + 1), *(data + 2));
631 oob->class_of_device = strtol(tmp, NULL, 16);
632 *props |= OOB_PROPS_COD;
638 oob->spair_hash = g_try_malloc0(OOB_SP_SIZE);
639 if (oob->spair_hash) {
640 memcpy(oob->spair_hash, data, OOB_SP_SIZE);
641 *props |= OOB_PROPS_SP_HASH;
645 case EIR_SP_RANDOMIZER:
646 oob->spair_randomizer = g_try_malloc0(OOB_SP_SIZE);
647 if (oob->spair_randomizer) {
648 memcpy(oob->spair_randomizer,
650 *props |= OOB_PROPS_SP_RANDOM;
654 case EIR_SECURITY_MGR_FLAGS:
655 oob->security_manager_oob_flags = *data;
658 case EIR_UUID128_ALL:
659 /* TODO: Process uuids128
663 default: /* ignore and skip */
664 near_error("Unknown EIR x%02x (len: %d)", eir_code,
669 eir_data += eir_len + 1;
674 * Because of some "old" implementation, "version" will help
675 * to determine the record data structure.
676 * Some specifications are proprietary (eg. "short mode")
677 * and are not fully documented.
678 * mime_properties is a bitmask and should reflect the fields found in
681 int __near_bluetooth_parse_oob_record(struct carrier_data *data,
682 uint16_t *mime_properties,
685 struct near_oob_data *oob;
686 uint16_t bt_oob_data_size;
687 uint8_t *ptr = data->data;
693 oob = g_try_malloc0(sizeof(struct near_oob_data));
695 if (data->type == BT_MIME_V2_1) {
697 * Total OOB data size (including size bytes)
698 * Some implementations (e.g. Android 4.1) stores
699 * the data_size in big endian but NDEF forum spec (BT Secure
700 * Simple Pairing) requires a little endian. At the same time,
701 * the NDEF forum NDEF spec define a payload length as single
702 * byte (and the payload size IS the oob data size).
704 bt_oob_data_size = near_get_le16(ptr);
705 if (bt_oob_data_size > 0xFF) /* Big Endian */
706 bt_oob_data_size = GUINT16_FROM_BE(bt_oob_data_size);
708 bt_oob_data_size -= 2 ; /* remove oob datas size len */
710 /* First item: BD_ADDR (mandatory) */
711 ptr = &data->data[2];
712 oob->bd_addr = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
713 ptr[5], ptr[4], ptr[3], ptr[2], ptr[1], ptr[0]);
715 /* Skip to the next element (optional) */
716 ptr += BT_ADDRESS_SIZE;
717 bt_oob_data_size -= BT_ADDRESS_SIZE ;
719 if (bt_oob_data_size)
720 bt_parse_eir(ptr, bt_oob_data_size, oob,
722 } else if (data->type == BT_MIME_V2_0) {
723 marker = *ptr++; /* could be '$' */
725 oob->bd_addr = g_strdup_printf(
726 "%02X:%02X:%02X:%02X:%02X:%02X",
727 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
728 ptr = ptr + BT_ADDRESS_SIZE;
730 /* Class of device */
731 tmp = g_strdup_printf("%02X%02X%02X",
732 *ptr, *(ptr + 1), *(ptr + 2));
734 oob->class_of_device = strtol(tmp, NULL, 16);
739 /* "Short mode" seems to use a 4 bytes code
740 * instead of 16 bytes...
742 if (marker == '$') { /* Short NFC */
743 memcpy(oob->authentication, ptr, 4);
746 memcpy(oob->authentication, ptr, 16);
750 /* get the device name */
751 oob->bt_name_len = *ptr++;
752 oob->bt_name = g_try_malloc0(oob->bt_name_len+1);
754 memcpy(oob->bt_name, ptr, oob->bt_name_len);
755 oob->bt_name[oob->bt_name_len+1] = 0;
757 ptr = ptr + oob->bt_name_len;
765 /* check and get the default adapter */
766 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
767 if (oob->def_adapter == NULL) {
768 near_error("bt_get_default_adapter failed");
773 return bt_do_pairing(oob);
776 int __near_bluetooth_pair(void *data)
778 struct near_oob_data *oob = data;
780 /* check and get the default adapter */
781 oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
782 if (oob->bt_name == NULL) {
783 near_error("bt_get_default_adapter failed: %d", -EIO);
788 return bt_do_pairing(oob);
791 /* This function is synchronous as oob datas change on each session */
792 static int bt_sync_oob_readlocaldata(DBusConnection *conn, char *adapter_path,
794 char *spair_randomizer)
796 DBusMessage *message, *reply;
798 int hash_len, rndm_len;
800 message = dbus_message_new_method_call(BLUEZ_SERVICE, adapter_path,
801 OOB_INTF, "ReadLocalData");
805 dbus_error_init(&error);
807 reply = dbus_connection_send_with_reply_and_block(conn,
808 message, -1, &error);
810 dbus_message_unref(message);
813 if (dbus_error_is_set(&error) == TRUE) {
814 near_error("%s", error.message);
815 dbus_error_free(&error);
817 near_error("Failed to set property");
822 if (dbus_message_get_args(reply, NULL,
823 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, spair_hash, &hash_len,
824 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
825 spair_randomizer, &rndm_len,
826 DBUS_TYPE_INVALID) == FALSE)
829 if ((hash_len != OOB_SP_SIZE) || (rndm_len != OOB_SP_SIZE)) {
830 DBG("no OOB data found !");
834 dbus_message_unref(reply);
835 DBG("OOB data found");
839 dbus_message_unref(reply);
844 * External API to get bt properties
845 * Prepare a "real" oob datas block
846 * mime_props is a bitmask we use to add or not specific fields in the
847 * oob frame (e.g.: OOB keys)
849 struct carrier_data *__near_bluetooth_local_get_properties(uint16_t mime_props)
851 struct carrier_data *data = NULL;
854 char hash[OOB_SP_SIZE];
855 char random[OOB_SP_SIZE];
857 /* Check adapter datas */
858 if (bt_def_oob_data.def_adapter == NULL) {
859 near_error("No bt adapter info");
863 data = g_try_malloc0(sizeof(*data));
867 data->size = sizeof(uint16_t) /* stored oob size */
868 + BT_ADDRESS_SIZE; /* device address */
870 offset = sizeof(uint16_t); /* Skip size...will be filled later */
872 /* Now prepare data frame */
873 memcpy(data->data + offset, bt_def_oob_data.bd_addr, BT_ADDRESS_SIZE);
874 offset += BT_ADDRESS_SIZE;
877 data->size += COD_SIZE + EIR_HEADER_LEN;
879 data->data[offset++] = COD_SIZE + EIR_SIZE_LEN;
880 data->data[offset++] = EIR_CLASS_OF_DEVICE;
882 memcpy(data->data + offset,
883 (uint8_t *)&bt_def_oob_data.class_of_device, COD_SIZE);
887 * The following data are generated dynamically so we have to read the
888 * local oob data. Only add OOB pairing keys if needed.
890 if ((mime_props & OOB_PROPS_SP) != 0 &&
891 bt_sync_oob_readlocaldata(bt_conn,
892 bt_def_oob_data.def_adapter,
893 hash, random) == OOB_SP_SIZE) {
894 data->size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
898 data->data[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
899 data->data[offset++] = EIR_SP_HASH;
900 memcpy(data->data + offset, hash, OOB_SP_SIZE);
901 offset += OOB_SP_SIZE;
904 if (random != NULL) {
905 data->data[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
906 data->data[offset++] = EIR_SP_RANDOMIZER;
907 memcpy(data->data + offset, random, OOB_SP_SIZE);
908 offset += OOB_SP_SIZE;
913 if (bt_def_oob_data.bt_name != NULL) {
916 data->size += EIR_HEADER_LEN;
918 if (data->size + bt_def_oob_data.bt_name_len
920 name_len = EIR_SIZE_MAX - data->size;
921 data->data[offset++] = name_len + EIR_SIZE_LEN;
923 data->data[offset++] = EIR_NAME_COMPLETE;
925 name_len = bt_def_oob_data.bt_name_len;
926 data->data[offset++] = name_len + EIR_SIZE_LEN;
928 data->data[offset++] = EIR_NAME_SHORT;
931 data->size += name_len;
932 memcpy(data->data + offset, bt_def_oob_data.bt_name, name_len);
936 data->data[0] = data->size ;
938 if (bt_def_oob_data.powered == TRUE)
939 data->state = CPS_ACTIVE;
941 data->state = CPS_INACTIVE;
950 /* BT adapter removed handler */
951 static gboolean bt_adapter_removed(DBusConnection *conn, DBusMessage *message,
954 DBusMessageIter iter;
955 struct near_oob_data *bt_props = user_data;
956 const char *adapter_path;
960 if (bt_props->def_adapter == NULL)
963 g_dbus_remove_watch(bt_conn, adapter_props_watch);
964 adapter_props_watch = 0;
966 if (dbus_message_iter_init(message, &iter) == FALSE)
969 dbus_message_iter_get_basic(&iter, &adapter_path);
971 if (g_strcmp0(adapter_path, bt_props->def_adapter) == 0) {
972 near_info("Remove the default adapter [%s]", adapter_path);
974 __bt_eir_free(bt_props);
975 bt_props->def_adapter = NULL;
981 /* BT default adapter changed handler */
982 static gboolean bt_default_adapter_changed(DBusConnection *conn,
983 DBusMessage *message,
986 struct near_oob_data *bt_props = user_data;
987 DBusMessageIter iter;
988 const char *adapter_path;
992 if (dbus_message_iter_init(message, &iter) == FALSE)
995 g_dbus_remove_watch(bt_conn, adapter_props_watch);
996 adapter_props_watch = 0;
998 dbus_message_iter_get_basic(&iter, &adapter_path);
999 DBG("New default adapter [%s]", adapter_path);
1001 /* Disable the old one */
1002 __bt_eir_free(bt_props);
1003 bt_props->def_adapter = NULL;
1006 bt_refresh_adapter_props(conn, user_data);
1011 static void bt_dbus_disconnect_cb(DBusConnection *conn, void *user_data)
1013 near_error("D-Bus disconnect (BT)");
1017 static gboolean register_bluez(gpointer user_data)
1021 register_bluez_timer = 0;
1023 removed_watch = g_dbus_add_signal_watch(bt_conn, NULL, NULL,
1027 &bt_def_oob_data, NULL);
1030 adapter_watch = g_dbus_add_signal_watch(bt_conn, NULL, NULL,
1032 DEFAULT_ADAPTER_CHANGED,
1033 bt_default_adapter_changed,
1034 &bt_def_oob_data, NULL);
1036 if (removed_watch == 0 || adapter_watch == 0) {
1037 near_error("BlueZ event handlers failed to register.");
1038 g_dbus_remove_watch(bt_conn, removed_watch);
1039 g_dbus_remove_watch(bt_conn, adapter_watch);
1044 if (bt_refresh_adapter_props(bt_conn, user_data) < 0)
1045 near_error("Failed to get BT adapter properties");
1050 static void bt_connect(DBusConnection *conn, void *data)
1052 DBG("connection %p with %p", conn, data);
1054 if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE) {
1055 DBG("Agent already registered");
1060 * BlueZ 5 will register itself as HandoverAgent, give it some time
1061 * to do it before going legacy way.
1063 register_bluez_timer = g_timeout_add_seconds(AGENT_REGISTER_TIMEOUT,
1064 register_bluez, data);
1067 static void bt_disconnect(DBusConnection *conn, void *user_data)
1071 /* If timer is running no BlueZ watchers were registered yet */
1072 if (register_bluez_timer > 0) {
1073 g_source_remove(register_bluez_timer);
1074 register_bluez_timer = 0;
1078 __bt_eir_free(user_data);
1080 g_dbus_remove_watch(bt_conn, removed_watch);
1083 g_dbus_remove_watch(bt_conn, adapter_watch);
1086 g_dbus_remove_watch(bt_conn, adapter_props_watch);
1087 adapter_props_watch = 0;
1090 static int bt_prepare_handlers(DBusConnection *conn)
1092 if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE)
1095 watch = g_dbus_add_service_watch(bt_conn, BLUEZ_SERVICE,
1098 &bt_def_oob_data, NULL);
1100 near_error("BlueZ service watch handler failed to register.");
1101 g_dbus_remove_watch(bt_conn, watch);
1108 void __near_bluetooth_legacy_start(void)
1112 bt_prepare_handlers(bt_conn);
1115 void __near_bluetooth_legacy_stop(void)
1119 g_dbus_remove_watch(bt_conn, watch);
1122 bt_disconnect(bt_conn, &bt_def_oob_data);
1125 /* Bluetooth exiting function */
1126 void __near_bluetooth_cleanup(void)
1130 if (bt_conn == NULL)
1133 __near_bluetooth_legacy_stop();
1135 dbus_connection_unref(bt_conn);
1139 * Bluetooth initialization function.
1140 * Allocate bt local settings storage
1141 * and setup event handlers
1143 int __near_bluetooth_init(void)
1149 dbus_error_init(&err);
1151 /* save the dbus connection */
1152 bt_conn = near_dbus_get_connection();
1153 if (bt_conn == NULL) {
1154 if (dbus_error_is_set(&err) == TRUE) {
1155 near_error("%s", err.message);
1156 dbus_error_free(&err);
1158 near_error("Can't register with system bus\n");
1162 /* dbus disconnect callback */
1163 g_dbus_set_disconnect_function(bt_conn, bt_dbus_disconnect_cb,
1166 /* Set bluez event handlers */
1167 return bt_prepare_handlers(bt_conn);