Commit 5b7f990927fe87ad3bec762a33c0e72bcbf6841e
1 parent
8de0a15483
Exists in
master
and in
7 other branches
[Bluetooth] Add basics to better support and handle eSCO links
To better support and handle eSCO links in the future a bunch of constants needs to be added and some basic routines need to be updated. This is the initial step. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Showing 5 changed files with 66 additions and 37 deletions Side-by-side Diff
include/net/bluetooth/hci.h
... | ... | @@ -107,14 +107,14 @@ |
107 | 107 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ |
108 | 108 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ |
109 | 109 | |
110 | -/* HCI Packet types */ | |
110 | +/* HCI data types */ | |
111 | 111 | #define HCI_COMMAND_PKT 0x01 |
112 | 112 | #define HCI_ACLDATA_PKT 0x02 |
113 | 113 | #define HCI_SCODATA_PKT 0x03 |
114 | 114 | #define HCI_EVENT_PKT 0x04 |
115 | 115 | #define HCI_VENDOR_PKT 0xff |
116 | 116 | |
117 | -/* HCI Packet types */ | |
117 | +/* HCI packet types */ | |
118 | 118 | #define HCI_DM1 0x0008 |
119 | 119 | #define HCI_DM3 0x0400 |
120 | 120 | #define HCI_DM5 0x4000 |
... | ... | @@ -129,6 +129,14 @@ |
129 | 129 | #define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) |
130 | 130 | #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) |
131 | 131 | |
132 | +/* eSCO packet types */ | |
133 | +#define ESCO_HV1 0x0001 | |
134 | +#define ESCO_HV2 0x0002 | |
135 | +#define ESCO_HV3 0x0004 | |
136 | +#define ESCO_EV3 0x0008 | |
137 | +#define ESCO_EV4 0x0010 | |
138 | +#define ESCO_EV5 0x0020 | |
139 | + | |
132 | 140 | /* ACL flags */ |
133 | 141 | #define ACL_CONT 0x01 |
134 | 142 | #define ACL_START 0x02 |
... | ... | @@ -138,6 +146,7 @@ |
138 | 146 | /* Baseband links */ |
139 | 147 | #define SCO_LINK 0x00 |
140 | 148 | #define ACL_LINK 0x01 |
149 | +#define ESCO_LINK 0x02 | |
141 | 150 | |
142 | 151 | /* LMP features */ |
143 | 152 | #define LMP_3SLOT 0x01 |
... | ... | @@ -161,6 +170,11 @@ |
161 | 170 | #define LMP_CVSD 0x01 |
162 | 171 | #define LMP_PSCHEME 0x02 |
163 | 172 | #define LMP_PCONTROL 0x04 |
173 | + | |
174 | +#define LMP_ESCO 0x80 | |
175 | + | |
176 | +#define LMP_EV4 0x01 | |
177 | +#define LMP_EV5 0x02 | |
164 | 178 | |
165 | 179 | #define LMP_SNIFF_SUBR 0x02 |
166 | 180 |
include/net/bluetooth/hci_core.h
... | ... | @@ -78,6 +78,7 @@ |
78 | 78 | __u16 voice_setting; |
79 | 79 | |
80 | 80 | __u16 pkt_type; |
81 | + __u16 esco_type; | |
81 | 82 | __u16 link_policy; |
82 | 83 | __u16 link_mode; |
83 | 84 | |
... | ... | @@ -452,6 +453,7 @@ |
452 | 453 | #define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) |
453 | 454 | #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) |
454 | 455 | #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) |
456 | +#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) | |
455 | 457 | |
456 | 458 | /* ----- HCI protocols ----- */ |
457 | 459 | struct hci_proto { |
net/bluetooth/hci_conn.c
... | ... | @@ -123,8 +123,8 @@ |
123 | 123 | conn->state = BT_CONNECT; |
124 | 124 | conn->out = 1; |
125 | 125 | |
126 | - cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | |
127 | 126 | cp.handle = cpu_to_le16(handle); |
127 | + cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | |
128 | 128 | |
129 | 129 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp); |
130 | 130 | } |
131 | 131 | |
... | ... | @@ -220,19 +220,19 @@ |
220 | 220 | |
221 | 221 | del_timer(&conn->disc_timer); |
222 | 222 | |
223 | - if (conn->type == SCO_LINK) { | |
224 | - struct hci_conn *acl = conn->link; | |
225 | - if (acl) { | |
226 | - acl->link = NULL; | |
227 | - hci_conn_put(acl); | |
228 | - } | |
229 | - } else { | |
223 | + if (conn->type == ACL_LINK) { | |
230 | 224 | struct hci_conn *sco = conn->link; |
231 | 225 | if (sco) |
232 | 226 | sco->link = NULL; |
233 | 227 | |
234 | 228 | /* Unacked frames */ |
235 | 229 | hdev->acl_cnt += conn->sent; |
230 | + } else { | |
231 | + struct hci_conn *acl = conn->link; | |
232 | + if (acl) { | |
233 | + acl->link = NULL; | |
234 | + hci_conn_put(acl); | |
235 | + } | |
236 | 236 | } |
237 | 237 | |
238 | 238 | tasklet_disable(&hdev->tx_task); |
239 | 239 | |
... | ... | @@ -297,9 +297,10 @@ |
297 | 297 | |
298 | 298 | /* Create SCO or ACL connection. |
299 | 299 | * Device _must_ be locked */ |
300 | -struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | |
300 | +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | |
301 | 301 | { |
302 | 302 | struct hci_conn *acl; |
303 | + struct hci_conn *sco; | |
303 | 304 | |
304 | 305 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
305 | 306 | |
306 | 307 | |
307 | 308 | |
308 | 309 | |
309 | 310 | |
310 | 311 | |
... | ... | @@ -313,28 +314,26 @@ |
313 | 314 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) |
314 | 315 | hci_acl_connect(acl); |
315 | 316 | |
316 | - if (type == SCO_LINK) { | |
317 | - struct hci_conn *sco; | |
317 | + if (type == ACL_LINK) | |
318 | + return acl; | |
318 | 319 | |
319 | - if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) { | |
320 | - if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) { | |
321 | - hci_conn_put(acl); | |
322 | - return NULL; | |
323 | - } | |
320 | + if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) { | |
321 | + if (!(sco = hci_conn_add(hdev, type, dst))) { | |
322 | + hci_conn_put(acl); | |
323 | + return NULL; | |
324 | 324 | } |
325 | - acl->link = sco; | |
326 | - sco->link = acl; | |
325 | + } | |
327 | 326 | |
328 | - hci_conn_hold(sco); | |
327 | + acl->link = sco; | |
328 | + sco->link = acl; | |
329 | 329 | |
330 | - if (acl->state == BT_CONNECTED && | |
331 | - (sco->state == BT_OPEN || sco->state == BT_CLOSED)) | |
332 | - hci_add_sco(sco, acl->handle); | |
330 | + hci_conn_hold(sco); | |
333 | 331 | |
334 | - return sco; | |
335 | - } else { | |
336 | - return acl; | |
337 | - } | |
332 | + if (acl->state == BT_CONNECTED && | |
333 | + (sco->state == BT_OPEN || sco->state == BT_CLOSED)) | |
334 | + hci_add_sco(sco, acl->handle); | |
335 | + | |
336 | + return sco; | |
338 | 337 | } |
339 | 338 | EXPORT_SYMBOL(hci_connect); |
340 | 339 |
net/bluetooth/hci_core.c
... | ... | @@ -851,6 +851,7 @@ |
851 | 851 | |
852 | 852 | hdev->flags = 0; |
853 | 853 | hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); |
854 | + hdev->esco_type = (ESCO_HV1); | |
854 | 855 | hdev->link_mode = (HCI_LM_ACCEPT); |
855 | 856 | |
856 | 857 | hdev->idle_timeout = 0; |
... | ... | @@ -1254,7 +1255,7 @@ |
1254 | 1255 | static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) |
1255 | 1256 | { |
1256 | 1257 | struct hci_conn_hash *h = &hdev->conn_hash; |
1257 | - struct hci_conn *conn = NULL; | |
1258 | + struct hci_conn *conn = NULL; | |
1258 | 1259 | int num = 0, min = ~0; |
1259 | 1260 | struct list_head *p; |
1260 | 1261 |
net/bluetooth/hci_event.c
... | ... | @@ -350,12 +350,25 @@ |
350 | 350 | if (hdev->features[0] & LMP_5SLOT) |
351 | 351 | hdev->pkt_type |= (HCI_DM5 | HCI_DH5); |
352 | 352 | |
353 | - if (hdev->features[1] & LMP_HV2) | |
354 | - hdev->pkt_type |= (HCI_HV2); | |
353 | + if (hdev->features[1] & LMP_HV2) { | |
354 | + hdev->pkt_type |= (HCI_HV2); | |
355 | + hdev->esco_type |= (ESCO_HV2); | |
356 | + } | |
355 | 357 | |
356 | - if (hdev->features[1] & LMP_HV3) | |
357 | - hdev->pkt_type |= (HCI_HV3); | |
358 | + if (hdev->features[1] & LMP_HV3) { | |
359 | + hdev->pkt_type |= (HCI_HV3); | |
360 | + hdev->esco_type |= (ESCO_HV3); | |
361 | + } | |
358 | 362 | |
363 | + if (hdev->features[3] & LMP_ESCO) | |
364 | + hdev->esco_type |= (ESCO_EV3); | |
365 | + | |
366 | + if (hdev->features[4] & LMP_EV4) | |
367 | + hdev->esco_type |= (ESCO_EV4); | |
368 | + | |
369 | + if (hdev->features[4] & LMP_EV5) | |
370 | + hdev->esco_type |= (ESCO_EV5); | |
371 | + | |
359 | 372 | BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, |
360 | 373 | lf->features[0], lf->features[1], lf->features[2]); |
361 | 374 | |
362 | 375 | |
... | ... | @@ -881,12 +894,12 @@ |
881 | 894 | if (conn) { |
882 | 895 | conn->sent -= count; |
883 | 896 | |
884 | - if (conn->type == SCO_LINK) { | |
885 | - if ((hdev->sco_cnt += count) > hdev->sco_pkts) | |
886 | - hdev->sco_cnt = hdev->sco_pkts; | |
887 | - } else { | |
897 | + if (conn->type == ACL_LINK) { | |
888 | 898 | if ((hdev->acl_cnt += count) > hdev->acl_pkts) |
889 | 899 | hdev->acl_cnt = hdev->acl_pkts; |
900 | + } else { | |
901 | + if ((hdev->sco_cnt += count) > hdev->sco_pkts) | |
902 | + hdev->sco_cnt = hdev->sco_pkts; | |
890 | 903 | } |
891 | 904 | } |
892 | 905 | } |