Bluetooth: Introduce dedicated Bluetooth address types

We use addresses in lots of places and with LE we always need to pass
around the type in addition to the address value. Defining dedicated
types for addresses makes the code much simpler.

Change-Id: Ie8b495dce50e3f084685909c19acc5d08e2cca10
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-05-25 09:13:33 +03:00 committed by Anas Nashif
commit 9b40ec3360
6 changed files with 136 additions and 84 deletions

View file

@ -35,6 +35,21 @@
#include <toolchain.h>
#include <stdint.h>
#define BT_ADDR_LE_PUBLIC 0x00
#define BT_ADDR_LE_RANDOM 0x01
typedef struct {
uint8_t val[6];
} bt_addr_t;
typedef struct {
uint8_t type;
uint8_t val[6];
} bt_addr_le_t;
#define BT_ADDR_ANY (&(bt_addr_t) {{0, 0, 0, 0, 0, 0}})
#define BT_ADDR_LE_ANY (&(bt_addr_le_t) { 0, {0, 0, 0, 0, 0, 0}})
/* EIR/AD definitions */
#define BT_EIR_FLAGS 0x01 /* AD flags */
#define BT_EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
@ -150,8 +165,8 @@ struct bt_hci_rp_read_buffer_size {
#define BT_HCI_OP_READ_BD_ADDR BT_OP(BT_OGF_INFO, 0x0009)
struct bt_hci_rp_read_bd_addr {
uint8_t status;
uint8_t bdaddr[6];
uint8_t status;
bt_addr_t bdaddr;
} PACK_STRUCT;
#define BT_HCI_OP_LE_READ_BUFFER_SIZE BT_OP(BT_OGF_LE, 0x0002)
@ -177,14 +192,13 @@ struct bt_hci_rp_le_read_local_features {
#define BT_HCI_OP_LE_SET_ADV_PARAMETERS BT_OP(BT_OGF_LE, 0x0006)
struct bt_hci_cp_le_set_adv_parameters {
uint16_t min_interval;
uint16_t max_interval;
uint8_t type;
uint8_t own_addr_type;
uint8_t direct_addr_type;
uint8_t direct_addr[6];
uint8_t channel_map;
uint8_t filter_policy;
uint16_t min_interval;
uint16_t max_interval;
uint8_t type;
uint8_t own_addr_type;
bt_addr_le_t direct_addr;
uint8_t channel_map;
uint8_t filter_policy;
} PACK_STRUCT;
#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008)
@ -297,27 +311,22 @@ struct bt_hci_evt_le_meta_event {
#define BT_HCI_EVT_LE_CONN_COMPLETE 0x01
struct bt_hci_evt_le_conn_complete {
uint8_t status;
uint16_t handle;
uint8_t role;
uint8_t peer_addr_type;
uint8_t peer_addr[6];
uint16_t interval;
uint16_t latency;
uint16_t supv_timeout;
uint8_t clock_accuracy;
uint8_t status;
uint16_t handle;
uint8_t role;
bt_addr_le_t peer_addr;
uint16_t interval;
uint16_t latency;
uint16_t supv_timeout;
uint8_t clock_accuracy;
} PACK_STRUCT;
#define BT_ADDR_LE_DEV_PUBLIC 0x00
#define BT_ADDR_LE_DEV_RANDOM 0x01
#define BT_HCI_EVT_LE_ADVERTISING_REPORT 0x02
struct bt_hci_ev_le_advertising_info {
uint8_t evt_type;
uint8_t bdaddr_type;
uint8_t bdaddr[6];
uint8_t length;
uint8_t data[0];
uint8_t evt_type;
bt_addr_le_t addr;
uint8_t length;
uint8_t data[0];
} PACK_STRUCT;
#define BT_HCI_EVT_LE_LTK_REQUEST 0x05

View file

@ -34,6 +34,7 @@
#include <toolchain.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <misc/byteorder.h>
#include <misc/util.h>

View file

@ -50,8 +50,8 @@ struct bt_conn {
struct bt_dev *dev;
uint16_t handle;
uint8_t dst[6];
uint8_t dst_type;
bt_addr_le_t src;
bt_addr_le_t dst;
uint8_t encrypt;

View file

@ -38,8 +38,8 @@
#include <misc/util.h>
#include <misc/byteorder.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include "hci_core.h"
#include "conn.h"
@ -79,24 +79,60 @@ static struct bt_dev dev;
static struct bt_keys key_list[CONFIG_BLUETOOTH_MAX_PAIRED];
const char *bt_bdaddr_str(const uint8_t bda[6])
#if defined(CONFIG_BLUETOOTH_DEBUG)
const char *bt_addr_str(const bt_addr_t *addr)
{
static char bdaddr_str[18];
static char bufs[2][18];
static uint8_t cur;
char *str;
sprintf(bdaddr_str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
bda[5], bda[4], bda[3], bda[2], bda[1], bda[0]);
str = bufs[cur++];
cur %= ARRAY_SIZE(bufs);
return bdaddr_str;
sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
addr->val[5], addr->val[4], addr->val[3],
addr->val[2], addr->val[1], addr->val[0]);
return str;
}
struct bt_keys *bt_keys_create(uint8_t bdaddr[6], uint8_t bdaddr_type)
const char *bt_addr_le_str(const bt_addr_le_t *addr)
{
static char bufs[2][27];
static uint8_t cur;
char *str, type[7];
str = bufs[cur++];
cur %= ARRAY_SIZE(bufs);
switch (addr->type) {
case BT_ADDR_LE_PUBLIC:
strcpy(type, "public");
break;
case BT_ADDR_LE_RANDOM:
strcpy(type, "random");
break;
default:
sprintf(type, "0x%02x", addr->type);
break;
}
sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (%s)",
addr->val[5], addr->val[4], addr->val[3],
addr->val[2], addr->val[1], addr->val[0], type);
return str;
}
#endif /* CONFIG_BLUETOOTH_DEBUG */
struct bt_keys *bt_keys_create(const bt_addr_le_t *addr)
{
struct bt_keys *keys;
int i;
BT_DBG("%s (%u)\n", bt_bdaddr_str(bdaddr), bdaddr_type);
BT_DBG("%s\n", bt_addr_le_str(addr));
keys = bt_keys_find(bdaddr, bdaddr_type);
keys = bt_keys_find(addr);
if (keys) {
return keys;
}
@ -104,9 +140,8 @@ struct bt_keys *bt_keys_create(uint8_t bdaddr[6], uint8_t bdaddr_type)
for (i = 0; i < ARRAY_SIZE(key_list); i++) {
keys = &key_list[i];
if (!memcmp(keys->bdaddr, BDADDR_ANY, 6)) {
memcpy(keys->bdaddr, bdaddr, 6);
keys->bdaddr_type = bdaddr_type;
if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
bt_addr_le_copy(&keys->addr, addr);
BT_DBG("created keys %p\n", keys);
return keys;
}
@ -117,17 +152,16 @@ struct bt_keys *bt_keys_create(uint8_t bdaddr[6], uint8_t bdaddr_type)
return NULL;
}
struct bt_keys *bt_keys_find(uint8_t bdaddr[6], uint8_t bdaddr_type)
struct bt_keys *bt_keys_find(const bt_addr_le_t *addr)
{
int i;
BT_DBG("%s (%u)\n", bt_bdaddr_str(bdaddr), bdaddr_type);
BT_DBG("%s\n", bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_list); i++) {
struct bt_keys *keys = &key_list[i];
if (!memcmp(keys->bdaddr, bdaddr, 6) &&
keys->bdaddr_type == bdaddr_type) {
if (!bt_addr_le_cmp(&keys->addr, addr)) {
BT_DBG("found keys %p\n", keys);
return keys;
}
@ -476,8 +510,9 @@ static void le_conn_complete(struct bt_buf *buf)
return;
}
memcpy(conn->dst, evt->peer_addr, sizeof(evt->peer_addr));
conn->dst_type = evt->peer_addr_type;
conn->src.type = BT_ADDR_LE_PUBLIC;
memcpy(conn->src.val, dev.bdaddr.val, sizeof(dev.bdaddr.val));
bt_addr_le_copy(&conn->dst, &evt->peer_addr);
conn->le_conn_interval = sys_le16_to_cpu(evt->interval);
bt_l2cap_connected(conn);
@ -524,7 +559,7 @@ static void le_ltk_request(struct bt_buf *buf)
return;
}
keys = bt_keys_find(conn->dst, conn->dst_type);
keys = bt_keys_find(&conn->dst);
if (keys && keys->slave_ltk.rand == evt->rand &&
keys->slave_ltk.ediv == evt->ediv) {
struct bt_hci_cp_le_ltk_req_reply *cp;
@ -742,7 +777,7 @@ static void read_bdaddr_complete(struct bt_buf *buf)
BT_DBG("status %u\n", rp->status);
memcpy(dev.bdaddr, rp->bdaddr, sizeof(dev.bdaddr));
bt_addr_copy(&dev.bdaddr, &rp->bdaddr);
}
static void read_le_features_complete(struct bt_buf *buf)

View file

@ -37,7 +37,7 @@
/* State tracking for the local Bluetooth controller */
struct bt_dev {
/* Local Bluetooth Device Address */
uint8_t bdaddr[6];
bt_addr_t bdaddr;
/* Controller version & manufacturer information */
uint8_t hci_version;
@ -81,6 +81,26 @@ struct bt_dev {
struct bt_driver *drv;
};
static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
struct bt_ltk {
uint64_t rand;
uint16_t ediv;
@ -88,14 +108,13 @@ struct bt_ltk {
};
struct bt_keys {
uint8_t bdaddr[6];
uint8_t bdaddr_type;
bt_addr_le_t addr;
struct bt_ltk slave_ltk;
};
struct bt_keys *bt_keys_create(uint8_t bdaddr[6], uint8_t bdaddr_type);
struct bt_keys *bt_keys_find(uint8_t bdaddr[6], uint8_t bdaddr_type);
struct bt_keys *bt_keys_create(const bt_addr_le_t *addr);
struct bt_keys *bt_keys_find(const bt_addr_le_t *addr);
void bt_keys_clear(struct bt_keys *keys);
struct bt_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len);
@ -106,4 +125,7 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct bt_buf *buf,
/* The helper is only safe to be called from internal fibers as it's
* not multi-threading safe
*/
const char *bt_bdaddr_str(const uint8_t bdaddr[6]);
#if defined(CONFIG_BLUETOOTH_DEBUG)
const char *bt_addr_str(const bt_addr_t *addr);
const char *bt_addr_le_str(const bt_addr_le_t *addr);
#endif

View file

@ -183,20 +183,19 @@ static int le_rand(void *buf, size_t len)
static int smp_c1(const uint8_t k[16], const uint8_t r[16],
const uint8_t preq[7], const uint8_t pres[7],
uint8_t iat, const uint8_t ia[6],
uint8_t rat, const uint8_t ra[6],
const bt_addr_le_t *ia, const bt_addr_le_t *ra,
uint8_t enc_data[16])
{
uint8_t p1[16], p2[16];
int err;
BT_DBG("k %s r %s\n", h(k, 16), h(r, 16));
BT_DBG("iat %u ia %s rat %u ra %s\n", iat, h(ia, 6), rat, h(ra, 6));
BT_DBG("ia %s ra %s\n", bt_addr_le_str(ia), bt_addr_le_str(ra));
BT_DBG("preq %s pres %s\n", h(preq, 7), h(pres, 7));
/* pres, preq, rat and iat are concatenated to generate p1 */
p1[0] = iat;
p1[1] = rat;
p1[0] = ia->type;
p1[1] = ra->type;
memcpy(p1 + 2, preq, 7);
memcpy(p1 + 9, pres, 7);
@ -213,8 +212,8 @@ static int smp_c1(const uint8_t k[16], const uint8_t r[16],
}
/* ra is concatenated with ia and padding to generate p2 */
memcpy(p2, ra, 6);
memcpy(p2 + 6, ia, 6);
memcpy(p2, ra->val, 6);
memcpy(p2 + 6, ia->val, 6);
memset(p2 + 12, 0, 4);
BT_DBG("p2 %s\n", h(p2, 16));
@ -353,8 +352,6 @@ static int smp_pairing_confirm(struct bt_conn *conn, struct bt_buf *buf)
struct bt_smp_pairing_confirm *req = (void *)buf->data;
struct bt_smp_pairing_confirm *rsp;
struct bt_smp *smp = conn->smp;
uint8_t init_addr_type, resp_addr_type;
uint8_t *init_addr, *resp_addr;
struct bt_buf *rsp_buf;
int err;
@ -374,14 +371,9 @@ static int smp_pairing_confirm(struct bt_conn *conn, struct bt_buf *buf)
rsp = bt_buf_add(rsp_buf, sizeof(*rsp));
/* FIXME: Right now we assume peripheral role */
init_addr = conn->dst;
init_addr_type = conn->dst_type;
resp_addr = conn->dev->bdaddr;
resp_addr_type = BT_ADDR_LE_DEV_PUBLIC;
err = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, init_addr_type,
init_addr, resp_addr_type, resp_addr, rsp->val);
/* FIXME: Right now we assume peripheral role for ia & ra */
err = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, &conn->dst,
&conn->src, rsp->val);
if (err) {
bt_buf_put(rsp_buf);
return BT_SMP_ERR_UNSPECIFIED;
@ -398,8 +390,6 @@ static int smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
struct bt_smp_pairing_random *rsp;
struct bt_buf *rsp_buf;
struct bt_smp *smp = conn->smp;
uint8_t init_addr_type, resp_addr_type;
uint8_t *init_addr, *resp_addr;
struct bt_keys *keys;
uint8_t cfm[16];
int err;
@ -412,14 +402,9 @@ static int smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
memcpy(smp->rrnd, req->val, sizeof(smp->rrnd));
/* FIXME: Right now we assume peripheral role */
init_addr = conn->dst;
init_addr_type = conn->dst_type;
resp_addr = conn->dev->bdaddr;
resp_addr_type = BT_ADDR_LE_DEV_PUBLIC;
err = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, init_addr_type,
init_addr, resp_addr_type, resp_addr, cfm);
/* FIXME: Right now we assume peripheral role for ia & ra */
err = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, &conn->dst,
&conn->src, cfm);
if (err) {
return BT_SMP_ERR_UNSPECIFIED;
}
@ -430,7 +415,7 @@ static int smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
return BT_SMP_ERR_CONFIRM_FAILED;
}
keys = bt_keys_create(conn->dst, conn->dst_type);
keys = bt_keys_create(&conn->dst);
if (!keys) {
BT_ERR("Unable to create new keys\n");
return BT_SMP_ERR_UNSPECIFIED;
@ -547,7 +532,7 @@ static void bt_smp_encrypt_change(struct bt_conn *conn)
return;
}
keys = bt_keys_find(conn->dst, conn->dst_type);
keys = bt_keys_find(&conn->dst);
if (!keys) {
BT_ERR("Unable to look up keys for conn %p\n");
return;