Bluetooth: controller: Add Read TX Power commands

Although the current BLE controller only supports a single TX power (0
dBm), the qualification tests require the 2 Read TX Power to be
present and supported in the controller, so implement them while
returning always 0 dBm.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2017-08-23 15:25:03 +02:00
commit a5fcafa155
4 changed files with 77 additions and 1 deletions

View file

@ -502,6 +502,20 @@ struct bt_hci_write_local_name {
#define BT_BREDR_SCAN_INQUIRY 0x01 #define BT_BREDR_SCAN_INQUIRY 0x01
#define BT_BREDR_SCAN_PAGE 0x02 #define BT_BREDR_SCAN_PAGE 0x02
#define BT_TX_POWER_LEVEL_CURRENT 0x00
#define BT_TX_POWER_LEVEL_MAX 0x01
#define BT_HCI_OP_READ_TX_POWER_LEVEL BT_OP(BT_OGF_BASEBAND, 0x002d)
struct bt_hci_cp_read_tx_power_level {
u16_t handle;
u8_t type;
} __packed;
struct bt_hci_rp_read_tx_power_level {
u8_t status;
u16_t handle;
s8_t tx_power_level;
} __packed;
#define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00 #define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00
#define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01 #define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01
#define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031) #define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031)

View file

@ -353,6 +353,24 @@ static void write_auth_payload_timeout(struct net_buf *buf,
} }
#endif /* CONFIG_BT_CTLR_LE_PING */ #endif /* CONFIG_BT_CTLR_LE_PING */
static void read_tx_power_level(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_cp_read_tx_power_level *cmd = (void *)buf->data;
struct bt_hci_rp_read_tx_power_level *rp;
u32_t status;
u16_t handle;
u8_t type;
handle = sys_le16_to_cpu(cmd->handle);
type = cmd->type;
rp = cmd_complete(evt, sizeof(*rp));
status = ll_tx_power_level_get(handle, type, &rp->tx_power_level);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_UNKNOWN_CONN_ID;
rp->handle = sys_cpu_to_le16(handle);
}
static int ctrl_bb_cmd_handle(u16_t ocf, struct net_buf *cmd, static int ctrl_bb_cmd_handle(u16_t ocf, struct net_buf *cmd,
struct net_buf **evt) struct net_buf **evt)
{ {
@ -369,6 +387,10 @@ static int ctrl_bb_cmd_handle(u16_t ocf, struct net_buf *cmd,
set_event_mask_page_2(cmd, evt); set_event_mask_page_2(cmd, evt);
break; break;
case BT_OCF(BT_HCI_OP_READ_TX_POWER_LEVEL):
read_tx_power_level(cmd, evt);
break;
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
case BT_OCF(BT_HCI_OP_SET_CTL_TO_HOST_FLOW): case BT_OCF(BT_HCI_OP_SET_CTL_TO_HOST_FLOW):
set_ctl_to_host_flow(cmd, evt); set_ctl_to_host_flow(cmd, evt);
@ -427,11 +449,12 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
rp->commands[2] |= BIT(7); rp->commands[2] |= BIT(7);
/* Set Event Mask, and Reset. */ /* Set Event Mask, and Reset. */
rp->commands[5] |= BIT(6) | BIT(7); rp->commands[5] |= BIT(6) | BIT(7);
/* Read TX Power Level. */
rp->commands[10] |= BIT(2);
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) #if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
/* Set FC, Host Buffer Size and Host Num Completed */ /* Set FC, Host Buffer Size and Host Num Completed */
rp->commands[10] |= BIT(5) | BIT(6) | BIT(7); rp->commands[10] |= BIT(5) | BIT(6) | BIT(7);
#endif #endif
/* Read Local Version Info, Read Local Supported Features. */ /* Read Local Version Info, Read Local Supported Features. */
rp->commands[14] |= BIT(3) | BIT(5); rp->commands[14] |= BIT(3) | BIT(5);
/* Read BD ADDR. */ /* Read BD ADDR. */
@ -514,6 +537,8 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
/* LE Read Local P256 Public Key and LE Generate DH Key*/ /* LE Read Local P256 Public Key and LE Generate DH Key*/
rp->commands[34] |= BIT(1) | BIT(2); rp->commands[34] |= BIT(1) | BIT(2);
#endif #endif
/* LE Read TX Power. */
rp->commands[38] |= BIT(7);
} }
static void read_local_features(struct net_buf *buf, struct net_buf **evt) static void read_local_features(struct net_buf *buf, struct net_buf **evt)
@ -1294,6 +1319,15 @@ static void le_set_privacy_mode(struct net_buf *buf, struct net_buf **evt)
} }
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */
static void le_read_tx_power(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_le_read_tx_power *rp;
rp = cmd_complete(evt, sizeof(*rp));
rp->status = 0x00;
ll_tx_power_get(&rp->min_tx_power, &rp->max_tx_power);
}
static int controller_cmd_handle(u16_t ocf, struct net_buf *cmd, static int controller_cmd_handle(u16_t ocf, struct net_buf *cmd,
struct net_buf **evt) struct net_buf **evt)
{ {
@ -1486,6 +1520,8 @@ static int controller_cmd_handle(u16_t ocf, struct net_buf *cmd,
break; break;
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */
case BT_OCF(BT_HCI_OP_LE_READ_TX_POWER):
le_read_tx_power(cmd, evt);
default: default:
return -EINVAL; return -EINVAL;

View file

@ -73,6 +73,8 @@ u32_t ll_version_ind_send(u16_t handle);
u32_t ll_terminate_ind_send(u16_t handle, u8_t reason); u32_t ll_terminate_ind_send(u16_t handle, u8_t reason);
void ll_timeslice_ticker_id_get(u8_t * const instance_index, u8_t * const user_id); void ll_timeslice_ticker_id_get(u8_t * const instance_index, u8_t * const user_id);
u32_t ll_rssi_get(u16_t handle, u8_t *rssi); u32_t ll_rssi_get(u16_t handle, u8_t *rssi);
u32_t ll_tx_power_level_get(u16_t handle, u8_t type, s8_t *tx_power_level);
void ll_tx_power_get(s8_t *min, s8_t *max);
#if defined(CONFIG_BT_CTLR_LE_PING) #if defined(CONFIG_BT_CTLR_LE_PING)
u32_t ll_apto_get(u16_t handle, u16_t *apto); u32_t ll_apto_get(u16_t handle, u16_t *apto);

View file

@ -9743,6 +9743,30 @@ u32_t ll_terminate_ind_send(u16_t handle, u8_t reason)
return 0; return 0;
} }
u32_t ll_tx_power_level_get(u16_t handle, u8_t type, s8_t *tx_power_level)
{
struct connection *conn;
conn = connection_get(handle);
if (!conn) {
return 1;
}
/*TODO: check type here for current or maximum */
/* We only support one TX Power Level: 0dBm */
*tx_power_level = 0;
return 0;
}
void ll_tx_power_get(s8_t *min, s8_t *max)
{
/* We only support one TX Power Level: 0dBm */
*min = 0;
*max = 0;
}
#if defined(CONFIG_BT_CTLR_CONN_RSSI) #if defined(CONFIG_BT_CTLR_CONN_RSSI)
u32_t ll_rssi_get(u16_t handle, u8_t *rssi) u32_t ll_rssi_get(u16_t handle, u8_t *rssi)
{ {