[Bluetooth] Read local version information on device init
The local version information are needed to identify certain feature sets of devices. They must be read on device init and stored for later use. It is also possible to access them through the device model. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
b4c612a473
commit
1143e5a6d4
|
@ -72,6 +72,9 @@ struct hci_dev {
|
||||||
__u8 type;
|
__u8 type;
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
__u8 features[8];
|
__u8 features[8];
|
||||||
|
__u8 hci_ver;
|
||||||
|
__u16 hci_rev;
|
||||||
|
__u16 manufacturer;
|
||||||
__u16 voice_setting;
|
__u16 voice_setting;
|
||||||
|
|
||||||
__u16 pkt_type;
|
__u16 pkt_type;
|
||||||
|
|
|
@ -206,6 +206,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
|
||||||
/* Read Local Supported Features */
|
/* Read Local Supported Features */
|
||||||
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
|
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
|
||||||
|
|
||||||
|
/* Read Local Version */
|
||||||
|
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
|
||||||
|
|
||||||
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
|
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
|
||||||
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
|
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
|
||||||
/* Command Complete OGF INFO_PARAM */
|
/* Command Complete OGF INFO_PARAM */
|
||||||
static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
|
static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
struct hci_rp_read_loc_version *lv;
|
||||||
struct hci_rp_read_local_features *lf;
|
struct hci_rp_read_local_features *lf;
|
||||||
struct hci_rp_read_buffer_size *bs;
|
struct hci_rp_read_buffer_size *bs;
|
||||||
struct hci_rp_read_bd_addr *ba;
|
struct hci_rp_read_bd_addr *ba;
|
||||||
|
@ -305,6 +306,23 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
|
||||||
BT_DBG("%s ocf 0x%x", hdev->name, ocf);
|
BT_DBG("%s ocf 0x%x", hdev->name, ocf);
|
||||||
|
|
||||||
switch (ocf) {
|
switch (ocf) {
|
||||||
|
case OCF_READ_LOCAL_VERSION:
|
||||||
|
lv = (struct hci_rp_read_loc_version *) skb->data;
|
||||||
|
|
||||||
|
if (lv->status) {
|
||||||
|
BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdev->hci_ver = lv->hci_ver;
|
||||||
|
hdev->hci_rev = btohs(lv->hci_rev);
|
||||||
|
hdev->manufacturer = btohs(lv->manufacturer);
|
||||||
|
|
||||||
|
BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
|
||||||
|
hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case OCF_READ_LOCAL_FEATURES:
|
case OCF_READ_LOCAL_FEATURES:
|
||||||
lf = (struct hci_rp_read_local_features *) skb->data;
|
lf = (struct hci_rp_read_local_features *) skb->data;
|
||||||
|
|
||||||
|
@ -329,7 +347,8 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
|
||||||
if (hdev->features[1] & LMP_HV3)
|
if (hdev->features[1] & LMP_HV3)
|
||||||
hdev->pkt_type |= (HCI_HV3);
|
hdev->pkt_type |= (HCI_HV3);
|
||||||
|
|
||||||
BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
|
BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
|
||||||
|
lf->features[0], lf->features[1], lf->features[2]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,24 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
|
||||||
return sprintf(buf, "%s\n", batostr(&bdaddr));
|
return sprintf(buf, "%s\n", batostr(&bdaddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = dev_get_drvdata(dev);
|
||||||
|
return sprintf(buf, "%d\n", hdev->manufacturer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = dev_get_drvdata(dev);
|
||||||
|
return sprintf(buf, "%d\n", hdev->hci_ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = dev_get_drvdata(dev);
|
||||||
|
return sprintf(buf, "%d\n", hdev->hci_rev);
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
|
static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = dev_get_drvdata(dev);
|
struct hci_dev *hdev = dev_get_drvdata(dev);
|
||||||
|
@ -153,6 +171,9 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
|
||||||
|
|
||||||
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
|
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
|
||||||
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
|
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
|
||||||
|
static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
|
||||||
|
static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
|
||||||
|
static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
|
||||||
static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
|
static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
|
||||||
|
|
||||||
static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
|
static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
|
||||||
|
@ -165,6 +186,9 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
|
||||||
static struct device_attribute *bt_attrs[] = {
|
static struct device_attribute *bt_attrs[] = {
|
||||||
&dev_attr_type,
|
&dev_attr_type,
|
||||||
&dev_attr_address,
|
&dev_attr_address,
|
||||||
|
&dev_attr_manufacturer,
|
||||||
|
&dev_attr_hci_version,
|
||||||
|
&dev_attr_hci_revision,
|
||||||
&dev_attr_inquiry_cache,
|
&dev_attr_inquiry_cache,
|
||||||
&dev_attr_idle_timeout,
|
&dev_attr_idle_timeout,
|
||||||
&dev_attr_sniff_max_interval,
|
&dev_attr_sniff_max_interval,
|
||||||
|
|
Loading…
Reference in a new issue