Bluetooth: Controller: Switch to Zephyr's hci.h for cmd handling

Continue using Zephyr's include/bluetooth/hci.h for HCI command
handling in more of the commands.
This commit ports the LE controller commands to hci.h.
This is the third commit in a series that transitions from
the structures in hci.c to the ones in hci.h.

Jira: ZEP-726

Change-Id: I3f11cca1da4aa6a20cce9706362818f8f6c87b0a
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2016-09-09 10:02:19 +02:00 committed by Johan Hedberg
commit 21b3fa240d

View file

@ -963,375 +963,502 @@ static int info_cmd_handle(uint8_t ocf, uint8_t *cp, uint8_t *len,
return 0; return 0;
} }
static int controller_cmd_handle(uint8_t ocf, struct hci_cmd *cmd, uint8_t *len, static void le_set_event_mask(uint8_t *cp, struct bt_hci_evt_hdr *evt)
struct hci_evt *evt)
{ {
uint32_t status; /** TODO */
uint32_t error_code;
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_read_buffer_size(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_read_buffer_size *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
rp->le_max_len = RADIO_LL_LENGTH_OCTETS_RX_MAX;
rp->le_max_num = RADIO_PACKET_COUNT_TX_MAX;
}
static void le_read_local_features(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_read_local_features *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
memset(&rp->features[0], 0x00, sizeof(rp->features));
rp->features[0] = RADIO_BLE_FEATURES;
}
static void le_set_random_address(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_random_address *cmd = (void *)cp;
ll_address_set(1, &cmd->bdaddr.val[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_set_adv_param(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_adv_param *cmd = (void *)cp;
uint8_t const c_adv_type[] = { uint8_t const c_adv_type[] = {
PDU_ADV_TYPE_ADV_IND, PDU_ADV_TYPE_DIRECT_IND, PDU_ADV_TYPE_ADV_IND, PDU_ADV_TYPE_DIRECT_IND,
PDU_ADV_TYPE_SCAN_IND, PDU_ADV_TYPE_NONCONN_IND }; PDU_ADV_TYPE_SCAN_IND, PDU_ADV_TYPE_NONCONN_IND };
struct hci_evt_cmd_cmplt *cc;
union hci_evt_cmd_cmplt_params *ccp;
struct hci_cmd_le_create_conn *le_cc;
struct hci_cmd_le_remote_conn_param_req_reply *le_cp_req_rep;
struct hci_cmd_le_remote_conn_param_req_neg_reply *le_cp_req_neg_rep;
cc = &evt->params.cmd_cmplt; ll_adv_params_set(cmd->min_interval, c_adv_type[cmd->type],
ccp = &evt->params.cmd_cmplt.params; cmd->own_addr_type, cmd->direct_addr.type,
switch (cmd->opcode.ocf) { &cmd->direct_addr.a.val[0], cmd->channel_map,
cmd->filter_policy);
case HCI_OCF_LE_SET_EVENT_MASK: evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_event_mask);
ccp->set_event_mask.status = HCI_EVT_ERROR_CODE_SUCCESS; HCI_CC_ST(evt)->status = 0x00;
}
static void le_read_adv_ch_tx_power(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_read_ch_tx_power *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
rp->tx_power_level = 0;
}
static void le_set_adv_data(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_adv_data *cmd = (void *)cp;
ll_adv_data_set(cmd->len, &cmd->data[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_set_scan_rsp_data(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_scan_rsp_data *cmd = (void *)cp;
ll_scan_data_set(cmd->len, &cmd->data[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_set_adv_enable(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_adv_enable *cmd = (void *)cp;
uint32_t status;
status = ll_adv_enable(cmd->enable);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_set_scan_params(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_scan_params *cmd = (void *)cp;
ll_scan_params_set(cmd->scan_type, cmd->interval, cmd->window,
cmd->addr_type, cmd->filter_policy);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_set_scan_enable(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_scan_enable *cmd = (void *)cp;
uint32_t status;
status = ll_scan_enable(cmd->enable);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_create_connection(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_create_conn *cmd = (void *)cp;
uint32_t status;
status = ll_create_connection(cmd->scan_interval,
cmd->scan_window,
cmd->filter_policy,
cmd->peer_addr.type,
&cmd->peer_addr.a.val[0],
cmd->own_addr_type,
cmd->conn_interval_max,
cmd->conn_latency,
cmd->supervision_timeout);
evt->evt = BT_HCI_EVT_CMD_STATUS;
evt->len = sizeof(struct bt_hci_evt_cmd_status);
HCI_CS(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_create_conn_cancel(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
uint32_t status;
status = radio_connect_disable();
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_read_wl_size(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_read_wl_size *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
rp->wl_size = 8;
}
static void le_clear_wl(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
radio_filter_clear();
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = 0x00;
}
static void le_add_dev_to_wl(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_add_dev_to_wl *cmd = (void *)cp;
uint32_t status;
status = radio_filter_add(cmd->addr.type, &cmd->addr.a.val[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = (!status) ? 0x00 :
BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
static void le_conn_update(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct hci_cp_le_conn_update *cmd = (void *)cp;
uint32_t status;
/** @todo if peer supports LE Conn Param Req,
* use Req cmd (1) instead of Initiate cmd (0).
*/
status = radio_conn_update(cmd->handle, 0, 0, cmd->conn_interval_max,
cmd->conn_latency, cmd->supervision_timeout);
evt->evt = BT_HCI_EVT_CMD_STATUS;
evt->len = sizeof(struct bt_hci_evt_cmd_status);
HCI_CS(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_set_host_ch_classif(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_host_ch_classif *cmd = (void *)cp;
uint32_t status;
status = radio_chm_update(&cmd->ch_map[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = HCI_CC_LEN(bt_hci_evt_cc_status);
HCI_CC_ST(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_read_remote_features(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_read_remote_features *cmd = (void *)cp;
uint32_t status;
status = radio_feature_req_send(cmd->handle);
evt->evt = BT_HCI_EVT_CMD_STATUS;
evt->len = sizeof(struct bt_hci_evt_cmd_status);
HCI_CS(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_encrypt(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_encrypt *cmd = (void *)cp;
struct bt_hci_rp_le_encrypt *rp = HCI_CC_RP(evt);
ecb_encrypt(&cmd->key[0], &cmd->plaintext[0], &rp->enc_data[0], 0);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
}
static void le_rand(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_rand *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
/** TODO fill rand */
}
static void le_start_encryption(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_start_encryption *cmd = (void *)cp;
uint32_t status;
status = radio_enc_req_send(cmd->handle,
(uint8_t *)&cmd->rand,
(uint8_t *)&cmd->ediv,
&cmd->ltk[0]);
evt->evt = BT_HCI_EVT_CMD_STATUS;
evt->len = sizeof(struct bt_hci_evt_cmd_status);
HCI_CS(evt)->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
}
static void le_ltk_req_reply(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_ltk_req_reply *cmd = (void *)cp;
struct bt_hci_rp_le_ltk_req_reply *rp = HCI_CC_RP(evt);
uint32_t status;
status = radio_start_enc_req_send(cmd->handle, 0x00, &cmd->ltk[0]);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
rp->handle = cmd->handle;
}
static void le_ltk_req_neg_reply(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_ltk_req_neg_reply *cmd = (void *)cp;
struct bt_hci_rp_le_ltk_req_neg_reply *rp = HCI_CC_RP(evt);
uint32_t status;
status = radio_start_enc_req_send(cmd->handle,
BT_HCI_ERR_PIN_OR_KEY_MISSING, NULL);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
rp->handle = cmd->handle;
}
static void le_read_supp_states(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_rp_le_read_supp_states *rp = HCI_CC_RP(evt);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = 0x00;
sys_put_le64(0x000003ffffffffff, rp->le_states);
}
static void le_conn_param_req_reply(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_conn_param_req_reply *cmd = (void *)cp;
struct bt_hci_rp_le_conn_param_req_reply *rp = HCI_CC_RP(evt);
uint32_t status;
status = radio_conn_update(cmd->handle, 2, 0,
cmd->interval_max,
cmd->latency,
cmd->timeout);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
rp->handle = cmd->handle;
}
static void le_conn_param_req_neg_reply(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_conn_param_req_neg_reply *cmd = (void *)cp;
struct bt_hci_rp_le_conn_param_req_neg_reply *rp = HCI_CC_RP(evt);
uint32_t status;
status = radio_conn_update(cmd->handle, 2, cmd->reason, 0, 0, 0);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
rp->handle = cmd->handle;
}
static void le_set_data_len(uint8_t *cp, struct bt_hci_evt_hdr *evt)
{
struct bt_hci_cp_le_set_data_len *cmd = (void *)cp;
struct bt_hci_rp_le_set_data_len *rp = HCI_CC_RP(evt);
uint32_t status;
/** @todo add reject_ext_ind support in ctrl.c */
status = radio_length_req_send(cmd->handle, cmd->tx_octets);
evt->evt = BT_HCI_EVT_CMD_COMPLETE;
evt->len = _HCI_CC_LEN(*rp);
rp->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
rp->handle = cmd->handle;
}
static int controller_cmd_handle(uint8_t ocf, uint8_t *cp, uint8_t *len,
struct bt_hci_evt_hdr *evt)
{
switch (ocf) {
case BT_OCF(BT_HCI_OP_LE_SET_EVENT_MASK):
le_set_event_mask(cp, evt);
break; break;
case HCI_OCF_LE_READ_BUFFER_SIZE: case BT_OCF(BT_HCI_OP_LE_READ_BUFFER_SIZE):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_read_buffer_size(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_read_buffer_size);
ccp->le_read_buffer_size.status = HCI_EVT_ERROR_CODE_SUCCESS;
ccp->le_read_buffer_size.acl_data_length =
RADIO_LL_LENGTH_OCTETS_RX_MAX;
ccp->le_read_buffer_size.acl_data_num =
RADIO_PACKET_COUNT_TX_MAX;
break; break;
case HCI_OCF_LE_READ_LOCAL_SUPPORTED_FEATURES: case BT_OCF(BT_HCI_OP_LE_READ_LOCAL_FEATURES):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_read_local_features(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_rd_loc_sup_features);
ccp->le_rd_loc_sup_features.status = HCI_EVT_ERROR_CODE_SUCCESS;
memset(&ccp->le_rd_loc_sup_features.features[0], 0x00,
sizeof(ccp->le_rd_loc_sup_features.features));
ccp->le_rd_loc_sup_features.features[0] = RADIO_BLE_FEATURES;
break; break;
case HCI_OCF_LE_SET_RANDOM_ADDRESS: case BT_OCF(BT_HCI_OP_LE_SET_RANDOM_ADDRESS):
ll_address_set(1, &cmd->params.le_set_rnd_addr.addr[0]); le_set_random_address(cp, evt);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_rnd_addr);
ccp->le_set_rnd_addr.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_SET_ADV_PARAMS: case BT_OCF(BT_HCI_OP_LE_SET_ADV_PARAM):
ll_adv_params_set(cmd->params.le_set_adv_params.interval_min, le_set_adv_param(cp, evt);
c_adv_type[cmd->params.le_set_adv_params.type],
cmd->params.le_set_adv_params.own_addr_type,
cmd->params.le_set_adv_params.direct_addr_type,
&cmd->params.le_set_adv_params.direct_addr[0],
cmd->params.le_set_adv_params.channel_map,
cmd->params.le_set_adv_params.filter_policy);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_adv_params);
ccp->le_set_adv_params.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_READ_ADV_CHL_TX_POWER: case BT_OCF(BT_HCI_OP_LE_READ_ADV_CH_TX_POWER):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_read_adv_ch_tx_power(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_rd_adv_chl_tx_pwr);
ccp->le_rd_adv_chl_tx_pwr.status = HCI_EVT_ERROR_CODE_SUCCESS;
ccp->le_rd_adv_chl_tx_pwr.transmit_power_level = 0;
break; break;
case HCI_OCF_LE_SET_ADV_DATA: case BT_OCF(BT_HCI_OP_LE_SET_ADV_DATA):
ll_adv_data_set(cmd->params.le_set_adv_data.len, le_set_adv_data(cp, evt);
&cmd->params.le_set_adv_data.data[0]);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_adv_data);
ccp->le_set_adv_data.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_SET_SCAN_RESP_DATA: case BT_OCF(BT_HCI_OP_LE_SET_SCAN_RSP_DATA):
ll_scan_data_set(cmd->params.le_set_scan_data.len, le_set_scan_rsp_data(cp, evt);
&cmd->params.le_set_scan_data.data[0]);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_scan_resp_data);
ccp->le_set_scan_resp_data.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_SET_ADV_ENABLE: case BT_OCF(BT_HCI_OP_LE_SET_ADV_ENABLE):
status = ll_adv_enable(cmd->params.le_set_adv_enable.enable); le_set_adv_enable(cp, evt);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_adv_enable);
ccp->le_set_adv_enable.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_SET_SCAN_PARAMS: case BT_OCF(BT_HCI_OP_LE_SET_SCAN_PARAMS):
ll_scan_params_set(cmd->params.le_set_scan_params. le_set_scan_params(cp, evt);
type,
cmd->params.le_set_scan_params.
interval,
cmd->params.le_set_scan_params.
window,
cmd->params.le_set_scan_params.
own_addr_type,
cmd->params.le_set_scan_params.
filter_policy);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_scan_params);
ccp->le_set_scan_params.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_SET_SCAN_ENABLE: case BT_OCF(BT_HCI_OP_LE_SET_SCAN_ENABLE):
status = ll_scan_enable(cmd->params.le_set_scan_enable.enable); le_set_scan_enable(cp, evt);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_scan_enable);
ccp->le_set_scan_enable.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_CREATE_CONNECTION: case BT_OCF(BT_HCI_OP_LE_CREATE_CONN):
le_cc = &cmd->params.le_create_conn; le_create_connection(cp, evt);
status = ll_create_connection(le_cc->scan_interval,
le_cc->scan_window,
le_cc->filter_policy,
le_cc->peer_addr_type,
&le_cc->peer_addr[0],
le_cc->own_addr_type,
le_cc->interval_max,
le_cc->latency,
le_cc->timeout);
evt->code = HCI_EVT_CODE_COMMAND_STATUS;
evt->len = sizeof(struct hci_evt_cmd_status);
evt->params.cmd_status.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_CREATE_CONNECTION_CANCEL: case BT_OCF(BT_HCI_OP_LE_CREATE_CONN_CANCEL):
status = radio_connect_disable(); le_create_conn_cancel(cp, evt);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_create_conn_cancel);
ccp->le_create_conn_cancel.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_READ_WHITELIST_SIZE: case BT_OCF(BT_HCI_OP_LE_READ_WL_SIZE):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_read_wl_size(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_read_whitelist_size);
ccp->le_read_whitelist_size.status = HCI_EVT_ERROR_CODE_SUCCESS;
ccp->le_read_whitelist_size.whitelist_size = 8;
break; break;
case HCI_OCF_LE_CLEAR_WHITELIST: case BT_OCF(BT_HCI_OP_LE_CLEAR_WL):
radio_filter_clear(); le_clear_wl(cp, evt);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_clear_whitelist);
ccp->le_clear_whitelist.status = HCI_EVT_ERROR_CODE_SUCCESS;
break; break;
case HCI_OCF_LE_ADD_DEVICE_TO_WHITELIST: case BT_OCF(BT_HCI_OP_LE_ADD_DEV_TO_WL):
error_code = radio_filter_add(cmd->params.le_add_dev_to_wlist. le_add_dev_to_wl(cp, evt);
addr_type,
&cmd->params.le_add_dev_to_wlist.addr[0]);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(
hci_evt_cmd_cmplt_le_add_device_to_whitelist);
ccp->le_add_dev_to_wlist.status = (error_code == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_MEM_CAPACITY_EXCEEDED;
break; break;
case HCI_OCF_LE_CONNECTION_UPDATE: case BT_OCF(BT_HCI_OP_LE_CONN_UPDATE):
status = radio_conn_update(cmd->params.le_conn_update.handle, le_conn_update(cp, evt);
0, 0,
cmd->params.le_conn_update.
interval_max,
cmd->params.le_conn_update.latency,
cmd->params.le_conn_update.timeout);
evt->code = HCI_EVT_CODE_COMMAND_STATUS;
evt->len = sizeof(struct hci_evt_cmd_status);
evt->params.cmd_status.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_SET_HOST_CHL_CLASSN: case BT_OCF(BT_HCI_OP_LE_SET_HOST_CH_CLASSIF):
error_code = radio_chm_update(&cmd->params. le_set_host_ch_classif(cp, evt);
le_set_host_chl_classn.channel_map[0]);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_host_chl_classn);
ccp->le_set_host_chl_classn.status = (error_code == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_READ_REMOTE_USED_FEATURES: case BT_OCF(BT_HCI_OP_LE_READ_REMOTE_FEATURES):
status = radio_feature_req_send(cmd->params. le_read_remote_features(cp, evt);
le_read_remote_used_feats.handle);
evt->code = HCI_EVT_CODE_COMMAND_STATUS;
evt->len = sizeof(struct hci_evt_cmd_status);
evt->params.cmd_status.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_ENCRYPT: case BT_OCF(BT_HCI_OP_LE_ENCRYPT):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_encrypt(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_encrypt);
ccp->le_encrypt.status = HCI_EVT_ERROR_CODE_SUCCESS;
ecb_encrypt(&cmd->params.le_encrypt.key[0],
&cmd->params.le_encrypt.plaintext[0],
&ccp->le_encrypt.encrypted[0], 0);
break; break;
case HCI_OCF_LE_RAND: case BT_OCF(BT_HCI_OP_LE_RAND):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_rand(cp, evt);
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_rand);
ccp->le_rand.status = HCI_EVT_ERROR_CODE_SUCCESS;
/** TODO fill rand */
break; break;
case HCI_OCF_LE_START_ENCRYPTION: case BT_OCF(BT_HCI_OP_LE_START_ENCRYPTION):
status = radio_enc_req_send(cmd->params. le_start_encryption(cp, evt);
le_start_encryption.handle,
&cmd->params.le_start_encryption.rand[0],
&cmd->params.le_start_encryption.ediv[0],
&cmd->params.le_start_encryption.ltk[0]);
evt->code = HCI_EVT_CODE_COMMAND_STATUS;
evt->len = sizeof(struct hci_evt_cmd_status);
evt->params.cmd_status.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
break; break;
case HCI_OCF_LE_LTK_REQUEST_REPLY: case BT_OCF(BT_HCI_OP_LE_LTK_REQ_REPLY):
status = le_ltk_req_reply(cp, evt);
radio_start_enc_req_send(cmd->params.le_ltk_reply.handle,
HCI_EVT_ERROR_CODE_SUCCESS,
&cmd->params.
le_ltk_reply.ltk[0]);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_ltk_reply);
ccp->le_ltk_reply.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
ccp->le_ltk_reply.conn_handle = cmd->params.le_ltk_reply.handle;
break; break;
case HCI_OCF_LE_LTK_NEGATIVE_REPLY: case BT_OCF(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY):
status = le_ltk_req_neg_reply(cp, evt);
radio_start_enc_req_send(cmd->params.le_ltk_neg_reply.handle,
HCI_EVT_ERROR_CODE_PIN_OR_KEY_MISSING,
0);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_ltk_negative_reply);
ccp->le_ltk_neg_reply.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
ccp->le_ltk_neg_reply.conn_handle =
cmd->params.le_ltk_neg_reply.handle;
break; break;
case HCI_OCF_LE_READ_SUPPORTED_STATES: case BT_OCF(BT_HCI_OP_LE_READ_SUPP_STATES):
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE; le_read_supp_states(cp, evt);
evt->len =
HCI_CC_LEN(hci_evt_cmd_cmplt_le_read_supported_states);
ccp->le_read_supported_states.status =
HCI_EVT_ERROR_CODE_SUCCESS;
ccp->le_read_supported_states.le_states = 0x000003ffffffffff;
break; break;
case HCI_OCF_LE_REMOTE_CONN_PARAM_REQ_REPLY: case BT_OCF(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY):
le_cp_req_rep = &cmd->params.le_remote_conn_param_req_reply; le_conn_param_req_reply(cp, evt);
status = radio_conn_update(le_cp_req_rep->handle, 2, 0,
le_cp_req_rep->interval_max,
le_cp_req_rep->latency,
le_cp_req_rep->timeout);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len =
HCI_CC_LEN(hci_evt_cmd_cmplt_le_remote_conn_param_req_reply);
ccp->le_remote_conn_param_req_reply.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
ccp->le_remote_conn_param_req_reply.conn_handle =
cmd->params.le_remote_conn_param_req_reply.handle;
break; break;
case HCI_OCF_LE_REMOTE_CONN_PARAM_REQ_NEG_REPLY: case BT_OCF(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY):
le_cp_req_neg_rep = le_conn_param_req_neg_reply(cp, evt);
&cmd->params.le_remote_conn_param_req_neg_reply;
status = radio_conn_update(le_cp_req_neg_rep->handle, 2,
le_cp_req_neg_rep->reason, 0, 0, 0);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(
hci_evt_cmd_cmplt_le_remote_conn_param_req_neg_reply);
ccp->le_remote_conn_param_req_neg_reply.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
ccp->le_remote_conn_param_req_neg_reply.conn_handle =
cmd->params.le_remote_conn_param_req_neg_reply.handle;
break; break;
case HCI_OCF_LE_SET_DATA_LENGTH: case BT_OCF(BT_HCI_OP_LE_SET_DATA_LEN):
status = radio_length_req_send( le_set_data_len(cp, evt);
cmd->params.le_set_data_length.handle,
cmd->params.le_set_data_length.tx_octets);
evt->code = HCI_EVT_CODE_COMMAND_COMPLETE;
evt->len = HCI_CC_LEN(hci_evt_cmd_cmplt_le_set_data_length);
ccp->le_set_data_length.status = (status == 0) ?
HCI_EVT_ERROR_CODE_SUCCESS :
HCI_EVT_ERROR_CODE_COMMAND_DISALLOWED;
ccp->le_set_data_length.conn_handle =
cmd->params.le_set_data_length.handle;
break; break;
default: default:
@ -1417,7 +1544,7 @@ static void hci_cmd_handle(struct bt_hci_cmd_hdr *cmd, uint8_t *len,
err = info_cmd_handle(ocf, cp, len, evt); err = info_cmd_handle(ocf, cp, len, evt);
break; break;
case BT_OGF_LE: case BT_OGF_LE:
err = controller_cmd_handle(ocf, (void *)cmd, len, (void *)evt); err = controller_cmd_handle(ocf, cp, len, evt);
break; break;
case BT_OGF_VS: case BT_OGF_VS:
err = vs_cmd_handle(ocf, (void *)cmd, len, (void *)evt); err = vs_cmd_handle(ocf, (void *)cmd, len, (void *)evt);