* [PATCH v11 02/10] Bluetooth: Remove unused mask parameter in sco_conn_defer_accept
From: Frédéric Dalleau @ 2013-08-19 12:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
>From Bluetooth Core v4.0 specification, 7.1.8 Accept Connection Request
Command "When accepting synchronous connection request, the Role
parameter is not used and will be ignored by the BR/EDR Controller."
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/sco.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9e20a30..05c2fc1 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -651,7 +651,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return err;
}
-static void sco_conn_defer_accept(struct hci_conn *conn, int mask)
+static void sco_conn_defer_accept(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
@@ -663,11 +663,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask)
struct hci_cp_accept_conn_req cp;
bacpy(&cp.bdaddr, &conn->dst);
-
- if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
- cp.role = 0x00; /* Become master */
- else
- cp.role = 0x01; /* Remain slave */
+ cp.role = 0x00; /* Ignored */
hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
} else {
@@ -697,7 +693,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_state == BT_CONNECT2 &&
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
- sco_conn_defer_accept(pi->conn->hcon, 0);
+ sco_conn_defer_accept(pi->conn->hcon);
sk->sk_state = BT_CONFIG;
msg->msg_namelen = 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 03/10] Bluetooth: Add Bluetooth socket voice option
From: Frédéric Dalleau @ 2013-08-19 12:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
This patch extends the current Bluetooth socket options with BT_VOICE.
This is intended to choose voice data type at runtime. It only applies
to SCO sockets. Incoming connections shall be setup during deferred
setup. Outgoing connections shall be setup before connect(). The desired
setting is stored in the SCO socket info. This patch declares needed
members, modifies getsockopt() and setsockopt().
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/bluetooth.h | 8 ++++++++
include/net/bluetooth/sco.h | 1 +
net/bluetooth/sco.c | 40 ++++++++++++++++++++++++++++++++++++-
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 10eb9b3..10d43d8 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -107,6 +107,14 @@ struct bt_power {
*/
#define BT_CHANNEL_POLICY_AMP_PREFERRED 2
+#define BT_VOICE 11
+struct bt_voice {
+ __u16 setting;
+};
+
+#define BT_VOICE_TRANSPARENT 0x0003
+#define BT_VOICE_CVSD_16BIT 0x0060
+
__printf(1, 2)
int bt_info(const char *fmt, ...);
__printf(1, 2)
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 1e35c43..e252a31 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -73,6 +73,7 @@ struct sco_conn {
struct sco_pinfo {
struct bt_sock bt;
__u32 flags;
+ __u16 setting;
struct sco_conn *conn;
};
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 05c2fc1..e8cda67 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -416,6 +416,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
sk->sk_protocol = proto;
sk->sk_state = BT_OPEN;
+ sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
+
setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
bt_sock_link(&sco_sk_list, sk);
@@ -709,7 +711,8 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
- int err = 0;
+ int len, err = 0;
+ struct bt_voice voice;
u32 opt;
BT_DBG("sk %p", sk);
@@ -735,6 +738,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
break;
+ case BT_VOICE:
+ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
+ sk->sk_state != BT_CONNECT2) {
+ err = -EINVAL;
+ break;
+ }
+
+ voice.setting = sco_pi(sk)->setting;
+
+ len = min_t(unsigned int, sizeof(voice), optlen);
+ if (copy_from_user((char *) &voice, optval, len)) {
+ err = -EFAULT;
+ break;
+ }
+
+ /* Explicitly check for these values */
+ if (voice.setting != BT_VOICE_TRANSPARENT &&
+ voice.setting != BT_VOICE_CVSD_16BIT) {
+ err = -EINVAL;
+ break;
+ }
+
+ sco_pi(sk)->setting = voice.setting;
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -804,6 +832,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
{
struct sock *sk = sock->sk;
int len, err = 0;
+ struct bt_voice voice;
BT_DBG("sk %p", sk);
@@ -829,6 +858,15 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
break;
+ case BT_VOICE:
+ voice.setting = sco_pi(sk)->setting;
+
+ len = min_t(unsigned int, len, sizeof(voice));
+ if (copy_to_user(optval, (char *)&voice, len))
+ err = -EFAULT;
+
+ break;
+
default:
err = -ENOPROTOOPT;
break;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 04/10] Bluetooth: Add constants for SCO airmode
From: Frédéric Dalleau @ 2013-08-19 12:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
This patch defines constants for SCO airmode from SCO voice setting. It
refers to Bluetooth Core V4.0 specification, Part E, Chap 6.12 which
describe SCO voice setting format.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 307a192..f403509 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1215,4 +1215,8 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
u8 bdaddr_to_le(u8 bdaddr_type);
+#define SCO_AIRMODE_MASK 0x0003
+#define SCO_AIRMODE_CVSD 0x0000
+#define SCO_AIRMODE_TRANSP 0x0003
+
#endif /* __HCI_CORE_H */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 05/10] Bluetooth: Use voice setting in deferred SCO connection request
From: Frédéric Dalleau @ 2013-08-19 12:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
When an incoming eSCO connection is requested, check the selected voice
setting and reply appropriately. Voice setting should have been
negotiated previously. For example, in case of HFP, the codec is
negotiated using AT commands on the RFCOMM channel. This patch only
changes replies for socket with deferred setup enabled.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/sco.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e8cda67..3b3d24a 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -653,7 +653,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return err;
}
-static void sco_conn_defer_accept(struct hci_conn *conn)
+static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
{
struct hci_dev *hdev = conn->hdev;
@@ -676,9 +676,21 @@ static void sco_conn_defer_accept(struct hci_conn *conn)
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
- cp.max_latency = __constant_cpu_to_le16(0xffff);
- cp.content_format = cpu_to_le16(hdev->voice_setting);
- cp.retrans_effort = 0xff;
+ cp.content_format = cpu_to_le16(setting);
+
+ switch (setting & SCO_AIRMODE_MASK) {
+ case SCO_AIRMODE_TRANSP:
+ if (conn->pkt_type & ESCO_2EV3)
+ cp.max_latency = __constant_cpu_to_le16(0x0008);
+ else
+ cp.max_latency = __constant_cpu_to_le16(0x000D);
+ cp.retrans_effort = 0x02;
+ break;
+ case SCO_AIRMODE_CVSD:
+ cp.max_latency = __constant_cpu_to_le16(0xffff);
+ cp.retrans_effort = 0xff;
+ break;
+ }
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp);
@@ -695,7 +707,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_state == BT_CONNECT2 &&
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
- sco_conn_defer_accept(pi->conn->hcon);
+ sco_conn_defer_accept(pi->conn->hcon, pi->setting);
sk->sk_state = BT_CONFIG;
msg->msg_namelen = 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 06/10] Bluetooth: Parameters for outgoing SCO connections
From: Frédéric Dalleau @ 2013-08-19 12:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
In order to establish a transparent SCO connection, the correct settings
must be specified in the Setup Synchronous Connection request. For that,
a setting field is added to ACL connection data to set up the desired
parameters. The patch also removes usage of hdev->voice_setting in CVSD
connection and makes use of T2 parameters for transparent data.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 5 +++--
net/bluetooth/hci_conn.c | 24 +++++++++++++++++++-----
net/bluetooth/sco.c | 2 +-
3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f403509..61ca2ce 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -320,6 +320,7 @@ struct hci_conn {
__u32 passkey_notify;
__u8 passkey_entered;
__u16 disc_timeout;
+ __u16 setting;
unsigned long flags;
__u8 remote_cap;
@@ -584,8 +585,8 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
__u8 dst_type, __u8 sec_level, __u8 auth_type);
-struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
- bdaddr_t *dst);
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ __u16 setting);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5f1f448..c0e56a5 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -185,13 +185,24 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
conn->attempt++;
cp.handle = cpu_to_le16(handle);
- cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
- cp.max_latency = __constant_cpu_to_le16(0xffff);
- cp.voice_setting = cpu_to_le16(hdev->voice_setting);
- cp.retrans_effort = 0xff;
+ cp.voice_setting = cpu_to_le16(conn->setting);
+
+ switch (conn->setting & SCO_AIRMODE_MASK) {
+ case SCO_AIRMODE_TRANSP:
+ cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
+ ~ESCO_2EV3);
+ cp.max_latency = __constant_cpu_to_le16(0x000d);
+ cp.retrans_effort = 0x02;
+ break;
+ case SCO_AIRMODE_CVSD:
+ cp.pkt_type = cpu_to_le16(conn->pkt_type);
+ cp.max_latency = __constant_cpu_to_le16(0xffff);
+ cp.retrans_effort = 0xff;
+ break;
+ }
hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}
@@ -560,7 +571,8 @@ static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
return acl;
}
-struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ __u16 setting)
{
struct hci_conn *acl;
struct hci_conn *sco;
@@ -583,6 +595,8 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst)
hci_conn_hold(sco);
+ sco->setting = setting;
+
if (acl->state == BT_CONNECTED &&
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3b3d24a..e82d792 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,7 +176,7 @@ static int sco_connect(struct sock *sk)
else
type = SCO_LINK;
- hcon = hci_connect_sco(hdev, type, dst);
+ hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 07/10] Bluetooth: Add constants and macro declaration for transparent data
From: Frédéric Dalleau @ 2013-08-19 12:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
This patch defines constants and macro for transparent data LMP
features. It refers to Bluetooth Core V4.0 specification, Part C, Chap
3.3 which defines LMP feature mask.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index a01fbb4..aaeaf09 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -238,6 +238,7 @@ enum {
#define LMP_CVSD 0x01
#define LMP_PSCHEME 0x02
#define LMP_PCONTROL 0x04
+#define LMP_TRANSPARENT 0x08
#define LMP_RSSI_INQ 0x40
#define LMP_ESCO 0x80
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 61ca2ce..b2bfab8 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -800,6 +800,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO)
#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR)
#define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES)
+#define lmp_transp_capable(dev) ((dev)->features[0][2] & LMP_TRANSPARENT)
/* ----- Extended LMP capabilities ----- */
#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 08/10] Bluetooth: Prevent transparent SCO on older devices
From: Frédéric Dalleau @ 2013-08-19 12:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
Older Bluetooth devices may not support Setup Synchronous Connection or
SCO transparent data. This is indicated by the corresponding LMP feature
bits. It is not possible to know if the adapter support these features
before setting BT_VOICE option since the socket is not bound to an
adapter. An adapter can also be added after the socket is created. The
socket can be bound to an address before adapter is plugged in.
Thus, on a such adapters, if user request BT_VOICE_TRANSPARENT, outgoing
connections fail on connect() and returns -EOPNOTSUPP. Incoming
connections do not fail. However, they should only be allowed depending
on what was specified in Write_Voice_Settings command.
EOPNOTSUPP is choosen because connect() system call is failing after
selecting route but before any connection attempt.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/sco.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e82d792..1170b6e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,6 +176,12 @@ static int sco_connect(struct sock *sk)
else
type = SCO_LINK;
+ if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
+ (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
+ err = -EOPNOTSUPP;
+ goto done;
+ }
+
hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 09/10] Bluetooth: Handle specific error for SCO connection fallback
From: Frédéric Dalleau @ 2013-08-19 12:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
Synchronous Connection Complete event can return error "Connection
Rejected due to Limited resources (0x10)".
Handling this error is required for SCO connection fallback. This error
happens when the server tried to accept the connection but failed to
negotiate settings.
This error code has been verified experimentally by sending a T2 request
to a T1 only SCO listener.
Client dump follows :
< HCI Command (0x01|0x0028) plen 17 [hci0] 3.696064
Handle: 12
Transmit bandwidth: 8000
Receive bandwidth: 8000
Max latency: 13
Setting: 0x0003
Retransmission effort: Optimize for link quality (0x02)
Packet type: 0x0380
> HCI Event (0x0f) plen 4 [hci0] 3.697034
Setup Synchronous Connection (0x01|0x0028) ncmd 1
Status: Success (0x00)
> HCI Event (0x2c) plen 17 [hci0] 3.736059
Status: Connection Rejected due to Limited Resources (0x0d)
Handle: 0
Address: xx:xx:xx:xx:xx:AB (OUI 70-F3-95)
Link type: eSCO (0x02)
Transmission interval: 0x0c
Retransmission window: 0x06
RX packet length: 60
TX packet length: 60
Air mode: Transparent (0x03)
Server dump follows :
> HCI Event (0x04) plen 10 [hci0] 4.741513
Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
Class: 0x620100
Major class: Computer (desktop, notebook, PDA, organizers)
Minor class: Uncategorized, code for device not assigned
Networking (LAN, Ad hoc)
Audio (Speaker, Microphone, Headset)
Telephony (Cordless telephony, Modem, Headset)
Link type: eSCO (0x02)
< HCI Command (0x01|0x0029) plen 21 [hci0] 4.743269
Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
Transmit bandwidth: 8000
Receive bandwidth: 8000
Max latency: 13
Setting: 0x0003
Retransmission effort: Optimize for link quality (0x02)
Packet type: 0x03c1
> HCI Event (0x0f) plen 4 [hci0] 4.745517
Accept Synchronous Connection (0x01|0x0029) ncmd 1
Status: Success (0x00)
> HCI Event (0x2c) plen 17 [hci0] 4.749508
Status: Connection Rejected due to Limited Resources (0x0d)
Handle: 0
Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
Link type: eSCO (0x02)
Transmission interval: 0x0c
Retransmission window: 0x06
RX packet length: 60
TX packet length: 60
Air mode: Transparent (0x03)
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_event.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 50e39f4..a8bb7bb 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2904,6 +2904,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
hci_conn_add_sysfs(conn);
break;
+ case 0x0d: /* Connection Rejected due to Limited Resources */
case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v11 10/10] Bluetooth: Add SCO connection fallback
From: Frédéric Dalleau @ 2013-08-19 12:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg
In-Reply-To: <1376915043-24531-1-git-send-email-frederic.dalleau@linux.intel.com>
When initiating a transparent eSCO connection, make use of T2 settings
at first try. T2 is the recommended settings from HFP 1.6 WideBand
Speech. Upon connection failure, try T1 settings.
When CVSD is requested and eSCO is supported, try to establish eSCO
connection using S3 settings. If it fails, fallback in sequence to S2,
S1, D1, D0 settings.
To know which setting should be used, conn->attempt is used. It
indicates the currently ongoing SCO connection attempt and can be used
as the index for the fallback settings table.
These setting and the fallback order are described in Bluetooth HFP 1.6
specification p. 101.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_conn.c | 44 +++++++++++++++++++++++++++++++-------
net/bluetooth/hci_event.c | 6 +++---
3 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b2bfab8..3ede820 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -570,7 +570,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
}
void hci_disconnect(struct hci_conn *conn, __u8 reason);
-void hci_setup_sync(struct hci_conn *conn, __u16 handle);
+bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c0e56a5..f081712 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -31,6 +31,24 @@
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/smp.h>
+struct sco_param {
+ u16 pkt_type;
+ u16 max_latency;
+};
+
+static const struct sco_param sco_param_cvsd[] = {
+ { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */
+ { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */
+ { EDR_ESCO_MASK | ESCO_EV3, 0x0007 }, /* S1 */
+ { EDR_ESCO_MASK | ESCO_HV3, 0xffff }, /* D1 */
+ { EDR_ESCO_MASK | ESCO_HV1, 0xffff }, /* D0 */
+};
+
+static const struct sco_param sco_param_wideband[] = {
+ { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */
+ { EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */
+};
+
static void hci_le_create_connection(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
@@ -172,10 +190,11 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle)
hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
}
-void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_setup_sync_conn cp;
+ const struct sco_param *param;
BT_DBG("hcon %p", conn);
@@ -192,19 +211,28 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
switch (conn->setting & SCO_AIRMODE_MASK) {
case SCO_AIRMODE_TRANSP:
- cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
- ~ESCO_2EV3);
- cp.max_latency = __constant_cpu_to_le16(0x000d);
+ if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
+ return false;
cp.retrans_effort = 0x02;
+ param = &sco_param_wideband[conn->attempt - 1];
break;
case SCO_AIRMODE_CVSD:
- cp.pkt_type = cpu_to_le16(conn->pkt_type);
- cp.max_latency = __constant_cpu_to_le16(0xffff);
- cp.retrans_effort = 0xff;
+ if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
+ return false;
+ cp.retrans_effort = 0x01;
+ param = &sco_param_cvsd[conn->attempt - 1];
break;
+ default:
+ return false;
}
- hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
+ cp.pkt_type = __cpu_to_le16(param->pkt_type);
+ cp.max_latency = __cpu_to_le16(param->max_latency);
+
+ if (hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0)
+ return false;
+
+ return true;
}
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a8bb7bb..94aab73 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2909,11 +2909,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
case 0x1f: /* Unspecified error */
- if (conn->out && conn->attempt < 2) {
+ if (conn->out) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK);
- hci_setup_sync(conn, conn->link->handle);
- goto unlock;
+ if (hci_setup_sync(conn, conn->link->handle))
+ goto unlock;
}
/* fall through */
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 0/8] Fix message order
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This set fixes a couple of issues introduced with the use of ObjectManager due
the processing of signals on idle to group changes, this has been causing
issues with external components such as ofono and pulseaudio that sometimes
receives connections from devices objects that have pending signals thus
cannot be properly processed or have to be assumed paired and with certain
UUIDs which is not ideal.
Luiz Augusto von Dentz (8):
gdbus: Fix not maintaining message order for signals
gdbus: Add g_dbus_send_message_with_reply
gdbus: Avoid calling dbus_connection_send*
gdbus: Fix emitting PropertiesChanged twice
core: Make use of g_dbus_send_message_with_reply
neard: Make use of g_dbus_send_message_with_reply
audio/media: Make use of g_dbus_send_message_with_reply
obexd: Make use of g_dbus_send_message*
gdbus/client.c | 14 ++---
gdbus/gdbus.h | 3 +
gdbus/object.c | 143 ++++++++++++++++++++++++------------------
obexd/plugins/bluetooth.c | 2 +-
obexd/plugins/pcsuite.c | 5 +-
obexd/plugins/syncevolution.c | 6 +-
obexd/src/manager.c | 3 +-
plugins/neard.c | 2 +-
profiles/audio/media.c | 2 +-
src/agent.c | 12 ++--
src/profile.c | 4 +-
11 files changed, 109 insertions(+), 87 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH BlueZ] build: Fix not checking readline.h for bluetooth-player
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
If --disable-client is passed to configure script is possible to build
BlueZ without readline which would cause the following error:
tools/bluetooth-player.c:36:31: fatal error: readline/readline.h: No such file or directory
#include <readline/readline.h>
^
---
Makefile.tools | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Makefile.tools b/Makefile.tools
index 3bb0e82..4bcb18e 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -172,8 +172,7 @@ if EXPERIMENTAL
noinst_PROGRAMS += tools/bdaddr tools/avinfo tools/avtest tools/scotest \
tools/hcieventmask tools/hcisecfilter tools/hwdb \
tools/btmgmt tools/btattach tools/btsnoop \
- tools/btiotest tools/mpris-player \
- tools/bluetooth-player
+ tools/btiotest tools/mpris-player
tools_bdaddr_SOURCES = tools/bdaddr.c src/oui.h src/oui.c
tools_bdaddr_LDADD = lib/libbluetooth-internal.la @UDEV_LIBS@
@@ -199,17 +198,13 @@ tools_btiotest_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
tools_mpris_player_SOURCES = tools/mpris-player.c
tools_mpris_player_LDADD = gdbus/libgdbus-internal.la @GLIB_LIBS@ @DBUS_LIBS@
-tools_bluetooth_player_SOURCES = tools/bluetooth-player.c \
- client/display.h client/display.c
-tools_bluetooth_player_LDADD = gdbus/libgdbus-internal.la \
- @GLIB_LIBS@ @DBUS_LIBS@ -lreadline
-
EXTRA_DIST += tools/bdaddr.1
endif
if READLINE
noinst_PROGRAMS += attrib/gatttool \
- tools/obex-client-tool tools/obex-server-tool
+ tools/obex-client-tool tools/obex-server-tool \
+ tools/bluetooth-player
attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
attrib/gattrib.c btio/btio.c \
@@ -226,6 +221,11 @@ tools_obex_client_tool_LDADD = lib/libbluetooth-internal.la \
tools_obex_server_tool_SOURCES = $(gobex_sources) $(btio_sources) \
tools/obex-server-tool.c
tools_obex_server_tool_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
+tools_bluetooth_player_SOURCES = tools/bluetooth-player.c \
+ client/display.h client/display.c
+tools_bluetooth_player_LDADD = gdbus/libgdbus-internal.la \
+ @GLIB_LIBS@ @DBUS_LIBS@ -lreadline
endif
if EXPERIMENTAL
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 1/8] gdbus: Fix not maintaining message order for signals
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In some cases the order of the messages is altered when a message is
sent without processing the pending signals first, currently this affect
client_check_order unit test:
/gdbus/client_check_order: **
ERROR:unit/test-gdbus-client.c:795:property_check_order: assertion failed: (g_strcmp0(string, "value1") == 0)
As can be observed the value of the property is not yet updated because the
signal it is still pending, once this fix is applied the test pass:
/gdbus/client_check_order: OK
Note that the flushing only works when g_dbus_send_message is used so
places where dbus_connection_send and other variants are called directly
may still change the order.
---
gdbus/object.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/gdbus/object.c b/gdbus/object.c
index 2f8ef45..b2ca1c2 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1494,6 +1494,35 @@ DBusMessage *g_dbus_create_reply(DBusMessage *message, int type, ...)
return reply;
}
+static void g_dbus_flush_object(struct generic_data *data)
+{
+ GSList *l;
+
+ if (data->process_id > 0) {
+ g_source_remove(data->process_id);
+ data->process_id = 0;
+ }
+
+ process_changes(data);
+
+ for (l = data->objects; l; l = l->next)
+ g_dbus_flush_object(l->data);
+}
+
+static void g_dbus_flush(DBusConnection *connection)
+{
+ static gboolean flushing = FALSE;
+
+ if (flushing || root == NULL || root->conn != connection)
+ return;
+
+ flushing = TRUE;
+
+ g_dbus_flush_object(root);
+
+ flushing = FALSE;
+}
+
gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
{
dbus_bool_t result = FALSE;
@@ -1510,6 +1539,9 @@ gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
goto out;
}
+ /* Flush pending signal to guarantee message order */
+ g_dbus_flush(connection);
+
result = dbus_connection_send(connection, message, NULL);
out:
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 2/8] gdbus: Add g_dbus_send_message_with_reply
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
g_dbus_send_message_with_reply flushes pending signals before calling
dbus_connection_send_with_reply so it does not alter the message order
---
gdbus/gdbus.h | 3 +++
gdbus/object.c | 11 +++++++++++
2 files changed, 14 insertions(+)
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 8b13393..9542109 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -250,6 +250,9 @@ DBusMessage *g_dbus_create_reply_valist(DBusMessage *message,
int type, va_list args);
gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message);
+gboolean g_dbus_send_message_with_reply(DBusConnection *connection,
+ DBusMessage *message,
+ DBusPendingCall **call, int timeout);
gboolean g_dbus_send_error(DBusConnection *connection, DBusMessage *message,
const char *name, const char *format, ...)
__attribute__((format(printf, 4, 5)));
diff --git a/gdbus/object.c b/gdbus/object.c
index b2ca1c2..5d43036 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1550,6 +1550,17 @@ out:
return result;
}
+gboolean g_dbus_send_message_with_reply(DBusConnection *connection,
+ DBusMessage *message,
+ DBusPendingCall **call, int timeout)
+{
+ /* Flush pending signal to guarantee message order */
+ g_dbus_flush(connection);
+
+ return dbus_connection_send_with_reply(connection, message, call,
+ timeout);
+}
+
gboolean g_dbus_send_error_valist(DBusConnection *connection,
DBusMessage *message, const char *name,
const char *format, va_list args)
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 3/8] gdbus: Avoid calling dbus_connection_send*
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
dbus_connection_send* should not be called directly except by
g_dbus_send_message.
---
gdbus/client.c | 14 ++++-----
gdbus/object.c | 92 ++++++++++++++++++++++------------------------------------
2 files changed, 42 insertions(+), 64 deletions(-)
diff --git a/gdbus/client.c b/gdbus/client.c
index d80e252..8ebfaad 100644
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -100,7 +100,7 @@ static gboolean modify_match(DBusConnection *conn, const char *member,
dbus_message_append_args(msg, DBUS_TYPE_STRING, &rule,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(conn, msg, &call, -1) == FALSE) {
+ if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
dbus_message_unref(msg);
return FALSE;
}
@@ -319,7 +319,7 @@ static void get_all_properties(GDBusProxy *proxy)
dbus_message_append_args(msg, DBUS_TYPE_STRING, &proxy->interface,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
dbus_message_unref(msg);
return;
@@ -575,7 +575,7 @@ gboolean g_dbus_proxy_refresh_property(GDBusProxy *proxy, const char *name)
&proxy->interface);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
dbus_message_unref(msg);
refresh_property_free(data);
@@ -668,7 +668,7 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
dbus_message_iter_append_basic(&variant, type, value);
dbus_message_iter_close_container(&iter, &variant);
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
dbus_message_unref(msg);
g_free(data);
@@ -742,7 +742,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
setup(&iter, data->user_data);
}
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, METHOD_CALL_TIMEOUT) == FALSE) {
dbus_message_unref(msg);
g_free(data);
@@ -1038,7 +1038,7 @@ static void get_managed_objects(GDBusClient *client)
dbus_message_append_args(msg, DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&client->get_objects_call, -1) == FALSE) {
dbus_message_unref(msg);
return;
@@ -1102,7 +1102,7 @@ static void get_name_owner(GDBusClient *client, const char *name)
dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(client->dbus_conn, msg,
+ if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&client->pending_call, -1) == FALSE) {
dbus_message_unref(msg);
return;
diff --git a/gdbus/object.c b/gdbus/object.c
index 5d43036..92f57a0 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -271,8 +271,7 @@ static DBusHandlerResult process_message(DBusConnection *connection,
if (reply == NULL)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- dbus_connection_send(connection, reply, NULL);
- dbus_message_unref(reply);
+ g_dbus_send_message(connection, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -312,19 +311,14 @@ void g_dbus_pending_error_valist(DBusConnection *connection,
for (list = pending_security; list; list = list->next) {
struct security_data *secdata = list->data;
- DBusMessage *reply;
if (secdata->pending != pending)
continue;
pending_security = g_slist_remove(pending_security, secdata);
- reply = g_dbus_create_error_valist(secdata->message,
+ g_dbus_send_error_valist(connection, secdata->message,
name, format, args);
- if (reply != NULL) {
- dbus_connection_send(connection, reply, NULL);
- dbus_message_unref(reply);
- }
dbus_message_unref(secdata->message);
g_free(secdata);
@@ -469,18 +463,13 @@ void g_dbus_pending_property_error_valist(GDBusPendingReply id,
va_list args)
{
struct property_data *propdata;
- DBusMessage *reply;
propdata = remove_pending_property_data(id);
if (propdata == NULL)
return;
- reply = g_dbus_create_error_valist(propdata->message, name, format,
- args);
- if (reply != NULL) {
- dbus_connection_send(propdata->conn, reply, NULL);
- dbus_message_unref(reply);
- }
+ g_dbus_send_error_valist(propdata->conn, propdata->message, name,
+ format, args);
dbus_message_unref(propdata->message);
g_free(propdata);
@@ -1319,45 +1308,6 @@ static gboolean check_signal(DBusConnection *conn, const char *path,
return FALSE;
}
-static dbus_bool_t emit_signal_valist(DBusConnection *conn,
- const char *path,
- const char *interface,
- const char *name,
- int first,
- va_list var_args)
-{
- DBusMessage *signal;
- dbus_bool_t ret;
- const GDBusArgInfo *args;
-
- if (!check_signal(conn, path, interface, name, &args))
- return FALSE;
-
- signal = dbus_message_new_signal(path, interface, name);
- if (signal == NULL) {
- error("Unable to allocate new %s.%s signal", interface, name);
- return FALSE;
- }
-
- ret = dbus_message_append_args_valist(signal, first, var_args);
- if (!ret)
- goto fail;
-
- if (g_dbus_args_have_signature(args, signal) == FALSE) {
- error("%s.%s: got unexpected signature '%s'", interface, name,
- dbus_message_get_signature(signal));
- ret = FALSE;
- goto fail;
- }
-
- ret = dbus_connection_send(conn, signal, NULL);
-
-fail:
- dbus_message_unref(signal);
-
- return ret;
-}
-
gboolean g_dbus_register_interface(DBusConnection *connection,
const char *path, const char *name,
const GDBusMethodTable *methods,
@@ -1634,7 +1584,7 @@ gboolean g_dbus_emit_signal(DBusConnection *connection,
va_start(args, type);
- result = emit_signal_valist(connection, path, interface,
+ result = g_dbus_emit_signal_valist(connection, path, interface,
name, type, args);
va_end(args);
@@ -1646,8 +1596,36 @@ gboolean g_dbus_emit_signal_valist(DBusConnection *connection,
const char *path, const char *interface,
const char *name, int type, va_list args)
{
- return emit_signal_valist(connection, path, interface,
- name, type, args);
+ DBusMessage *signal;
+ dbus_bool_t ret;
+ const GDBusArgInfo *args_info;
+
+ if (!check_signal(connection, path, interface, name, &args_info))
+ return FALSE;
+
+ signal = dbus_message_new_signal(path, interface, name);
+ if (signal == NULL) {
+ error("Unable to allocate new %s.%s signal", interface, name);
+ return FALSE;
+ }
+
+ ret = dbus_message_append_args_valist(signal, type, args);
+ if (!ret)
+ goto fail;
+
+ if (g_dbus_args_have_signature(args_info, signal) == FALSE) {
+ error("%s.%s: got unexpected signature '%s'", interface, name,
+ dbus_message_get_signature(signal));
+ ret = FALSE;
+ goto fail;
+ }
+
+ return g_dbus_send_message(connection, signal);
+
+fail:
+ dbus_message_unref(signal);
+
+ return ret;
}
static void process_properties_from_interface(struct generic_data *data,
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 4/8] gdbus: Fix emitting PropertiesChanged twice
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This fixes double emission of PropertiesChanged introduced by flushing
changes, the flushing can happen during the pending processing so the
pending_prop flag needs to be updated in the beginning and the list of
properties can be freed before g_dbus_send_message as it is not required
anymore.
---
gdbus/object.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 92f57a0..ae73061 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1636,6 +1636,8 @@ static void process_properties_from_interface(struct generic_data *data,
DBusMessageIter iter, dict, array;
GSList *invalidated;
+ data->pending_prop = FALSE;
+
if (iface->pending_prop == NULL)
return;
@@ -1685,10 +1687,10 @@ static void process_properties_from_interface(struct generic_data *data,
g_slist_free(invalidated);
dbus_message_iter_close_container(&iter, &array);
- g_dbus_send_message(data->conn, signal);
-
g_slist_free(iface->pending_prop);
iface->pending_prop = NULL;
+
+ g_dbus_send_message(data->conn, signal);
}
static void process_property_changes(struct generic_data *data)
@@ -1700,8 +1702,6 @@ static void process_property_changes(struct generic_data *data)
process_properties_from_interface(data, iface);
}
-
- data->pending_prop = FALSE;
}
void g_dbus_emit_property_changed(DBusConnection *connection,
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 5/8] core: Make use of g_dbus_send_message_with_reply
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This replaces dbus_connection_send_with_reply with
g_dbus_send_message_with_reply which does not alter message order.
---
src/agent.c | 12 ++++++------
src/profile.c | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/agent.c b/src/agent.c
index b9e6e8c..7880ba6 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -370,7 +370,7 @@ static int agent_call_authorize_service(struct agent_request *req,
DBUS_TYPE_STRING, &uuid,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(),
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
req->msg, &req->call,
REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
@@ -480,7 +480,7 @@ static int pincode_request_new(struct agent_request *req, const char *device_pat
dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(), req->msg,
&req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
return -EIO;
@@ -574,7 +574,7 @@ static int passkey_request_new(struct agent_request *req,
dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(), req->msg,
&req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
return -EIO;
@@ -632,7 +632,7 @@ static int confirmation_request_new(struct agent_request *req,
DBUS_TYPE_UINT32, &passkey,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(), req->msg,
&req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
return -EIO;
@@ -689,7 +689,7 @@ static int authorization_request_new(struct agent_request *req,
DBUS_TYPE_OBJECT_PATH, &device_path,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(), req->msg,
&req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
return -EIO;
@@ -823,7 +823,7 @@ static int display_pincode_request_new(struct agent_request *req,
DBUS_TYPE_STRING, &pincode,
DBUS_TYPE_INVALID);
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(), req->msg,
&req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
return -EIO;
diff --git a/src/profile.c b/src/profile.c
index 90c3535..57aead7 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -938,7 +938,7 @@ static bool send_new_connection(struct ext_profile *ext, struct ext_io *conn)
dbus_message_iter_close_container(&iter, &dict);
- if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
+ if (!g_dbus_send_message_with_reply(btd_get_dbus_connection(),
msg, &conn->pending, -1)) {
error("%s: sending NewConnection failed", ext->name);
dbus_message_unref(msg);
@@ -1682,7 +1682,7 @@ static int send_disconn_req(struct ext_profile *ext, struct ext_io *conn)
dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
+ if (!g_dbus_send_message_with_reply(btd_get_dbus_connection(),
msg, &conn->pending, -1)) {
error("%s: sending RequestDisconnection failed", ext->name);
dbus_message_unref(msg);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 6/8] neard: Make use of g_dbus_send_message_with_reply
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This replaces dbus_connection_send_with_reply with
g_dbus_send_message_with_reply which does not alter message order.
---
plugins/neard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/neard.c b/plugins/neard.c
index e4a4d71..ea91c4d 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -158,7 +158,7 @@ static void register_agent(bool append_carrier)
dbus_message_append_args(message, DBUS_TYPE_STRING, &carrier,
DBUS_TYPE_INVALID);
- if (!dbus_connection_send_with_reply(btd_get_dbus_connection(),
+ if (!g_dbus_send_message_with_reply(btd_get_dbus_connection(),
message, &call, -1)) {
dbus_message_unref(message);
error("D-Bus send failed");
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 7/8] audio/media: Make use of g_dbus_send_message_with_reply
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This replaces dbus_connection_send_with_reply with
g_dbus_send_message_with_reply which does not alter message order.
---
profiles/audio/media.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 5a06b99..9c72b8d 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -325,7 +325,7 @@ static gboolean media_endpoint_async_call(DBusMessage *msg,
request = g_new0(struct endpoint_request, 1);
/* Timeout should be less than avdtp request timeout (4 seconds) */
- if (dbus_connection_send_with_reply(btd_get_dbus_connection(),
+ if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
msg, &request->call,
REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 8/8] obexd: Make use of g_dbus_send_message*
From: Luiz Augusto von Dentz @ 2013-08-19 14:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376922779-11802-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This replaces dbus_connection_send* with g_dbus_send_message* which do
not alter message order.
---
obexd/plugins/bluetooth.c | 2 +-
obexd/plugins/pcsuite.c | 5 ++---
obexd/plugins/syncevolution.c | 6 +++---
obexd/src/manager.c | 3 +--
4 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c
index e4d518e..10f5e4f 100644
--- a/obexd/plugins/bluetooth.c
+++ b/obexd/plugins/bluetooth.c
@@ -317,7 +317,7 @@ static int register_profile(struct bluetooth_profile *profile)
}
dbus_message_iter_close_container(&iter, &opt);
- if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
+ if (!g_dbus_send_message_with_reply(connection, msg, &call, -1)) {
ret = -1;
unregister_profile(profile);
goto failed;
diff --git a/obexd/plugins/pcsuite.c b/obexd/plugins/pcsuite.c
index 4ce2fe4..6460aa9 100644
--- a/obexd/plugins/pcsuite.c
+++ b/obexd/plugins/pcsuite.c
@@ -351,7 +351,7 @@ static gboolean send_backup_dbus_message(const char *oper,
DBUS_TYPE_INVALID);
if (strcmp(oper, "open") == 0) {
- ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
+ ret = g_dbus_send_message_with_reply(conn, msg, &pending_call,
BACKUP_DBUS_TIMEOUT);
dbus_message_unref(msg);
if (ret) {
@@ -363,8 +363,7 @@ static gboolean send_backup_dbus_message(const char *oper,
} else
dbus_connection_unref(conn);
} else {
- ret = dbus_connection_send(conn, msg, NULL);
- dbus_message_unref(msg);
+ g_dbus_send_message(conn, msg);
dbus_connection_unref(conn);
}
diff --git a/obexd/plugins/syncevolution.c b/obexd/plugins/syncevolution.c
index 2d25d28..edc00c8 100644
--- a/obexd/plugins/syncevolution.c
+++ b/obexd/plugins/syncevolution.c
@@ -314,7 +314,7 @@ static int synce_close(void *object)
dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &normal,
DBUS_TYPE_STRING, &error, DBUS_TYPE_INVALID);
- dbus_connection_send_with_reply(context->dbus_conn, msg, &call, -1);
+ g_dbus_send_message_with_reply(context->dbus_conn, msg, &call, -1);
dbus_pending_call_set_notify(call, close_cb, NULL, NULL);
dbus_message_unref(msg);
dbus_pending_call_unref(call);
@@ -380,7 +380,7 @@ static ssize_t synce_read(void *object, void *buf, size_t count)
dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &authenticate,
DBUS_TYPE_STRING, &session, DBUS_TYPE_INVALID);
- if (!dbus_connection_send_with_reply(conn, msg, &call, -1)) {
+ if (!g_dbus_send_message_with_reply(conn, msg, &call, -1)) {
error("D-Bus call to %s failed.", SYNCE_SERVER_INTERFACE);
dbus_message_unref(msg);
return -EPERM;
@@ -424,7 +424,7 @@ static ssize_t synce_write(void *object, const void *buf, size_t count)
dbus_message_append_args(msg, DBUS_TYPE_STRING, &type,
DBUS_TYPE_INVALID);
- if (!dbus_connection_send_with_reply(context->dbus_conn, msg,
+ if (!g_dbus_send_message_with_reply(context->dbus_conn, msg,
&call, -1)) {
error("D-Bus call to %s failed.", SYNCE_CONN_INTERFACE);
dbus_message_unref(msg);
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
index dbfbef8..f64b7b9 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
@@ -776,8 +776,7 @@ int manager_request_authorization(struct obex_transfer *transfer, int32_t time,
dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &transfer->path,
DBUS_TYPE_INVALID);
- if (!dbus_connection_send_with_reply(connection,
- msg, &call, TIMEOUT)) {
+ if (!g_dbus_send_message_with_reply(connection, msg, &call, TIMEOUT)) {
dbus_message_unref(msg);
return -EPERM;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 1/2] build: Fix not rebuilding bluetoothd if gdbus changes
From: Luiz Augusto von Dentz @ 2013-08-19 14:48 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
src_bluetoothd_DEPENDENCIES should list all local libraries including gdbus
otherwise it does not get recompiled whenever gdbus changes.
---
Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index b8890ec..bf66c2b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -157,7 +157,7 @@ src_bluetoothd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic \
-Wl,--version-script=$(srcdir)/src/bluetooth.ver
src_bluetoothd_DEPENDENCIES = lib/libbluetooth-internal.la \
- src/bluetooth.service
+ gdbus/libgdbus-internal.la src/bluetooth.service
src_bluetoothd_CFLAGS = $(AM_CFLAGS) -DBLUETOOTH_PLUGIN_BUILTIN \
-DPLUGINDIR=\""$(build_plugindir)"\"
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 2/2] unit: Add gdbus/client_check_order
From: Luiz Augusto von Dentz @ 2013-08-19 14:48 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1376923727-12152-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
unit/test-gdbus-client.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/unit/test-gdbus-client.c b/unit/test-gdbus-client.c
index a594384..488d4ec 100644
--- a/unit/test-gdbus-client.c
+++ b/unit/test-gdbus-client.c
@@ -35,6 +35,7 @@ struct context {
GMainLoop *main_loop;
DBusConnection *dbus_conn;
GDBusClient *dbus_client;
+ GDBusProxy *proxy;
void *data;
guint timeout_source;
};
@@ -779,6 +780,74 @@ static void client_string_changed(void)
destroy_context(context);
}
+static void property_check_order(const DBusError *err, void *user_data)
+{
+ struct context *context = user_data;
+ GDBusProxy *proxy = context->proxy;
+ DBusMessageIter iter;
+ const char *string;
+
+ g_assert(!dbus_error_is_set(err));
+
+ g_assert(g_dbus_proxy_get_property(proxy, "String", &iter));
+
+ dbus_message_iter_get_basic(&iter, &string);
+ g_assert(g_strcmp0(string, "value1") == 0);
+
+ g_dbus_client_unref(context->dbus_client);
+}
+
+static void proxy_check_order(GDBusProxy *proxy, void *user_data)
+{
+ struct context *context = user_data;
+ const char *string;
+
+ if (g_test_verbose())
+ g_print("proxy %s found\n",
+ g_dbus_proxy_get_interface(proxy));
+
+ context->proxy = proxy;
+ string = "value1";
+ g_assert(g_dbus_proxy_set_property_basic(proxy, "String",
+ DBUS_TYPE_STRING, &string,
+ property_check_order, context,
+ NULL));
+}
+
+static void client_check_order(void)
+{
+ struct context *context = create_context();
+ static const GDBusPropertyTable string_properties[] = {
+ { "String", "s", get_string, set_string, string_exists },
+ { },
+ };
+
+ if (context == NULL)
+ return;
+
+ context->data = g_strdup("value");
+ g_dbus_register_interface(context->dbus_conn,
+ SERVICE_PATH, SERVICE_NAME,
+ methods, signals, string_properties,
+ context, NULL);
+
+ context->dbus_client = g_dbus_client_new(context->dbus_conn,
+ SERVICE_NAME, SERVICE_PATH);
+
+ g_dbus_client_set_disconnect_watch(context->dbus_client,
+ disconnect_handler, context);
+ g_dbus_client_set_proxy_handlers(context->dbus_client,
+ proxy_check_order, NULL, NULL,
+ context);
+
+ g_main_loop_run(context->main_loop);
+
+ g_dbus_unregister_interface(context->dbus_conn,
+ SERVICE_PATH, SERVICE_NAME);
+
+ destroy_context(context);
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -809,5 +878,7 @@ int main(int argc, char *argv[])
g_test_add_func("/gdbus/client_string_changed",
client_string_changed);
+ g_test_add_func("/gdbus/client_check_order", client_check_order);
+
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v5 0/6] rfcomm: Implement rfcomm as a proper tty_port
From: Peter Hurley @ 2013-08-19 20:20 UTC (permalink / raw)
To: gustavo; +Cc: Gianluca Anzolin, marcel, linux-bluetooth, gregkh, jslaby
In-Reply-To: <51F94E67.3040402@hurleysoftware.com>
On 07/31/2013 01:50 PM, Peter Hurley wrote:
> On 07/29/2013 11:08 AM, Gianluca Anzolin wrote:
>> This patchset addresses an issue with the rfcomm tty driver in the
>> current stable kernels that manifests itself as a sudden lockup of the
>> whole machine or as a OOPS if we are lucky enough (I wasn't).
>>
>> Triggering the problem is very easy:
>>
>> 1) establish a bluetooth connection with a bluetooth host
>> 2) open the tty it provides with some program
>> 3) turn off the bluetooth host or take it out of range
>>
>> After a timeout the machine freezes.
>>
>> Another way to trigger these lockups is to simply release the rfcomm
>> tty.
>>
>> This happens beacuse the underlying tty_struct objects and tty_port
>> objects are freed while being used: the code doesn't take proper
>> references to them.
>>
>> The following patches address the problem by implementing a proper
>> tty_port driver for rfcomm.
>>
>> There are still some issues left: one relevant to flow control (which is
>> also missing in the current code) and another relevant to a corner case
>> in rfcomm_dev_state_change() that I intend to fix with a future patch.
>> They are commented with a FIXME.
>>
>> Changes from v4:
>> [PATCH 3/6]: left the debug message in rfcomm_tty_open()
>> [PATCH 5/6]: always use !test_and_set_bit() to release the tty_port
>
> I reviewed these changes and retested. All ok.
Gustavo,
This series fixes a crashing regression from 3.10+ forward.
Why is this not in linux-next yet?
Regards,
Peter Hurley
>> Gianluca Anzolin (6):
>> rfcomm: Take proper tty_struct references
>> rfcomm: Remove the device from the list in the destructor
>> rfcomm: Move the tty initialization and cleanup out of open/close
>> rfcomm: Implement .activate, .shutdown and .carrier_raised methods
>> rfcomm: Fix the reference counting of tty_port
>> rfcomm: Purge the dlc->tx_queue to avoid circular dependency
>>
>> net/bluetooth/rfcomm/tty.c | 271 +++++++++++++++++++++------------------------
>> 1 file changed, 126 insertions(+), 145 deletions(-)
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v3] Bluetooth: btmrvl: add calibration data download support
From: Bing Zhao @ 2013-08-19 22:10 UTC (permalink / raw)
To: linux-bluetooth
Cc: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, linux-wireless,
Bing Zhao, Amitkumar Karwar
From: Amitkumar Karwar <akarwar@marvell.com>
A text file containing calibration data in hex format can
be provided at following path:
/lib/firmware/mrvl/sd8797_caldata.conf
The data will be downloaded to firmware during initialization.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: Remove module parameter. The calibration data will be downloaded
only when the device speicific data file is provided.
(Marcel Holtmann)
v3: Fix crash (misaligned memory access) on ARM
drivers/bluetooth/btmrvl_drv.h | 10 ++-
drivers/bluetooth/btmrvl_main.c | 140 +++++++++++++++++++++++++++++++++++++++-
drivers/bluetooth/btmrvl_sdio.c | 9 ++-
drivers/bluetooth/btmrvl_sdio.h | 2 +
4 files changed, 157 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 27068d1..5ef5e84 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -23,6 +23,8 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
+#include <linux/ctype.h>
+#include <linux/firmware.h>
#define BTM_HEADER_LEN 4
#define BTM_UPLD_SIZE 2312
@@ -41,6 +43,8 @@ struct btmrvl_thread {
struct btmrvl_device {
void *card;
struct hci_dev *hcidev;
+ struct device *dev;
+ const char *cal_data;
u8 dev_type;
@@ -91,6 +95,7 @@ struct btmrvl_private {
#define BT_CMD_HOST_SLEEP_CONFIG 0x59
#define BT_CMD_HOST_SLEEP_ENABLE 0x5A
#define BT_CMD_MODULE_CFG_REQ 0x5B
+#define BT_CMD_LOAD_CONFIG_DATA 0x61
/* Sub-commands: Module Bringup/Shutdown Request/Response */
#define MODULE_BRINGUP_REQ 0xF1
@@ -116,10 +121,13 @@ struct btmrvl_private {
#define PS_SLEEP 0x01
#define PS_AWAKE 0x00
+#define BT_CMD_DATA_SIZE 32
+#define BT_CAL_DATA_SIZE 28
+
struct btmrvl_cmd {
__le16 ocf_ogf;
u8 length;
- u8 data[4];
+ u8 data[BT_CMD_DATA_SIZE];
} __packed;
struct btmrvl_event {
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 9a9f518..77e940e 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -57,8 +57,9 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
ocf = hci_opcode_ocf(opcode);
ogf = hci_opcode_ogf(opcode);
- if (ocf == BT_CMD_MODULE_CFG_REQ &&
- priv->btmrvl_dev.sendcmdflag) {
+ if ((ocf == BT_CMD_MODULE_CFG_REQ ||
+ ocf == BT_CMD_LOAD_CONFIG_DATA) &&
+ priv->btmrvl_dev.sendcmdflag) {
priv->btmrvl_dev.sendcmdflag = false;
priv->adapter->cmd_complete = true;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
@@ -552,6 +553,132 @@ static int btmrvl_service_main_thread(void *data)
return 0;
}
+static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
+{
+ const u8 *s = src;
+ u8 *d = dst;
+ int ret;
+ u8 tmp[3];
+
+ while ((s - src) < len) {
+ if (*s && (isspace(*s) || *s == '\t')) {
+ s++;
+ continue;
+ }
+
+ if (isxdigit(*s)) {
+ if ((d - dst) >= dst_size) {
+ BT_ERR("calibration data file too big!!!");
+ return -EINVAL;
+ }
+
+ memcpy(tmp, s, 2);
+ tmp[2] = '\0';
+
+ ret = kstrtou8(tmp, 16, d++);
+ if (ret < 0)
+ return ret;
+
+ s += 2;
+ } else {
+ s++;
+ }
+ }
+ if (d == dst)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int btmrvl_load_cal_data(struct btmrvl_private *priv,
+ u8 *config_data)
+{
+ struct sk_buff *skb;
+ struct btmrvl_cmd *cmd;
+ int i;
+
+ skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct btmrvl_cmd *)skb->data;
+ cmd->ocf_ogf =
+ cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_LOAD_CONFIG_DATA));
+ cmd->length = BT_CMD_DATA_SIZE;
+ cmd->data[0] = 0x00;
+ cmd->data[1] = 0x00;
+ cmd->data[2] = 0x00;
+ cmd->data[3] = BT_CMD_DATA_SIZE - 4;
+
+ /* swap cal-data bytes */
+ for (i = 4; i < BT_CMD_DATA_SIZE; i++)
+ cmd->data[i] = config_data[(i/4)*8 - 1 - i];
+
+ bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+ skb_put(skb, sizeof(*cmd));
+ skb->dev = (void *)priv->btmrvl_dev.hcidev;
+ skb_queue_head(&priv->adapter->tx_queue, skb);
+ priv->btmrvl_dev.sendcmdflag = true;
+ priv->adapter->cmd_complete = false;
+
+ print_hex_dump_bytes("Calibration data: ",
+ DUMP_PREFIX_OFFSET, cmd->data, BT_CMD_DATA_SIZE);
+
+ wake_up_interruptible(&priv->main_thread.wait_q);
+ if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
+ priv->adapter->cmd_complete,
+ msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) {
+ BT_ERR("Timeout while loading calibration data");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int
+btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
+{
+ u8 cal_data[BT_CAL_DATA_SIZE];
+ int ret;
+
+ ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
+ if (ret)
+ return ret;
+
+ ret = btmrvl_load_cal_data(priv, cal_data);
+ if (ret) {
+ BT_ERR("Fail to load calibrate data");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int btmrvl_cal_data_config(struct btmrvl_private *priv)
+{
+ const struct firmware *cfg;
+ int ret;
+ const char *cal_data = priv->btmrvl_dev.cal_data;
+
+ if (!cal_data)
+ return 0;
+
+ ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
+ if (ret < 0) {
+ BT_DBG("Failed to get %s file, skipping cal data download",
+ cal_data);
+ ret = 0;
+ goto done;
+ }
+
+ ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
+done:
+ if (cfg)
+ release_firmware(cfg);
+
+ return ret;
+}
+
int btmrvl_register_hdev(struct btmrvl_private *priv)
{
struct hci_dev *hdev = NULL;
@@ -583,12 +710,21 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
goto err_hci_register_dev;
}
+ ret = btmrvl_cal_data_config(priv);
+ if (ret) {
+ BT_ERR("Set cal data failed");
+ goto err_cal_data_config;
+ }
+
#ifdef CONFIG_DEBUG_FS
btmrvl_debugfs_init(hdev);
#endif
return 0;
+err_cal_data_config:
+ hci_unregister_dev(hdev);
+
err_hci_register_dev:
hci_free_dev(hdev);
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 00da6df..af7f48d 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -18,7 +18,6 @@
* this warranty disclaimer.
**/
-#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/mmc/sdio_ids.h>
@@ -102,6 +101,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
+ .cal_data = NULL,
.reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64,
};
@@ -109,6 +109,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
+ .cal_data = NULL,
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -116,6 +117,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
+ .cal_data = "mrvl/sd8797_caldata.conf",
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -123,6 +125,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin",
+ .cal_data = NULL,
.reg = &btmrvl_reg_88xx,
.sd_blksz_fw_dl = 256,
};
@@ -1006,6 +1009,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper;
card->firmware = data->firmware;
+ card->cal_data = data->cal_data;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
}
@@ -1034,6 +1038,8 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
}
card->priv = priv;
+ priv->btmrvl_dev.dev = &card->func->dev;
+ priv->btmrvl_dev.cal_data = card->cal_data;
/* Initialize the interface specific function pointers */
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1222,4 +1228,5 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 43d35a6..6872d9e 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -85,6 +85,7 @@ struct btmrvl_sdio_card {
u32 ioport;
const char *helper;
const char *firmware;
+ const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
u8 rx_unit;
@@ -94,6 +95,7 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
+ const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
};
--
1.8.0
^ permalink raw reply related
* Re: [PATCH BlueZ 1/8] gdbus: Fix not maintaining message order for signals
From: Lucas De Marchi @ 2013-08-19 23:59 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: BlueZ development
In-Reply-To: <1376922779-11802-3-git-send-email-luiz.dentz@gmail.com>
On Mon, Aug 19, 2013 at 11:32 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> In some cases the order of the messages is altered when a message is
> sent without processing the pending signals first, currently this affect
Here and in every commit message: I think it should be made clear that
we are talking about properties and object manager signals, not
generic signals. Other signals are not affected by the out-of-order
issue.
> client_check_order unit test:
>
> /gdbus/client_check_order: **
> ERROR:unit/test-gdbus-client.c:795:property_check_order: assertion failed: (g_strcmp0(string, "value1") == 0)
>
> As can be observed the value of the property is not yet updated because the
> signal it is still pending, once this fix is applied the test pass:
>
> /gdbus/client_check_order: OK
>
> Note that the flushing only works when g_dbus_send_message is used so
> places where dbus_connection_send and other variants are called directly
> may still change the order.
> ---
> gdbus/object.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/gdbus/object.c b/gdbus/object.c
> index 2f8ef45..b2ca1c2 100644
> --- a/gdbus/object.c
> +++ b/gdbus/object.c
> @@ -1494,6 +1494,35 @@ DBusMessage *g_dbus_create_reply(DBusMessage *message, int type, ...)
> return reply;
> }
>
> +static void g_dbus_flush_object(struct generic_data *data)
> +{
> + GSList *l;
> +
> + if (data->process_id > 0) {
> + g_source_remove(data->process_id);
> + data->process_id = 0;
> + }
> +
> + process_changes(data);
> +
> + for (l = data->objects; l; l = l->next)
> + g_dbus_flush_object(l->data);
wouldn't it be better swap these 2 so we flush the pending messages
from children first, then from the parent? Then we can even guarantee
this ordering by moving this code to process_changes().
> +}
> +
> +static void g_dbus_flush(DBusConnection *connection)
> +{
> + static gboolean flushing = FALSE;
this static var makes no sense with multiple connections, does it?
> +
> + if (flushing || root == NULL || root->conn != connection)
> + return;
> +
> + flushing = TRUE;
> +
> + g_dbus_flush_object(root);
> +
> + flushing = FALSE;
> +}
> +
> gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
> {
> dbus_bool_t result = FALSE;
> @@ -1510,6 +1539,9 @@ gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
> goto out;
> }
>
> + /* Flush pending signal to guarantee message order */
> + g_dbus_flush(connection);
> +
> result = dbus_connection_send(connection, message, NULL);
>
> out:
> --
Otherwise looks good.
Lucas De Marchi
^ permalink raw reply
* Re: [PATCH BlueZ 1/2] build: Fix not rebuilding bluetoothd if gdbus changes
From: Lucas De Marchi @ 2013-08-20 0:01 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: BlueZ development
In-Reply-To: <1376923727-12152-1-git-send-email-luiz.dentz@gmail.com>
On Mon, Aug 19, 2013 at 11:48 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> src_bluetoothd_DEPENDENCIES should list all local libraries including gdbus
> otherwise it does not get recompiled whenever gdbus changes.
relinked, not recompiled
Lucas De Marchi
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox