diff options
author | Nick Pelly <npelly@google.com> | 2010-02-11 11:54:28 -0800 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-02-24 14:40:25 -0800 |
commit | 3b077241e02041b1f03fee912896b8de1d7ac096 (patch) | |
tree | 84ee3979bac6a23375660876c5b68e2f49a0a19c /include | |
parent | e7e66e1a05730d61f5e009208de6848a8de717f7 (diff) |
Bluetooth: Allow SCO/eSCO packet type selection for outgoing SCO connections.
__u16 sco_pkt_type is introduced to struct sockaddr_sco. It allows bitwise
selection of SCO/eSCO packet types. Currently those bits are:
0x0001 HV1 may be used.
0x0002 HV2 may be used.
0x0004 HV3 may be used.
0x0008 EV3 may be used.
0x0010 EV4 may be used.
0x0020 EV5 may be used.
0x0040 2-EV3 may be used.
0x0080 3-EV3 may be used.
0x0100 2-EV5 may be used.
0x0200 3-EV5 may be used.
This is similar to the Packet Type parameter in the HCI Setup Synchronous
Connection Command, except that we are not reversing the logic on the EDR bits.
This makes the use of sco_pkt_tpye forward portable for the use case of
white-listing packet types, which we expect will be the primary use case.
If sco_pkt_type is zero, or userspace uses the old struct sockaddr_sco,
then the default behavior is to allow all packet types.
Packet type selection is just a request made to the Bluetooth chipset, and
it is up to the link manager on the chipset to negiotiate and decide on the
actual packet types used. Furthermore, when a SCO/eSCO connection is eventually
made there is no way for the host stack to determine which packet type was used
(however it is possible to get the link type of SCO or eSCO).
sco_pkt_type is ignored for incoming SCO connections. It is possible
to add this in the future as a parameter to the Accept Synchronous Connection
Command, however its a little trickier because the kernel does not
currently preserve sockaddr_sco data between userspace calls to accept().
The most common use for sco_pkt_type will be to white-list only SCO packets,
which can be done with the hci.h constant SCO_ESCO_MASK.
This patch is motivated by broken Bluetooth carkits such as the Motorolo
HF850 (it claims to support eSCO, but will actually reject eSCO connections
after 5 seconds) and the 2007/2008 Infiniti G35/37 (fails to route audio
if a 2-EV5 packet type is negiotiated). With this patch userspace can maintain
a list of compatible packet types to workaround remote devices such as these.
Based on a patch by Marcel Holtmann.
Change-Id: I304d8fda5b4145254820a3003820163bf53de5a5
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/bluetooth/hci.h | 6 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 7 | ||||
-rw-r--r-- | include/net/bluetooth/sco.h | 4 |
3 files changed, 12 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 4f7795f27e04..b32dcff93911 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -139,8 +139,10 @@ enum { #define ESCO_2EV5 0x0100 #define ESCO_3EV5 0x0200 -#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) -#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) +#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) +#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) +#define ALL_ESCO_MASK (SCO_ESCO_MASK | ESCO_EV3 | ESCO_EV4 | ESCO_EV5 | \ + EDR_ESCO_MASK) /* ACL flags */ #define ACL_START 0x00 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b6d36cbb2773..cbcc5b102cdb 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -326,12 +326,15 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_add_sco(struct hci_conn *conn, __u16 handle); void hci_setup_sync(struct hci_conn *conn, __u16 handle); -struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, + __u16 pkt_type, bdaddr_t *dst); int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); -struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, + __u16 pkt_type, bdaddr_t *dst, + __u8 sec_level, __u8 auth_type); int hci_conn_check_link_mode(struct hci_conn *conn); int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); int hci_conn_change_link_key(struct hci_conn *conn); diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index e28a2a771471..924338ac3223 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -37,6 +37,7 @@ struct sockaddr_sco { sa_family_t sco_family; bdaddr_t sco_bdaddr; + __u16 sco_pkt_type; }; /* SCO socket options */ @@ -72,7 +73,8 @@ struct sco_conn { struct sco_pinfo { struct bt_sock bt; - __u32 flags; + __u16 pkt_type; + struct sco_conn *conn; }; |