Bluetooth: Controller: Handle LL_UNKNOWN_RSP PDU for remote features
When a peer controller does not recognize one of the LL control PDUs received, it will issue an LL_UNKNOWN_RSP PDU to let the peer know that it does not recognize the request. The controller now handles this incoming PDU and completes the procedure by issuing the appropriate HCI event in the case of an LL_FEATURE_REQ and _RSP pair. Jira: ZEP-1220 Change-Id: I7c04a346441f04deee41198daa6309c11ae1b571 Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
d7f4fd74a9
commit
6ccfa64b5c
2 changed files with 33 additions and 10 deletions
|
@ -1081,18 +1081,38 @@ static void encrypt_change(uint8_t err, uint16_t handle,
|
|||
ep->encrypt = !err ? 1 : 0;
|
||||
}
|
||||
|
||||
static void le_remote_feat_complete(struct pdu_data *pdu_data, uint16_t handle,
|
||||
struct net_buf *buf)
|
||||
static void le_remote_feat_complete(uint8_t status, struct pdu_data *pdu_data,
|
||||
uint16_t handle, struct net_buf *buf)
|
||||
{
|
||||
struct bt_hci_ev_le_remote_feat_complete *sep;
|
||||
|
||||
sep = meta_evt(buf, BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE, sizeof(*sep));
|
||||
|
||||
sep->status = 0x00;
|
||||
sep->status = status;
|
||||
sep->handle = sys_cpu_to_le16(handle);
|
||||
memcpy(&sep->features[0],
|
||||
&pdu_data->payload.llctrl.ctrldata.feature_rsp.features[0],
|
||||
sizeof(sep->features));
|
||||
if (!status) {
|
||||
memcpy(&sep->features[0],
|
||||
&pdu_data->payload.llctrl.ctrldata.feature_rsp.features[0],
|
||||
sizeof(sep->features));
|
||||
} else {
|
||||
memset(&sep->features[0], 0x00, sizeof(sep->features));
|
||||
}
|
||||
}
|
||||
|
||||
static void le_unknown_rsp(struct pdu_data *pdu_data, uint16_t handle,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
|
||||
switch (pdu_data->payload.llctrl.ctrldata.unknown_rsp.type) {
|
||||
case PDU_DATA_LLCTRL_TYPE_SLAVE_FEATURE_REQ:
|
||||
le_remote_feat_complete(BT_HCI_ERR_UNSUPP_REMOTE_FEATURE,
|
||||
NULL, handle, buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void remote_version_info(struct pdu_data *pdu_data, uint16_t handle,
|
||||
|
@ -1162,7 +1182,7 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx,
|
|||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP:
|
||||
le_remote_feat_complete(pdu_data, handle, buf);
|
||||
le_remote_feat_complete(0x00, pdu_data, handle, buf);
|
||||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_VERSION_IND:
|
||||
|
@ -1184,6 +1204,10 @@ static void encode_data_ctrl(struct radio_pdu_node_rx *node_rx,
|
|||
le_data_len_change(pdu_data, handle, buf);
|
||||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP:
|
||||
le_unknown_rsp(pdu_data, handle, buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ASSERT(0);
|
||||
return;
|
||||
|
|
|
@ -1677,9 +1677,8 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx,
|
|||
*/
|
||||
*rx_enqueue = 1;
|
||||
} else {
|
||||
/** @todo check opcode in unknown rsp, and take
|
||||
* necessary actions
|
||||
*/
|
||||
/* enqueue the error and let HCI handle it */
|
||||
*rx_enqueue = 1;
|
||||
/* Procedure complete */
|
||||
_radio.conn_curr->procedure_expire = 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue