* Re: [RFC v4 6/6] Bluetooth: Manually enable or disable 6LoWPAN between devices
From: Marcel Holtmann @ 2013-11-14 8:07 UTC (permalink / raw)
To: Jukka Rissanen; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384337495-9043-7-git-send-email-jukka.rissanen@linux.intel.com>
Hi Jukka,
> This is a temporary patch where user can manually enable or
> disable BT 6LoWPAN functionality between devices.
> Eventually the connection is established automatically if
> the devices are advertising suitable capability and this patch
> can be removed.
>
> Before connecting the devices do this
>
> echo 1 > /sys/kernel/debug/bluetooth/hci0/6lowpan
>
> This enables 6LoWPAN support and creates the bt0 interface
> automatically when devices are finally connected.
>
> Rebooting or unloading the bluetooth kernel module will also clear the
> settings from the kernel.
>
> Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> ---
> net/bluetooth/6lowpan.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/6lowpan.h | 1 +
> net/bluetooth/hci_core.c | 4 ++
> 3 files changed, 110 insertions(+)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 5f0489c..579a75f 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -26,6 +26,8 @@
> */
>
> #include <linux/version.h>
> +#include <linux/debugfs.h>
> +#include <linux/string.h>
> #include <linux/bitops.h>
> #include <linux/if_arp.h>
> #include <linux/netdevice.h>
> @@ -1571,6 +1573,109 @@ static struct notifier_block bt_6lowpan_dev_notifier = {
> .notifier_call = device_event,
> };
>
> +static LIST_HEAD(user_enabled);
> +DEFINE_RWLOCK(enabled_lock);
make this one static as well.
> +
> +struct lowpan_enabled {
> + __u8 dev_name[HCI_MAX_NAME_LENGTH];
> + bool enabled;
> + struct list_head list;
> +};
> +
> +static int debugfs_show(struct seq_file *f, void *p)
> +{
> + struct lowpan_enabled *entry, *tmp;
> + bool found = false;
> +
> + write_lock(&enabled_lock);
> + list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> + seq_printf(f, "%d\n", entry->enabled);
> + found = true;
> + }
> + write_unlock(&enabled_lock);
> +
> + if (!found)
> + seq_printf(f, "0\n");
> +
> + return 0;
> +}
So I do not get this one. Why not just use the bit set in hci_dev. This looks like just wrong.
> +
> +static int debugfs_open(struct inode *inode, struct file *file)
> +{
> + return single_open(file, debugfs_show, inode->i_private);
> +}
> +
> +static ssize_t writer(struct file *fp, const char __user *user_buffer,
> + size_t count, loff_t *position)
> +{
> + struct hci_dev *hdev = fp->f_inode->i_private;
> + struct lowpan_enabled *entry = NULL, *tmp;
> + bool new_value, old_value;
> + char buf[3] = { 0 };
> + ssize_t ret;
> +
> + BT_DBG("dev %s count %zd", hdev->dev_name, count);
> +
> + ret = simple_write_to_buffer(buf, 2, position, user_buffer, count);
> + if (ret <= 0)
> + return ret;
> +
> + if (strtobool(buf, &new_value) < 0)
> + return -EINVAL;
> +
> + ret = -ENOENT;
> +
> + write_lock(&enabled_lock);
> + list_for_each_entry_safe(entry, tmp, &user_enabled, list) {
> + if (!strncmp(entry->dev_name, hdev->dev_name,
> + HCI_MAX_NAME_LENGTH)) {
> + old_value = entry->enabled;
> + entry->enabled = new_value;
> + ret = 0;
> + break;
> + }
> + }
> + write_unlock(&enabled_lock);
> +
> + if (ret == 0 && old_value == new_value)
> + return count;
> +
> + if (ret < 0) {
> + entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> + if (!entry)
> + return -ENOMEM;
> +
> + strncpy(entry->dev_name, hdev->dev_name, HCI_MAX_NAME_LENGTH);
> + entry->enabled = new_value;
> +
> + write_lock(&enabled_lock);
> + INIT_LIST_HEAD(&entry->list);
> + list_add(&entry->list, &user_enabled);
> + write_unlock(&enabled_lock);
> + }
> +
> + if (new_value == true)
> + set_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
> + else
> + clear_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
> +
> + return count;
> +}
> +
> +static const struct file_operations ble_6lowpan_debugfs_fops = {
> + .open = debugfs_open,
> + .read = seq_read,
> + .write = writer,
> + .llseek = seq_lseek,
> + .release = single_release,
> +};
> +
> +void bt_6lowpan_add_debugfs(struct hci_dev *hdev)
> +{
> + debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
> + &ble_6lowpan_debugfs_fops);
> +}
> +
> int bt_6lowpan_init(void)
> {
> return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
> diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h
> index 680eac8..5f60cf2 100644
> --- a/net/bluetooth/6lowpan.h
> +++ b/net/bluetooth/6lowpan.h
> @@ -22,5 +22,6 @@ int bt_6lowpan_add_conn(struct l2cap_conn *conn);
> int bt_6lowpan_del_conn(struct l2cap_conn *conn);
> int bt_6lowpan_init(void);
> void bt_6lowpan_cleanup(void);
> +void bt_6lowpan_add_debugfs(struct hci_dev *hdev);
>
> #endif /* __6LOWPAN_H */
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 03e8355..a229ce0 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -34,6 +34,8 @@
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
>
> +#include "6lowpan.h"
> +
> static void hci_rx_work(struct work_struct *work);
> static void hci_cmd_work(struct work_struct *work);
> static void hci_tx_work(struct work_struct *work);
> @@ -1408,6 +1410,8 @@ static int __hci_init(struct hci_dev *hdev)
> hdev, &conn_max_interval_fops);
> }
>
> + bt_6lowpan_add_debugfs(hdev);
> +
Since we only set the HCI_6LOWPAN_ENABLED bit, why not move this whole code into hci_core.c. It is just setting the bit, right?
Regards
Marcel
^ permalink raw reply
* Re: [RFC v4 3/6] Bluetooth: Initial skeleton code for BT 6LoWPAN
From: Marcel Holtmann @ 2013-11-14 7:58 UTC (permalink / raw)
To: Jukka Rissanen; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384337495-9043-4-git-send-email-jukka.rissanen@linux.intel.com>
Hi Jukka,
> Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
> ---
> include/net/bluetooth/l2cap.h | 1 +
> net/bluetooth/6lowpan.c | 544 ++++++++++++++++++++++++++++++++++++++++++
> net/bluetooth/6lowpan.h | 26 ++
> net/bluetooth/Makefile | 2 +-
> net/bluetooth/l2cap_core.c | 22 +-
> 5 files changed, 593 insertions(+), 2 deletions(-)
> create mode 100644 net/bluetooth/6lowpan.c
> create mode 100644 net/bluetooth/6lowpan.h
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 5132990..c28ac0d 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -133,6 +133,7 @@ struct l2cap_conninfo {
> #define L2CAP_FC_L2CAP 0x02
> #define L2CAP_FC_CONNLESS 0x04
> #define L2CAP_FC_A2MP 0x08
> +#define L2CAP_FC_6LOWPAN 0x3e
can you add a comment here that 0x3e is the reserved value and temporary. Just to make it clear to everybody looking and using this code.
> /* L2CAP Control Field bit masks */
> #define L2CAP_CTRL_SAR 0xC000
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> new file mode 100644
> index 0000000..85754e2
> --- /dev/null
> +++ b/net/bluetooth/6lowpan.c
> @@ -0,0 +1,544 @@
> +/*
> + Copyright (c) 2013 Intel Corp.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License version 2 and
> + only version 2 as published by the Free Software Foundation.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +*/
> +
> +#include <linux/version.h>
> +#include <linux/bitops.h>
> +#include <linux/if_arp.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +
> +#include <net/ipv6.h>
> +#include <net/ip6_route.h>
> +#include <net/addrconf.h>
> +
> +#include <net/af_ieee802154.h>
What are we using this one for? Just curious.
> +
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +#include <net/bluetooth/l2cap.h>
> +
> +#include "../ieee802154/6lowpan.h" /* for the compression defines */
> +
> +#define IFACE_NAME_TEMPLATE "bt%d"
> +#define EUI64_ADDR_LEN 8
> +
> +struct skb_cb {
> + struct in6_addr addr;
> + struct l2cap_conn *conn;
> +};
> +#define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
> +
> +/*
> + * The devices list contains those devices that we are acting
> + * as a proxy. The BT 6LoWPAN device is a virtual device that
> + * connects to the Bluetooth LE device. The real connection to
> + * BT device is done via l2cap layer. There exists one
> + * virtual device / one BT 6LoWPAN network (=hciX device).
> + * The list contains struct lowpan_dev elements.
> + */
> +static LIST_HEAD(bt_6lowpan_devices);
> +static DEFINE_RWLOCK(devices_lock);
> +
> +struct lowpan_dev {
> + struct net_device *dev;
> + struct work_struct delete_netdev;
> + struct list_head list;
> +};
> +
> +struct peer {
Maybe lowpan_peer is a better name. peer sounds a bit too general.
> + struct list_head list;
> + struct l2cap_conn *conn;
> +
> + /* peer addresses in various formats */
> + unsigned char eui64_addr[EUI64_ADDR_LEN];
> + struct in6_addr peer_addr;
> +};
> +
> +struct lowpan_info {
> + struct net_device *net;
> + struct list_head peers;
> + int peer_count;
What are we using the peer_count for? Would a kref be useful?
> +};
> +
> +static inline struct lowpan_info *lowpan_info(const struct net_device *dev)
> +{
> + return netdev_priv(dev);
> +}
> +
> +static inline void peer_add(struct lowpan_info *info, struct peer *peer)
> +{
> + list_add(&peer->list, &info->peers);
> + info->peer_count++;
> +}
> +
> +static inline void peer_del(struct lowpan_info *info, struct peer *peer)
> +{
> + list_del(&peer->list);
> + info->peer_count--;
> + if (info->peer_count < 0) {
> + BT_ERR("peer count underflow");
> + info->peer_count = 0;
> + }
> +}
> +
> +static inline struct peer *peer_lookup_ba(struct lowpan_info *info,
> + __u8 type, bdaddr_t *ba)
You need to get the coding style fixed here. Please make sure you clean these up.
In addition, I think we used the order of BD_ADDR first and then address type. Check what we do in the core and in SMP. I just want to make sure that we do this consistently.
> +{
> + struct peer *peer, *tmp;
> +
> + BT_DBG("peers %d addr %pMR type %d", info->peer_count, ba, type);
> +
> + list_for_each_entry_safe(peer, tmp, &info->peers, list) {
> + BT_DBG("addr %pMR type %d",
> + &peer->conn->hcon->dst, peer->conn->hcon->dst_type);
> +
> + if (!bacmp(&peer->conn->hcon->dst, ba))
> + return peer;
> + }
> +
> + return NULL;
> +}
> +
> +static inline struct peer *peer_lookup_conn(struct lowpan_info *info,
> + struct l2cap_conn *conn)
> +{
> + struct peer *peer, *tmp;
> +
> + list_for_each_entry_safe(peer, tmp, &info->peers, list) {
> + if (peer->conn == conn)
> + return peer;
> + }
> +
> + return NULL;
> +}
> +
> +static struct peer *lookup_peer(struct l2cap_conn *conn,
> + struct lowpan_info **dev)
> +{
> + struct lowpan_dev *entry, *tmp;
> + struct peer *peer = NULL;
> +
> + write_lock(&devices_lock);
> +
> + list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> + struct lowpan_info *info = lowpan_info(entry->dev);
> +
> + if (dev)
> + *dev = info;
> +
> + peer = peer_lookup_conn(info, conn);
> + if (peer)
> + break;
Don’t we want to move the *dev assignment only when we find a match?
> + }
> +
> + write_unlock(&devices_lock);
> +
> + return peer;
> +}
> +
> +/* print data in line */
> +static inline void raw_dump_inline(const char *caller, char *msg,
> + unsigned char *buf, int len)
> +{
> + if (msg)
> + pr_debug("%s():%s: ", caller, msg);
> + print_hex_dump_debug("", DUMP_PREFIX_NONE,
> + 16, 1, buf, len, false);
> +}
> +
> +/*
> + * print data in a table format:
> + *
> + * addr: xx xx xx xx xx xx
> + * addr: xx xx xx xx xx xx
> + * ...
> + */
> +static inline void raw_dump_table(const char *caller, char *msg,
> + unsigned char *buf, int len)
> +{
> + if (msg)
> + pr_debug("%s():%s:\n", caller, msg);
> + print_hex_dump_debug("\t", DUMP_PREFIX_OFFSET,
> + 16, 1, buf, len, false);
> +}
> +
> +static int recv_pkt(struct sk_buff *skb, struct net_device *dev)
> +{
> + kfree_skb(skb);
> + return NET_RX_DROP;
> +}
> +
> +/* Packet from BT LE device */
> +int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> +{
> + struct lowpan_info *info = NULL;
> + struct peer *peer;
> + int err = -ENOENT;
> +
> + peer = lookup_peer(conn, &info);
> + if (!peer)
> + return -ENOENT;
> +
> + if (info && info->net) {
> + err = recv_pkt(skb, info->net, conn);
> + BT_DBG("recv pkt %d", err);
> + }
} else {
err = -ENOENT;
}
And remove the assignment at the top.
Can info really be ever NULL?
> +
> + return err;
> +}
> +
> +static void do_send(struct l2cap_conn *conn, struct sk_buff *skb)
> +{
> + BT_DBG("conn %p, skb %p len %d priority %u", conn, skb, skb->len,
> + skb->priority);
> +
> + return;
Remove the return here. That is against the coding style.
> +}
> +
> +static int conn_send(struct l2cap_conn *conn,
> + void *msg, size_t len, u32 priority,
> + struct net_device *dev)
> +{
> + struct sk_buff *skb = {0};
No idea how the {0} works here. I am not sure we really should be doing that. Why do we need that? And how do we ensure that not accidentally call a kfree_skb() on it.
> +
> + do_send(conn, skb);
> + return 0;
> +}
> +
> +/* Packet to BT LE device */
> +static int send_pkt(struct l2cap_conn *conn, const void *saddr,
> + const void *daddr, struct sk_buff *skb,
> + struct net_device *dev)
> +{
> + raw_dump_table(__func__, "raw skb data dump before fragmentation",
> + skb->data, skb->len);
> +
> + return conn_send(conn, skb->data, skb->len, 0, dev);
> +}
Within this patch, I can not really see the point in having 3 function to just do the send. Hope in the final code it makes sense.
> +
> +static int send_mcast_pkt(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct sk_buff *local_skb;
> + struct lowpan_dev *entry, *tmp;
> + int err = 0;
> +
> + write_lock(&devices_lock);
> +
> + list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> + struct peer *pentry, *ptmp;
> + struct lowpan_info *info;
> +
> + if (entry->dev != dev)
> + continue;
> +
> + info = lowpan_info(entry->dev);
> +
> + list_for_each_entry_safe(pentry, ptmp, &info->peers, list) {
> + local_skb = skb_clone(skb, GFP_ATOMIC);
> +
> + err = send_pkt(pentry->conn, dev->dev_addr,
> + pentry->eui64_addr,
> + local_skb, dev);
> +
> + kfree_skb(local_skb);
> + }
> + }
> +
> + write_unlock(&devices_lock);
> +
> + return err;
> +}
> +
> +static netdev_tx_t xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + int err = -ENOENT;
> + unsigned char *eui64_addr;
> + struct lowpan_info *info;
> + struct peer *peer;
> + bdaddr_t addr;
> + u8 addr_type;
> +
> + if (ipv6_addr_is_multicast(&lowpan_cb(skb)->addr)) {
> + /*
> + * We need to send the packet to every device
> + * behind this interface.
> + */
> + err = send_mcast_pkt(skb, dev);
> + } else {
> + get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
> + eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
> + info = lowpan_info(dev);
> +
> + write_lock(&devices_lock);
> + peer = peer_lookup_ba(info, addr_type, &addr);
> + write_unlock(&devices_lock);
> +
> + BT_DBG("xmit from %s to %pMR (%pI6c), peer %p", dev->name,
> + &addr, &lowpan_cb(skb)->addr, peer);
> +
> + if (peer && peer->conn)
> + err = send_pkt(peer->conn,
> + dev->dev_addr,
> + eui64_addr,
> + skb,
> + dev);
This breaking looks excessive. Do we need it? Does it not fit on two lines?
> + }
> + dev_kfree_skb(skb);
> +
> + if (err)
> + BT_DBG("ERROR: xmit failed (%d)", err);
> +
> + return (err < 0) ? NET_XMIT_DROP : err;
> +}
> +
> +static const struct net_device_ops netdev_ops = {
> + .ndo_start_xmit = xmit,
> +};
> +
> +static void netdev_setup(struct net_device *dev)
> +{
> + dev->addr_len = EUI64_ADDR_LEN;
> + dev->type = ARPHRD_RAWIP;
> +
> + dev->hard_header_len = 0;
> + dev->needed_tailroom = 0;
> + dev->mtu = IPV6_MIN_MTU;
> + dev->tx_queue_len = 0;
> + dev->flags = IFF_RUNNING | IFF_POINTOPOINT;
> + dev->watchdog_timeo = 0;
> +
> + dev->netdev_ops = &netdev_ops;
> + dev->destructor = free_netdev;
> +}
> +
> +static struct device_type bt_type = {
> + .name = "bluetooth",
> +};
> +
> +static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
> +{
> + /* addr is the BT address in little-endian format */
> + eui[0] = addr[5];
> + eui[1] = addr[4];
> + eui[2] = addr[3];
> + eui[3] = 0xFF;
> + eui[4] = 0xFE;
> + eui[5] = addr[2];
> + eui[6] = addr[1];
> + eui[7] = addr[0];
> +
> + eui[0] ^= 2;
> +
> + /*
> + * Universal/local bit set, RFC 4291
> + */
> + if (addr_type == BDADDR_LE_PUBLIC)
> + eui[0] |= 1;
> + else
> + eui[0] &= ~1;
> +}
> +
> +static void set_dev_addr(struct net_device *net, bdaddr_t *addr,
> + u8 addr_type)
> +{
> + net->addr_assign_type = NET_ADDR_PERM;
> + set_addr(net->dev_addr, addr->b, addr_type);
> + net->dev_addr[0] ^= 2;
> +}
> +
> +static void ifup(struct net_device *net)
> +{
> + int err;
> +
> + rtnl_lock();
> + err = dev_open(net);
> + if (err < 0)
> + BT_INFO("iface %s cannot be opened (%d)", net->name, err);
> + rtnl_unlock();
> +}
> +
> +/*
> + * This gets called when BT LE 6LoWPAN device is connected. We then
> + * create network device that acts as a proxy between BT LE device
> + * and kernel network stack.
> + */
> +int bt_6lowpan_add_conn(struct l2cap_conn *conn)
> +{
> + struct lowpan_info *dev = NULL;
> + struct peer *peer = NULL;
> + struct net_device *net;
> + struct lowpan_dev *entry;
> + int err = 0;
> +
> + peer = lookup_peer(conn, &dev);
> + if (peer)
> + return -EEXIST;
> +
> + /*
> + * If net device exists already, just add route.
> + */
> + if (dev && !peer)
> + goto add_peer;
> +
> + net = alloc_netdev(sizeof(struct lowpan_info), IFACE_NAME_TEMPLATE,
> + netdev_setup);
> + if (!net)
> + return -ENOMEM;
> +
> + dev = netdev_priv(net);
> + dev->net = net;
> + INIT_LIST_HEAD(&dev->peers);
> +
> + set_dev_addr(net, &conn->hcon->src, conn->hcon->src_type);
> +
> + net->netdev_ops = &netdev_ops;
> + SET_NETDEV_DEV(net, &conn->hcon->dev);
> + SET_NETDEV_DEVTYPE(net, &bt_type);
> +
> + err = register_netdev(net);
> + if (err < 0) {
> + BT_INFO("register_netdev failed %d", err);
> + free_netdev(net);
> + goto out;
> + }
> +
> + BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR",
> + net->ifindex, &conn->hcon->dst, &conn->hcon->src);
> + set_bit(__LINK_STATE_PRESENT, &net->state);
> +
> + entry = kzalloc(sizeof(struct lowpan_dev), GFP_KERNEL);
> + if (!entry) {
> + unregister_netdev(net);
> + return -ENOMEM;
> + }
> +
> + entry->dev = net;
> +
> + write_lock(&devices_lock);
> + INIT_LIST_HEAD(&entry->list);
> + list_add(&entry->list, &bt_6lowpan_devices);
> + write_unlock(&devices_lock);
> +
> + ifup(net);
> +
> +add_peer:
> + peer = kzalloc(sizeof(struct peer), GFP_KERNEL);
> + if (!peer)
> + return -ENOMEM;
> +
> + peer->conn = conn;
> + memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
> +
> + /* RFC 2464 ch. 5 */
> + peer->peer_addr.s6_addr[0] = 0xFE;
> + peer->peer_addr.s6_addr[1] = 0x80;
> + set_addr((u8 *)&peer->peer_addr.s6_addr + 8, conn->hcon->dst.b,
> + conn->hcon->dst_type);
> +
> + memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
> + EUI64_ADDR_LEN);
> +
> + write_lock(&devices_lock);
> + INIT_LIST_HEAD(&peer->list);
> + peer_add(dev, peer);
> + write_unlock(&devices_lock);
> +
> + netdev_notify_peers(dev->net); /* send neighbour adv at startup */
> +
> +out:
> + return err;
> +}
> +
> +static void delete_netdev(struct work_struct *work)
> +{
> + struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
> + delete_netdev);
> +
> + unregister_netdev(entry->dev);
> +
> + /* The entry pointer is deleted in device_event() */
> +}
> +
> +int bt_6lowpan_del_conn(struct l2cap_conn *conn)
> +{
> + struct lowpan_dev *entry, *tmp;
> + struct lowpan_info *info = NULL;
> + struct peer *peer;
> + int err = -ENOENT;
> +
> + write_lock(&devices_lock);
> +
> + list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
> + info = lowpan_info(entry->dev);
> + peer = peer_lookup_conn(info, conn);
> + if (peer) {
> + peer_del(info, peer);
> + err = 0;
> + break;
> + }
> + }
> +
> + write_unlock(&devices_lock);
> +
> + if (!err && info && info->peer_count == 0) {
> + /*
> + * This function is called with hci dev lock held which means
> + * that we must delete the netdevice in worker thread.
> + */
> + INIT_WORK(&entry->delete_netdev, delete_netdev);
> + schedule_work(&entry->delete_netdev);
> + }
> +
> + return err;
> +}
> +
> +static int device_event(struct notifier_block *unused,
> + unsigned long event, void *ptr)
> +{
> + struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> + struct lowpan_dev *entry, *tmp;
> +
> + if (dev->type != ARPHRD_RAWIP)
> + return NOTIFY_DONE;
> +
> + switch (event) {
> + case NETDEV_UNREGISTER:
> + write_lock(&devices_lock);
> + list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices,
> + list) {
> + if (entry->dev == dev) {
> + list_del(&entry->list);
> + kfree(entry);
> + break;
> + }
> + }
> + write_unlock(&devices_lock);
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block bt_6lowpan_dev_notifier = {
> + .notifier_call = device_event,
> +};
> +
> +int bt_6lowpan_init(void)
> +{
> + return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
> +}
> +
> +void bt_6lowpan_cleanup(void)
> +{
> + unregister_netdevice_notifier(&bt_6lowpan_dev_notifier);
> +}
> diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h
> new file mode 100644
> index 0000000..680eac8
> --- /dev/null
> +++ b/net/bluetooth/6lowpan.h
> @@ -0,0 +1,26 @@
> +/*
> + Copyright (c) 2013 Intel Corp.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License version 2 and
> + only version 2 as published by the Free Software Foundation.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +*/
> +
> +#ifndef __6LOWPAN_H
> +#define __6LOWPAN_H
> +
> +#include <linux/skbuff.h>
> +#include <net/bluetooth/l2cap.h>
> +
> +int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
> +int bt_6lowpan_add_conn(struct l2cap_conn *conn);
> +int bt_6lowpan_del_conn(struct l2cap_conn *conn);
> +int bt_6lowpan_init(void);
> +void bt_6lowpan_cleanup(void);
> +
> +#endif /* __6LOWPAN_H */
> diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
> index 6a791e7..80cb215 100644
> --- a/net/bluetooth/Makefile
> +++ b/net/bluetooth/Makefile
> @@ -10,6 +10,6 @@ obj-$(CONFIG_BT_HIDP) += hidp/
>
> bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
> hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
> - a2mp.o amp.o
> + a2mp.o amp.o 6lowpan.o
>
> subdir-ccflags-y += -D__CHECK_ENDIAN__
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 4af3821..155485f 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -40,6 +40,7 @@
> #include "smp.h"
> #include "a2mp.h"
> #include "amp.h"
> +#include "6lowpan.h"
>
> bool disable_ertm;
>
> @@ -6473,6 +6474,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
> l2cap_conn_del(conn->hcon, EACCES);
> break;
>
> + case L2CAP_FC_6LOWPAN:
> + bt_6lowpan_recv(conn, skb);
> + break;
> +
> default:
> l2cap_data_channel(conn, cid, skb);
> break;
> @@ -6510,6 +6515,11 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
> return exact ? lm1 : lm2;
> }
>
> +static bool is_bt_6lowpan(struct hci_conn *hcon)
> +{
> + return false;
> +}
> +
> void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> {
> struct l2cap_conn *conn;
> @@ -6518,8 +6528,12 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
>
> if (!status) {
> conn = l2cap_conn_add(hcon);
> - if (conn)
> + if (conn) {
> l2cap_conn_ready(conn);
> +
> + if (is_bt_6lowpan(hcon))
> + bt_6lowpan_add_conn(conn);
> + }
At the end, is this not the only location that checks if 6loWPAN is enabled? I would not bother with the is_bt_6lowpan helper and just do it right away in bt_6lowpan_add_conn.
> } else {
> l2cap_conn_del(hcon, bt_to_errno(status));
> }
> @@ -6540,6 +6554,9 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
> {
> BT_DBG("hcon %p reason %d", hcon, reason);
>
> + if (is_bt_6lowpan(hcon))
> + bt_6lowpan_del_conn(hcon->l2cap_data);
> +
Same here. Do it inside bt_6lowpan_del_conn.
> l2cap_conn_del(hcon, bt_to_errno(reason));
> }
>
> @@ -6817,11 +6834,14 @@ int __init l2cap_init(void)
> l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
> NULL, &l2cap_debugfs_fops);
>
> + bt_6lowpan_init();
> +
> return 0;
> }
>
> void l2cap_exit(void)
> {
> + bt_6lowpan_cleanup();
> debugfs_remove(l2cap_debugfs);
> l2cap_cleanup_sockets();
> }
Regards
Marcel
^ permalink raw reply
* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Marcel Holtmann @ 2013-11-14 7:33 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Oprisenescu, CatalinX, linux-bluetooth@vger.kernel.org,
Trandafir, IonutX
In-Reply-To: <CABBYNZJSdzsuuzEJctKo_UiKExX4_XXW+zzphhZcHzCuOoLBwg@mail.gmail.com>
Hi Luiz,
>> Following is an issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
>>
>> If malloc returns a random NULL bluetoothd exits with core dumped.
>> In this case we do the following:
>> -start bluetoothd,
>> -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
>>
>> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
>>
>> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
>>
>> A fix proposal, handling the use-case is attached.
>
> Im afraid if we start treating all the out of memory cases we wont
> have time to do anything else, and quite frankly if this happens for
> real the least concern would be bluetoothd, so I believe we should
> just treat OOM cases as unrecoverable. Since this can happen with any
> dbus_error, I would probably suggest to wrap it perhaps we a
> g_dbus_error API that does assert in OOM.
I am fine with fixing obvious ones. However long-term these tiny sized memory allocation must just abort the program if we run out of memory. Since there is no recovery from it anyway.
Regards
Marcel
^ permalink raw reply
* [PATCH] android/debug: Move debug functions to hal-utils.c
From: Andrei Emeltchenko @ 2013-11-14 7:14 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Debug functions will be used by HALs and haltest.
---
android/Android.mk | 2 -
android/Makefile.am | 3 -
android/client/if-av.c | 1 +
android/client/if-bt.c | 1 +
android/client/if-hf.c | 1 +
android/client/if-hh.c | 1 +
android/client/if-main.h | 2 -
android/client/if-pan.c | 1 +
android/client/if-sock.c | 1 +
android/client/textconv.c | 300 ---------------------------------------------
android/client/textconv.h | 120 ------------------
android/hal-bluetooth.c | 3 +-
android/hal-utils.c | 269 ++++++++++++++++++++++++++++++++++++++++
android/hal-utils.h | 103 ++++++++++++++++
14 files changed, 379 insertions(+), 429 deletions(-)
delete mode 100644 android/client/textconv.c
delete mode 100644 android/client/textconv.h
diff --git a/android/Android.mk b/android/Android.mk
index 0bc0e82..53c766b 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -87,7 +87,6 @@ LOCAL_SRC_FILES := \
hal-hidhost.c \
hal-pan.c \
hal-a2dp.c \
- client/textconv.c \
hal-utils.c \
LOCAL_C_INCLUDES += \
@@ -118,7 +117,6 @@ LOCAL_SRC_FILES := \
client/pollhandler.c \
client/terminal.c \
client/history.c \
- client/textconv.c \
client/tabcompletion.c \
client/if-av.c \
client/if-bt.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index debe7c1..e81d1a5 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -59,7 +59,6 @@ android_haltest_SOURCES = android/client/haltest.c \
android/client/pollhandler.c \
android/client/terminal.c \
android/client/history.c \
- android/client/textconv.c \
android/client/tabcompletion.c \
android/client/if-av.c \
android/client/if-bt.c \
@@ -102,9 +101,7 @@ EXTRA_DIST += android/client/terminal.c \
android/client/if-hh.c \
android/client/if-pan.c \
android/client/if-sock.c \
- android/client/textconv.c \
android/client/tabcompletion.c \
- android/client/textconv.h \
android/client/if-main.h \
android/client/pollhandler.h \
android/client/history.h \
diff --git a/android/client/if-av.c b/android/client/if-av.c
index 3f133eb..0470e0d 100644
--- a/android/client/if-av.c
+++ b/android/client/if-av.c
@@ -16,6 +16,7 @@
*/
#include "if-main.h"
+#include "../hal-utils.h"
const btav_interface_t *if_av = NULL;
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 10ae125..0cd43db 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -17,6 +17,7 @@
#include "if-main.h"
#include "terminal.h"
+#include "../hal-utils.h"
const bt_interface_t *if_bluetooth;
diff --git a/android/client/if-hf.c b/android/client/if-hf.c
index c23fb13..d0e7a66 100644
--- a/android/client/if-hf.c
+++ b/android/client/if-hf.c
@@ -16,6 +16,7 @@
*/
#include "if-main.h"
+#include "../hal-utils.h"
const bthf_interface_t *if_hf = NULL;
diff --git a/android/client/if-hh.c b/android/client/if-hh.c
index 005b13a..b8ebc8e 100644
--- a/android/client/if-hh.c
+++ b/android/client/if-hh.c
@@ -23,6 +23,7 @@
#include "if-main.h"
#include "pollhandler.h"
+#include "../hal-utils.h"
const bthh_interface_t *if_hh = NULL;
diff --git a/android/client/if-main.h b/android/client/if-main.h
index dea7237..a83f48b 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -44,8 +44,6 @@
#include <hardware/bt_gatt_server.h>
#endif
-#include "textconv.h"
-
/* Interfaces from hal that can be populated during application lifetime */
extern const bt_interface_t *if_bluetooth;
extern const btav_interface_t *if_av;
diff --git a/android/client/if-pan.c b/android/client/if-pan.c
index dcc7e80..a11f2a3 100644
--- a/android/client/if-pan.c
+++ b/android/client/if-pan.c
@@ -18,6 +18,7 @@
#include <hardware/bluetooth.h>
#include "if-main.h"
+#include "../hal-utils.h"
const btpan_interface_t *if_pan = NULL;
diff --git a/android/client/if-sock.c b/android/client/if-sock.c
index dcaf048..2cd06e8 100644
--- a/android/client/if-sock.c
+++ b/android/client/if-sock.c
@@ -21,6 +21,7 @@
#include "if-main.h"
#include "pollhandler.h"
+#include "../hal-utils.h"
const btsock_interface_t *if_sock = NULL;
diff --git a/android/client/textconv.c b/android/client/textconv.c
deleted file mode 100644
index dcbe53e..0000000
--- a/android/client/textconv.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <hardware/bluetooth.h>
-
-#include "../hal-utils.h"
-
-#include "textconv.h"
-
-/*
- * Following are maps of defines found in bluetooth header files to strings
- *
- * Those mappings are used to accurately use defines as input parameters in
- * command line as well as for printing of statuses
- */
-
-INTMAP(bt_status_t, -1, "(unknown)")
- DELEMENT(BT_STATUS_SUCCESS),
- DELEMENT(BT_STATUS_FAIL),
- DELEMENT(BT_STATUS_NOT_READY),
- DELEMENT(BT_STATUS_NOMEM),
- DELEMENT(BT_STATUS_BUSY),
- DELEMENT(BT_STATUS_DONE),
- DELEMENT(BT_STATUS_UNSUPPORTED),
- DELEMENT(BT_STATUS_PARM_INVALID),
- DELEMENT(BT_STATUS_UNHANDLED),
- DELEMENT(BT_STATUS_AUTH_FAILURE),
- DELEMENT(BT_STATUS_RMT_DEV_DOWN),
-ENDMAP
-
-INTMAP(bt_state_t, -1, "(unknown)")
- DELEMENT(BT_STATE_OFF),
- DELEMENT(BT_STATE_ON),
-ENDMAP
-
-INTMAP(bt_device_type_t, -1, "(unknown)")
- DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
- DELEMENT(BT_DEVICE_DEVTYPE_BLE),
- DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
-ENDMAP
-
-INTMAP(bt_scan_mode_t, -1, "(unknown)")
- DELEMENT(BT_SCAN_MODE_NONE),
- DELEMENT(BT_SCAN_MODE_CONNECTABLE),
- DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
-ENDMAP
-
-INTMAP(bt_discovery_state_t, -1, "(unknown)")
- DELEMENT(BT_DISCOVERY_STOPPED),
- DELEMENT(BT_DISCOVERY_STARTED),
-ENDMAP
-
-INTMAP(bt_acl_state_t, -1, "(unknown)")
- DELEMENT(BT_ACL_STATE_CONNECTED),
- DELEMENT(BT_ACL_STATE_DISCONNECTED),
-ENDMAP
-
-INTMAP(bt_bond_state_t, -1, "(unknown)")
- DELEMENT(BT_BOND_STATE_NONE),
- DELEMENT(BT_BOND_STATE_BONDING),
- DELEMENT(BT_BOND_STATE_BONDED),
-ENDMAP
-
-INTMAP(bt_ssp_variant_t, -1, "(unknown)")
- DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
- DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
- DELEMENT(BT_SSP_VARIANT_CONSENT),
- DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
-ENDMAP
-
-INTMAP(bt_property_type_t, -1, "(unknown)")
- DELEMENT(BT_PROPERTY_BDNAME),
- DELEMENT(BT_PROPERTY_BDADDR),
- DELEMENT(BT_PROPERTY_UUIDS),
- DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
- DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
- DELEMENT(BT_PROPERTY_SERVICE_RECORD),
- DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
- DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
- DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
- DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
- DELEMENT(BT_PROPERTY_REMOTE_RSSI),
-#if PLATFORM_SDK_VERSION > 17
- DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
-#endif
- DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
-ENDMAP
-
-INTMAP(bt_cb_thread_evt, -1, "(unknown)")
- DELEMENT(ASSOCIATE_JVM),
- DELEMENT(DISASSOCIATE_JVM),
-ENDMAP
-
-/* Find first index of given value in table m */
-int int2str_findint(int v, const struct int2str m[])
-{
- int i;
-
- for (i = 0; m[i].str; ++i) {
- if (m[i].val == v)
- return i;
- }
- return -1;
-}
-
-/* Find first index of given string in table m */
-int int2str_findstr(const char *str, const struct int2str m[])
-{
- int i;
-
- for (i = 0; m[i].str; ++i) {
- if (strcmp(m[i].str, str) == 0)
- return i;
- }
- return -1;
-}
-
-/*
- * convert bd_addr to string
- * buf must be at least 18 char long
- *
- * returns buf
- */
-const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
-{
- const uint8_t *p = bd_addr->address;
-
- snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
- p[0], p[1], p[2], p[3], p[4], p[5]);
-
- return buf;
-}
-
-/* converts string to bt_bdaddr_t */
-void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
-{
- uint8_t *p = bd_addr->address;
-
- sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
-}
-
-/* converts string to uuid */
-void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
-{
- int i = 0;
-
- memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
-
- while (*str && i < (int) sizeof(bt_uuid_t)) {
- while (*str == '-')
- str++;
-
- if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
- break;
-
- i++;
- str += 2;
- }
-}
-
-const char *enum_defines(void *v, int i)
-{
- const struct int2str *m = v;
-
- return m[i].str != NULL ? m[i].str : NULL;
-}
-
-const char *enum_strings(void *v, int i)
-{
- const char **m = v;
-
- return m[i] != NULL ? m[i] : NULL;
-}
-
-const char *enum_one_string(void *v, int i)
-{
- const char *m = v;
-
- return (i == 0) && (m[0] != 0) ? m : NULL;
-}
-
-const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
-{
- static char buf[MAX_ADDR_STR_LEN];
-
- return bt_bdaddr_t2str(bd_addr, buf);
-}
-
-const char *btproperty2str(const bt_property_t *property)
-{
- static char buf[4096];
- char *p;
-
- p = buf + sprintf(buf, "type=%s len=%d val=",
- bt_property_type_t2str(property->type),
- property->len);
-
- switch (property->type) {
- case BT_PROPERTY_BDNAME:
- case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
- snprintf(p, property->len + 1, "%s",
- ((bt_bdname_t *) property->val)->name);
- break;
-
- case BT_PROPERTY_BDADDR:
- sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
- break;
-
- case BT_PROPERTY_CLASS_OF_DEVICE:
- sprintf(p, "%06x", *((int *) property->val));
- break;
-
- case BT_PROPERTY_TYPE_OF_DEVICE:
- sprintf(p, "%s", bt_device_type_t2str(
- *((bt_device_type_t *) property->val)));
- break;
-
- case BT_PROPERTY_REMOTE_RSSI:
- sprintf(p, "%d", *((char *) property->val));
- break;
-
- case BT_PROPERTY_ADAPTER_SCAN_MODE:
- sprintf(p, "%s",
- bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
- break;
-
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
- sprintf(p, "%d", *((int *) property->val));
- break;
-
- case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
- {
- int count = property->len / sizeof(bt_bdaddr_t);
- char *ptr = property->val;
-
- strcat(p, "{");
-
- while (count--) {
- strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
- if (count)
- strcat(p, ", ");
- ptr += sizeof(bt_bdaddr_t);
- }
-
- strcat(p, "}");
-
- }
- break;
-
- case BT_PROPERTY_UUIDS:
- {
- int count = property->len / sizeof(bt_uuid_t);
- uint8_t *ptr = property->val;
-
- strcat(p, "{");
-
- while (count--) {
- strcat(p, btuuid2str(ptr));
- if (count)
- strcat(p, ", ");
- ptr += sizeof(bt_uuid_t);
- }
-
- strcat(p, "}");
-
- }
- break;
-
- case BT_PROPERTY_SERVICE_RECORD:
- {
- bt_service_record_t *rec = property->val;
-
- sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
- rec->channel, rec->name);
- }
- break;
-
- default:
- sprintf(p, "%p", property->val);
- }
-
- return buf;
-}
diff --git a/android/client/textconv.h b/android/client/textconv.h
deleted file mode 100644
index 0a72805..0000000
--- a/android/client/textconv.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- * Begin mapping section
- *
- * There are some mappings between integer values (enums) and strings
- * to be presented to user. To make it easier to convert between those two
- * set of macros is given. It is specially useful when we want to have
- * strings that match constants from header files like:
- * BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
- * Example of usage:
- *
- * INTMAP(int, -1, "invalid")
- * DELEMENT(BT_STATUS_SUCCESS)
- * DELEMENT(BT_STATUS_FAIL)
- * MELEMENT(123, "Some strange value")
- * ENDMAP
- *
- * Just by doing this we have mapping table plus two functions:
- * int str2int(const char *str);
- * const char *int2str(int v);
- *
- * second argument to INTMAP specifies value to be returned from
- * str2int function when there is not mapping for such number
- * third argument specifies default value to be returned from int2str
- *
- * If same mapping is to be used in several source files put
- * INTMAP in c file and DECINTMAP in h file.
- *
- * For mappings that are to be used in single file only
- * use SINTMAP which will create the same but everything will be marked
- * as static.
- */
-
-struct int2str {
- int val; /* int value */
- const char *str; /* corresponding string */
-};
-
-int int2str_findint(int v, const struct int2str m[]);
-int int2str_findstr(const char *str, const struct int2str m[]);
-const char *enum_defines(void *v, int i);
-const char *enum_strings(void *v, int i);
-const char *enum_one_string(void *v, int i);
-
-#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
-#define DECINTMAP(type) \
-extern struct int2str __##type##2str[]; \
-const char *type##2##str(type v); \
-type str##2##type(const char *str); \
-
-#define INTMAP(type, deft, defs) \
-const char *type##2##str(type v) \
-{ \
- int i = int2str_findint((int) v, __##type##2str); \
- return (i < 0) ? defs : __##type##2str[i].str; \
-} \
-type str##2##type(const char *str) \
-{ \
- int i = int2str_findstr(str, __##type##2str); \
- return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
-} \
-struct int2str __##type##2str[] = {
-
-#define SINTMAP(type, deft, defs) \
-static struct int2str __##type##2str[]; \
-static inline const char *type##2##str(type v) \
-{ \
- int i = int2str_findint((int) v, __##type##2str); \
- return (i < 0) ? defs : __##type##2str[i].str; \
-} \
-static inline type str##2##type(const char *str) \
-{ \
- int i = int2str_findstr(str, __##type##2str); \
- return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
-} \
-static struct int2str __##type##2str[] = {
-
-#define ENDMAP {0, NULL} };
-
-/* use this to generate string from header file constant */
-#define MELEMENT(v, s) {v, s}
-/* use this to have arbitrary mapping from int to string */
-#define DELEMENT(s) {s, #s}
-/* End of mapping section */
-
-#define MAX_ADDR_STR_LEN 18
-const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
-void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
-
-void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
-
-const char *btproperty2str(const bt_property_t *property);
-const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
-
-DECINTMAP(bt_status_t);
-DECINTMAP(bt_state_t);
-DECINTMAP(bt_device_type_t);
-DECINTMAP(bt_scan_mode_t);
-DECINTMAP(bt_discovery_state_t);
-DECINTMAP(bt_acl_state_t);
-DECINTMAP(bt_bond_state_t);
-DECINTMAP(bt_ssp_variant_t);
-DECINTMAP(bt_property_type_t);
-DECINTMAP(bt_cb_thread_evt);
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 1cfd994..078d537 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -24,8 +24,7 @@
#include "hal.h"
#include "hal-msg.h"
#include "hal-ipc.h"
-
-#include "client/textconv.h"
+#include "hal-utils.h"
static const bt_callbacks_t *bt_hal_cbacks = NULL;
diff --git a/android/hal-utils.c b/android/hal-utils.c
index 7ac5047..4f44d98 100644
--- a/android/hal-utils.c
+++ b/android/hal-utils.c
@@ -55,3 +55,272 @@ const char *btuuid2str(const uint8_t *uuid)
return bt_uuid_t2str(uuid, buf);
}
+
+INTMAP(bt_status_t, -1, "(unknown)")
+ DELEMENT(BT_STATUS_SUCCESS),
+ DELEMENT(BT_STATUS_FAIL),
+ DELEMENT(BT_STATUS_NOT_READY),
+ DELEMENT(BT_STATUS_NOMEM),
+ DELEMENT(BT_STATUS_BUSY),
+ DELEMENT(BT_STATUS_DONE),
+ DELEMENT(BT_STATUS_UNSUPPORTED),
+ DELEMENT(BT_STATUS_PARM_INVALID),
+ DELEMENT(BT_STATUS_UNHANDLED),
+ DELEMENT(BT_STATUS_AUTH_FAILURE),
+ DELEMENT(BT_STATUS_RMT_DEV_DOWN),
+ENDMAP
+
+INTMAP(bt_state_t, -1, "(unknown)")
+ DELEMENT(BT_STATE_OFF),
+ DELEMENT(BT_STATE_ON),
+ENDMAP
+
+INTMAP(bt_device_type_t, -1, "(unknown)")
+ DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
+ DELEMENT(BT_DEVICE_DEVTYPE_BLE),
+ DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
+ENDMAP
+
+INTMAP(bt_scan_mode_t, -1, "(unknown)")
+ DELEMENT(BT_SCAN_MODE_NONE),
+ DELEMENT(BT_SCAN_MODE_CONNECTABLE),
+ DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
+ENDMAP
+
+INTMAP(bt_discovery_state_t, -1, "(unknown)")
+ DELEMENT(BT_DISCOVERY_STOPPED),
+ DELEMENT(BT_DISCOVERY_STARTED),
+ENDMAP
+
+INTMAP(bt_acl_state_t, -1, "(unknown)")
+ DELEMENT(BT_ACL_STATE_CONNECTED),
+ DELEMENT(BT_ACL_STATE_DISCONNECTED),
+ENDMAP
+
+INTMAP(bt_bond_state_t, -1, "(unknown)")
+ DELEMENT(BT_BOND_STATE_NONE),
+ DELEMENT(BT_BOND_STATE_BONDING),
+ DELEMENT(BT_BOND_STATE_BONDED),
+ENDMAP
+
+INTMAP(bt_ssp_variant_t, -1, "(unknown)")
+ DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
+ DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
+ DELEMENT(BT_SSP_VARIANT_CONSENT),
+ DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
+ENDMAP
+
+INTMAP(bt_property_type_t, -1, "(unknown)")
+ DELEMENT(BT_PROPERTY_BDNAME),
+ DELEMENT(BT_PROPERTY_BDADDR),
+ DELEMENT(BT_PROPERTY_UUIDS),
+ DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
+ DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
+ DELEMENT(BT_PROPERTY_SERVICE_RECORD),
+ DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
+ DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
+ DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
+ DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
+ DELEMENT(BT_PROPERTY_REMOTE_RSSI),
+#if PLATFORM_SDK_VERSION > 17
+ DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
+#endif
+ DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
+ENDMAP
+
+INTMAP(bt_cb_thread_evt, -1, "(unknown)")
+ DELEMENT(ASSOCIATE_JVM),
+ DELEMENT(DISASSOCIATE_JVM),
+ENDMAP
+
+/* Find first index of given value in table m */
+int int2str_findint(int v, const struct int2str m[])
+{
+ int i;
+
+ for (i = 0; m[i].str; ++i) {
+ if (m[i].val == v)
+ return i;
+ }
+ return -1;
+}
+
+/* Find first index of given string in table m */
+int int2str_findstr(const char *str, const struct int2str m[])
+{
+ int i;
+
+ for (i = 0; m[i].str; ++i) {
+ if (strcmp(m[i].str, str) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * convert bd_addr to string
+ * buf must be at least 18 char long
+ *
+ * returns buf
+ */
+const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
+{
+ const uint8_t *p = bd_addr->address;
+
+ snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+
+ return buf;
+}
+
+/* converts string to bt_bdaddr_t */
+void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
+{
+ uint8_t *p = bd_addr->address;
+
+ sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
+}
+
+/* converts string to uuid */
+void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
+{
+ int i = 0;
+
+ memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
+
+ while (*str && i < (int) sizeof(bt_uuid_t)) {
+ while (*str == '-')
+ str++;
+
+ if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
+ break;
+
+ i++;
+ str += 2;
+ }
+}
+
+const char *enum_defines(void *v, int i)
+{
+ const struct int2str *m = v;
+
+ return m[i].str != NULL ? m[i].str : NULL;
+}
+
+const char *enum_strings(void *v, int i)
+{
+ const char **m = v;
+
+ return m[i] != NULL ? m[i] : NULL;
+}
+
+const char *enum_one_string(void *v, int i)
+{
+ const char *m = v;
+
+ return (i == 0) && (m[0] != 0) ? m : NULL;
+}
+
+const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
+{
+ static char buf[MAX_ADDR_STR_LEN];
+
+ return bt_bdaddr_t2str(bd_addr, buf);
+}
+
+const char *btproperty2str(const bt_property_t *property)
+{
+ static char buf[4096];
+ char *p;
+
+ p = buf + sprintf(buf, "type=%s len=%d val=",
+ bt_property_type_t2str(property->type),
+ property->len);
+
+ switch (property->type) {
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ snprintf(p, property->len + 1, "%s",
+ ((bt_bdname_t *) property->val)->name);
+ break;
+
+ case BT_PROPERTY_BDADDR:
+ sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
+ break;
+
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ sprintf(p, "%06x", *((int *) property->val));
+ break;
+
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ sprintf(p, "%s", bt_device_type_t2str(
+ *((bt_device_type_t *) property->val)));
+ break;
+
+ case BT_PROPERTY_REMOTE_RSSI:
+ sprintf(p, "%d", *((char *) property->val));
+ break;
+
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ sprintf(p, "%s",
+ bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
+ break;
+
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ sprintf(p, "%d", *((int *) property->val));
+ break;
+
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ {
+ int count = property->len / sizeof(bt_bdaddr_t);
+ char *ptr = property->val;
+
+ strcat(p, "{");
+
+ while (count--) {
+ strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
+ if (count)
+ strcat(p, ", ");
+ ptr += sizeof(bt_bdaddr_t);
+ }
+
+ strcat(p, "}");
+
+ }
+ break;
+
+ case BT_PROPERTY_UUIDS:
+ {
+ int count = property->len / sizeof(bt_uuid_t);
+ uint8_t *ptr = property->val;
+
+ strcat(p, "{");
+
+ while (count--) {
+ strcat(p, btuuid2str(ptr));
+ if (count)
+ strcat(p, ", ");
+ ptr += sizeof(bt_uuid_t);
+ }
+
+ strcat(p, "}");
+
+ }
+ break;
+
+ case BT_PROPERTY_SERVICE_RECORD:
+ {
+ bt_service_record_t *rec = property->val;
+
+ sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
+ rec->channel, rec->name);
+ }
+ break;
+
+ default:
+ sprintf(p, "%p", property->val);
+ }
+
+ return buf;
+}
diff --git a/android/hal-utils.h b/android/hal-utils.h
index 8c74653..75de7e9 100644
--- a/android/hal-utils.h
+++ b/android/hal-utils.h
@@ -15,8 +15,11 @@
*
*/
+#include <hardware/bluetooth.h>
+
#define MAX_UUID_STR_LEN 37
#define HAL_UUID_LEN 16
+#define MAX_ADDR_STR_LEN 18
static const char BT_BASE_UUID[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
@@ -25,3 +28,103 @@ static const char BT_BASE_UUID[] = {
const char *bt_uuid_t2str(const uint8_t *uuid, char *buf);
const char *btuuid2str(const uint8_t *uuid);
+const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
+void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
+void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
+const char *btproperty2str(const bt_property_t *property);
+const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
+
+/**
+ * Begin mapping section
+ *
+ * There are some mappings between integer values (enums) and strings
+ * to be presented to user. To make it easier to convert between those two
+ * set of macros is given. It is specially useful when we want to have
+ * strings that match constants from header files like:
+ * BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
+ * Example of usage:
+ *
+ * INTMAP(int, -1, "invalid")
+ * DELEMENT(BT_STATUS_SUCCESS)
+ * DELEMENT(BT_STATUS_FAIL)
+ * MELEMENT(123, "Some strange value")
+ * ENDMAP
+ *
+ * Just by doing this we have mapping table plus two functions:
+ * int str2int(const char *str);
+ * const char *int2str(int v);
+ *
+ * second argument to INTMAP specifies value to be returned from
+ * str2int function when there is not mapping for such number
+ * third argument specifies default value to be returned from int2str
+ *
+ * If same mapping is to be used in several source files put
+ * INTMAP in c file and DECINTMAP in h file.
+ *
+ * For mappings that are to be used in single file only
+ * use SINTMAP which will create the same but everything will be marked
+ * as static.
+ */
+
+struct int2str {
+ int val; /* int value */
+ const char *str; /* corresponding string */
+};
+
+int int2str_findint(int v, const struct int2str m[]);
+int int2str_findstr(const char *str, const struct int2str m[]);
+const char *enum_defines(void *v, int i);
+const char *enum_strings(void *v, int i);
+const char *enum_one_string(void *v, int i);
+
+#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
+#define DECINTMAP(type) \
+extern struct int2str __##type##2str[]; \
+const char *type##2##str(type v); \
+type str##2##type(const char *str); \
+
+#define INTMAP(type, deft, defs) \
+const char *type##2##str(type v) \
+{ \
+ int i = int2str_findint((int) v, __##type##2str); \
+ return (i < 0) ? defs : __##type##2str[i].str; \
+} \
+type str##2##type(const char *str) \
+{ \
+ int i = int2str_findstr(str, __##type##2str); \
+ return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
+} \
+struct int2str __##type##2str[] = {
+
+#define SINTMAP(type, deft, defs) \
+static struct int2str __##type##2str[]; \
+static inline const char *type##2##str(type v) \
+{ \
+ int i = int2str_findint((int) v, __##type##2str); \
+ return (i < 0) ? defs : __##type##2str[i].str; \
+} \
+static inline type str##2##type(const char *str) \
+{ \
+ int i = int2str_findstr(str, __##type##2str); \
+ return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
+} \
+static struct int2str __##type##2str[] = {
+
+#define ENDMAP {0, NULL} };
+
+/* use this to generate string from header file constant */
+#define MELEMENT(v, s) {v, s}
+/* use this to have arbitrary mapping from int to string */
+#define DELEMENT(s) {s, #s}
+/* End of mapping section */
+
+DECINTMAP(bt_status_t);
+DECINTMAP(bt_state_t);
+DECINTMAP(bt_device_type_t);
+DECINTMAP(bt_scan_mode_t);
+DECINTMAP(bt_discovery_state_t);
+DECINTMAP(bt_acl_state_t);
+DECINTMAP(bt_bond_state_t);
+DECINTMAP(bt_ssp_variant_t);
+DECINTMAP(bt_property_type_t);
+DECINTMAP(bt_cb_thread_evt);
--
1.7.10.4
^ permalink raw reply related
* [PATCH] linux-firmware: Update Intel Bluetooth devices firmware patch files
From: Tedd Ho-Jeong An @ 2013-11-14 1:21 UTC (permalink / raw)
To: dwmw2, ben; +Cc: don.try, tedd.an, linux-bluetooth
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch updates firmware patch files for following Intel Bluetooth devices:
- Intel Wireless Bluetooth 7260
- Intel Wireless Bluetooth 3160
This patch fixes
- sometimes device doesn't response to HCI_reset after multiple reboot
- issue with HCI stress testing
- issue with some multi profile cases
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
WHENCE | 4 ++--
intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq | Bin 16761 -> 18145 bytes
intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq | Bin 16516 -> 17917 bytes
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/WHENCE b/WHENCE
index 2d52804..b4429ca 100644
--- a/WHENCE
+++ b/WHENCE
@@ -2195,9 +2195,9 @@ Driver: btusb - Bluetooth USB driver
File: intel/ibt-hw-37.7.bseq
Version: 1316.02.00
File: intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq
-Version: 1334.02.2E
+Version: 1344.01.33
File: intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq
-Version: 1334.02.2E
+Version: 1344.01.33
Licence: Redistributable. See LICENCE.ibt_firmware for details
diff --git a/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq b/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq
index cd23169b8bd7ef8b7bfa2ddaed0c44dc52910ffc..49554882ae6a94e9943d7d69c37f935c814f2aed 100644
GIT binary patch
delta 6475
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
KUs-C+XZ|0#s4+eO
delta 5183
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
WGyt^ZR)v<3%6zKmo%bru)c*tjvYT!I
diff --git a/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq b/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq
index 44736e45b6764b8aa3369ec0a2c18f4657e02ef9..ac13fab3fcc85efe1898f7399eb7b255002cb98a 100644
GIT binary patch
delta 6429
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
delta 5038
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
--
1.8.1.2
^ permalink raw reply related
* Re: Adapter name reset on suspend/resume
From: Marcel Holtmann @ 2013-11-13 23:28 UTC (permalink / raw)
To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384350278.5071.6.camel@nuvo>
Hi Bastien,
> After suspending and resuming my laptop, hci0's name is reset to what
> looks like the factory name:
> $ hciconfig -a | grep Name
> Name: 'BCM20702A'
>
> This is the device in question:
> Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
>
> And my laptop is a Lenovo X1 Carbon.
>
> Neither udevadm nor btmon show the device going away on suspend and
> coming back on resume.
can you start btmon, call hciconfig hci0 name, then suspend, then resume, call hciconfig hci0 name again.
I am wondering if for some reason the suspend/resume actually does a HCI Reset without telling us. The name normally only gets reset to BCM20702A when doing a full reset.
Another possibility is that we actually forgot to set it in the first place. I am pretty sure I have intensively tested and that should not happen, but you might just found a corner case.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/2] android: Shutdown if IPC command for unregistered service is received
From: Johan Hedberg @ 2013-11-13 17:50 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1384354033-21724-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Wed, Nov 13, 2013, Szymon Janc wrote:
> Sending commands to not registered services is violation of IPC spec
> and should result in daemon shutdown.
> ---
> android/main.c | 6 ++++++
> 1 file changed, 6 insertions(+)
Both patches have been applied (with some minor tweaks). Thanks.
Johan
^ permalink raw reply
* Re: bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Luiz Augusto von Dentz @ 2013-11-13 15:03 UTC (permalink / raw)
To: Oprisenescu, CatalinX; +Cc: linux-bluetooth@vger.kernel.org, Trandafir, IonutX
In-Reply-To: <6522C4F948C6F5419BA5943E1E79DD2A8ABBAE@IRSMSX104.ger.corp.intel.com>
Hi,
On Wed, Nov 13, 2013 at 4:09 PM, Oprisenescu, CatalinX
<catalinx.oprisenescu@intel.com> wrote:
> Hello,
>
> Following is an issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
>
> If malloc returns a random NULL bluetoothd exits with core dumped.
> In this case we do the following:
> -start bluetoothd,
> -at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
>
> ~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
>
> Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
>
> A fix proposal, handling the use-case is attached.
Im afraid if we start treating all the out of memory cases we wont
have time to do anything else, and quite frankly if this happens for
real the least concern would be bluetoothd, so I believe we should
just treat OOM cases as unrecoverable. Since this can happen with any
dbus_error, I would probably suggest to wrap it perhaps we a
g_dbus_error API that does assert in OOM.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH BlueZ] audio/A2DP: Return -ENOPROTOOPT if record doesn't exist
From: Johan Hedberg @ 2013-11-13 14:49 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384349196-18190-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Wed, Nov 13, 2013, Luiz Augusto von Dentz wrote:
> In case record is not registered it means no endpoint is available so
> return -ENOPROTOOPT to indicate that it is currently not available.
> ---
> profiles/audio/a2dp.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] android/hidhost: Fix memory leak
From: Johan Hedberg @ 2013-11-13 14:48 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1384352974-24036-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Nov 13, 2013, Andrei Emeltchenko wrote:
> ---
> android/hidhost.c | 1 +
> 1 file changed, 1 insertion(+)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH 2/2] android: Core service should be always registered
From: Szymon Janc @ 2013-11-13 14:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384354033-21724-1-git-send-email-szymon.janc@tieto.com>
Core service is used to register other services and shall be always
consider registered.
---
android/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/android/main.c b/android/main.c
index 12284f7..03720e8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -74,7 +74,8 @@ static guint adapter_timeout = 0;
static GIOChannel *hal_cmd_io = NULL;
static GIOChannel *hal_notif_io = NULL;
-static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
+/* Core Service (ID=0) should be always consider registered */
+static bool services[HAL_SERVICE_ID_MAX + 1] = { true, false };
static void service_register(void *buf, uint16_t len)
{
--
1.8.4.2
^ permalink raw reply related
* [PATCH 1/2] android: Shutdown if IPC command for unregistered service is received
From: Szymon Janc @ 2013-11-13 14:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Sending commands to not registered services is violation of IPC spec
and should result in daemon shutdown.
---
android/main.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/android/main.c b/android/main.c
index 36cc8aa..12284f7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -252,6 +252,12 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
DBG("service_id %u opcode %u len %u", msg->service_id, msg->opcode,
msg->len);
+ if (msg->service_id > HAL_SERVICE_ID_MAX ||
+ !services[msg->service_id]) {
+ error("HAL command of not registered service, terminating");
+ goto fail;
+ }
+
switch (msg->service_id) {
case HAL_SERVICE_ID_CORE:
handle_service_core(msg->opcode, msg->payload, msg->len);
--
1.8.4.2
^ permalink raw reply related
* [PATCH 2/2] android/hidhost: Use correct error structure
From: Andrei Emeltchenko @ 2013-11-13 14:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384352974-24036-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/hidhost.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index ff3eae0..3c1f074 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1128,12 +1128,12 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
return;
}
- bt_io_get(chan, &err,
+ bt_io_get(chan, &gerr,
BT_IO_OPT_SOURCE_BDADDR, &src,
BT_IO_OPT_DEST_BDADDR, &dst,
BT_IO_OPT_PSM, &psm,
BT_IO_OPT_INVALID);
- if (err) {
+ if (gerr) {
error("%s", gerr->message);
g_io_channel_shutdown(chan, TRUE, NULL);
g_error_free(gerr);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/2] android/hidhost: Fix memory leak
From: Andrei Emeltchenko @ 2013-11-13 14:29 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/hidhost.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/android/hidhost.c b/android/hidhost.c
index 910014f..ff3eae0 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1136,6 +1136,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
if (err) {
error("%s", gerr->message);
g_io_channel_shutdown(chan, TRUE, NULL);
+ g_error_free(gerr);
return;
}
--
1.7.10.4
^ permalink raw reply related
* bluetoothd failure after a "malloc retun NULL" injection (attachment fix)
From: Oprisenescu, CatalinX @ 2013-11-13 14:09 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org; +Cc: Trandafir, IonutX
[-- Attachment #1: Type: text/plain, Size: 1303 bytes --]
Hello,
Following is an issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
If malloc returns a random NULL bluetoothd exits with core dumped.
In this case we do the following:
-start bluetoothd,
-at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
Analyzing the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
A fix proposal, handling the use-case is attached.
Regards,
Calin Oprisenescu.
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
[-- Attachment #2: 0001-Provide-fix-for-malloc-null-injection.patch --]
[-- Type: application/octet-stream, Size: 967 bytes --]
From 567732c84278f94fc3d8c749c0e40de349e9f00a Mon Sep 17 00:00:00 2001
From: Calin Oprisenescu <catalinx.oprisenescu@intel.com>
Date: Tue, 5 Nov 2013 12:27:20 +0200
Subject: [PATCH] Provide fix for malloc null injection ASD100001565
Change-Id: I7a249f815335e65ae6771d5d1ff58497dbdbb7db
Author: Calin Oprisenescu <catalinx.oprisenescu@intel.com>
Committer: Calin Oprisenescu <catalinx.oprisenescu@intel.com>
---
src/main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/main.c b/src/main.c
index 91d90b4..3bf2ae4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -427,6 +427,10 @@ static int connect_dbus(void)
conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, BLUEZ_NAME, &err);
if (!conn) {
if (dbus_error_is_set(&err)) {
+ if (dbus_error_has_name (&err, DBUS_ERROR_NO_MEMORY)) {
+ dbus_error_free(&err);
+ return -ENOMEM;
+ }
g_printerr("D-Bus setup failed: %s\n", err.message);
dbus_error_free(&err);
return -EIO;
--
1.8.4.msysgit.0
^ permalink raw reply related
* bluetoothd failure after a "malloc retun NULL" injection
From: Oprisenescu, CatalinX @ 2013-11-13 14:05 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org; +Cc: Trandafir, IonutX
Hello,
Following is a issue encountered and handled using bluez-5.10 on a 32bit Tizen 2.0 IVI based distribution.
If malloc returns a random NULL bluetoothd exits with core dumped.
In this case we do the following:
-start bluetoothd,
-at a random malloc call from any library (*lib*.so*), a random NULL will be returned by bluetoothd with a ld_preloaded library.
~# LD_PRELOAD=/root/lib_wrapper.so /usr/libexec/bluetooth/bluetoothd -E
Analizyng the dump, it points directly to a DBUS_ERROR_NO_MEMORY which, after handling, keeps bluetoothd from dumping and allowing it to return the fatal error occurred as exit status, thus failing gracefully.
A fix proposal, handling the use-case is attached.
Regards,
Calin Oprisenescu.
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
^ permalink raw reply
* Re: shutdown(3) and bluetooth.
From: John W. Linville @ 2013-11-13 14:02 UTC (permalink / raw)
To: David Miller; +Cc: davej, netdev, linux-bluetooth, linux-wireless
In-Reply-To: <20131112.161350.946584501122269943.davem@davemloft.net>
On Tue, Nov 12, 2013 at 04:13:50PM -0500, David Miller wrote:
> From: Dave Jones <davej@redhat.com>
> Date: Tue, 12 Nov 2013 16:11:25 -0500
>
> > Is shutdown() allowed to block indefinitely ? The man page doesn't say either way,
> > and I've noticed that my fuzz tester occasionally hangs for days spinning in bt_sock_wait_state()
> >
> > Is there something I should be doing to guarantee that this operation
> > will either time out, or return instantly ?
> >
> > In this specific case, I doubt anything is on the "sender" end of the socket, so
> > it's going to be waiting forever for a state change that won't arrive.
>
> Adding bluetooth and wireless lists. Dave, please consult MAINTAINERS when
> asking questions like this, thanks!
I don't have an authoritative answer. I do, however, seem to recall
that trying to shutdown a SunOS box with a hung NFS mount would seem
to hang forever. I don't think that is a great metric for how we
should behave, of course...
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Andrei Emeltchenko @ 2013-11-13 13:56 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20131113121537.GA11291@x220.p-661hnu-f1>
Hi Johan,
On Wed, Nov 13, 2013 at 02:15:37PM +0200, Johan Hedberg wrote:
> > +struct rfcomm_slot {
> > + int fd;
> > + int hal_fd;
> > + int real_sock;
> > + uint32_t channel;
> > +};
>
> You should really have comments here for what each struct member is used
> for (you have this info in your cover letter but it should also be part
> of the code). Why do you keep hal_fd here? Shouldn't we close it on our
> side as soon as we've handed it over to the HAL?
Basically hal_fd is needed until it is passed to the Android framework.
Do you want it to be like this:
int hal_fd;
rfslot = create_rfslot(&hal_fd, int sock);
send(hal_fd);
close(hal_fd);
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Adapter name reset on suspend/resume
From: Bastien Nocera @ 2013-11-13 13:44 UTC (permalink / raw)
To: linux-bluetooth
Heya,
After suspending and resuming my laptop, hci0's name is reset to what
looks like the factory name:
$ hciconfig -a | grep Name
Name: 'BCM20702A'
This is the device in question:
Bus 001 Device 004: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
And my laptop is a Lenovo X1 Carbon.
Neither udevadm nor btmon show the device going away on suspend and
coming back on resume.
Any ideas?
^ permalink raw reply
* [PATCH BlueZ] audio/A2DP: Return -ENOPROTOOPT if record doesn't exist
From: Luiz Augusto von Dentz @ 2013-11-13 13:26 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In case record is not registered it means no endpoint is available so
return -ENOPROTOOPT to indicate that it is currently not available.
---
profiles/audio/a2dp.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 6b3d6b2..864cb18 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1861,10 +1861,22 @@ static void a2dp_sink_remove(struct btd_service *service)
static int a2dp_source_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
+ struct btd_adapter *adapter = device_get_adapter(dev);
+ struct a2dp_server *server;
const char *path = device_get_path(dev);
DBG("path %s", path);
+ server = find_server(servers, adapter);
+ if (!server || !server->sink_enabled) {
+ DBG("Unexpected error: cannot find server");
+ return -EPROTONOSUPPORT;
+ }
+
+ /* Return protocol not available if no record/endpoint exists */
+ if (server->sink_record_id == 0)
+ return -ENOPROTOOPT;
+
return source_connect(service);
}
@@ -1881,10 +1893,22 @@ static int a2dp_source_disconnect(struct btd_service *service)
static int a2dp_sink_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
+ struct btd_adapter *adapter = device_get_adapter(dev);
+ struct a2dp_server *server;
const char *path = device_get_path(dev);
DBG("path %s", path);
+ server = find_server(servers, adapter);
+ if (!server || !server->source_enabled) {
+ DBG("Unexpected error: cannot find server");
+ return -EPROTONOSUPPORT;
+ }
+
+ /* Return protocol not available if no record/endpoint exists */
+ if (server->source_record_id == 0)
+ return -ENOPROTOOPT;
+
return sink_connect(service);
}
--
1.8.3.1
^ permalink raw reply related
* Re: [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Johan Hedberg @ 2013-11-13 13:16 UTC (permalink / raw)
To: Andrei Emeltchenko, linux-bluetooth
In-Reply-To: <20131113125213.GG21468@aemeltch-MOBL1>
Hi Andrei,
On Wed, Nov 13, 2013, Andrei Emeltchenko wrote:
> > A table would probably make more sense here. What about the SDP records
> > that need to be registered? Also, I'd stick to the assigned numbers from
> > our doc/assigned-numbers.txt.
>
> If I use table then we need a loop here.
Correct.
> So shall we change default Android assigned number to ours? Some devices
> assume that numbers and we would have worse interoperability.
A device which hard-codes a remote RFCOMM channel and never does an SDP
lookup wouldn't be able to pass qualification or interoperate with any
device that doesn't have the same hard-coded channel. So I really doubt
such devices exist on the market, unless you can provide some proof.
Johan
^ permalink raw reply
* Re: [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Andrei Emeltchenko @ 2013-11-13 12:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20131113121537.GA11291@x220.p-661hnu-f1>
Hi Johan,
On Wed, Nov 13, 2013 at 02:15:37PM +0200, Johan Hedberg wrote:
> Hi Andrei,
>
> On Mon, Nov 11, 2013, Andrei Emeltchenko wrote:
> > Handle HAL socket listen call. Create RFCOMM socket and wait for events.
> > ---
> > android/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 92 insertions(+), 2 deletions(-)
> >
> > diff --git a/android/socket.c b/android/socket.c
> > index c283c5f..80cb39e 100644
> > --- a/android/socket.c
> > +++ b/android/socket.c
> > @@ -27,22 +27,112 @@
> >
> > #include <glib.h>
> > #include <stdbool.h>
> > +#include <errno.h>
> >
> > #include "lib/bluetooth.h"
> > +#include "btio/btio.h"
> > #include "log.h"
> > #include "hal-msg.h"
> > #include "hal-ipc.h"
> > #include "ipc.h"
> > +#include "adapter.h"
> > #include "socket.h"
> >
> > +/* Simple list of RFCOMM server sockets */
> > +GList *rfcomm_srv_list = NULL;
> > +/* Simple list of RFCOMM accepted sockets */
> > +GList *rfcomm_accepted_list = NULL;
>
> What are these lists needed for? When/how will their items be freed?
> How about calling them "servers" and "connections"?
I will add code freeing those.
>
> > +struct rfcomm_slot {
> > + int fd;
> > + int hal_fd;
> > + int real_sock;
> > + uint32_t channel;
> > +};
>
> You should really have comments here for what each struct member is used
> for (you have this info in your cover letter but it should also be part
> of the code). Why do you keep hal_fd here? Shouldn't we close it on our
> side as soon as we've handed it over to the HAL? Why do you use uint32_t
> for the channel? RFCOMM channels are uint8_t and have a range of 1-31.
I will change it to int since we need to write int to Android framework.
>
> > +static struct rfcomm_slot *create_rfslot(int sock)
> > {
> > - DBG("Not implemented");
> > + int fds[2] = {-1, -1};
> > + struct rfcomm_slot *rfslot;
> > +
> > + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
> > + error("socketpair(): %s", strerror(errno));
> > + return NULL;
> > + }
> > +
> > + rfslot = g_malloc0(sizeof(*rfslot));
> > + rfslot->fd = fds[0];
> > + rfslot->hal_fd = fds[1];
> > + rfslot->real_sock = sock;
> > +
> > + return rfslot;
> > +}
> > +
> > +static const uint8_t UUID_PBAP[] = {
> > + 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
> > + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
> > +};
> > +#define RFCOMM_CHAN_PBAP 19
> > +
> > +static const uint8_t UUID_OPP[] = {
> > + 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
> > + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
> > +};
> > +#define RFCOMM_CHAN_OPP 12
>
> A table would probably make more sense here. What about the SDP records
> that need to be registered? Also, I'd stick to the assigned numbers from
> our doc/assigned-numbers.txt.
If I use table then we need a loop here.
So shall we change default Android assigned number to ours? Some devices
assume that numbers and we would have worse interoperability.
Best regards
Andrei Emeltchenko
>
> > +static int handle_listen(void *buf)
> > +{
> > + struct hal_cmd_sock_listen *cmd = buf;
> > + const bdaddr_t *src = bt_adapter_get_address();
> > + struct rfcomm_slot *rfslot;
> > + GIOChannel *io;
> > + GError *err = NULL;
> > + int ch;
> > +
> > + DBG("");
> > +
> > + ch = get_rfcomm_chan(cmd->uuid);
> > + if (ch < 0)
> > + return -1;
> > +
> > + DBG("rfcomm channel %u", ch);
> > +
> > + rfslot = create_rfslot(-1);
> > +
> > + io = bt_io_listen(connect_cb, NULL, rfslot, NULL, &err,
> > + BT_IO_OPT_SOURCE_BDADDR, src,
> > + BT_IO_OPT_CHANNEL, ch,
> > + BT_IO_OPT_INVALID);
>
> Might make sense to pass a proper GDestroyNotify callback here so that
> once you finally implement proper freeing of data it can be done in a
> clean way.
>
> Johan
^ permalink raw reply
* Re: [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Johan Hedberg @ 2013-11-13 12:15 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1384178627-25991-5-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Nov 11, 2013, Andrei Emeltchenko wrote:
> Handle HAL socket listen call. Create RFCOMM socket and wait for events.
> ---
> android/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/android/socket.c b/android/socket.c
> index c283c5f..80cb39e 100644
> --- a/android/socket.c
> +++ b/android/socket.c
> @@ -27,22 +27,112 @@
>
> #include <glib.h>
> #include <stdbool.h>
> +#include <errno.h>
>
> #include "lib/bluetooth.h"
> +#include "btio/btio.h"
> #include "log.h"
> #include "hal-msg.h"
> #include "hal-ipc.h"
> #include "ipc.h"
> +#include "adapter.h"
> #include "socket.h"
>
> +/* Simple list of RFCOMM server sockets */
> +GList *rfcomm_srv_list = NULL;
> +/* Simple list of RFCOMM accepted sockets */
> +GList *rfcomm_accepted_list = NULL;
What are these lists needed for? When/how will their items be freed?
How about calling them "servers" and "connections"?
> +struct rfcomm_slot {
> + int fd;
> + int hal_fd;
> + int real_sock;
> + uint32_t channel;
> +};
You should really have comments here for what each struct member is used
for (you have this info in your cover letter but it should also be part
of the code). Why do you keep hal_fd here? Shouldn't we close it on our
side as soon as we've handed it over to the HAL? Why do you use uint32_t
for the channel? RFCOMM channels are uint8_t and have a range of 1-31.
> +static struct rfcomm_slot *create_rfslot(int sock)
> {
> - DBG("Not implemented");
> + int fds[2] = {-1, -1};
> + struct rfcomm_slot *rfslot;
> +
> + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
> + error("socketpair(): %s", strerror(errno));
> + return NULL;
> + }
> +
> + rfslot = g_malloc0(sizeof(*rfslot));
> + rfslot->fd = fds[0];
> + rfslot->hal_fd = fds[1];
> + rfslot->real_sock = sock;
> +
> + return rfslot;
> +}
> +
> +static const uint8_t UUID_PBAP[] = {
> + 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
> + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
> +};
> +#define RFCOMM_CHAN_PBAP 19
> +
> +static const uint8_t UUID_OPP[] = {
> + 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
> + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
> +};
> +#define RFCOMM_CHAN_OPP 12
A table would probably make more sense here. What about the SDP records
that need to be registered? Also, I'd stick to the assigned numbers from
our doc/assigned-numbers.txt.
> +static int handle_listen(void *buf)
> +{
> + struct hal_cmd_sock_listen *cmd = buf;
> + const bdaddr_t *src = bt_adapter_get_address();
> + struct rfcomm_slot *rfslot;
> + GIOChannel *io;
> + GError *err = NULL;
> + int ch;
> +
> + DBG("");
> +
> + ch = get_rfcomm_chan(cmd->uuid);
> + if (ch < 0)
> + return -1;
> +
> + DBG("rfcomm channel %u", ch);
> +
> + rfslot = create_rfslot(-1);
> +
> + io = bt_io_listen(connect_cb, NULL, rfslot, NULL, &err,
> + BT_IO_OPT_SOURCE_BDADDR, src,
> + BT_IO_OPT_CHANNEL, ch,
> + BT_IO_OPT_INVALID);
Might make sense to pass a proper GDestroyNotify callback here so that
once you finally implement proper freeing of data it can be done in a
clean way.
Johan
^ permalink raw reply
* Re: [RFC] android/debug: Move debug functions to hal-utils.c
From: Andrei Emeltchenko @ 2013-11-13 11:35 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1383923100-19574-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Fri, Nov 08, 2013 at 05:05:00PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Any comment on this patch?
Best regards
Andrei Emeltchenko
>
> Debug functions will be used by HALs and haltest.
> ---
> android/Android.mk | 2 -
> android/Makefile.am | 3 -
> android/client/if-av.c | 1 +
> android/client/if-bt.c | 1 +
> android/client/if-hf.c | 1 +
> android/client/if-hh.c | 1 +
> android/client/if-main.h | 2 -
> android/client/if-pan.c | 1 +
> android/client/if-sock.c | 1 +
> android/client/textconv.c | 300 ---------------------------------------------
> android/client/textconv.h | 120 ------------------
> android/hal-bluetooth.c | 3 +-
> android/hal-utils.c | 269 ++++++++++++++++++++++++++++++++++++++++
> android/hal-utils.h | 103 ++++++++++++++++
> 14 files changed, 379 insertions(+), 429 deletions(-)
> delete mode 100644 android/client/textconv.c
> delete mode 100644 android/client/textconv.h
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 0bc0e82..53c766b 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -87,7 +87,6 @@ LOCAL_SRC_FILES := \
> hal-hidhost.c \
> hal-pan.c \
> hal-a2dp.c \
> - client/textconv.c \
> hal-utils.c \
>
> LOCAL_C_INCLUDES += \
> @@ -118,7 +117,6 @@ LOCAL_SRC_FILES := \
> client/pollhandler.c \
> client/terminal.c \
> client/history.c \
> - client/textconv.c \
> client/tabcompletion.c \
> client/if-av.c \
> client/if-bt.c \
> diff --git a/android/Makefile.am b/android/Makefile.am
> index debe7c1..e81d1a5 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -59,7 +59,6 @@ android_haltest_SOURCES = android/client/haltest.c \
> android/client/pollhandler.c \
> android/client/terminal.c \
> android/client/history.c \
> - android/client/textconv.c \
> android/client/tabcompletion.c \
> android/client/if-av.c \
> android/client/if-bt.c \
> @@ -102,9 +101,7 @@ EXTRA_DIST += android/client/terminal.c \
> android/client/if-hh.c \
> android/client/if-pan.c \
> android/client/if-sock.c \
> - android/client/textconv.c \
> android/client/tabcompletion.c \
> - android/client/textconv.h \
> android/client/if-main.h \
> android/client/pollhandler.h \
> android/client/history.h \
> diff --git a/android/client/if-av.c b/android/client/if-av.c
> index 3f133eb..0470e0d 100644
> --- a/android/client/if-av.c
> +++ b/android/client/if-av.c
> @@ -16,6 +16,7 @@
> */
>
> #include "if-main.h"
> +#include "../hal-utils.h"
>
> const btav_interface_t *if_av = NULL;
>
> diff --git a/android/client/if-bt.c b/android/client/if-bt.c
> index 10ae125..0cd43db 100644
> --- a/android/client/if-bt.c
> +++ b/android/client/if-bt.c
> @@ -17,6 +17,7 @@
>
> #include "if-main.h"
> #include "terminal.h"
> +#include "../hal-utils.h"
>
> const bt_interface_t *if_bluetooth;
>
> diff --git a/android/client/if-hf.c b/android/client/if-hf.c
> index c23fb13..d0e7a66 100644
> --- a/android/client/if-hf.c
> +++ b/android/client/if-hf.c
> @@ -16,6 +16,7 @@
> */
>
> #include "if-main.h"
> +#include "../hal-utils.h"
>
> const bthf_interface_t *if_hf = NULL;
>
> diff --git a/android/client/if-hh.c b/android/client/if-hh.c
> index 005b13a..b8ebc8e 100644
> --- a/android/client/if-hh.c
> +++ b/android/client/if-hh.c
> @@ -23,6 +23,7 @@
>
> #include "if-main.h"
> #include "pollhandler.h"
> +#include "../hal-utils.h"
>
> const bthh_interface_t *if_hh = NULL;
>
> diff --git a/android/client/if-main.h b/android/client/if-main.h
> index dea7237..a83f48b 100644
> --- a/android/client/if-main.h
> +++ b/android/client/if-main.h
> @@ -44,8 +44,6 @@
> #include <hardware/bt_gatt_server.h>
> #endif
>
> -#include "textconv.h"
> -
> /* Interfaces from hal that can be populated during application lifetime */
> extern const bt_interface_t *if_bluetooth;
> extern const btav_interface_t *if_av;
> diff --git a/android/client/if-pan.c b/android/client/if-pan.c
> index dcc7e80..a11f2a3 100644
> --- a/android/client/if-pan.c
> +++ b/android/client/if-pan.c
> @@ -18,6 +18,7 @@
> #include <hardware/bluetooth.h>
>
> #include "if-main.h"
> +#include "../hal-utils.h"
>
> const btpan_interface_t *if_pan = NULL;
>
> diff --git a/android/client/if-sock.c b/android/client/if-sock.c
> index dcaf048..2cd06e8 100644
> --- a/android/client/if-sock.c
> +++ b/android/client/if-sock.c
> @@ -21,6 +21,7 @@
>
> #include "if-main.h"
> #include "pollhandler.h"
> +#include "../hal-utils.h"
>
> const btsock_interface_t *if_sock = NULL;
>
> diff --git a/android/client/textconv.c b/android/client/textconv.c
> deleted file mode 100644
> index dcbe53e..0000000
> --- a/android/client/textconv.c
> +++ /dev/null
> @@ -1,300 +0,0 @@
> -/*
> - * Copyright (C) 2013 Intel Corporation
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - * http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - *
> - */
> -
> -#include <string.h>
> -#include <stdio.h>
> -#include <hardware/bluetooth.h>
> -
> -#include "../hal-utils.h"
> -
> -#include "textconv.h"
> -
> -/*
> - * Following are maps of defines found in bluetooth header files to strings
> - *
> - * Those mappings are used to accurately use defines as input parameters in
> - * command line as well as for printing of statuses
> - */
> -
> -INTMAP(bt_status_t, -1, "(unknown)")
> - DELEMENT(BT_STATUS_SUCCESS),
> - DELEMENT(BT_STATUS_FAIL),
> - DELEMENT(BT_STATUS_NOT_READY),
> - DELEMENT(BT_STATUS_NOMEM),
> - DELEMENT(BT_STATUS_BUSY),
> - DELEMENT(BT_STATUS_DONE),
> - DELEMENT(BT_STATUS_UNSUPPORTED),
> - DELEMENT(BT_STATUS_PARM_INVALID),
> - DELEMENT(BT_STATUS_UNHANDLED),
> - DELEMENT(BT_STATUS_AUTH_FAILURE),
> - DELEMENT(BT_STATUS_RMT_DEV_DOWN),
> -ENDMAP
> -
> -INTMAP(bt_state_t, -1, "(unknown)")
> - DELEMENT(BT_STATE_OFF),
> - DELEMENT(BT_STATE_ON),
> -ENDMAP
> -
> -INTMAP(bt_device_type_t, -1, "(unknown)")
> - DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
> - DELEMENT(BT_DEVICE_DEVTYPE_BLE),
> - DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
> -ENDMAP
> -
> -INTMAP(bt_scan_mode_t, -1, "(unknown)")
> - DELEMENT(BT_SCAN_MODE_NONE),
> - DELEMENT(BT_SCAN_MODE_CONNECTABLE),
> - DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
> -ENDMAP
> -
> -INTMAP(bt_discovery_state_t, -1, "(unknown)")
> - DELEMENT(BT_DISCOVERY_STOPPED),
> - DELEMENT(BT_DISCOVERY_STARTED),
> -ENDMAP
> -
> -INTMAP(bt_acl_state_t, -1, "(unknown)")
> - DELEMENT(BT_ACL_STATE_CONNECTED),
> - DELEMENT(BT_ACL_STATE_DISCONNECTED),
> -ENDMAP
> -
> -INTMAP(bt_bond_state_t, -1, "(unknown)")
> - DELEMENT(BT_BOND_STATE_NONE),
> - DELEMENT(BT_BOND_STATE_BONDING),
> - DELEMENT(BT_BOND_STATE_BONDED),
> -ENDMAP
> -
> -INTMAP(bt_ssp_variant_t, -1, "(unknown)")
> - DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
> - DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
> - DELEMENT(BT_SSP_VARIANT_CONSENT),
> - DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
> -ENDMAP
> -
> -INTMAP(bt_property_type_t, -1, "(unknown)")
> - DELEMENT(BT_PROPERTY_BDNAME),
> - DELEMENT(BT_PROPERTY_BDADDR),
> - DELEMENT(BT_PROPERTY_UUIDS),
> - DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
> - DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
> - DELEMENT(BT_PROPERTY_SERVICE_RECORD),
> - DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
> - DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
> - DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
> - DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
> - DELEMENT(BT_PROPERTY_REMOTE_RSSI),
> -#if PLATFORM_SDK_VERSION > 17
> - DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
> -#endif
> - DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
> -ENDMAP
> -
> -INTMAP(bt_cb_thread_evt, -1, "(unknown)")
> - DELEMENT(ASSOCIATE_JVM),
> - DELEMENT(DISASSOCIATE_JVM),
> -ENDMAP
> -
> -/* Find first index of given value in table m */
> -int int2str_findint(int v, const struct int2str m[])
> -{
> - int i;
> -
> - for (i = 0; m[i].str; ++i) {
> - if (m[i].val == v)
> - return i;
> - }
> - return -1;
> -}
> -
> -/* Find first index of given string in table m */
> -int int2str_findstr(const char *str, const struct int2str m[])
> -{
> - int i;
> -
> - for (i = 0; m[i].str; ++i) {
> - if (strcmp(m[i].str, str) == 0)
> - return i;
> - }
> - return -1;
> -}
> -
> -/*
> - * convert bd_addr to string
> - * buf must be at least 18 char long
> - *
> - * returns buf
> - */
> -const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
> -{
> - const uint8_t *p = bd_addr->address;
> -
> - snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
> - p[0], p[1], p[2], p[3], p[4], p[5]);
> -
> - return buf;
> -}
> -
> -/* converts string to bt_bdaddr_t */
> -void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
> -{
> - uint8_t *p = bd_addr->address;
> -
> - sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
> - &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
> -}
> -
> -/* converts string to uuid */
> -void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
> -{
> - int i = 0;
> -
> - memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
> -
> - while (*str && i < (int) sizeof(bt_uuid_t)) {
> - while (*str == '-')
> - str++;
> -
> - if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
> - break;
> -
> - i++;
> - str += 2;
> - }
> -}
> -
> -const char *enum_defines(void *v, int i)
> -{
> - const struct int2str *m = v;
> -
> - return m[i].str != NULL ? m[i].str : NULL;
> -}
> -
> -const char *enum_strings(void *v, int i)
> -{
> - const char **m = v;
> -
> - return m[i] != NULL ? m[i] : NULL;
> -}
> -
> -const char *enum_one_string(void *v, int i)
> -{
> - const char *m = v;
> -
> - return (i == 0) && (m[0] != 0) ? m : NULL;
> -}
> -
> -const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
> -{
> - static char buf[MAX_ADDR_STR_LEN];
> -
> - return bt_bdaddr_t2str(bd_addr, buf);
> -}
> -
> -const char *btproperty2str(const bt_property_t *property)
> -{
> - static char buf[4096];
> - char *p;
> -
> - p = buf + sprintf(buf, "type=%s len=%d val=",
> - bt_property_type_t2str(property->type),
> - property->len);
> -
> - switch (property->type) {
> - case BT_PROPERTY_BDNAME:
> - case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
> - snprintf(p, property->len + 1, "%s",
> - ((bt_bdname_t *) property->val)->name);
> - break;
> -
> - case BT_PROPERTY_BDADDR:
> - sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
> - break;
> -
> - case BT_PROPERTY_CLASS_OF_DEVICE:
> - sprintf(p, "%06x", *((int *) property->val));
> - break;
> -
> - case BT_PROPERTY_TYPE_OF_DEVICE:
> - sprintf(p, "%s", bt_device_type_t2str(
> - *((bt_device_type_t *) property->val)));
> - break;
> -
> - case BT_PROPERTY_REMOTE_RSSI:
> - sprintf(p, "%d", *((char *) property->val));
> - break;
> -
> - case BT_PROPERTY_ADAPTER_SCAN_MODE:
> - sprintf(p, "%s",
> - bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
> - break;
> -
> - case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
> - sprintf(p, "%d", *((int *) property->val));
> - break;
> -
> - case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
> - {
> - int count = property->len / sizeof(bt_bdaddr_t);
> - char *ptr = property->val;
> -
> - strcat(p, "{");
> -
> - while (count--) {
> - strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
> - if (count)
> - strcat(p, ", ");
> - ptr += sizeof(bt_bdaddr_t);
> - }
> -
> - strcat(p, "}");
> -
> - }
> - break;
> -
> - case BT_PROPERTY_UUIDS:
> - {
> - int count = property->len / sizeof(bt_uuid_t);
> - uint8_t *ptr = property->val;
> -
> - strcat(p, "{");
> -
> - while (count--) {
> - strcat(p, btuuid2str(ptr));
> - if (count)
> - strcat(p, ", ");
> - ptr += sizeof(bt_uuid_t);
> - }
> -
> - strcat(p, "}");
> -
> - }
> - break;
> -
> - case BT_PROPERTY_SERVICE_RECORD:
> - {
> - bt_service_record_t *rec = property->val;
> -
> - sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
> - rec->channel, rec->name);
> - }
> - break;
> -
> - default:
> - sprintf(p, "%p", property->val);
> - }
> -
> - return buf;
> -}
> diff --git a/android/client/textconv.h b/android/client/textconv.h
> deleted file mode 100644
> index 0a72805..0000000
> --- a/android/client/textconv.h
> +++ /dev/null
> @@ -1,120 +0,0 @@
> -/*
> - * Copyright (C) 2013 Intel Corporation
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - * http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - *
> - */
> -
> -/**
> - * Begin mapping section
> - *
> - * There are some mappings between integer values (enums) and strings
> - * to be presented to user. To make it easier to convert between those two
> - * set of macros is given. It is specially useful when we want to have
> - * strings that match constants from header files like:
> - * BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
> - * Example of usage:
> - *
> - * INTMAP(int, -1, "invalid")
> - * DELEMENT(BT_STATUS_SUCCESS)
> - * DELEMENT(BT_STATUS_FAIL)
> - * MELEMENT(123, "Some strange value")
> - * ENDMAP
> - *
> - * Just by doing this we have mapping table plus two functions:
> - * int str2int(const char *str);
> - * const char *int2str(int v);
> - *
> - * second argument to INTMAP specifies value to be returned from
> - * str2int function when there is not mapping for such number
> - * third argument specifies default value to be returned from int2str
> - *
> - * If same mapping is to be used in several source files put
> - * INTMAP in c file and DECINTMAP in h file.
> - *
> - * For mappings that are to be used in single file only
> - * use SINTMAP which will create the same but everything will be marked
> - * as static.
> - */
> -
> -struct int2str {
> - int val; /* int value */
> - const char *str; /* corresponding string */
> -};
> -
> -int int2str_findint(int v, const struct int2str m[]);
> -int int2str_findstr(const char *str, const struct int2str m[]);
> -const char *enum_defines(void *v, int i);
> -const char *enum_strings(void *v, int i);
> -const char *enum_one_string(void *v, int i);
> -
> -#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
> -#define DECINTMAP(type) \
> -extern struct int2str __##type##2str[]; \
> -const char *type##2##str(type v); \
> -type str##2##type(const char *str); \
> -
> -#define INTMAP(type, deft, defs) \
> -const char *type##2##str(type v) \
> -{ \
> - int i = int2str_findint((int) v, __##type##2str); \
> - return (i < 0) ? defs : __##type##2str[i].str; \
> -} \
> -type str##2##type(const char *str) \
> -{ \
> - int i = int2str_findstr(str, __##type##2str); \
> - return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
> -} \
> -struct int2str __##type##2str[] = {
> -
> -#define SINTMAP(type, deft, defs) \
> -static struct int2str __##type##2str[]; \
> -static inline const char *type##2##str(type v) \
> -{ \
> - int i = int2str_findint((int) v, __##type##2str); \
> - return (i < 0) ? defs : __##type##2str[i].str; \
> -} \
> -static inline type str##2##type(const char *str) \
> -{ \
> - int i = int2str_findstr(str, __##type##2str); \
> - return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
> -} \
> -static struct int2str __##type##2str[] = {
> -
> -#define ENDMAP {0, NULL} };
> -
> -/* use this to generate string from header file constant */
> -#define MELEMENT(v, s) {v, s}
> -/* use this to have arbitrary mapping from int to string */
> -#define DELEMENT(s) {s, #s}
> -/* End of mapping section */
> -
> -#define MAX_ADDR_STR_LEN 18
> -const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
> -void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
> -
> -void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
> -
> -const char *btproperty2str(const bt_property_t *property);
> -const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
> -
> -DECINTMAP(bt_status_t);
> -DECINTMAP(bt_state_t);
> -DECINTMAP(bt_device_type_t);
> -DECINTMAP(bt_scan_mode_t);
> -DECINTMAP(bt_discovery_state_t);
> -DECINTMAP(bt_acl_state_t);
> -DECINTMAP(bt_bond_state_t);
> -DECINTMAP(bt_ssp_variant_t);
> -DECINTMAP(bt_property_type_t);
> -DECINTMAP(bt_cb_thread_evt);
> diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
> index 3e5d41f..5c14649 100644
> --- a/android/hal-bluetooth.c
> +++ b/android/hal-bluetooth.c
> @@ -24,8 +24,7 @@
> #include "hal.h"
> #include "hal-msg.h"
> #include "hal-ipc.h"
> -
> -#include "client/textconv.h"
> +#include "hal-utils.h"
>
> static const bt_callbacks_t *bt_hal_cbacks = NULL;
>
> diff --git a/android/hal-utils.c b/android/hal-utils.c
> index 7ac5047..4f44d98 100644
> --- a/android/hal-utils.c
> +++ b/android/hal-utils.c
> @@ -55,3 +55,272 @@ const char *btuuid2str(const uint8_t *uuid)
>
> return bt_uuid_t2str(uuid, buf);
> }
> +
> +INTMAP(bt_status_t, -1, "(unknown)")
> + DELEMENT(BT_STATUS_SUCCESS),
> + DELEMENT(BT_STATUS_FAIL),
> + DELEMENT(BT_STATUS_NOT_READY),
> + DELEMENT(BT_STATUS_NOMEM),
> + DELEMENT(BT_STATUS_BUSY),
> + DELEMENT(BT_STATUS_DONE),
> + DELEMENT(BT_STATUS_UNSUPPORTED),
> + DELEMENT(BT_STATUS_PARM_INVALID),
> + DELEMENT(BT_STATUS_UNHANDLED),
> + DELEMENT(BT_STATUS_AUTH_FAILURE),
> + DELEMENT(BT_STATUS_RMT_DEV_DOWN),
> +ENDMAP
> +
> +INTMAP(bt_state_t, -1, "(unknown)")
> + DELEMENT(BT_STATE_OFF),
> + DELEMENT(BT_STATE_ON),
> +ENDMAP
> +
> +INTMAP(bt_device_type_t, -1, "(unknown)")
> + DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
> + DELEMENT(BT_DEVICE_DEVTYPE_BLE),
> + DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
> +ENDMAP
> +
> +INTMAP(bt_scan_mode_t, -1, "(unknown)")
> + DELEMENT(BT_SCAN_MODE_NONE),
> + DELEMENT(BT_SCAN_MODE_CONNECTABLE),
> + DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
> +ENDMAP
> +
> +INTMAP(bt_discovery_state_t, -1, "(unknown)")
> + DELEMENT(BT_DISCOVERY_STOPPED),
> + DELEMENT(BT_DISCOVERY_STARTED),
> +ENDMAP
> +
> +INTMAP(bt_acl_state_t, -1, "(unknown)")
> + DELEMENT(BT_ACL_STATE_CONNECTED),
> + DELEMENT(BT_ACL_STATE_DISCONNECTED),
> +ENDMAP
> +
> +INTMAP(bt_bond_state_t, -1, "(unknown)")
> + DELEMENT(BT_BOND_STATE_NONE),
> + DELEMENT(BT_BOND_STATE_BONDING),
> + DELEMENT(BT_BOND_STATE_BONDED),
> +ENDMAP
> +
> +INTMAP(bt_ssp_variant_t, -1, "(unknown)")
> + DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
> + DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
> + DELEMENT(BT_SSP_VARIANT_CONSENT),
> + DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
> +ENDMAP
> +
> +INTMAP(bt_property_type_t, -1, "(unknown)")
> + DELEMENT(BT_PROPERTY_BDNAME),
> + DELEMENT(BT_PROPERTY_BDADDR),
> + DELEMENT(BT_PROPERTY_UUIDS),
> + DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
> + DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
> + DELEMENT(BT_PROPERTY_SERVICE_RECORD),
> + DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
> + DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
> + DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
> + DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
> + DELEMENT(BT_PROPERTY_REMOTE_RSSI),
> +#if PLATFORM_SDK_VERSION > 17
> + DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
> +#endif
> + DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
> +ENDMAP
> +
> +INTMAP(bt_cb_thread_evt, -1, "(unknown)")
> + DELEMENT(ASSOCIATE_JVM),
> + DELEMENT(DISASSOCIATE_JVM),
> +ENDMAP
> +
> +/* Find first index of given value in table m */
> +int int2str_findint(int v, const struct int2str m[])
> +{
> + int i;
> +
> + for (i = 0; m[i].str; ++i) {
> + if (m[i].val == v)
> + return i;
> + }
> + return -1;
> +}
> +
> +/* Find first index of given string in table m */
> +int int2str_findstr(const char *str, const struct int2str m[])
> +{
> + int i;
> +
> + for (i = 0; m[i].str; ++i) {
> + if (strcmp(m[i].str, str) == 0)
> + return i;
> + }
> + return -1;
> +}
> +
> +/*
> + * convert bd_addr to string
> + * buf must be at least 18 char long
> + *
> + * returns buf
> + */
> +const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
> +{
> + const uint8_t *p = bd_addr->address;
> +
> + snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
> + p[0], p[1], p[2], p[3], p[4], p[5]);
> +
> + return buf;
> +}
> +
> +/* converts string to bt_bdaddr_t */
> +void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
> +{
> + uint8_t *p = bd_addr->address;
> +
> + sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
> + &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
> +}
> +
> +/* converts string to uuid */
> +void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
> +{
> + int i = 0;
> +
> + memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
> +
> + while (*str && i < (int) sizeof(bt_uuid_t)) {
> + while (*str == '-')
> + str++;
> +
> + if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
> + break;
> +
> + i++;
> + str += 2;
> + }
> +}
> +
> +const char *enum_defines(void *v, int i)
> +{
> + const struct int2str *m = v;
> +
> + return m[i].str != NULL ? m[i].str : NULL;
> +}
> +
> +const char *enum_strings(void *v, int i)
> +{
> + const char **m = v;
> +
> + return m[i] != NULL ? m[i] : NULL;
> +}
> +
> +const char *enum_one_string(void *v, int i)
> +{
> + const char *m = v;
> +
> + return (i == 0) && (m[0] != 0) ? m : NULL;
> +}
> +
> +const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
> +{
> + static char buf[MAX_ADDR_STR_LEN];
> +
> + return bt_bdaddr_t2str(bd_addr, buf);
> +}
> +
> +const char *btproperty2str(const bt_property_t *property)
> +{
> + static char buf[4096];
> + char *p;
> +
> + p = buf + sprintf(buf, "type=%s len=%d val=",
> + bt_property_type_t2str(property->type),
> + property->len);
> +
> + switch (property->type) {
> + case BT_PROPERTY_BDNAME:
> + case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
> + snprintf(p, property->len + 1, "%s",
> + ((bt_bdname_t *) property->val)->name);
> + break;
> +
> + case BT_PROPERTY_BDADDR:
> + sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
> + break;
> +
> + case BT_PROPERTY_CLASS_OF_DEVICE:
> + sprintf(p, "%06x", *((int *) property->val));
> + break;
> +
> + case BT_PROPERTY_TYPE_OF_DEVICE:
> + sprintf(p, "%s", bt_device_type_t2str(
> + *((bt_device_type_t *) property->val)));
> + break;
> +
> + case BT_PROPERTY_REMOTE_RSSI:
> + sprintf(p, "%d", *((char *) property->val));
> + break;
> +
> + case BT_PROPERTY_ADAPTER_SCAN_MODE:
> + sprintf(p, "%s",
> + bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
> + break;
> +
> + case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
> + sprintf(p, "%d", *((int *) property->val));
> + break;
> +
> + case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
> + {
> + int count = property->len / sizeof(bt_bdaddr_t);
> + char *ptr = property->val;
> +
> + strcat(p, "{");
> +
> + while (count--) {
> + strcat(p, bdaddr2str((bt_bdaddr_t *) ptr));
> + if (count)
> + strcat(p, ", ");
> + ptr += sizeof(bt_bdaddr_t);
> + }
> +
> + strcat(p, "}");
> +
> + }
> + break;
> +
> + case BT_PROPERTY_UUIDS:
> + {
> + int count = property->len / sizeof(bt_uuid_t);
> + uint8_t *ptr = property->val;
> +
> + strcat(p, "{");
> +
> + while (count--) {
> + strcat(p, btuuid2str(ptr));
> + if (count)
> + strcat(p, ", ");
> + ptr += sizeof(bt_uuid_t);
> + }
> +
> + strcat(p, "}");
> +
> + }
> + break;
> +
> + case BT_PROPERTY_SERVICE_RECORD:
> + {
> + bt_service_record_t *rec = property->val;
> +
> + sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
> + rec->channel, rec->name);
> + }
> + break;
> +
> + default:
> + sprintf(p, "%p", property->val);
> + }
> +
> + return buf;
> +}
> diff --git a/android/hal-utils.h b/android/hal-utils.h
> index 8c74653..75de7e9 100644
> --- a/android/hal-utils.h
> +++ b/android/hal-utils.h
> @@ -15,8 +15,11 @@
> *
> */
>
> +#include <hardware/bluetooth.h>
> +
> #define MAX_UUID_STR_LEN 37
> #define HAL_UUID_LEN 16
> +#define MAX_ADDR_STR_LEN 18
>
> static const char BT_BASE_UUID[] = {
> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
> @@ -25,3 +28,103 @@ static const char BT_BASE_UUID[] = {
>
> const char *bt_uuid_t2str(const uint8_t *uuid, char *buf);
> const char *btuuid2str(const uint8_t *uuid);
> +const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
> +void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
> +void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
> +const char *btproperty2str(const bt_property_t *property);
> +const char *bdaddr2str(const bt_bdaddr_t *bd_addr);
> +
> +/**
> + * Begin mapping section
> + *
> + * There are some mappings between integer values (enums) and strings
> + * to be presented to user. To make it easier to convert between those two
> + * set of macros is given. It is specially useful when we want to have
> + * strings that match constants from header files like:
> + * BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS"
> + * Example of usage:
> + *
> + * INTMAP(int, -1, "invalid")
> + * DELEMENT(BT_STATUS_SUCCESS)
> + * DELEMENT(BT_STATUS_FAIL)
> + * MELEMENT(123, "Some strange value")
> + * ENDMAP
> + *
> + * Just by doing this we have mapping table plus two functions:
> + * int str2int(const char *str);
> + * const char *int2str(int v);
> + *
> + * second argument to INTMAP specifies value to be returned from
> + * str2int function when there is not mapping for such number
> + * third argument specifies default value to be returned from int2str
> + *
> + * If same mapping is to be used in several source files put
> + * INTMAP in c file and DECINTMAP in h file.
> + *
> + * For mappings that are to be used in single file only
> + * use SINTMAP which will create the same but everything will be marked
> + * as static.
> + */
> +
> +struct int2str {
> + int val; /* int value */
> + const char *str; /* corresponding string */
> +};
> +
> +int int2str_findint(int v, const struct int2str m[]);
> +int int2str_findstr(const char *str, const struct int2str m[]);
> +const char *enum_defines(void *v, int i);
> +const char *enum_strings(void *v, int i);
> +const char *enum_one_string(void *v, int i);
> +
> +#define TYPE_ENUM(type) ((void *) &__##type##2str[0])
> +#define DECINTMAP(type) \
> +extern struct int2str __##type##2str[]; \
> +const char *type##2##str(type v); \
> +type str##2##type(const char *str); \
> +
> +#define INTMAP(type, deft, defs) \
> +const char *type##2##str(type v) \
> +{ \
> + int i = int2str_findint((int) v, __##type##2str); \
> + return (i < 0) ? defs : __##type##2str[i].str; \
> +} \
> +type str##2##type(const char *str) \
> +{ \
> + int i = int2str_findstr(str, __##type##2str); \
> + return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
> +} \
> +struct int2str __##type##2str[] = {
> +
> +#define SINTMAP(type, deft, defs) \
> +static struct int2str __##type##2str[]; \
> +static inline const char *type##2##str(type v) \
> +{ \
> + int i = int2str_findint((int) v, __##type##2str); \
> + return (i < 0) ? defs : __##type##2str[i].str; \
> +} \
> +static inline type str##2##type(const char *str) \
> +{ \
> + int i = int2str_findstr(str, __##type##2str); \
> + return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \
> +} \
> +static struct int2str __##type##2str[] = {
> +
> +#define ENDMAP {0, NULL} };
> +
> +/* use this to generate string from header file constant */
> +#define MELEMENT(v, s) {v, s}
> +/* use this to have arbitrary mapping from int to string */
> +#define DELEMENT(s) {s, #s}
> +/* End of mapping section */
> +
> +DECINTMAP(bt_status_t);
> +DECINTMAP(bt_state_t);
> +DECINTMAP(bt_device_type_t);
> +DECINTMAP(bt_scan_mode_t);
> +DECINTMAP(bt_discovery_state_t);
> +DECINTMAP(bt_acl_state_t);
> +DECINTMAP(bt_bond_state_t);
> +DECINTMAP(bt_ssp_variant_t);
> +DECINTMAP(bt_property_type_t);
> +DECINTMAP(bt_cb_thread_evt);
> --
> 1.7.10.4
>
> --
> 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
* Re: [PATCH_v3 3/3] android/pan: Handle connection and control state notifications
From: Johan Hedberg @ 2013-11-13 11:16 UTC (permalink / raw)
To: Ravi Kumar Veeramally; +Cc: Szymon Janc, linux-bluetooth
In-Reply-To: <5283506A.4090105@linux.intel.com>
Hi Ravi,
On Wed, Nov 13, 2013, Ravi Kumar Veeramally wrote:
> On 11/13/2013 11:59 AM, Szymon Janc wrote:
> >Hi,
> >
> >>>>+
> >>>>+ switch (opcode) {
> >>>>+ case HAL_EV_PAN_CONN_STATE:
> >>>>+ handle_conn_state(buf);
> >>>>+ break;
> >>>>+ case HAL_EV_PAN_CTRL_STATE:
> >>>>+ handle_ctrl_state(buf);
> >>>>+ break;
> >>>>+ default:
> >>>>+ DBG("Unhandled callback opcode=0x%x", opcode);
> >>>>+ break;
> >>>>+ }
> >>>> }
> >>>What I don't like about this is that you're not pushing the data length
> >>>to the handler functions. If you did that the handler functions could:
> >>>
> >>> if (len < sizeof(*ev))
> >>> return;
> >>>
> >>>Instead of return we could also just abort - what's the general policy
> >>>on the HAL side regarding invalid data from the daemon? How does this
> >>>relate to the work Szymon is doing to add proper checks for the IPC
> >>>data? Is that only for the daemon side?
> >>>
> >>>Are we missing similar checks in other HALs too?
> >> Yes, we are not doing similar checks in other HALs
> >>(hal-bluetooth/a2dp/hid/) too.
> >> Very few places in hal-bluetooth length is passing but validation is
> >>not done.
> >> I will fix them all and send you the patch.
> >As mentioned in my RFC, messages have very similar format and can be checked
> >in single place using some common macros. I'm now working on addressing Johan
> >comments in that RFC. As suggested I'm going to use tables of handlers instead
> >switch-case and this should also allow to refactor current code to avoid
> >switch-cases we currently have. Services will simply register own tables of
> >handlers for service they implement. Idea is that check will be done in common
> >place and then handlers will have form of void handle_foo(struct foo *ev) with
> >guarantee that passed command/event is memory size valid.
> >
> >Plan is to make this generic code use both by hal and daemon.
> >
> >So, I'm not sure if it makes much sense to fix passing buf+len to all handlers
> >we have now.
> >
> >If you have other ideas for this please comment.
> >
> Ok, good to know.
> Johan: Can you now apply my left over patch?
Yes, it's already done, however I'd really like to see the patches to
fix all this asap.
Johan
^ 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