Commit 1f4e5444 authored by Marcel Holtmann's avatar Marcel Holtmann

[Bluetooth] Support for tracking the voice setting

This patch makes sure that the Bluetooth core layer always knows the
current voice setting. It will be read on device initialization and
then stored in the hci_dev structure.
parent 7508df7c
...@@ -253,6 +253,17 @@ struct hci_cp_write_dev_class { ...@@ -253,6 +253,17 @@ struct hci_cp_write_dev_class {
__u8 dev_class[3]; __u8 dev_class[3];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define OCF_READ_VOICE_SETTING 0x0025
struct hci_rp_read_voice_setting {
__u8 status;
__u16 voice_setting;
} __attribute__ ((packed));
#define OCF_WRITE_VOICE_SETTING 0x0026
struct hci_cp_write_voice_setting {
__u16 voice_setting;
} __attribute__ ((packed));
#define OCF_HOST_BUFFER_SIZE 0x0033 #define OCF_HOST_BUFFER_SIZE 0x0033
struct hci_cp_host_buffer_size { struct hci_cp_host_buffer_size {
__u16 acl_mtu; __u16 acl_mtu;
......
...@@ -71,11 +71,12 @@ struct hci_dev { ...@@ -71,11 +71,12 @@ struct hci_dev {
__u8 type; __u8 type;
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 features[8]; __u8 features[8];
__u16 voice_setting;
__u16 pkt_type; __u16 pkt_type;
__u16 link_policy; __u16 link_policy;
__u16 link_mode; __u16 link_mode;
atomic_t cmd_cnt; atomic_t cmd_cnt;
unsigned int acl_cnt; unsigned int acl_cnt;
unsigned int sco_cnt; unsigned int sco_cnt;
...@@ -88,7 +89,7 @@ struct hci_dev { ...@@ -88,7 +89,7 @@ struct hci_dev {
unsigned long cmd_last_tx; unsigned long cmd_last_tx;
unsigned long acl_last_tx; unsigned long acl_last_tx;
unsigned long sco_last_tx; unsigned long sco_last_tx;
struct tasklet_struct cmd_task; struct tasklet_struct cmd_task;
struct tasklet_struct rx_task; struct tasklet_struct rx_task;
struct tasklet_struct tx_task; struct tasklet_struct tx_task;
...@@ -119,7 +120,7 @@ struct hci_dev { ...@@ -119,7 +120,7 @@ struct hci_dev {
#endif #endif
struct module *owner; struct module *owner;
int (*open)(struct hci_dev *hdev); int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev);
......
...@@ -237,6 +237,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) ...@@ -237,6 +237,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Read BD Address */ /* Read BD Address */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL); hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
/* Read Voice Setting */
hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
/* Optional initialization */ /* Optional initialization */
/* Clear Event Filters */ /* Clear Event Filters */
......
...@@ -123,6 +123,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * ...@@ -123,6 +123,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{ {
__u8 status, param; __u8 status, param;
__u16 setting;
struct hci_rp_read_voice_setting *vs;
void *sent; void *sent;
BT_DBG("%s ocf 0x%x", hdev->name, ocf); BT_DBG("%s ocf 0x%x", hdev->name, ocf);
...@@ -198,6 +200,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb ...@@ -198,6 +200,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE); sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
if (!sent) if (!sent)
break; break;
status = *((__u8 *) skb->data); status = *((__u8 *) skb->data);
param = *((__u8 *) sent); param = *((__u8 *) sent);
...@@ -215,6 +218,39 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb ...@@ -215,6 +218,39 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
hci_req_complete(hdev, status); hci_req_complete(hdev, status);
break; break;
case OCF_READ_VOICE_SETTING:
vs = (struct hci_rp_read_voice_setting *) skb->data;
if (vs->status) {
BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vc->status);
break;
}
setting = __le16_to_cpu(vs->voice_setting);
if (hdev->voice_setting != setting ) {
hdev->voice_setting = setting;
BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
}
break;
case OCF_WRITE_VOICE_SETTING:
sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
if (!sent)
break;
status = *((__u8 *) skb->data);
setting = __le16_to_cpu(get_unaligned((__u16 *) sent));
if (!status && hdev->voice_setting != setting) {
hdev->voice_setting = setting;
BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
}
hci_req_complete(hdev, status);
break;
case OCF_HOST_BUFFER_SIZE: case OCF_HOST_BUFFER_SIZE:
status = *((__u8 *) skb->data); status = *((__u8 *) skb->data);
if (status) { if (status) {
...@@ -282,7 +318,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s ...@@ -282,7 +318,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt); hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
break; break;
case OCF_READ_BD_ADDR: case OCF_READ_BD_ADDR:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment