zephyr/subsys/bluetooth/controller/ll_sw/pdu.h

419 lines
9.2 KiB
C

/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _PDU_H_
#define _PDU_H_
#define BDADDR_SIZE 6
/* PDU Sizes */
#define PDU_AC_PAYLOAD_SIZE_MAX 37
#define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \
PDU_AC_PAYLOAD_SIZE_MAX)
#define PDU_EM_SIZE_MAX offsetof(struct pdu_data, lldata)
struct pdu_adv_adv_ind {
u8_t addr[BDADDR_SIZE];
u8_t data[31];
} __packed;
struct pdu_adv_direct_ind {
u8_t adv_addr[BDADDR_SIZE];
u8_t tgt_addr[BDADDR_SIZE];
} __packed;
struct pdu_adv_scan_rsp {
u8_t addr[BDADDR_SIZE];
u8_t data[31];
} __packed;
struct pdu_adv_scan_req {
u8_t scan_addr[BDADDR_SIZE];
u8_t adv_addr[BDADDR_SIZE];
} __packed;
struct pdu_adv_connect_ind {
u8_t init_addr[BDADDR_SIZE];
u8_t adv_addr[BDADDR_SIZE];
struct {
u8_t access_addr[4];
u8_t crc_init[3];
u8_t win_size;
u16_t win_offset;
u16_t interval;
u16_t latency;
u16_t timeout;
u8_t chan_map[5];
u8_t hop:5;
u8_t sca:3;
} __packed;
} __packed;
#if defined(CONFIG_BT_CTLR_ADV_EXT)
struct pdu_adv_com_ext_adv {
u8_t ext_hdr_len:6;
u8_t adv_mode:2;
u8_t ext_hdr_adi_adv_data[254];
} __packed;
enum ext_adv_mode {
EXT_ADV_MODE_NON_CONN_NON_SCAN = 0x00,
EXT_ADV_MODE_CONN_NON_SCAN = 0x01,
EXT_ADV_MODE_NON_CONN_SCAN = 0x02,
};
struct ext_adv_hdr {
u8_t adv_addr:1;
u8_t tgt_addr:1;
u8_t rfu0:1;
u8_t adi:1;
u8_t aux_ptr:1;
u8_t sync_info:1;
u8_t tx_pwr:1;
u8_t rfu1:1;
} __packed;
struct ext_adv_adi {
u16_t did:12;
u16_t sid:4;
} __packed;
struct ext_adv_aux_ptr {
u8_t chan_idx:6;
u8_t ca:1;
u8_t offs_units:1;
u16_t offs:13;
u16_t phy:3;
} __packed;
enum ext_adv_aux_ptr_ca {
EXT_ADV_AUX_PTR_CA_500_PPM = 0x00,
EXT_ADV_AUX_PTR_CA_50_PPM = 0x01,
};
enum ext_adv_offs_units {
EXT_ADV_AUX_PTR_OFFS_UNITS_30 = 0x00,
EXT_ADV_AUX_PTR_OFFS_UNITS_300 = 0x01,
};
enum ext_adv_aux_phy {
EXT_ADV_AUX_PHY_LE_1M = 0x00,
EXT_ADV_AUX_PHY_LE_2M = 0x01,
EXT_ADV_AUX_PHY_LE_COD = 0x02,
};
struct ext_adv_sync_info {
u16_t sync_pkt_offs:13;
u16_t offs_units:1;
u16_t rfu:2;
u16_t interval;
u8_t sca_chm[5];
u32_t aa;
u8_t crc_init[3];
u16_t evt_cntr;
} __packed;
#endif /* CONFIG_BT_CTLR_ADV_EXT */
enum pdu_adv_type {
PDU_ADV_TYPE_ADV_IND = 0x00,
PDU_ADV_TYPE_DIRECT_IND = 0x01,
PDU_ADV_TYPE_NONCONN_IND = 0x02,
PDU_ADV_TYPE_SCAN_REQ = 0x03,
PDU_ADV_TYPE_AUX_SCAN_REQ = PDU_ADV_TYPE_SCAN_REQ,
PDU_ADV_TYPE_SCAN_RSP = 0x04,
PDU_ADV_TYPE_CONNECT_IND = 0x05,
PDU_ADV_TYPE_AUX_CONNECT_REQ = PDU_ADV_TYPE_CONNECT_IND,
PDU_ADV_TYPE_SCAN_IND = 0x06,
PDU_ADV_TYPE_EXT_IND = 0x07,
PDU_ADV_TYPE_AUX_ADV_IND = PDU_ADV_TYPE_EXT_IND,
PDU_ADV_TYPE_AUX_SCAN_RSP = PDU_ADV_TYPE_EXT_IND,
PDU_ADV_TYPE_AUX_SYNC_IND = PDU_ADV_TYPE_EXT_IND,
PDU_ADV_TYPE_AUX_CHAIN_IND = PDU_ADV_TYPE_EXT_IND,
PDU_ADV_TYPE_AUX_CONNECT_RSP = 0x08,
} __packed;
struct pdu_adv {
u8_t type:4;
u8_t rfu:1;
u8_t chan_sel:1;
u8_t tx_addr:1;
u8_t rx_addr:1;
u8_t len:8;
union {
u8_t payload[0];
struct pdu_adv_adv_ind adv_ind;
struct pdu_adv_direct_ind direct_ind;
struct pdu_adv_scan_req scan_req;
struct pdu_adv_scan_rsp scan_rsp;
struct pdu_adv_connect_ind connect_ind;
#if defined(CONFIG_BT_CTLR_ADV_EXT)
struct pdu_adv_com_ext_adv adv_ext_ind;
#endif /* CONFIG_BT_CTLR_ADV_EXT */
} __packed;
} __packed;
enum pdu_data_llid {
PDU_DATA_LLID_RESV = 0x00,
PDU_DATA_LLID_DATA_CONTINUE = 0x01,
PDU_DATA_LLID_DATA_START = 0x02,
PDU_DATA_LLID_CTRL = 0x03,
};
enum pdu_data_llctrl_type {
PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND = 0x00,
PDU_DATA_LLCTRL_TYPE_CHAN_MAP_IND = 0x01,
PDU_DATA_LLCTRL_TYPE_TERMINATE_IND = 0x02,
PDU_DATA_LLCTRL_TYPE_ENC_REQ = 0x03,
PDU_DATA_LLCTRL_TYPE_ENC_RSP = 0x04,
PDU_DATA_LLCTRL_TYPE_START_ENC_REQ = 0x05,
PDU_DATA_LLCTRL_TYPE_START_ENC_RSP = 0x06,
PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP = 0x07,
PDU_DATA_LLCTRL_TYPE_FEATURE_REQ = 0x08,
PDU_DATA_LLCTRL_TYPE_FEATURE_RSP = 0x09,
PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ = 0x0A,
PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP = 0x0B,
PDU_DATA_LLCTRL_TYPE_VERSION_IND = 0x0C,
PDU_DATA_LLCTRL_TYPE_REJECT_IND = 0x0D,
PDU_DATA_LLCTRL_TYPE_SLAVE_FEATURE_REQ = 0x0E,
PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ = 0x0F,
PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP = 0x10,
PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND = 0x11,
PDU_DATA_LLCTRL_TYPE_PING_REQ = 0x12,
PDU_DATA_LLCTRL_TYPE_PING_RSP = 0x13,
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ = 0x14,
PDU_DATA_LLCTRL_TYPE_LENGTH_RSP = 0x15,
PDU_DATA_LLCTRL_TYPE_PHY_REQ = 0x16,
PDU_DATA_LLCTRL_TYPE_PHY_RSP = 0x17,
PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND = 0x18,
PDU_DATA_LLCTRL_TYPE_MIN_USED_CHAN_IND = 0x19,
};
struct pdu_data_llctrl_conn_update_ind {
u8_t win_size;
u16_t win_offset;
u16_t interval;
u16_t latency;
u16_t timeout;
u16_t instant;
} __packed;
struct pdu_data_llctrl_chan_map_ind {
u8_t chm[5];
u16_t instant;
} __packed;
struct pdu_data_llctrl_terminate_ind {
u8_t error_code;
} __packed;
struct pdu_data_llctrl_enc_req {
u8_t rand[8];
u8_t ediv[2];
u8_t skdm[8];
u8_t ivm[4];
} __packed;
struct pdu_data_llctrl_enc_rsp {
u8_t skds[8];
u8_t ivs[4];
} __packed;
struct pdu_data_llctrl_start_enc_req {
/* no members */
} __packed;
struct pdu_data_llctrl_start_enc_rsp {
/* no members */
} __packed;
struct pdu_data_llctrl_unknown_rsp {
u8_t type;
} __packed;
struct pdu_data_llctrl_feature_req {
u8_t features[8];
} __packed;
struct pdu_data_llctrl_feature_rsp {
u8_t features[8];
} __packed;
struct pdu_data_llctrl_pause_enc_req {
/* no members */
} __packed;
struct pdu_data_llctrl_pause_enc_rsp {
/* no members */
} __packed;
struct pdu_data_llctrl_version_ind {
u8_t version_number;
u16_t company_id;
u16_t sub_version_number;
} __packed;
struct pdu_data_llctrl_reject_ind {
u8_t error_code;
} __packed;
struct pdu_data_llctrl_slave_feature_req {
u8_t features[8];
} __packed;
struct pdu_data_llctrl_conn_param_req {
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
u8_t preferred_periodicity;
u16_t reference_conn_event_count;
u16_t offset0;
u16_t offset1;
u16_t offset2;
u16_t offset3;
u16_t offset4;
u16_t offset5;
} __packed;
struct pdu_data_llctrl_conn_param_rsp {
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
u8_t preferred_periodicity;
u16_t reference_conn_event_count;
u16_t offset0;
u16_t offset1;
u16_t offset2;
u16_t offset3;
u16_t offset4;
u16_t offset5;
} __packed;
struct pdu_data_llctrl_reject_ext_ind {
u8_t reject_opcode;
u8_t error_code;
} __packed;
struct pdu_data_llctrl_ping_req {
/* no members */
} __packed;
struct pdu_data_llctrl_ping_rsp {
/* no members */
} __packed;
struct pdu_data_llctrl_length_req {
u16_t max_rx_octets;
u16_t max_rx_time;
u16_t max_tx_octets;
u16_t max_tx_time;
} __packed;
struct pdu_data_llctrl_length_rsp {
u16_t max_rx_octets;
u16_t max_rx_time;
u16_t max_tx_octets;
u16_t max_tx_time;
} __packed;
struct pdu_data_llctrl_phy_req {
u8_t tx_phys;
u8_t rx_phys;
} __packed;
struct pdu_data_llctrl_phy_rsp {
u8_t tx_phys;
u8_t rx_phys;
} __packed;
struct pdu_data_llctrl_phy_upd_ind {
u8_t m_to_s_phy;
u8_t s_to_m_phy;
u16_t instant;
} __packed;
struct pdu_data_llctrl_min_used_chans_ind {
u8_t phys;
u8_t min_used_chans;
} __packed;
struct pdu_data_llctrl {
u8_t opcode;
union {
struct pdu_data_llctrl_conn_update_ind conn_update_ind;
struct pdu_data_llctrl_chan_map_ind chan_map_ind;
struct pdu_data_llctrl_terminate_ind terminate_ind;
struct pdu_data_llctrl_enc_req enc_req;
struct pdu_data_llctrl_enc_rsp enc_rsp;
struct pdu_data_llctrl_start_enc_req start_enc_req;
struct pdu_data_llctrl_start_enc_rsp start_enc_rsp;
struct pdu_data_llctrl_unknown_rsp unknown_rsp;
struct pdu_data_llctrl_feature_req feature_req;
struct pdu_data_llctrl_feature_rsp feature_rsp;
struct pdu_data_llctrl_pause_enc_req pause_enc_req;
struct pdu_data_llctrl_pause_enc_rsp pause_enc_rsp;
struct pdu_data_llctrl_version_ind version_ind;
struct pdu_data_llctrl_reject_ind reject_ind;
struct pdu_data_llctrl_slave_feature_req slave_feature_req;
struct pdu_data_llctrl_conn_param_req conn_param_req;
struct pdu_data_llctrl_conn_param_rsp conn_param_rsp;
struct pdu_data_llctrl_reject_ext_ind reject_ext_ind;
struct pdu_data_llctrl_ping_req ping_req;
struct pdu_data_llctrl_ping_rsp ping_rsp;
struct pdu_data_llctrl_length_req length_req;
struct pdu_data_llctrl_length_rsp length_rsp;
struct pdu_data_llctrl_phy_req phy_req;
struct pdu_data_llctrl_phy_rsp phy_rsp;
struct pdu_data_llctrl_phy_upd_ind phy_upd_ind;
struct pdu_data_llctrl_min_used_chans_ind min_used_chans_ind;
} __packed;
} __packed;
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
struct profile {
u8_t lcur;
u8_t lmin;
u8_t lmax;
u8_t cur;
u8_t min;
u8_t max;
} __packed;
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
struct pdu_data {
u8_t ll_id:2;
u8_t nesn:1;
u8_t sn:1;
u8_t md:1;
u8_t rfu:3;
u8_t len:8;
#if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR)
u8_t resv:8; /* TODO: remove nRF specific code */
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH_CLEAR */
union {
struct pdu_data_llctrl llctrl;
u8_t lldata[0];
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
u8_t rssi;
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
struct profile profile;
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
} __packed;
} __packed;
#endif /* _PDU_H_ */