mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2025-01-25 05:43:33 +08:00
Move name resolving control into hciops
Due to the way legacy name resolving is handled for the mgmt interface the entire logic that was previously part of the core daemon needs to be moved into hciops. Essentially hciops now contains what the mgmt code in the kernel will do when mgmtops is used.
This commit is contained in:
parent
9a1006eebc
commit
2a8c76faaf
297
plugins/hciops.c
297
plugins/hciops.c
@ -57,6 +57,7 @@
|
||||
#define DISCOV_HALTED 0
|
||||
#define DISCOV_INQ 1
|
||||
#define DISCOV_SCAN 2
|
||||
#define DISCOV_NAMES 3
|
||||
|
||||
#define TIMEOUT_BR_LE_SCAN 5120 /* TGAP(100)/2 */
|
||||
#define TIMEOUT_LE_SCAN 10240 /* TGAP(gen_disc_scan_min) */
|
||||
@ -64,7 +65,7 @@
|
||||
#define LENGTH_BR_INQ 0x08
|
||||
#define LENGTH_BR_LE_INQ 0x04
|
||||
|
||||
static int hciops_start_scanning(int index, int timeout);
|
||||
static int start_scanning(int index, int timeout);
|
||||
|
||||
static int child_pipe[2] = { -1, -1 };
|
||||
|
||||
@ -106,6 +107,19 @@ struct oob_data {
|
||||
uint8_t randomizer[16];
|
||||
};
|
||||
|
||||
enum name_state {
|
||||
NAME_UNKNOWN,
|
||||
NAME_NEEDED,
|
||||
NAME_NOT_NEEDED,
|
||||
NAME_PENDING,
|
||||
};
|
||||
|
||||
struct found_dev {
|
||||
bdaddr_t bdaddr;
|
||||
int8_t rssi;
|
||||
enum name_state name_state;
|
||||
};
|
||||
|
||||
static int max_dev = -1;
|
||||
static struct dev_info {
|
||||
int id;
|
||||
@ -153,19 +167,76 @@ static struct dev_info {
|
||||
|
||||
GSList *connections;
|
||||
|
||||
GSList *found_devs;
|
||||
GSList *need_name;
|
||||
|
||||
guint stop_scan_id;
|
||||
} *devs = NULL;
|
||||
|
||||
static inline int get_state(int index)
|
||||
static int found_dev_rssi_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
const struct found_dev *d1 = a, *d2 = b;
|
||||
int rssi1, rssi2;
|
||||
|
||||
return dev->discov_state;
|
||||
if (d2->name_state == NAME_NOT_NEEDED)
|
||||
return -1;
|
||||
|
||||
rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi;
|
||||
rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi;
|
||||
|
||||
return rssi1 - rssi2;
|
||||
}
|
||||
|
||||
static inline gboolean is_resolvname_enabled(void)
|
||||
static int found_dev_bda_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return main_opts.name_resolv ? TRUE : FALSE;
|
||||
const struct found_dev *d1 = a, *d2 = b;
|
||||
|
||||
return bacmp(&d1->bdaddr, &d2->bdaddr);
|
||||
}
|
||||
|
||||
static void found_dev_cleanup(struct dev_info *info)
|
||||
{
|
||||
g_slist_free_full(info->found_devs, g_free);
|
||||
info->found_devs = NULL;
|
||||
|
||||
g_slist_free_full(info->need_name, g_free);
|
||||
info->need_name = NULL;
|
||||
}
|
||||
|
||||
static int resolve_name(struct dev_info *info, bdaddr_t *bdaddr)
|
||||
{
|
||||
remote_name_req_cp cp;
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("hci%d dba %s", info->id, addr);
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, bdaddr);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
|
||||
if (hci_send_cmd(info->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ,
|
||||
REMOTE_NAME_REQ_CP_SIZE, &cp) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resolve_names(struct dev_info *info, struct btd_adapter *adapter)
|
||||
{
|
||||
struct found_dev *dev;
|
||||
|
||||
DBG("found_dev %u need_name %u", g_slist_length(info->found_devs),
|
||||
g_slist_length(info->need_name));
|
||||
|
||||
if (g_slist_length(info->need_name) == 0)
|
||||
return -ENOENT;
|
||||
|
||||
dev = info->need_name->data;
|
||||
resolve_name(info, &dev->bdaddr);
|
||||
dev->name_state = NAME_PENDING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_state(int index, int state)
|
||||
@ -188,14 +259,16 @@ static void set_state(int index, int state)
|
||||
|
||||
switch (dev->discov_state) {
|
||||
case DISCOV_HALTED:
|
||||
if (adapter_get_state(adapter) == STATE_SUSPENDED)
|
||||
return;
|
||||
|
||||
adapter_set_state(adapter, STATE_IDLE);
|
||||
found_dev_cleanup(dev);
|
||||
adapter_set_discovering(adapter, FALSE);
|
||||
break;
|
||||
case DISCOV_INQ:
|
||||
case DISCOV_SCAN:
|
||||
adapter_set_state(adapter, STATE_DISCOV);
|
||||
adapter_set_discovering(adapter, TRUE);
|
||||
break;
|
||||
case DISCOV_NAMES:
|
||||
if (resolve_names(dev, adapter) < 0)
|
||||
set_state(index, DISCOV_HALTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1706,13 +1779,10 @@ static inline void inquiry_complete_evt(int index, uint8_t status)
|
||||
adapter_type = get_adapter_type(index);
|
||||
|
||||
if (adapter_type == BR_EDR_LE &&
|
||||
adapter_has_discov_sessions(adapter)) {
|
||||
int err = hciops_start_scanning(index, TIMEOUT_BR_LE_SCAN);
|
||||
if (err < 0)
|
||||
set_state(index, DISCOV_HALTED);
|
||||
} else {
|
||||
set_state(index, DISCOV_HALTED);
|
||||
}
|
||||
start_scanning(index, TIMEOUT_BR_LE_SCAN) == 0)
|
||||
return;
|
||||
|
||||
set_state(index, DISCOV_NAMES);
|
||||
}
|
||||
|
||||
static inline void cc_inquiry_cancel(int index, uint8_t status)
|
||||
@ -1727,15 +1797,14 @@ static inline void cc_inquiry_cancel(int index, uint8_t status)
|
||||
|
||||
static inline void cc_le_set_scan_enable(int index, uint8_t status)
|
||||
{
|
||||
int state;
|
||||
struct dev_info *info = &devs[index];
|
||||
|
||||
if (status) {
|
||||
error("LE Set Scan Enable Failed with status 0x%02x", status);
|
||||
return;
|
||||
}
|
||||
|
||||
state = get_state(index);
|
||||
if (state == DISCOV_SCAN)
|
||||
if (info->discov_state == DISCOV_SCAN)
|
||||
set_state(index, DISCOV_HALTED);
|
||||
else
|
||||
set_state(index, DISCOV_SCAN);
|
||||
@ -1816,16 +1885,43 @@ static inline void remote_name_information(int index, void *ptr)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
evt_remote_name_req_complete *evt = ptr;
|
||||
struct btd_adapter *adapter;
|
||||
char name[MAX_NAME_LENGTH + 1];
|
||||
struct found_dev *found;
|
||||
|
||||
GSList *match;
|
||||
|
||||
DBG("hci%d status %u", index, evt->status);
|
||||
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
if (!evt->status)
|
||||
if (evt->status == 0) {
|
||||
memcpy(name, evt->name, MAX_NAME_LENGTH);
|
||||
btd_event_remote_name(&dev->bdaddr, &evt->bdaddr, name);
|
||||
}
|
||||
|
||||
btd_event_remote_name(&dev->bdaddr, &evt->bdaddr, evt->status, name);
|
||||
adapter = manager_find_adapter_by_id(index);
|
||||
if (!adapter) {
|
||||
error("No matching adapter found");
|
||||
return;
|
||||
}
|
||||
|
||||
match = g_slist_find_custom(dev->need_name, &evt->bdaddr,
|
||||
found_dev_bda_cmp);
|
||||
if (match == NULL)
|
||||
return;
|
||||
|
||||
found = match->data;
|
||||
found->name_state = NAME_NOT_NEEDED;
|
||||
|
||||
dev->need_name = g_slist_remove_link(dev->need_name, match);
|
||||
|
||||
match->next = dev->found_devs;
|
||||
dev->found_devs = match;
|
||||
dev->found_devs = g_slist_sort(dev->found_devs, found_dev_rssi_cmp);
|
||||
|
||||
if (resolve_names(dev, adapter) < 0)
|
||||
set_state(index, DISCOV_HALTED);
|
||||
}
|
||||
|
||||
static inline void remote_version_information(int index, void *ptr)
|
||||
@ -1848,24 +1944,48 @@ static inline void remote_version_information(int index, void *ptr)
|
||||
btohs(evt->lmp_subver));
|
||||
}
|
||||
|
||||
static void dev_found(struct dev_info *info, bdaddr_t *dba, addr_type_t type,
|
||||
uint8_t cod, int8_t rssi, uint8_t cfm_name,
|
||||
uint8_t *eir, uint8_t eir_len)
|
||||
{
|
||||
struct found_dev *dev;
|
||||
GSList *match;
|
||||
|
||||
match = g_slist_find_custom(info->found_devs, dba, found_dev_bda_cmp);
|
||||
if (match != NULL) {
|
||||
cfm_name = 0;
|
||||
goto event;
|
||||
}
|
||||
|
||||
dev = g_new0(struct found_dev, 1);
|
||||
bacpy(&dev->bdaddr, dba);
|
||||
dev->rssi = rssi;
|
||||
if (cfm_name)
|
||||
dev->name_state = NAME_UNKNOWN;
|
||||
else
|
||||
dev->name_state = NAME_NOT_NEEDED;
|
||||
|
||||
info->found_devs = g_slist_prepend(info->found_devs, dev);
|
||||
|
||||
event:
|
||||
btd_event_device_found(&info->bdaddr, dba, type, cod, rssi, cfm_name,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static inline void inquiry_result(int index, int plen, void *ptr)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
uint8_t num = *(uint8_t *) ptr++;
|
||||
int i;
|
||||
|
||||
/* Skip if it is not in Inquiry state */
|
||||
if (get_state(index) != DISCOV_INQ)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
inquiry_info *info = ptr;
|
||||
uint32_t class = info->dev_class[0] |
|
||||
(info->dev_class[1] << 8) |
|
||||
(info->dev_class[2] << 16);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
ADDR_TYPE_BREDR, class, 0, 0, NULL, 0);
|
||||
dev_found(dev, &info->bdaddr, ADDR_TYPE_BREDR, class, 0, 1,
|
||||
NULL, 0);
|
||||
ptr += INQUIRY_INFO_SIZE;
|
||||
}
|
||||
}
|
||||
@ -1886,9 +2006,8 @@ static inline void inquiry_result_with_rssi(int index, int plen, void *ptr)
|
||||
| (info->dev_class[1] << 8)
|
||||
| (info->dev_class[2] << 16);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
ADDR_TYPE_BREDR, class,
|
||||
info->rssi, 0, NULL, 0);
|
||||
dev_found(dev, &info->bdaddr, ADDR_TYPE_BREDR, class,
|
||||
info->rssi, 1, NULL, 0);
|
||||
ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE;
|
||||
}
|
||||
} else {
|
||||
@ -1898,9 +2017,8 @@ static inline void inquiry_result_with_rssi(int index, int plen, void *ptr)
|
||||
| (info->dev_class[1] << 8)
|
||||
| (info->dev_class[2] << 16);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
ADDR_TYPE_BREDR, class,
|
||||
info->rssi, 0, NULL, 0);
|
||||
dev_found(dev, &info->bdaddr, ADDR_TYPE_BREDR, class,
|
||||
info->rssi, 1, NULL, 0);
|
||||
ptr += INQUIRY_INFO_WITH_RSSI_SIZE;
|
||||
}
|
||||
}
|
||||
@ -1918,9 +2036,8 @@ static inline void extended_inquiry_result(int index, int plen, void *ptr)
|
||||
| (info->dev_class[1] << 8)
|
||||
| (info->dev_class[2] << 16);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
ADDR_TYPE_BREDR, class, info->rssi,
|
||||
0, info->data, HCI_MAX_EIR_LENGTH);
|
||||
dev_found(dev, &info->bdaddr, ADDR_TYPE_BREDR, class,
|
||||
info->rssi, 1, info->data, HCI_MAX_EIR_LENGTH);
|
||||
ptr += EXTENDED_INQUIRY_INFO_SIZE;
|
||||
}
|
||||
}
|
||||
@ -2158,9 +2275,8 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
|
||||
info = (le_advertising_info *) &meta->data[1];
|
||||
rssi = *(info->data + info->length);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
le_addr_type(info->bdaddr_type), 0, rssi, 0,
|
||||
info->data, info->length);
|
||||
dev_found(dev, &info->bdaddr, le_addr_type(info->bdaddr_type), 0, rssi,
|
||||
0, info->data, info->length);
|
||||
|
||||
num_reports--;
|
||||
|
||||
@ -2169,9 +2285,8 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
|
||||
RSSI_SIZE);
|
||||
rssi = *(info->data + info->length);
|
||||
|
||||
btd_event_device_found(&dev->bdaddr, &info->bdaddr,
|
||||
le_addr_type(info->bdaddr_type),
|
||||
0, rssi, 0, info->data, info->length);
|
||||
dev_found(dev, &info->bdaddr, le_addr_type(info->bdaddr_type),
|
||||
0, rssi, 0, info->data, info->length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2921,7 +3036,7 @@ static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hciops_start_inquiry(int index, uint8_t length)
|
||||
static int start_inquiry(int index, uint8_t length)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
|
||||
@ -2973,7 +3088,7 @@ static gboolean stop_le_scan_cb(gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int hciops_start_scanning(int index, int timeout)
|
||||
static int start_scanning(int index, int timeout)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
le_set_scan_parameters_cp cp;
|
||||
@ -3018,26 +3133,6 @@ static int hciops_stop_scanning(int index)
|
||||
return le_set_scan_enable(index, 0);
|
||||
}
|
||||
|
||||
static int hciops_resolve_name(int index, bdaddr_t *bdaddr)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
remote_name_req_cp cp;
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("hci%d dba %s", index, addr);
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, bdaddr);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
|
||||
if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ,
|
||||
REMOTE_NAME_REQ_CP_SIZE, &cp) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hciops_set_name(int index, const char *name)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
@ -3058,19 +3153,32 @@ static int hciops_set_name(int index, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr)
|
||||
static int cancel_resolve_name(int index)
|
||||
{
|
||||
struct dev_info *dev = &devs[index];
|
||||
struct dev_info *info = &devs[index];
|
||||
struct found_dev *dev;
|
||||
remote_name_req_cancel_cp cp;
|
||||
char addr[18];
|
||||
struct btd_adapter *adapter;
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("hci%d dba %s", index, addr);
|
||||
DBG("hci%d", index);
|
||||
|
||||
if (g_slist_length(info->need_name) == 0)
|
||||
return 0;
|
||||
|
||||
dev = info->need_name->data;
|
||||
if (dev->name_state != NAME_PENDING)
|
||||
return 0;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, bdaddr);
|
||||
bacpy(&cp.bdaddr, &dev->bdaddr);
|
||||
|
||||
if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL,
|
||||
adapter = manager_find_adapter_by_id(index);
|
||||
if (adapter)
|
||||
adapter_set_discovering(adapter, FALSE);
|
||||
|
||||
found_dev_cleanup(info);
|
||||
|
||||
if (hci_send_cmd(info->sk, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL,
|
||||
REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp) < 0)
|
||||
return -errno;
|
||||
|
||||
@ -3081,13 +3189,15 @@ static int hciops_start_discovery(int index)
|
||||
{
|
||||
int adapter_type = get_adapter_type(index);
|
||||
|
||||
DBG("hci%u", index);
|
||||
|
||||
switch (adapter_type) {
|
||||
case BR_EDR_LE:
|
||||
return hciops_start_inquiry(index, LENGTH_BR_LE_INQ);
|
||||
return start_inquiry(index, LENGTH_BR_LE_INQ);
|
||||
case BR_EDR:
|
||||
return hciops_start_inquiry(index, LENGTH_BR_INQ);
|
||||
return start_inquiry(index, LENGTH_BR_INQ);
|
||||
case LE_ONLY:
|
||||
return hciops_start_scanning(index, TIMEOUT_LE_SCAN);
|
||||
return start_scanning(index, TIMEOUT_LE_SCAN);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -3104,6 +3214,8 @@ static int hciops_stop_discovery(int index)
|
||||
return hciops_stop_inquiry(index);
|
||||
case DISCOV_SCAN:
|
||||
return hciops_stop_scanning(index);
|
||||
case DISCOV_NAMES:
|
||||
cancel_resolve_name(index);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -3622,7 +3734,36 @@ static int hciops_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
|
||||
static int hciops_confirm_name(int index, bdaddr_t *bdaddr,
|
||||
gboolean name_known)
|
||||
{
|
||||
return -ENOSYS;
|
||||
struct dev_info *info = &devs[index];
|
||||
struct found_dev *dev;
|
||||
GSList *match;
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("hci%u %s name_known %u", index, addr, name_known);
|
||||
|
||||
match = g_slist_find_custom(info->found_devs, bdaddr,
|
||||
found_dev_bda_cmp);
|
||||
if (match == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
dev = match->data;
|
||||
|
||||
if (name_known) {
|
||||
dev->name_state = NAME_NOT_NEEDED;
|
||||
info->found_devs = g_slist_sort(info->found_devs,
|
||||
found_dev_rssi_cmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->name_state = NAME_NEEDED;
|
||||
info->found_devs = g_slist_remove_link(info->found_devs, match);
|
||||
|
||||
match->next = info->need_name;
|
||||
info->need_name = match;
|
||||
info->need_name = g_slist_sort(info->need_name, found_dev_rssi_cmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct btd_adapter_ops hci_ops = {
|
||||
@ -3634,8 +3775,6 @@ static struct btd_adapter_ops hci_ops = {
|
||||
.set_limited_discoverable = hciops_set_limited_discoverable,
|
||||
.start_discovery = hciops_start_discovery,
|
||||
.stop_discovery = hciops_stop_discovery,
|
||||
.resolve_name = hciops_resolve_name,
|
||||
.cancel_resolve_name = hciops_cancel_resolve_name,
|
||||
.set_name = hciops_set_name,
|
||||
.set_dev_class = hciops_set_dev_class,
|
||||
.set_fast_connectable = hciops_set_fast_connectable,
|
||||
|
@ -1310,7 +1310,7 @@ static void mgmt_remote_name(int sk, uint16_t index, void *buf, size_t len)
|
||||
ba2str(&ev->bdaddr, addr);
|
||||
DBG("hci%u addr %s, name %s", index, addr, ev->name);
|
||||
|
||||
btd_event_remote_name(&info->bdaddr, &ev->bdaddr, 0, (char *) ev->name);
|
||||
btd_event_remote_name(&info->bdaddr, &ev->bdaddr, (char *) ev->name);
|
||||
}
|
||||
|
||||
static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len)
|
||||
@ -1318,7 +1318,6 @@ static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len)
|
||||
struct mgmt_mode *ev = buf;
|
||||
struct controller_info *info;
|
||||
struct btd_adapter *adapter;
|
||||
int state;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
error("Too small discovering event");
|
||||
@ -1338,12 +1337,7 @@ static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len)
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
if (ev->val)
|
||||
state = STATE_DISCOV;
|
||||
else
|
||||
state = STATE_IDLE;
|
||||
|
||||
adapter_set_state(adapter, state);
|
||||
adapter_set_discovering(adapter, ev->val);
|
||||
}
|
||||
|
||||
static void mgmt_device_blocked(int sk, uint16_t index, void *buf, size_t len)
|
||||
@ -1636,16 +1630,6 @@ static int mgmt_stop_discovery(int index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mgmt_resolve_name(int index, bdaddr_t *bdaddr)
|
||||
{
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("index %d addr %s", index, addr);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static int mgmt_set_name(int index, const char *name)
|
||||
{
|
||||
char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)];
|
||||
@ -1667,16 +1651,6 @@ static int mgmt_set_name(int index, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mgmt_cancel_resolve_name(int index, bdaddr_t *bdaddr)
|
||||
{
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
DBG("index %d addr %s", index, addr);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static int mgmt_set_fast_connectable(int index, gboolean enable)
|
||||
{
|
||||
char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)];
|
||||
@ -2080,8 +2054,6 @@ static struct btd_adapter_ops mgmt_ops = {
|
||||
.set_limited_discoverable = mgmt_set_limited_discoverable,
|
||||
.start_discovery = mgmt_start_discovery,
|
||||
.stop_discovery = mgmt_stop_discovery,
|
||||
.resolve_name = mgmt_resolve_name,
|
||||
.cancel_resolve_name = mgmt_cancel_resolve_name,
|
||||
.set_name = mgmt_set_name,
|
||||
.set_dev_class = mgmt_set_dev_class,
|
||||
.set_fast_connectable = mgmt_set_fast_connectable,
|
||||
|
360
src/adapter.c
360
src/adapter.c
@ -134,7 +134,9 @@ struct btd_adapter {
|
||||
GSList *devices; /* Devices structure pointers */
|
||||
GSList *mode_sessions; /* Request Mode sessions */
|
||||
GSList *disc_sessions; /* Discovery sessions */
|
||||
guint scheduler_id; /* Scheduler handle */
|
||||
guint discov_id; /* Discovery timer */
|
||||
gboolean discovering; /* Discovery active */
|
||||
gboolean discov_suspended; /* Discovery suspended */
|
||||
guint auto_timeout_id; /* Automatic connections timeout */
|
||||
sdp_list_t *services; /* Services associated to adapter */
|
||||
|
||||
@ -153,26 +155,6 @@ struct btd_adapter {
|
||||
GSList *loaded_drivers;
|
||||
};
|
||||
|
||||
static int found_device_cmp(const struct remote_dev_info *d1,
|
||||
const struct remote_dev_info *d2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (bacmp(&d2->bdaddr, BDADDR_ANY)) {
|
||||
ret = bacmp(&d1->bdaddr, &d2->bdaddr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (d2->name_status != NAME_ANY) {
|
||||
ret = (d1->name_status - d2->name_status);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dev_info_free(void *data)
|
||||
{
|
||||
struct remote_dev_info *dev = data;
|
||||
@ -190,71 +172,6 @@ int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
|
||||
return adapter_ops->set_dev_class(adapter->dev_id, major, minor);
|
||||
}
|
||||
|
||||
static int pending_remote_name_cancel(struct btd_adapter *adapter)
|
||||
{
|
||||
struct remote_dev_info *dev, match;
|
||||
int err;
|
||||
|
||||
/* find the pending remote name request */
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, BDADDR_ANY);
|
||||
match.name_status = NAME_REQUESTED;
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
if (!dev) /* no pending request */
|
||||
return -ENODATA;
|
||||
|
||||
err = adapter_ops->cancel_resolve_name(adapter->dev_id, &dev->bdaddr);
|
||||
if (err < 0)
|
||||
error("Remote name cancel failed: %s(%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
adapter_set_state(adapter, STATE_IDLE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adapter_resolve_names(struct btd_adapter *adapter)
|
||||
{
|
||||
struct remote_dev_info *dev, match;
|
||||
int err;
|
||||
|
||||
/* Do not attempt to resolve more names if on suspended state */
|
||||
if (adapter->state == STATE_SUSPENDED)
|
||||
return 0;
|
||||
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, BDADDR_ANY);
|
||||
match.name_status = NAME_REQUIRED;
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
if (!dev)
|
||||
return -ENODATA;
|
||||
|
||||
/* send at least one request or return failed if the list is empty */
|
||||
do {
|
||||
/* flag to indicate the current remote name requested */
|
||||
dev->name_status = NAME_REQUESTED;
|
||||
|
||||
err = adapter_ops->resolve_name(adapter->dev_id, &dev->bdaddr);
|
||||
|
||||
if (!err)
|
||||
break;
|
||||
|
||||
error("Unable to send HCI remote name req: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
/* if failed, request the next element */
|
||||
/* remove the element from the list */
|
||||
adapter_remove_found_device(adapter, &dev->bdaddr);
|
||||
|
||||
/* get the next element */
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
} while (dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const char *mode2str(uint8_t mode)
|
||||
{
|
||||
switch(mode) {
|
||||
@ -634,10 +551,9 @@ static GSList *remove_bredr(GSList *all)
|
||||
return le;
|
||||
}
|
||||
|
||||
/* Called when a session gets removed or the adapter is stopped */
|
||||
static void stop_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
pending_remote_name_cancel(adapter);
|
||||
|
||||
adapter->found_devices = remove_bredr(adapter->found_devices);
|
||||
|
||||
if (adapter->oor_devices) {
|
||||
@ -646,15 +562,15 @@ static void stop_discovery(struct btd_adapter *adapter)
|
||||
}
|
||||
|
||||
/* Reset if suspended, otherwise remove timer (software scheduler)
|
||||
or request inquiry to stop */
|
||||
if (adapter->state == STATE_SUSPENDED) {
|
||||
adapter_set_state(adapter, STATE_IDLE);
|
||||
* or request inquiry to stop */
|
||||
if (adapter->discov_suspended) {
|
||||
adapter->discov_suspended = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (adapter->scheduler_id) {
|
||||
g_source_remove(adapter->scheduler_id);
|
||||
adapter->scheduler_id = 0;
|
||||
if (adapter->discov_id > 0) {
|
||||
g_source_remove(adapter->discov_id);
|
||||
adapter->discov_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1142,30 +1058,15 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
|
||||
ADDR_TYPE_BREDR);
|
||||
}
|
||||
|
||||
static int start_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
/* Do not start if suspended */
|
||||
if (adapter->state == STATE_SUSPENDED)
|
||||
return 0;
|
||||
|
||||
/* Postpone discovery if still resolving names */
|
||||
if (adapter->state == STATE_RESOLVNAME)
|
||||
return -EINPROGRESS;
|
||||
|
||||
pending_remote_name_cancel(adapter);
|
||||
|
||||
return adapter_ops->start_discovery(adapter->dev_id);
|
||||
}
|
||||
|
||||
static gboolean discovery_cb(gpointer user_data)
|
||||
{
|
||||
struct btd_adapter *adapter = user_data;
|
||||
int err;
|
||||
|
||||
err = start_discovery(adapter);
|
||||
if (err == -EINPROGRESS)
|
||||
return TRUE;
|
||||
else if (err < 0)
|
||||
adapter->discov_id = 0;
|
||||
|
||||
err = adapter_ops->start_discovery(adapter->dev_id);
|
||||
if (err < 0)
|
||||
error("start_discovery: %s (%d)", strerror(-err), -err);
|
||||
|
||||
return FALSE;
|
||||
@ -1197,8 +1098,11 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
|
||||
g_slist_free(adapter->oor_devices);
|
||||
adapter->oor_devices = NULL;
|
||||
|
||||
err = start_discovery(adapter);
|
||||
if (err < 0 && err != -EINPROGRESS)
|
||||
if (adapter->discov_suspended)
|
||||
goto done;
|
||||
|
||||
err = adapter_ops->start_discovery(adapter->dev_id);
|
||||
if (err < 0)
|
||||
return btd_error_failed(msg, strerror(-err));
|
||||
|
||||
done:
|
||||
@ -1294,13 +1198,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
|
||||
DBUS_TYPE_UINT32, &adapter->pairable_timeout);
|
||||
|
||||
|
||||
if (adapter->state == STATE_DISCOV)
|
||||
value = TRUE;
|
||||
else
|
||||
value = FALSE;
|
||||
|
||||
/* Discovering */
|
||||
dict_append_entry(&dict, "Discovering", DBUS_TYPE_BOOLEAN, &value);
|
||||
dict_append_entry(&dict, "Discovering", DBUS_TYPE_BOOLEAN,
|
||||
&adapter->discovering);
|
||||
|
||||
/* Devices */
|
||||
devices = g_new0(char *, g_slist_length(adapter->devices) + 1);
|
||||
@ -1545,15 +1445,14 @@ static struct btd_device *create_device_internal(DBusConnection *conn,
|
||||
struct btd_adapter *adapter,
|
||||
const char *address, int *err)
|
||||
{
|
||||
struct remote_dev_info *dev, match;
|
||||
struct remote_dev_info *dev;
|
||||
struct btd_device *device;
|
||||
bdaddr_t addr;
|
||||
addr_type_t type;
|
||||
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
str2ba(address, &match.bdaddr);
|
||||
match.name_status = NAME_ANY;
|
||||
str2ba(address, &addr);
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
dev = adapter_search_found_devices(adapter, &addr);
|
||||
if (dev)
|
||||
type = dev->type;
|
||||
else
|
||||
@ -2198,13 +2097,6 @@ static void emit_device_disappeared(gpointer data, gpointer user_data)
|
||||
adapter->found_devices = g_slist_remove(adapter->found_devices, dev);
|
||||
}
|
||||
|
||||
static void update_oor_devices(struct btd_adapter *adapter)
|
||||
{
|
||||
g_slist_foreach(adapter->oor_devices, emit_device_disappeared, adapter);
|
||||
g_slist_free_full(adapter->oor_devices, dev_info_free);
|
||||
adapter->oor_devices = g_slist_copy(adapter->found_devices);
|
||||
}
|
||||
|
||||
void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
|
||||
uint8_t *on_mode, gboolean *pairable)
|
||||
{
|
||||
@ -2241,7 +2133,6 @@ void btd_adapter_start(struct btd_adapter *adapter)
|
||||
adapter->up = TRUE;
|
||||
adapter->discov_timeout = get_discoverable_timeout(address);
|
||||
adapter->pairable_timeout = get_pairable_timeout(address);
|
||||
adapter->state = STATE_IDLE;
|
||||
adapter->mode = MODE_CONNECTABLE;
|
||||
adapter->off_timer = 0;
|
||||
|
||||
@ -2386,7 +2277,7 @@ int btd_adapter_stop(struct btd_adapter *adapter)
|
||||
ADAPTER_INTERFACE, "Pairable",
|
||||
DBUS_TYPE_BOOLEAN, &prop_false);
|
||||
|
||||
if (adapter->state != STATE_IDLE)
|
||||
if (adapter->discovering)
|
||||
emit_property_changed(connection, adapter->path,
|
||||
ADAPTER_INTERFACE, "Discovering",
|
||||
DBUS_TYPE_BOOLEAN, &prop_false);
|
||||
@ -2397,7 +2288,6 @@ int btd_adapter_stop(struct btd_adapter *adapter)
|
||||
adapter->up = FALSE;
|
||||
adapter->scan_mode = SCAN_DISABLED;
|
||||
adapter->mode = MODE_OFF;
|
||||
adapter->state = STATE_IDLE;
|
||||
adapter->off_requested = FALSE;
|
||||
|
||||
call_adapter_powered_callbacks(adapter, FALSE);
|
||||
@ -2573,82 +2463,73 @@ void adapter_set_allow_name_changes(struct btd_adapter *adapter,
|
||||
adapter->allow_name_changes = allow_name_changes;
|
||||
}
|
||||
|
||||
static inline void suspend_discovery(struct btd_adapter *adapter)
|
||||
void adapter_set_discovering(struct btd_adapter *adapter,
|
||||
gboolean discovering)
|
||||
{
|
||||
if (adapter->state != STATE_SUSPENDED)
|
||||
const char *path = adapter->path;
|
||||
|
||||
adapter->discovering = discovering;
|
||||
|
||||
emit_property_changed(connection, path,
|
||||
ADAPTER_INTERFACE, "Discovering",
|
||||
DBUS_TYPE_BOOLEAN, &discovering);
|
||||
|
||||
if (discovering)
|
||||
return;
|
||||
|
||||
g_slist_foreach(adapter->oor_devices, emit_device_disappeared, adapter);
|
||||
g_slist_free_full(adapter->oor_devices, dev_info_free);
|
||||
adapter->oor_devices = g_slist_copy(adapter->found_devices);
|
||||
|
||||
if (!adapter_has_discov_sessions(adapter) || adapter->discov_suspended)
|
||||
return;
|
||||
|
||||
DBG("hci%u enabling timer, disc_sessions %u", adapter->dev_id,
|
||||
g_slist_length(adapter->disc_sessions));
|
||||
|
||||
adapter->discov_id = g_timeout_add_seconds(main_opts.discov_interval,
|
||||
discovery_cb, adapter);
|
||||
}
|
||||
|
||||
static void suspend_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
if (adapter->disc_sessions == NULL || adapter->discov_suspended)
|
||||
return;
|
||||
|
||||
DBG("Suspending discovery");
|
||||
|
||||
if (adapter->oor_devices) {
|
||||
g_slist_free(adapter->oor_devices);
|
||||
adapter->oor_devices = NULL;
|
||||
}
|
||||
|
||||
if (adapter->scheduler_id) {
|
||||
g_source_remove(adapter->scheduler_id);
|
||||
adapter->scheduler_id = 0;
|
||||
}
|
||||
adapter->discov_suspended = TRUE;
|
||||
|
||||
adapter_ops->stop_discovery(adapter->dev_id);
|
||||
if (adapter->discov_id > 0) {
|
||||
g_source_remove(adapter->discov_id);
|
||||
adapter->discov_id = 0;
|
||||
} else
|
||||
adapter_ops->stop_discovery(adapter->dev_id);
|
||||
}
|
||||
|
||||
void adapter_set_state(struct btd_adapter *adapter, int state)
|
||||
static int found_device_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const char *path = adapter->path;
|
||||
gboolean discov_active;
|
||||
const struct remote_dev_info *d = a;
|
||||
const bdaddr_t *bdaddr = b;
|
||||
|
||||
if (adapter->state == state)
|
||||
return;
|
||||
if (bacmp(bdaddr, BDADDR_ANY) == 0)
|
||||
return 0;
|
||||
|
||||
adapter->state = state;
|
||||
|
||||
DBG("hci%d: new state %d", adapter->dev_id, adapter->state);
|
||||
|
||||
switch (adapter->state) {
|
||||
case STATE_IDLE:
|
||||
if (main_opts.name_resolv &&
|
||||
adapter_has_discov_sessions(adapter) &&
|
||||
adapter_resolve_names(adapter) == 0) {
|
||||
adapter->state = STATE_RESOLVNAME;
|
||||
return;
|
||||
}
|
||||
|
||||
update_oor_devices(adapter);
|
||||
|
||||
discov_active = FALSE;
|
||||
emit_property_changed(connection, path,
|
||||
ADAPTER_INTERFACE, "Discovering",
|
||||
DBUS_TYPE_BOOLEAN, &discov_active);
|
||||
|
||||
if (adapter_has_discov_sessions(adapter)) {
|
||||
adapter->scheduler_id = g_timeout_add_seconds(
|
||||
main_opts.discov_interval,
|
||||
discovery_cb, adapter);
|
||||
}
|
||||
break;
|
||||
case STATE_DISCOV:
|
||||
discov_active = TRUE;
|
||||
emit_property_changed(connection, path,
|
||||
ADAPTER_INTERFACE, "Discovering",
|
||||
DBUS_TYPE_BOOLEAN, &discov_active);
|
||||
break;
|
||||
case STATE_SUSPENDED:
|
||||
suspend_discovery(adapter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int adapter_get_state(struct btd_adapter *adapter)
|
||||
{
|
||||
return adapter->state;
|
||||
return bacmp(&d->bdaddr, bdaddr);
|
||||
}
|
||||
|
||||
struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter,
|
||||
struct remote_dev_info *match)
|
||||
bdaddr_t *bdaddr)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
l = g_slist_find_custom(adapter->found_devices, match,
|
||||
(GCompareFunc) found_device_cmp);
|
||||
l = g_slist_find_custom(adapter->found_devices, bdaddr,
|
||||
found_device_cmp);
|
||||
if (l)
|
||||
return l->data;
|
||||
|
||||
@ -2815,8 +2696,7 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
|
||||
static struct remote_dev_info *found_device_new(const bdaddr_t *bdaddr,
|
||||
addr_type_t type, const char *name,
|
||||
const char *alias, uint32_t class,
|
||||
gboolean legacy, name_status_t status,
|
||||
int flags)
|
||||
gboolean legacy, int flags)
|
||||
{
|
||||
struct remote_dev_info *dev;
|
||||
|
||||
@ -2827,7 +2707,6 @@ static struct remote_dev_info *found_device_new(const bdaddr_t *bdaddr,
|
||||
dev->alias = g_strdup(alias);
|
||||
dev->class = class;
|
||||
dev->legacy = legacy;
|
||||
dev->name_status = status;
|
||||
if (flags >= 0)
|
||||
dev->flags = flags;
|
||||
|
||||
@ -2897,11 +2776,10 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
|
||||
uint8_t confirm_name,
|
||||
uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
struct remote_dev_info *dev, match;
|
||||
struct remote_dev_info *dev;
|
||||
struct eir_data eir_data;
|
||||
char *alias, *name;
|
||||
gboolean legacy;
|
||||
name_status_t name_status;
|
||||
gboolean legacy, name_known;
|
||||
int err;
|
||||
|
||||
memset(&eir_data, 0, sizeof(eir_data));
|
||||
@ -2914,12 +2792,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
|
||||
if (eir_data.name != NULL && eir_data.name_complete)
|
||||
write_device_name(&adapter->bdaddr, bdaddr, eir_data.name);
|
||||
|
||||
/* Device already seen in the discovery session ? */
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, bdaddr);
|
||||
match.name_status = NAME_ANY;
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
dev = adapter_search_found_devices(adapter, bdaddr);
|
||||
if (dev) {
|
||||
adapter->oor_devices = g_slist_remove(adapter->oor_devices,
|
||||
dev);
|
||||
@ -2941,30 +2814,21 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
|
||||
|
||||
if (!name && main_opts.name_resolv &&
|
||||
adapter_has_discov_sessions(adapter))
|
||||
name_status = NAME_REQUIRED;
|
||||
else
|
||||
name_status = NAME_NOT_REQUIRED;
|
||||
} else {
|
||||
legacy = FALSE;
|
||||
name_status = NAME_NOT_REQUIRED;
|
||||
}
|
||||
|
||||
if (confirm_name) {
|
||||
gboolean name_known;
|
||||
|
||||
if (name_status == NAME_REQUIRED)
|
||||
name_known = FALSE;
|
||||
else
|
||||
name_known = TRUE;
|
||||
|
||||
adapter_ops->confirm_name(adapter->dev_id, bdaddr,
|
||||
name_known);
|
||||
} else {
|
||||
legacy = FALSE;
|
||||
name_known = TRUE;
|
||||
}
|
||||
|
||||
if (confirm_name)
|
||||
adapter_ops->confirm_name(adapter->dev_id, bdaddr, name_known);
|
||||
|
||||
alias = read_stored_data(&adapter->bdaddr, bdaddr, "aliases");
|
||||
|
||||
dev = found_device_new(bdaddr, type, name, alias, class, legacy,
|
||||
name_status, eir_data.flags);
|
||||
eir_data.flags);
|
||||
free(name);
|
||||
free(alias);
|
||||
|
||||
@ -2984,22 +2848,6 @@ done:
|
||||
eir_data_free(&eir_data);
|
||||
}
|
||||
|
||||
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
|
||||
{
|
||||
struct remote_dev_info *dev, match;
|
||||
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, bdaddr);
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
dev->name_status = NAME_NOT_REQUIRED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
|
||||
{
|
||||
const gchar *path = adapter_get_path(adapter);
|
||||
@ -3116,24 +2964,6 @@ gboolean adapter_has_discov_sessions(struct btd_adapter *adapter)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void adapter_suspend_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
if (adapter->disc_sessions == NULL ||
|
||||
adapter->state == STATE_SUSPENDED)
|
||||
return;
|
||||
|
||||
DBG("Suspending discovery");
|
||||
|
||||
adapter_set_state(adapter, STATE_SUSPENDED);
|
||||
}
|
||||
|
||||
void adapter_resume_discovery(struct btd_adapter *adapter)
|
||||
{
|
||||
DBG("Resuming discovery");
|
||||
|
||||
adapter_set_state(adapter, STATE_IDLE);
|
||||
}
|
||||
|
||||
int btd_register_adapter_driver(struct btd_adapter_driver *driver)
|
||||
{
|
||||
adapter_drivers = g_slist_append(adapter_drivers, driver);
|
||||
@ -3607,6 +3437,7 @@ int btd_adapter_set_did(struct btd_adapter *adapter, uint16_t vendor,
|
||||
int adapter_create_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr,
|
||||
uint8_t io_cap)
|
||||
{
|
||||
suspend_discovery(adapter);
|
||||
return adapter_ops->create_bonding(adapter->dev_id, bdaddr, io_cap);
|
||||
}
|
||||
|
||||
@ -3615,6 +3446,27 @@ int adapter_cancel_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr)
|
||||
return adapter_ops->cancel_bonding(adapter->dev_id, bdaddr);
|
||||
}
|
||||
|
||||
void adapter_bonding_complete(struct btd_adapter *adapter, bdaddr_t *bdaddr,
|
||||
uint8_t status)
|
||||
{
|
||||
struct btd_device *device;
|
||||
char addr[18];
|
||||
|
||||
ba2str(bdaddr, addr);
|
||||
if (status == 0)
|
||||
device = adapter_get_device(connection, adapter, addr);
|
||||
else
|
||||
device = adapter_find_device(adapter, addr);
|
||||
|
||||
if (device != NULL)
|
||||
device_bonding_complete(device, status);
|
||||
|
||||
if (adapter->discov_suspended) {
|
||||
adapter->discov_suspended = FALSE;
|
||||
adapter_ops->start_discovery(adapter->dev_id);
|
||||
}
|
||||
}
|
||||
|
||||
int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
|
||||
{
|
||||
return adapter_ops->read_local_oob_data(adapter->dev_id);
|
||||
|
@ -36,24 +36,11 @@
|
||||
#define MODE_DISCOVERABLE 0x02
|
||||
#define MODE_UNKNOWN 0xff
|
||||
|
||||
/* Discover states */
|
||||
#define STATE_IDLE 0
|
||||
#define STATE_DISCOV 1
|
||||
#define STATE_RESOLVNAME 2
|
||||
#define STATE_SUSPENDED 3
|
||||
|
||||
#define MAX_NAME_LENGTH 248
|
||||
|
||||
/* Invalid SSP passkey value used to indicate negative replies */
|
||||
#define INVALID_PASSKEY 0xffffffff
|
||||
|
||||
typedef enum {
|
||||
NAME_ANY,
|
||||
NAME_NOT_REQUIRED, /* used by get remote name without name resolving */
|
||||
NAME_REQUIRED, /* remote name needs be resolved */
|
||||
NAME_REQUESTED, /* HCI remote name request was sent */
|
||||
} name_status_t;
|
||||
|
||||
typedef enum {
|
||||
ADDR_TYPE_BREDR,
|
||||
ADDR_TYPE_LE_PUBLIC,
|
||||
@ -77,7 +64,6 @@ struct remote_dev_info {
|
||||
char *name;
|
||||
char *alias;
|
||||
dbus_bool_t legacy;
|
||||
name_status_t name_status;
|
||||
char **uuids;
|
||||
size_t uuid_count;
|
||||
GSList *services;
|
||||
@ -106,19 +92,20 @@ gboolean adapter_init(struct btd_adapter *adapter);
|
||||
void adapter_remove(struct btd_adapter *adapter);
|
||||
void adapter_set_allow_name_changes(struct btd_adapter *adapter,
|
||||
gboolean allow_name_changes);
|
||||
void adapter_set_discovering(struct btd_adapter *adapter,
|
||||
gboolean discovering);
|
||||
uint16_t adapter_get_dev_id(struct btd_adapter *adapter);
|
||||
const gchar *adapter_get_path(struct btd_adapter *adapter);
|
||||
void adapter_get_address(struct btd_adapter *adapter, bdaddr_t *bdaddr);
|
||||
void adapter_set_state(struct btd_adapter *adapter, int state);
|
||||
int adapter_get_state(struct btd_adapter *adapter);
|
||||
struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter,
|
||||
struct remote_dev_info *match);
|
||||
bdaddr_t *bdaddr);
|
||||
void adapter_update_found_devices(struct btd_adapter *adapter,
|
||||
bdaddr_t *bdaddr, addr_type_t type,
|
||||
uint32_t class, int8_t rssi,
|
||||
uint8_t confirm_name,
|
||||
uint8_t *data, uint8_t data_len);
|
||||
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
|
||||
void adapter_emit_device_found(struct btd_adapter *adapter,
|
||||
struct remote_dev_info *dev);
|
||||
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
|
||||
@ -137,8 +124,6 @@ void adapter_add_connection(struct btd_adapter *adapter,
|
||||
void adapter_remove_connection(struct btd_adapter *adapter,
|
||||
struct btd_device *device);
|
||||
gboolean adapter_has_discov_sessions(struct btd_adapter *adapter);
|
||||
void adapter_suspend_discovery(struct btd_adapter *adapter);
|
||||
void adapter_resume_discovery(struct btd_adapter *adapter);
|
||||
|
||||
struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
|
||||
void btd_adapter_unref(struct btd_adapter *adapter);
|
||||
@ -192,8 +177,6 @@ struct btd_adapter_ops {
|
||||
int (*start_discovery) (int index);
|
||||
int (*stop_discovery) (int index);
|
||||
|
||||
int (*resolve_name) (int index, bdaddr_t *bdaddr);
|
||||
int (*cancel_resolve_name) (int index, bdaddr_t *bdaddr);
|
||||
int (*set_name) (int index, const char *name);
|
||||
int (*set_dev_class) (int index, uint8_t major, uint8_t minor);
|
||||
int (*set_fast_connectable) (int index, gboolean enable);
|
||||
@ -275,6 +258,9 @@ int adapter_create_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr,
|
||||
|
||||
int adapter_cancel_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr);
|
||||
|
||||
void adapter_bonding_complete(struct btd_adapter *adapter, bdaddr_t *bdaddr,
|
||||
uint8_t status);
|
||||
|
||||
int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
|
||||
|
||||
int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
|
||||
|
@ -2183,8 +2183,6 @@ static void bonding_request_free(struct bonding_req *bonding)
|
||||
|
||||
device->bonding = NULL;
|
||||
|
||||
adapter_resume_discovery(device->adapter);
|
||||
|
||||
if (!device->agent)
|
||||
return;
|
||||
|
||||
@ -2256,8 +2254,6 @@ proceed:
|
||||
bonding->conn = dbus_connection_ref(conn);
|
||||
bonding->msg = dbus_message_ref(msg);
|
||||
|
||||
adapter_suspend_discovery(device->adapter);
|
||||
|
||||
return bonding;
|
||||
}
|
||||
|
||||
|
56
src/event.c
56
src/event.c
@ -218,8 +218,7 @@ void btd_event_bonding_complete(bdaddr_t *local, bdaddr_t *peer,
|
||||
if (!get_adapter_and_device(local, peer, &adapter, &device, create))
|
||||
return;
|
||||
|
||||
if (device)
|
||||
device_bonding_complete(device, status);
|
||||
adapter_bonding_complete(adapter, peer, status);
|
||||
}
|
||||
|
||||
void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
|
||||
@ -291,7 +290,7 @@ void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
|
||||
gboolean legacy)
|
||||
{
|
||||
struct btd_adapter *adapter;
|
||||
struct remote_dev_info *dev, match;
|
||||
struct remote_dev_info *dev;
|
||||
|
||||
adapter = manager_find_adapter(local);
|
||||
if (!adapter) {
|
||||
@ -299,11 +298,7 @@ void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, peer);
|
||||
match.name_status = NAME_ANY;
|
||||
|
||||
dev = adapter_search_found_devices(adapter, &match);
|
||||
dev = adapter_search_found_devices(adapter, peer);
|
||||
if (dev)
|
||||
dev->legacy = legacy;
|
||||
}
|
||||
@ -330,44 +325,33 @@ void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class)
|
||||
device_set_class(device, class);
|
||||
}
|
||||
|
||||
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
|
||||
char *name)
|
||||
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
|
||||
{
|
||||
struct btd_adapter *adapter;
|
||||
char srcaddr[18], dstaddr[18];
|
||||
char srcaddr[18];
|
||||
struct btd_device *device;
|
||||
struct remote_dev_info match, *dev_info;
|
||||
struct remote_dev_info *dev_info;
|
||||
|
||||
if (status == 0) {
|
||||
if (!g_utf8_validate(name, -1, NULL)) {
|
||||
int i;
|
||||
if (!g_utf8_validate(name, -1, NULL)) {
|
||||
int i;
|
||||
|
||||
/* Assume ASCII, and replace all non-ASCII with
|
||||
* spaces */
|
||||
for (i = 0; name[i] != '\0'; i++) {
|
||||
if (!isascii(name[i]))
|
||||
name[i] = ' ';
|
||||
}
|
||||
/* Remove leading and trailing whitespace characters */
|
||||
g_strstrip(name);
|
||||
/* Assume ASCII, and replace all non-ASCII with spaces */
|
||||
for (i = 0; name[i] != '\0'; i++) {
|
||||
if (!isascii(name[i]))
|
||||
name[i] = ' ';
|
||||
}
|
||||
|
||||
write_device_name(local, peer, name);
|
||||
/* Remove leading and trailing whitespace characters */
|
||||
g_strstrip(name);
|
||||
}
|
||||
|
||||
write_device_name(local, peer, name);
|
||||
|
||||
if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
|
||||
return;
|
||||
|
||||
ba2str(local, srcaddr);
|
||||
ba2str(peer, dstaddr);
|
||||
|
||||
if (status != 0)
|
||||
goto proceed;
|
||||
|
||||
bacpy(&match.bdaddr, peer);
|
||||
match.name_status = NAME_ANY;
|
||||
|
||||
dev_info = adapter_search_found_devices(adapter, &match);
|
||||
dev_info = adapter_search_found_devices(adapter, peer);
|
||||
if (dev_info) {
|
||||
g_free(dev_info->name);
|
||||
dev_info->name = g_strdup(name);
|
||||
@ -376,12 +360,6 @@ void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
|
||||
|
||||
if (device)
|
||||
device_set_name(device, name);
|
||||
|
||||
proceed:
|
||||
/* remove from remote name request list */
|
||||
adapter_remove_found_device(adapter, peer);
|
||||
|
||||
adapter_set_state(adapter, STATE_IDLE);
|
||||
}
|
||||
|
||||
int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
|
||||
|
@ -28,7 +28,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, addr_type_t type,
|
||||
uint8_t *data, uint8_t data_len);
|
||||
void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy);
|
||||
void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class);
|
||||
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name);
|
||||
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name);
|
||||
void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer);
|
||||
void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
|
||||
void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer);
|
||||
|
Loading…
Reference in New Issue
Block a user