#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 ALL_ESCO_MASK (SCO_ESCO_MASK | ESCO_EV3 | ESCO_EV4 | ESCO_EV5 | \
- EDR_ESCO_MASK)
+#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
+#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
/* ACL flags */
#define ACL_START 0x00
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,
- __u16 pkt_type, bdaddr_t *dst);
+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int 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,
- __u16 pkt_type, bdaddr_t *dst,
- __u8 sec_level, __u8 auth_type);
+struct hci_conn *hci_connect(struct hci_dev *hdev, int 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);
struct sockaddr_sco {
sa_family_t sco_family;
bdaddr_t sco_bdaddr;
- __u16 sco_pkt_type;
};
/* SCO socket options */
struct sco_pinfo {
struct bt_sock bt;
- __u16 pkt_type;
-
+ __u32 flags;
struct sco_conn *conn;
};
hci_conn_enter_sniff_mode(conn);
}
-struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type,
- __u16 pkt_type, bdaddr_t *dst)
+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
break;
case SCO_LINK:
- if (!pkt_type)
- pkt_type = SCO_ESCO_MASK;
+ if (lmp_esco_capable(hdev))
+ conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
+ (hdev->esco_type & EDR_ESCO_MASK);
+ else
+ conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
+ break;
case ESCO_LINK:
- if (!pkt_type)
- pkt_type = ALL_ESCO_MASK;
- if (lmp_esco_capable(hdev)) {
- /* HCI Setup Synchronous Connection Command uses
- reverse logic on the EDR_ESCO_MASK bits */
- conn->pkt_type = (pkt_type ^ EDR_ESCO_MASK) &
- hdev->esco_type;
- } else {
- /* Legacy HCI Add Sco Connection Command uses a
- shifted bitmask */
- conn->pkt_type = (pkt_type << 5) & hdev->pkt_type &
- SCO_PTYPE_MASK;
- }
+ conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
break;
}
/* Create SCO or ACL connection.
* Device _must_ be locked */
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type,
- __u16 pkt_type, bdaddr_t *dst,
- __u8 sec_level, __u8 auth_type)
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
{
struct hci_conn *acl;
struct hci_conn *sco;
BT_DBG("%s dst %s", hdev->name, batostr(dst));
if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
- if (!(acl = hci_conn_add(hdev, ACL_LINK, 0, dst)))
+ if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
return NULL;
}
return acl;
if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
- if (!(sco = hci_conn_add(hdev, type, pkt_type, dst))) {
+ if (!(sco = hci_conn_add(hdev, type, dst))) {
hci_conn_put(acl);
return NULL;
}
}
} else {
if (!conn) {
- conn = hci_conn_add(hdev, ACL_LINK, 0, &cp->bdaddr);
+ conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
if (conn) {
conn->out = 1;
conn->link_mode |= HCI_LM_MASTER;
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
- /* pkt_type not yet used for incoming connections */
- if (!(conn = hci_conn_add(hdev, ev->link_type, 0,
- &ev->bdaddr))) {
+ if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
BT_ERR("No memmory for new connection");
hci_dev_unlock(hdev);
return;
}
}
- hcon = hci_connect(hdev, ACL_LINK, 0, dst,
+ hcon = hci_connect(hdev, ACL_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type);
if (!hcon)
goto done;
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
- __u16 pkt_type = sco_pi(sk)->pkt_type;
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
if (lmp_esco_capable(hdev) && !disable_esco)
type = ESCO_LINK;
- else {
+ else
type = SCO_LINK;
- pkt_type &= SCO_ESCO_MASK;
- }
- hcon = hci_connect(hdev, type, pkt_type, dst,
- BT_SECURITY_LOW, HCI_AT_NO_BONDING);
+ hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
if (!hcon)
goto done;
return 0;
}
-static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
- struct sockaddr_sco sa;
+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
struct sock *sk = sock->sk;
- bdaddr_t *src = &sa.sco_bdaddr;
- int len, err = 0;
+ bdaddr_t *src = &sa->sco_bdaddr;
+ int err = 0;
- BT_DBG("sk %p %s", sk, batostr(&sa.sco_bdaddr));
+ BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
- memset(&sa, 0, sizeof(sa));
- len = min_t(unsigned int, sizeof(sa), alen);
- memcpy(&sa, addr, len);
-
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
err = -EADDRINUSE;
} else {
/* Save source address */
- bacpy(&bt_sk(sk)->src, &sa.sco_bdaddr);
- sco_pi(sk)->pkt_type = sa.sco_pkt_type;
+ bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
sk->sk_state = BT_BOUND;
}
static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
struct sock *sk = sock->sk;
- struct sockaddr_sco sa;
- int len, err = 0;
+ int err = 0;
+
BT_DBG("sk %p", sk);
- if (!addr || addr->sa_family != AF_BLUETOOTH)
+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
return -EINVAL;
- memset(&sa, 0, sizeof(sa));
- len = min_t(unsigned int, sizeof(sa), alen);
- memcpy(&sa, addr, len);
-
- lock_sock(sk);
+ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
+ return -EBADFD;
- if (sk->sk_type != SOCK_SEQPACKET) {
- err = -EINVAL;
- goto done;
- }
+ if (sk->sk_type != SOCK_SEQPACKET)
+ return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
- err = -EBADFD;
- goto done;
- }
+ lock_sock(sk);
/* Set destination address and psm */
- bacpy(&bt_sk(sk)->dst, &sa.sco_bdaddr);
- sco_pi(sk)->pkt_type = sa.sco_pkt_type;
+ bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
if ((err = sco_connect(sk)))
goto done;
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
else
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
- sa->sco_pkt_type = sco_pi(sk)->pkt_type;
return 0;
}