diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2014-07-01 08:11:21 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-07-03 11:42:53 -0400 |
commit | c70a7e4cc8d22cb1ce684637ef8a4bb3a80d15b7 (patch) | |
tree | 9e0f367a948a61c4c645b929c6824778f8bf25bc /net | |
parent | af58925ca6175695e502fa792f43a946f7474765 (diff) |
Bluetooth: Add support for Not Connectable flag for Device Found events
The Device Found events of the management interface should indicate if
it is possible to connect to a remote device or if it is broadcaster
only advertising. To allow this differentation the Not Connectable flag
is introduced that will be set when it is known that a device can not
be connected.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_event.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a4854a5d9298..8097559ebb48 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1089,13 +1089,15 @@ static void clear_pending_adv_report(struct hci_dev *hdev) | |||
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1091 | static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1092 | u8 bdaddr_type, s8 rssi, u8 *data, u8 len) | 1092 | u8 bdaddr_type, s8 rssi, u32 flags, |
1093 | u8 *data, u8 len) | ||
1093 | { | 1094 | { |
1094 | struct discovery_state *d = &hdev->discovery; | 1095 | struct discovery_state *d = &hdev->discovery; |
1095 | 1096 | ||
1096 | bacpy(&d->last_adv_addr, bdaddr); | 1097 | bacpy(&d->last_adv_addr, bdaddr); |
1097 | d->last_adv_addr_type = bdaddr_type; | 1098 | d->last_adv_addr_type = bdaddr_type; |
1098 | d->last_adv_rssi = rssi; | 1099 | d->last_adv_rssi = rssi; |
1100 | d->last_adv_flags = flags; | ||
1099 | memcpy(d->last_adv_data, data, len); | 1101 | memcpy(d->last_adv_data, data, len); |
1100 | d->last_adv_data_len = len; | 1102 | d->last_adv_data_len = len; |
1101 | } | 1103 | } |
@@ -1132,7 +1134,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
1132 | 1134 | ||
1133 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, | 1135 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, |
1134 | d->last_adv_addr_type, NULL, | 1136 | d->last_adv_addr_type, NULL, |
1135 | d->last_adv_rssi, 0, | 1137 | d->last_adv_rssi, d->last_adv_flags, |
1136 | d->last_adv_data, | 1138 | d->last_adv_data, |
1137 | d->last_adv_data_len, NULL, 0); | 1139 | d->last_adv_data_len, NULL, 0); |
1138 | } | 1140 | } |
@@ -4209,6 +4211,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4209 | { | 4211 | { |
4210 | struct discovery_state *d = &hdev->discovery; | 4212 | struct discovery_state *d = &hdev->discovery; |
4211 | bool match; | 4213 | bool match; |
4214 | u32 flags; | ||
4212 | 4215 | ||
4213 | /* Passive scanning shouldn't trigger any device found events */ | 4216 | /* Passive scanning shouldn't trigger any device found events */ |
4214 | if (hdev->le_scan_type == LE_SCAN_PASSIVE) { | 4217 | if (hdev->le_scan_type == LE_SCAN_PASSIVE) { |
@@ -4217,6 +4220,27 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4217 | return; | 4220 | return; |
4218 | } | 4221 | } |
4219 | 4222 | ||
4223 | /* When receiving non-connectable or scannable undirected | ||
4224 | * advertising reports, this means that the remote device is | ||
4225 | * not connectable and then clearly indicate this in the | ||
4226 | * device found event. | ||
4227 | * | ||
4228 | * When receiving a scan response, then there is no way to | ||
4229 | * know if the remote device is connectable or not. However | ||
4230 | * since scan responses are merged with a previously seen | ||
4231 | * advertising report, the flags field from that report | ||
4232 | * will be used. | ||
4233 | * | ||
4234 | * In the really unlikely case that a controller get confused | ||
4235 | * and just sends a scan response event, then it is marked as | ||
4236 | * not connectable as well. | ||
4237 | */ | ||
4238 | if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || | ||
4239 | type == LE_ADV_SCAN_RSP) | ||
4240 | flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; | ||
4241 | else | ||
4242 | flags = 0; | ||
4243 | |||
4220 | /* If there's nothing pending either store the data from this | 4244 | /* If there's nothing pending either store the data from this |
4221 | * event or send an immediate device found event if the data | 4245 | * event or send an immediate device found event if the data |
4222 | * should not be stored for later. | 4246 | * should not be stored for later. |
@@ -4227,12 +4251,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4227 | */ | 4251 | */ |
4228 | if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { | 4252 | if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { |
4229 | store_pending_adv_report(hdev, bdaddr, bdaddr_type, | 4253 | store_pending_adv_report(hdev, bdaddr, bdaddr_type, |
4230 | rssi, data, len); | 4254 | rssi, flags, data, len); |
4231 | return; | 4255 | return; |
4232 | } | 4256 | } |
4233 | 4257 | ||
4234 | mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, | 4258 | mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, |
4235 | rssi, 0, data, len, NULL, 0); | 4259 | rssi, flags, data, len, NULL, 0); |
4236 | return; | 4260 | return; |
4237 | } | 4261 | } |
4238 | 4262 | ||
@@ -4249,7 +4273,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4249 | if (!match) | 4273 | if (!match) |
4250 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, | 4274 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, |
4251 | d->last_adv_addr_type, NULL, | 4275 | d->last_adv_addr_type, NULL, |
4252 | d->last_adv_rssi, 0, | 4276 | d->last_adv_rssi, d->last_adv_flags, |
4253 | d->last_adv_data, | 4277 | d->last_adv_data, |
4254 | d->last_adv_data_len, NULL, 0); | 4278 | d->last_adv_data_len, NULL, 0); |
4255 | 4279 | ||
@@ -4258,7 +4282,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4258 | */ | 4282 | */ |
4259 | if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { | 4283 | if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { |
4260 | store_pending_adv_report(hdev, bdaddr, bdaddr_type, | 4284 | store_pending_adv_report(hdev, bdaddr, bdaddr_type, |
4261 | rssi, data, len); | 4285 | rssi, flags, data, len); |
4262 | return; | 4286 | return; |
4263 | } | 4287 | } |
4264 | 4288 | ||
@@ -4267,7 +4291,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4267 | */ | 4291 | */ |
4268 | clear_pending_adv_report(hdev); | 4292 | clear_pending_adv_report(hdev); |
4269 | mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, | 4293 | mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, |
4270 | rssi, 0, data, len, NULL, 0); | 4294 | rssi, flags, data, len, NULL, 0); |
4271 | return; | 4295 | return; |
4272 | } | 4296 | } |
4273 | 4297 | ||
@@ -4276,7 +4300,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, | |||
4276 | * sending a merged device found event. | 4300 | * sending a merged device found event. |
4277 | */ | 4301 | */ |
4278 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, | 4302 | mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, |
4279 | d->last_adv_addr_type, NULL, rssi, 0, | 4303 | d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, |
4280 | d->last_adv_data, d->last_adv_data_len, data, len); | 4304 | d->last_adv_data, d->last_adv_data_len, data, len); |
4281 | clear_pending_adv_report(hdev); | 4305 | clear_pending_adv_report(hdev); |
4282 | } | 4306 | } |