From d7fac9bf8ce6c2afcf6a5407c2a03d457657c953 Mon Sep 17 00:00:00 2001 From: Wolfgang Puffitsch Date: Thu, 7 Feb 2019 10:08:31 +0100 Subject: [PATCH] Bluetooth: controller: Support big-endian archs in split controller. Use reverse order for bitfields on big-endian architectures. Treat all PDU data as little-endian and add conversions as needed. Treat access address as 4-byte value instead of u32_t to avoid flipping endianness. Signed-off-by: Wolfgang Puffitsch --- subsys/bluetooth/controller/hci/hci.c | 12 +- .../controller/ll_sw/nordic/lll/lll_adv.c | 3 +- .../controller/ll_sw/nordic/lll/lll_scan.c | 17 +- subsys/bluetooth/controller/ll_sw/pdu.h | 77 ++++- subsys/bluetooth/controller/ll_sw/ull_conn.c | 297 +++++++++++------- .../bluetooth/controller/ll_sw/ull_master.c | 34 +- subsys/bluetooth/controller/ll_sw/ull_slave.c | 16 +- 7 files changed, 300 insertions(+), 156 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index fa80c1182e..50d304146f 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -1806,13 +1806,13 @@ static void vs_read_version_info(struct net_buf *buf, struct net_buf **evt) rp = cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; - rp->hw_platform = BT_HCI_VS_HW_PLAT; - rp->hw_variant = BT_HCI_VS_HW_VAR; + rp->hw_platform = sys_cpu_to_le16(BT_HCI_VS_HW_PLAT); + rp->hw_variant = sys_cpu_to_le16(BT_HCI_VS_HW_VAR); rp->fw_variant = 0; rp->fw_version = (KERNEL_VERSION_MAJOR & 0xff); - rp->fw_revision = KERNEL_VERSION_MINOR; - rp->fw_build = (KERNEL_PATCHLEVEL & 0xffff); + rp->fw_revision = sys_cpu_to_le16(KERNEL_VERSION_MINOR); + rp->fw_build = sys_cpu_to_le32(KERNEL_PATCHLEVEL & 0xffff); } static void vs_read_supported_commands(struct net_buf *buf, @@ -3142,8 +3142,8 @@ static void remote_version_info(struct pdu_data *pdu_data, u16_t handle, ep->status = 0x00; ep->handle = sys_cpu_to_le16(handle); ep->version = ver_ind->version_number; - ep->manufacturer = sys_cpu_to_le16(ver_ind->company_id); - ep->subversion = sys_cpu_to_le16(ver_ind->sub_version_number); + ep->manufacturer = ver_ind->company_id; + ep->subversion = ver_ind->sub_version_number; } #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c index 6fddfe3ac9..e937d6c6b9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -116,7 +117,7 @@ static int init_reset(void) static int prepare_cb(struct lll_prepare_param *prepare_param) { struct lll_adv *lll = prepare_param->param; - u32_t aa = 0x8e89bed6; + u32_t aa = sys_cpu_to_le32(0x8e89bed6); u32_t ticks_at_event; struct evt_hdr *evt; u32_t remainder_us; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index b7b5645530..9da1952779 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "hal/ccm.h" #include "hal/radio.h" @@ -117,7 +118,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param) { struct lll_scan *lll = prepare_param->param; struct node_rx_pdu *node_rx; - u32_t aa = 0x8e89bed6; + u32_t aa = sys_cpu_to_le32(0x8e89bed6); u32_t ticks_at_event; struct evt_hdr *evt; u32_t remainder_us; @@ -702,7 +703,7 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok, if (!IS_ENABLED(CONFIG_BT_CTLR_SCHED_ADVANCED) || lll->conn_win_offset_us == 0) { conn_space_us = conn_offset_us; - pdu_tx->connect_ind.win_offset = 0; + pdu_tx->connect_ind.win_offset = sys_cpu_to_le16(0); } else { conn_space_us = lll->conn_win_offset_us; while ((conn_space_us & ((u32_t)1 << 31)) || @@ -710,13 +711,17 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok, conn_space_us += conn_interval_us; } pdu_tx->connect_ind.win_offset = - (conn_space_us - conn_offset_us) / 1250; + sys_cpu_to_le16((conn_space_us - + conn_offset_us) / 1250); pdu_tx->connect_ind.win_size++; } - pdu_tx->connect_ind.interval = lll_conn->interval; - pdu_tx->connect_ind.latency = lll_conn->latency; - pdu_tx->connect_ind.timeout = lll->conn_timeout; + pdu_tx->connect_ind.interval = + sys_cpu_to_le16(lll_conn->interval); + pdu_tx->connect_ind.latency = + sys_cpu_to_le16(lll_conn->latency); + pdu_tx->connect_ind.timeout = + sys_cpu_to_le16(lll->conn_timeout); memcpy(&pdu_tx->connect_ind.chan_map[0], &lll_conn->data_chan_map[0], sizeof(pdu_tx->connect_ind.chan_map)); diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index 90316aa75b..c88067e4c1 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -82,15 +82,30 @@ struct pdu_adv_connect_ind { u16_t latency; u16_t timeout; u8_t chan_map[5]; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t hop:5; u8_t sca:3; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t sca:3; + u8_t hop:5; +#else +#error "Unsupported endianness" +#endif + } __packed; } __packed; #if defined(CONFIG_BT_CTLR_ADV_EXT) struct pdu_adv_com_ext_adv { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t ext_hdr_len:6; u8_t adv_mode:2; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t adv_mode:2; + u8_t ext_hdr_len:6; +#else +#error "Unsupported endianness" +#endif u8_t ext_hdr_adi_adv_data[254]; } __packed; @@ -101,6 +116,7 @@ enum ext_adv_mode { }; struct ext_adv_hdr { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t adv_addr:1; u8_t tgt_addr:1; u8_t rfu0:1; @@ -109,19 +125,48 @@ struct ext_adv_hdr { u8_t sync_info:1; u8_t tx_pwr:1; u8_t rfu1:1; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t rfu1:1; + u8_t tx_pwr:1; + u8_t sync_info:1; + u8_t aux_ptr:1; + u8_t adi:1; + u8_t rfu0:1; + u8_t tgt_addr:1; + u8_t adv_addr:1; +#else +#error "Unsupported endianness" +#endif } __packed; struct ext_adv_adi { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u16_t did:12; u16_t sid:4; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u16_t sid:4; + u16_t did:12; +#else +#error "Unsupported endianness" +#endif } __packed; struct ext_adv_aux_ptr { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t chan_idx:6; u8_t ca:1; u8_t offs_units:1; u16_t offs:13; u16_t phy:3; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t offs_units:1; + u8_t ca:1; + u8_t chan_idx:6; + u16_t phy:3; + u16_t offs:13; +#else +#error "Unsupported endianness" +#endif } __packed; enum ext_adv_aux_ptr_ca { @@ -141,9 +186,17 @@ enum ext_adv_aux_phy { }; struct ext_adv_sync_info { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u16_t sync_pkt_offs:13; u16_t offs_units:1; u16_t rfu:2; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u16_t rfu:2; + u16_t offs_units:1; + u16_t sync_pkt_offs:13; +#else +#error "Unsupported endianness" +#endif u16_t interval; u8_t sca_chm[5]; u32_t aa; @@ -171,13 +224,23 @@ enum pdu_adv_type { } __packed; struct pdu_adv { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t type:4; u8_t rfu:1; u8_t chan_sel:1; u8_t tx_addr:1; u8_t rx_addr:1; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t rx_addr:1; + u8_t tx_addr:1; + u8_t chan_sel:1; + u8_t rfu:1; + u8_t type:4; +#else +#error "Unsupported endianness" +#endif - u8_t len:8; + u8_t len; union { u8_t payload[0]; @@ -423,13 +486,23 @@ struct profile { #endif /* CONFIG_BT_CTLR_PROFILE_ISR */ struct pdu_data { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u8_t ll_id:2; u8_t nesn:1; u8_t sn:1; u8_t md:1; u8_t rfu:3; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8_t rfu:3; + u8_t md:1; + u8_t sn:1; + u8_t nesn:1; + u8_t ll_id:2; +#else +#error "Unsupported endianness" +#endif - u8_t len:8; + u8_t len; #if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR) u8_t resv:8; /* TODO: remove nRF specific code */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 4ebeaf6a6d..6099d9e4d5 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "hal/ecb.h" #include "hal/ccm.h" @@ -1433,15 +1434,15 @@ static inline void event_conn_upd_init(struct ll_conn *conn, pdu_ctrl_tx->llctrl.conn_update_ind.win_size = conn->llcp.conn_upd.win_size; pdu_ctrl_tx->llctrl.conn_update_ind.win_offset = - conn->llcp.conn_upd.win_offset_us / 1250; + sys_cpu_to_le16(conn->llcp.conn_upd.win_offset_us / 1250); pdu_ctrl_tx->llctrl.conn_update_ind.interval = - conn->llcp.conn_upd.interval; + sys_cpu_to_le16(conn->llcp.conn_upd.interval); pdu_ctrl_tx->llctrl.conn_update_ind.latency = - conn->llcp.conn_upd.latency; + sys_cpu_to_le16(conn->llcp.conn_upd.latency); pdu_ctrl_tx->llctrl.conn_update_ind.timeout = - conn->llcp.conn_upd.timeout; + sys_cpu_to_le16(conn->llcp.conn_upd.timeout); pdu_ctrl_tx->llctrl.conn_update_ind.instant = - conn->llcp.conn_upd.instant; + sys_cpu_to_le16(conn->llcp.conn_upd.instant); #if defined(CONFIG_BT_CTLR_SCHED_ADVANCED) { @@ -1797,7 +1798,7 @@ static inline void event_ch_map_prep(struct ll_conn *conn, &conn->llcp.chan_map.chm[0], sizeof(pdu_ctrl_tx->llctrl.chan_map_ind.chm)); pdu_ctrl_tx->llctrl.chan_map_ind.instant = - conn->llcp.chan_map.instant; + sys_cpu_to_le16(conn->llcp.chan_map.instant); ctrl_tx_enqueue(conn, tx); } @@ -2040,6 +2041,8 @@ static inline void event_vex_prep(struct ll_conn *conn) tx = mem_acquire(&mem_conn_tx_ctrl.free); if (tx) { struct pdu_data *pdu = (void *)tx->pdu; + u16_t cid; + u16_t svn; /* procedure request acked */ conn->llcp_ack = conn->llcp_req; @@ -2056,10 +2059,10 @@ static inline void event_vex_prep(struct ll_conn *conn) PDU_DATA_LLCTRL_TYPE_VERSION_IND; pdu->llctrl.version_ind.version_number = LL_VERSION_NUMBER; - pdu->llctrl.version_ind.company_id = - CONFIG_BT_CTLR_COMPANY_ID; - pdu->llctrl.version_ind.sub_version_number = - CONFIG_BT_CTLR_SUBVERSION_NUMBER; + cid = sys_cpu_to_le16(CONFIG_BT_CTLR_COMPANY_ID); + svn = sys_cpu_to_le16(CONFIG_BT_CTLR_SUBVERSION_NUMBER); + pdu->llctrl.version_ind.company_id = cid; + pdu->llctrl.version_ind.sub_version_number = svn; ctrl_tx_enqueue(conn, tx); @@ -2093,9 +2096,9 @@ static inline void event_vex_prep(struct ll_conn *conn) pdu->llctrl.version_ind.version_number = conn->llcp_version.version_number; pdu->llctrl.version_ind.company_id = - conn->llcp_version.company_id; + sys_cpu_to_le16(conn->llcp_version.company_id); pdu->llctrl.version_ind.sub_version_number = - conn->llcp_version.sub_version_number; + sys_cpu_to_le16(conn->llcp_version.sub_version_number); /* enqueue version ind structure into rx queue */ ll_rx_put(rx->hdr.link, rx); @@ -2130,18 +2133,18 @@ static inline void event_conn_param_req(struct ll_conn *conn, sizeof(struct pdu_data_llctrl_conn_param_req); pdu_ctrl_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ; p = (void *)&pdu_ctrl_tx->llctrl.conn_param_req; - p->interval_min = conn->llcp_conn_param.interval_min; - p->interval_max = conn->llcp_conn_param.interval_max; - p->latency = conn->llcp_conn_param.latency; - p->timeout = conn->llcp_conn_param.timeout; + p->interval_min = sys_cpu_to_le16(conn->llcp_conn_param.interval_min); + p->interval_max = sys_cpu_to_le16(conn->llcp_conn_param.interval_max); + p->latency = sys_cpu_to_le16(conn->llcp_conn_param.latency); + p->timeout = sys_cpu_to_le16(conn->llcp_conn_param.timeout); p->preferred_periodicity = 0; - p->reference_conn_event_count = event_counter; - p->offset0 = 0x0000; - p->offset1 = 0xffff; - p->offset2 = 0xffff; - p->offset3 = 0xffff; - p->offset4 = 0xffff; - p->offset5 = 0xffff; + p->reference_conn_event_count = sys_cpu_to_le16(event_counter); + p->offset0 = sys_cpu_to_le16(0x0000); + p->offset1 = sys_cpu_to_le16(0xffff); + p->offset2 = sys_cpu_to_le16(0xffff); + p->offset3 = sys_cpu_to_le16(0xffff); + p->offset4 = sys_cpu_to_le16(0xffff); + p->offset5 = sys_cpu_to_le16(0xffff); ctrl_tx_enqueue(conn, tx); @@ -2271,20 +2274,24 @@ static inline void event_conn_param_rsp(struct ll_conn *conn) sizeof(struct pdu_data_llctrl_conn_param_rsp); pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP; rsp = (void *)&pdu->llctrl.conn_param_rsp; - rsp->interval_min = conn->llcp_conn_param.interval_min; - rsp->interval_max = conn->llcp_conn_param.interval_max; - rsp->latency = conn->llcp_conn_param.latency; - rsp->timeout = conn->llcp_conn_param.timeout; + rsp->interval_min = + sys_cpu_to_le16(conn->llcp_conn_param.interval_min); + rsp->interval_max = + sys_cpu_to_le16(conn->llcp_conn_param.interval_max); + rsp->latency = + sys_cpu_to_le16(conn->llcp_conn_param.latency); + rsp->timeout = + sys_cpu_to_le16(conn->llcp_conn_param.timeout); rsp->preferred_periodicity = conn->llcp_conn_param.preferred_periodicity; rsp->reference_conn_event_count = - conn->llcp_conn_param.reference_conn_event_count; - rsp->offset0 = conn->llcp_conn_param.offset0; - rsp->offset1 = conn->llcp_conn_param.offset1; - rsp->offset2 = conn->llcp_conn_param.offset2; - rsp->offset3 = conn->llcp_conn_param.offset3; - rsp->offset4 = conn->llcp_conn_param.offset4; - rsp->offset5 = conn->llcp_conn_param.offset5; + sys_cpu_to_le16(conn->llcp_conn_param.reference_conn_event_count); + rsp->offset0 = sys_cpu_to_le16(conn->llcp_conn_param.offset0); + rsp->offset1 = sys_cpu_to_le16(conn->llcp_conn_param.offset1); + rsp->offset2 = sys_cpu_to_le16(conn->llcp_conn_param.offset2); + rsp->offset3 = sys_cpu_to_le16(conn->llcp_conn_param.offset3); + rsp->offset4 = sys_cpu_to_le16(conn->llcp_conn_param.offset4); + rsp->offset5 = sys_cpu_to_le16(conn->llcp_conn_param.offset5); ctrl_tx_enqueue(conn, tx); @@ -2328,10 +2335,10 @@ static inline void event_conn_param_app_req(struct ll_conn *conn) sizeof(struct pdu_data_llctrl_conn_param_req); pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ; p = (void *) &pdu->llctrl.conn_param_req; - p->interval_min = conn->llcp_conn_param.interval_min; - p->interval_max = conn->llcp_conn_param.interval_max; - p->latency = conn->llcp_conn_param.latency; - p->timeout = conn->llcp_conn_param.timeout; + p->interval_min = sys_cpu_to_le16(conn->llcp_conn_param.interval_min); + p->interval_max = sys_cpu_to_le16(conn->llcp_conn_param.interval_max); + p->latency = sys_cpu_to_le16(conn->llcp_conn_param.latency); + p->timeout = sys_cpu_to_le16(conn->llcp_conn_param.timeout); /* enqueue connection parameter request into rx queue */ ll_rx_put(rx->hdr.link, rx); @@ -2812,7 +2819,7 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn, ind = &pdu_ctrl_tx->llctrl.phy_upd_ind; ind->m_to_s_phy = conn->llcp.phy_upd_ind.tx; ind->s_to_m_phy = conn->llcp.phy_upd_ind.rx; - ind->instant = conn->llcp.phy_upd_ind.instant; + ind->instant = sys_cpu_to_le16(conn->llcp.phy_upd_ind.instant); ctrl_tx_enqueue(conn, tx); } else if (((event_counter - conn->llcp.phy_upd_ind.instant) & 0xFFFF) @@ -2866,8 +2873,10 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn, static u8_t conn_upd_recv(struct ll_conn *conn, memq_link_t *link, struct node_rx_pdu **rx, struct pdu_data *pdu) { - if (((pdu->llctrl.conn_update_ind.instant - conn->lll.event_counter) & - 0xFFFF) > 0x7FFF) { + u16_t instant; + + instant = sys_le16_to_cpu(pdu->llctrl.conn_update_ind.instant); + if (((instant - conn->lll.event_counter) & 0xFFFF) > 0x7FFF) { /* Mark for buffer for release */ (*rx)->hdr.type = NODE_RX_TYPE_DC_PDU_RELEASE; @@ -2893,11 +2902,14 @@ static u8_t conn_upd_recv(struct ll_conn *conn, memq_link_t *link, conn->llcp.conn_upd.win_size = pdu->llctrl.conn_update_ind.win_size; conn->llcp.conn_upd.win_offset_us = - pdu->llctrl.conn_update_ind.win_offset * 1250; - conn->llcp.conn_upd.interval = pdu->llctrl.conn_update_ind.interval; - conn->llcp.conn_upd.latency = pdu->llctrl.conn_update_ind.latency; - conn->llcp.conn_upd.timeout = pdu->llctrl.conn_update_ind.timeout; - conn->llcp.conn_upd.instant = pdu->llctrl.conn_update_ind.instant; + sys_le16_to_cpu(pdu->llctrl.conn_update_ind.win_offset) * 1250; + conn->llcp.conn_upd.interval = + sys_le16_to_cpu(pdu->llctrl.conn_update_ind.interval); + conn->llcp.conn_upd.latency = + sys_le16_to_cpu(pdu->llctrl.conn_update_ind.latency); + conn->llcp.conn_upd.timeout = + sys_le16_to_cpu(pdu->llctrl.conn_update_ind.timeout); + conn->llcp.conn_upd.instant = instant; conn->llcp.conn_upd.state = LLCP_CUI_STATE_INPROG; conn->llcp.conn_upd.is_internal = 0; @@ -2924,9 +2936,10 @@ static u8_t chan_map_upd_recv(struct ll_conn *conn, struct node_rx_pdu *rx, struct pdu_data *pdu) { u8_t err = 0; + u16_t instant; - if (((pdu->llctrl.chan_map_ind.instant - conn->lll.event_counter) & - 0xffff) > 0x7fff) { + instant = sys_le16_to_cpu(pdu->llctrl.chan_map_ind.instant); + if (((instant - conn->lll.event_counter) & 0xffff) > 0x7fff) { err = BT_HCI_ERR_INSTANT_PASSED; goto chan_map_upd_recv_exit; @@ -2942,7 +2955,7 @@ static u8_t chan_map_upd_recv(struct ll_conn *conn, struct node_rx_pdu *rx, memcpy(&conn->llcp.chan_map.chm[0], &pdu->llctrl.chan_map_ind.chm[0], sizeof(conn->llcp.chan_map.chm)); - conn->llcp.chan_map.instant = pdu->llctrl.chan_map_ind.instant; + conn->llcp.chan_map.instant = instant; conn->llcp.chan_map.initiate = 0; conn->llcp_type = LLCP_CHAN_MAP; @@ -3309,8 +3322,9 @@ static int version_ind_send(struct ll_conn *conn, struct node_rx_pdu *rx, pdu_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_VERSION_IND; v = &pdu_tx->llctrl.version_ind; v->version_number = LL_VERSION_NUMBER; - v->company_id = CONFIG_BT_CTLR_COMPANY_ID; - v->sub_version_number = CONFIG_BT_CTLR_SUBVERSION_NUMBER; + v->company_id = sys_cpu_to_le16(CONFIG_BT_CTLR_COMPANY_ID); + v->sub_version_number = + sys_cpu_to_le16(CONFIG_BT_CTLR_SUBVERSION_NUMBER); ctrl_tx_sec_enqueue(conn, tx); @@ -3330,8 +3344,9 @@ static int version_ind_send(struct ll_conn *conn, struct node_rx_pdu *rx, v = &pdu_rx->llctrl.version_ind; conn->llcp_version.version_number = v->version_number; - conn->llcp_version.company_id = v->company_id; - conn->llcp_version.sub_version_number = v->sub_version_number; + conn->llcp_version.company_id = sys_le16_to_cpu(v->company_id); + conn->llcp_version.sub_version_number = + sys_le16_to_cpu(v->sub_version_number); conn->llcp_version.rx = 1; return 0; @@ -3639,6 +3654,7 @@ static inline u8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link, struct pdu_data *pdu_rx) { struct pdu_data_llctrl_phy_upd_ind *ind = &pdu_rx->llctrl.phy_upd_ind; + u16_t instant; /* Both tx and rx PHY unchanged */ if (!((ind->m_to_s_phy | ind->s_to_m_phy) & 0x07)) { @@ -3677,7 +3693,8 @@ static inline u8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link, } /* instant passed */ - if (((ind->instant - conn->lll.event_counter) & 0xffff) > 0x7fff) { + instant = sys_le16_to_cpu(ind->instant); + if (((instant - conn->lll.event_counter) & 0xffff) > 0x7fff) { /* Mark for buffer for release */ (*rx)->hdr.type = NODE_RX_TYPE_DC_PDU_RELEASE; @@ -3703,7 +3720,7 @@ static inline u8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link, conn->llcp.phy_upd_ind.tx = ind->s_to_m_phy; conn->llcp.phy_upd_ind.rx = ind->m_to_s_phy; - conn->llcp.phy_upd_ind.instant = ind->instant; + conn->llcp.phy_upd_ind.instant = instant; conn->llcp.phy_upd_ind.initiate = 0; LL_ASSERT(!conn->llcp_rx); @@ -4240,18 +4257,28 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, &pdu_rx->llctrl.conn_param_req; struct lll_conn *lll = &conn->lll; + /* Extract parameters */ + u16_t interval_min = + sys_le16_to_cpu(cpr->interval_min); + u16_t interval_max = + sys_le16_to_cpu(cpr->interval_max); + u16_t latency = + sys_le16_to_cpu(cpr->latency); + u16_t timeout = + sys_le16_to_cpu(cpr->timeout); + u16_t preferred_periodicity = + cpr->preferred_periodicity; + /* Invalid parameters */ - if ((cpr->interval_min < 6) || - (cpr->interval_max > 3200) || - (cpr->interval_min > cpr->interval_max) || - (cpr->latency > 499) || - (cpr->timeout < 10) || - (cpr->timeout > 3200) || - ((cpr->timeout * 4) <= - ((cpr->latency + 1) * - cpr->interval_max)) || - (cpr->preferred_periodicity > - cpr->interval_max)) { + if ((interval_min < 6) || + (interval_max > 3200) || + (interval_min > interval_max) || + (latency > 499) || + (timeout < 10) || + (timeout > 3200) || + ((timeout * 4) <= + ((latency + 1) * interval_max)) || + (preferred_periodicity > interval_max)) { nack = reject_ext_ind_send(conn, *rx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ, BT_HCI_ERR_INVALID_LL_PARAM); @@ -4261,21 +4288,27 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, /* save parameters to be used to select offset */ conn->llcp_conn_param.interval_min = - cpr->interval_min; + interval_min; conn->llcp_conn_param.interval_max = - cpr->interval_max; - conn->llcp_conn_param.latency = cpr->latency; - conn->llcp_conn_param.timeout = cpr->timeout; + interval_max; + conn->llcp_conn_param.latency = latency; + conn->llcp_conn_param.timeout = timeout; conn->llcp_conn_param.preferred_periodicity = - cpr->preferred_periodicity; + preferred_periodicity; conn->llcp_conn_param.reference_conn_event_count = - cpr->reference_conn_event_count; - conn->llcp_conn_param.offset0 = cpr->offset0; - conn->llcp_conn_param.offset1 = cpr->offset1; - conn->llcp_conn_param.offset2 = cpr->offset2; - conn->llcp_conn_param.offset3 = cpr->offset3; - conn->llcp_conn_param.offset4 = cpr->offset4; - conn->llcp_conn_param.offset5 = cpr->offset5; + sys_le16_to_cpu(cpr->reference_conn_event_count); + conn->llcp_conn_param.offset0 = + sys_le16_to_cpu(cpr->offset0); + conn->llcp_conn_param.offset1 = + sys_le16_to_cpu(cpr->offset1); + conn->llcp_conn_param.offset2 = + sys_le16_to_cpu(cpr->offset2); + conn->llcp_conn_param.offset3 = + sys_le16_to_cpu(cpr->offset3); + conn->llcp_conn_param.offset4 = + sys_le16_to_cpu(cpr->offset4); + conn->llcp_conn_param.offset5 = + sys_le16_to_cpu(cpr->offset5); /* enqueue the conn param req, if parameters * changed, else respond. @@ -4333,15 +4366,23 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, &pdu_rx->llctrl.conn_param_req; struct lll_conn *lll = &conn->lll; + /* Extract parameters */ + u16_t interval_min = sys_le16_to_cpu(cpr->interval_min); + u16_t interval_max = sys_le16_to_cpu(cpr->interval_max); + u16_t latency = sys_le16_to_cpu(cpr->latency); + u16_t timeout = sys_le16_to_cpu(cpr->timeout); + u16_t preferred_periodicity = + cpr->preferred_periodicity; + /* Invalid parameters */ - if ((cpr->interval_min < 6) || - (cpr->interval_max > 3200) || - (cpr->interval_min > cpr->interval_max) || - (cpr->latency > 499) || - (cpr->timeout < 10) || (cpr->timeout > 3200) || - ((cpr->timeout * 4) <= ((cpr->latency + 1) * - cpr->interval_max)) || - (cpr->preferred_periodicity > cpr->interval_max)) { + if ((interval_min < 6) || + (interval_max > 3200) || + (interval_min > interval_max) || + (latency > 499) || + (timeout < 10) || (timeout > 3200) || + ((timeout * 4) <= + ((latency + 1) * interval_max)) || + (preferred_periodicity > interval_max)) { nack = reject_ext_ind_send(conn, *rx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ, BT_HCI_ERR_INVALID_LL_PARAM); @@ -4351,20 +4392,26 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, /* resp to be generated by app, for now save * parameters */ - conn->llcp_conn_param.interval_min = cpr->interval_min; - conn->llcp_conn_param.interval_max = cpr->interval_max; - conn->llcp_conn_param.latency = cpr->latency; - conn->llcp_conn_param.timeout = cpr->timeout; + conn->llcp_conn_param.interval_min = interval_min; + conn->llcp_conn_param.interval_max = interval_max; + conn->llcp_conn_param.latency = latency; + conn->llcp_conn_param.timeout = timeout; conn->llcp_conn_param.preferred_periodicity = - cpr->preferred_periodicity; + preferred_periodicity; conn->llcp_conn_param.reference_conn_event_count = - cpr->reference_conn_event_count; - conn->llcp_conn_param.offset0 = cpr->offset0; - conn->llcp_conn_param.offset1 = cpr->offset1; - conn->llcp_conn_param.offset2 = cpr->offset2; - conn->llcp_conn_param.offset3 = cpr->offset3; - conn->llcp_conn_param.offset4 = cpr->offset4; - conn->llcp_conn_param.offset5 = cpr->offset5; + sys_le16_to_cpu(cpr->reference_conn_event_count); + conn->llcp_conn_param.offset0 = + sys_le16_to_cpu(cpr->offset0); + conn->llcp_conn_param.offset1 = + sys_le16_to_cpu(cpr->offset1); + conn->llcp_conn_param.offset2 = + sys_le16_to_cpu(cpr->offset2); + conn->llcp_conn_param.offset3 = + sys_le16_to_cpu(cpr->offset3); + conn->llcp_conn_param.offset4 = + sys_le16_to_cpu(cpr->offset4); + conn->llcp_conn_param.offset5 = + sys_le16_to_cpu(cpr->offset5); /* enqueue the conn param req, if parameters changed, * else respond @@ -4415,15 +4462,23 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, struct pdu_data_llctrl_conn_param_req *cpr = (void *) &pdu_rx->llctrl.conn_param_req; + /* Extract parameters */ + u16_t interval_min = sys_le16_to_cpu(cpr->interval_min); + u16_t interval_max = sys_le16_to_cpu(cpr->interval_max); + u16_t latency = sys_le16_to_cpu(cpr->latency); + u16_t timeout = sys_le16_to_cpu(cpr->timeout); + u16_t preferred_periodicity = + cpr->preferred_periodicity; + /* Invalid parameters */ - if ((cpr->interval_min < 6) || - (cpr->interval_max > 3200) || - (cpr->interval_min > cpr->interval_max) || - (cpr->latency > 499) || - (cpr->timeout < 10) || (cpr->timeout > 3200) || - ((cpr->timeout * 4) <= ((cpr->latency + 1) * - cpr->interval_max)) || - (cpr->preferred_periodicity > cpr->interval_max)) { + if ((interval_min < 6) || + (interval_max > 3200) || + (interval_min > interval_max) || + (latency > 499) || + (timeout < 10) || (timeout > 3200) || + ((timeout * 4) <= + ((latency + 1) * interval_max)) || + (preferred_periodicity > interval_max)) { nack = reject_ext_ind_send(conn, *rx, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP, BT_HCI_ERR_INVALID_LL_PARAM); @@ -4435,20 +4490,26 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx, /* save parameters to be used to select offset */ - conn->llcp_conn_param.interval_min = cpr->interval_min; - conn->llcp_conn_param.interval_max = cpr->interval_max; - conn->llcp_conn_param.latency = cpr->latency; - conn->llcp_conn_param.timeout = cpr->timeout; + conn->llcp_conn_param.interval_min = interval_min; + conn->llcp_conn_param.interval_max = interval_max; + conn->llcp_conn_param.latency = latency; + conn->llcp_conn_param.timeout = timeout; conn->llcp_conn_param.preferred_periodicity = - cpr->preferred_periodicity; + preferred_periodicity; conn->llcp_conn_param.reference_conn_event_count = - cpr->reference_conn_event_count; - conn->llcp_conn_param.offset0 = cpr->offset0; - conn->llcp_conn_param.offset1 = cpr->offset1; - conn->llcp_conn_param.offset2 = cpr->offset2; - conn->llcp_conn_param.offset3 = cpr->offset3; - conn->llcp_conn_param.offset4 = cpr->offset4; - conn->llcp_conn_param.offset5 = cpr->offset5; + sys_le16_to_cpu(cpr->reference_conn_event_count); + conn->llcp_conn_param.offset0 = + sys_le16_to_cpu(cpr->offset0); + conn->llcp_conn_param.offset1 = + sys_le16_to_cpu(cpr->offset1); + conn->llcp_conn_param.offset2 = + sys_le16_to_cpu(cpr->offset2); + conn->llcp_conn_param.offset3 = + sys_le16_to_cpu(cpr->offset3); + conn->llcp_conn_param.offset4 = + sys_le16_to_cpu(cpr->offset4); + conn->llcp_conn_param.offset5 = + sys_le16_to_cpu(cpr->offset5); /* Perform connection update */ conn->llcp_conn_param.state = LLCP_CPR_STATE_RSP; diff --git a/subsys/bluetooth/controller/ll_sw/ull_master.c b/subsys/bluetooth/controller/ll_sw/ull_master.c index c802c2928d..c4cced3ac6 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_master.c +++ b/subsys/bluetooth/controller/ll_sw/ull_master.c @@ -6,6 +6,7 @@ #include #include +#include #include "util/util.h" #include "util/memq.h" @@ -42,7 +43,7 @@ static void ticker_op_stop_scan_cb(u32_t status, void *params); static void ticker_op_cb(u32_t status, void *params); -static u32_t access_addr_get(void); +static void access_addr_get(u8_t access_addr[]); u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, u8_t filter_policy, u8_t peer_addr_type, @@ -55,7 +56,7 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, struct lll_scan *lll; struct ll_conn *conn; memq_link_t *link; - u32_t access_addr; + u8_t access_addr[4]; u32_t err; u8_t hop; @@ -96,7 +97,7 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, conn_lll = &conn->lll; - access_addr = access_addr_get(); + access_addr_get(access_addr); memcpy(conn_lll->access_addr, &access_addr, sizeof(conn_lll->access_addr)); bt_rand(&conn_lll->crc_init[0], 3); @@ -746,7 +747,7 @@ static void ticker_op_cb(u32_t status, void *params) * - It shall have no more than eleven transitions in the least significant 16 * bits. */ -static u32_t access_addr_get(void) +static void access_addr_get(u8_t access_addr[]) { #if defined(CONFIG_BT_CTLR_PHY_CODED) u8_t transitions_lsb16; @@ -755,7 +756,7 @@ static u32_t access_addr_get(void) u8_t consecutive_cnt; u8_t consecutive_bit; u32_t adv_aa_check; - u32_t access_addr; + u32_t aa; u8_t transitions; u8_t bit_idx; u8_t retry; @@ -765,7 +766,8 @@ again: LL_ASSERT(retry); retry--; - bt_rand(&access_addr, sizeof(u32_t)); + bt_rand(access_addr, 4); + aa = sys_get_le32(access_addr); bit_idx = 31; transitions = 0; @@ -774,7 +776,7 @@ again: ones_count_lsb8 = 0; transitions_lsb16 = 0; #endif /* CONFIG_BT_CTLR_PHY_CODED */ - consecutive_bit = (access_addr >> bit_idx) & 0x01; + consecutive_bit = (aa >> bit_idx) & 0x01; while (bit_idx--) { #if defined(CONFIG_BT_CTLR_PHY_CODED) u8_t transitions_lsb16_prev = transitions_lsb16; @@ -783,7 +785,7 @@ again: u8_t transitions_prev = transitions; u8_t bit; - bit = (access_addr >> bit_idx) & 0x01; + bit = (aa >> bit_idx) & 0x01; if (bit == consecutive_bit) { consecutive_cnt++; } else { @@ -822,7 +824,7 @@ again: ((bit_idx < 28) && (transitions < 2))))) { if (consecutive_bit) { consecutive_bit = 0; - access_addr &= ~BIT(bit_idx); + aa &= ~BIT(bit_idx); #if defined(CONFIG_BT_CTLR_PHY_CODED) if (bit_idx < 8) { ones_count_lsb8--; @@ -830,7 +832,7 @@ again: #endif /* CONFIG_BT_CTLR_PHY_CODED */ } else { consecutive_bit = 1; - access_addr |= BIT(bit_idx); + aa |= BIT(bit_idx); #if defined(CONFIG_BT_CTLR_PHY_CODED) if (bit_idx < 8) { ones_count_lsb8++; @@ -869,9 +871,9 @@ again: #endif /* CONFIG_BT_CTLR_PHY_CODED */ 0) { if (consecutive_bit) { - access_addr &= ~(BIT(bit_idx + 1) - 1); + aa &= ~(BIT(bit_idx + 1) - 1); } else { - access_addr |= (BIT(bit_idx + 1) - 1); + aa |= (BIT(bit_idx + 1) - 1); } break; @@ -882,17 +884,17 @@ again: * It shall not be a sequence that differs from the advertising channel * packets Access Address by only one bit. */ - adv_aa_check = access_addr ^ 0x8e89bed6; + adv_aa_check = aa ^ 0x8e89bed6; if (util_ones_count_get((u8_t *)&adv_aa_check, sizeof(adv_aa_check)) <= 1) { goto again; } /* It shall not have all four octets equal. */ - if (!((access_addr & 0xFFFF) ^ (access_addr >> 16)) && - !((access_addr & 0xFF) ^ (access_addr >> 24))) { + if (!((aa & 0xFFFF) ^ (aa >> 16)) && + !((aa & 0xFF) ^ (aa >> 24))) { goto again; } - return access_addr; + sys_put_le32(aa, access_addr); } diff --git a/subsys/bluetooth/controller/ll_sw/ull_slave.c b/subsys/bluetooth/controller/ll_sw/ull_slave.c index 74eb51e5ce..19bdcb429a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_slave.c +++ b/subsys/bluetooth/controller/ll_sw/ull_slave.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "hal/ticker.h" @@ -60,6 +61,7 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx, u8_t peer_addr_type; u16_t win_offset; u16_t timeout; + u16_t interval; u8_t chan_sel; ((struct lll_adv *)ftr->param)->conn = NULL; @@ -76,11 +78,12 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx, lll->data_chan_count = util_ones_count_get(&lll->data_chan_map[0], sizeof(lll->data_chan_map)); lll->data_chan_hop = pdu_adv->connect_ind.hop; - lll->interval = pdu_adv->connect_ind.interval; - lll->latency = pdu_adv->connect_ind.latency; + interval = sys_le16_to_cpu(pdu_adv->connect_ind.interval); + lll->interval = interval; + lll->latency = sys_le16_to_cpu(pdu_adv->connect_ind.latency); - win_offset = pdu_adv->connect_ind.win_offset; - conn_interval_us = pdu_adv->connect_ind.interval * 1250; + win_offset = sys_le16_to_cpu(pdu_adv->connect_ind.win_offset); + conn_interval_us = interval * 1250; /* calculate the window widening */ lll->slave.sca = pdu_adv->connect_ind.sca; @@ -92,9 +95,9 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx, lll->slave.window_size_event_us = pdu_adv->connect_ind.win_size * 1250; /* procedure timeouts */ + timeout = sys_le16_to_cpu(pdu_adv->connect_ind.timeout); conn->supervision_reload = - RADIO_CONN_EVENTS((pdu_adv->connect_ind.timeout * 10 * 1000), - conn_interval_us); + RADIO_CONN_EVENTS((timeout * 10 * 1000), conn_interval_us); conn->procedure_reload = RADIO_CONN_EVENTS((40 * 1000 * 1000), conn_interval_us); @@ -120,7 +123,6 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx, chan_sel = pdu_adv->chan_sel; peer_addr_type = pdu_adv->tx_addr; memcpy(peer_addr, pdu_adv->connect_ind.init_addr, BDADDR_SIZE); - timeout = pdu_adv->connect_ind.timeout; cc = (void *)pdu_adv; cc->status = 0;