Bluetooth: controller: Fix master terminate procedure
Fix master terminate procedure so that if slave responded to the ack from master for the LL_TERMINATE_IND then the master correctly disconnected. This fixes TP/CON/MAS/BV-09-C [Master Accepting Termination] in LL.TS.5.0.0. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no> Tested-by: Ulrich Myhre <ulmy@nordicsemi.no>
This commit is contained in:
parent
9fc4fefc47
commit
52ee6622c0
2 changed files with 37 additions and 37 deletions
|
@ -3011,6 +3011,7 @@ static inline void isr_close_conn(void)
|
|||
u16_t ticks_drift_minus;
|
||||
u16_t latency_event;
|
||||
u16_t elapsed_event;
|
||||
u8_t reason_peer;
|
||||
u16_t lazy;
|
||||
u8_t force;
|
||||
|
||||
|
@ -3019,11 +3020,13 @@ static inline void isr_close_conn(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Remote Initiated terminate happened in this event for Slave */
|
||||
if ((_radio.role == ROLE_SLAVE) &&
|
||||
_radio.conn_curr->llcp_terminate.reason_peer) {
|
||||
terminate_ind_rx_enqueue(_radio.conn_curr,
|
||||
_radio.conn_curr->llcp_terminate.reason_peer);
|
||||
/* Master transmitted ack for the received terminate ind or
|
||||
* Slave received terminate ind.
|
||||
*/
|
||||
reason_peer = _radio.conn_curr->llcp_terminate.reason_peer;
|
||||
if (reason_peer && ((_radio.role == ROLE_SLAVE) ||
|
||||
_radio.conn_curr->master.terminate_ack)) {
|
||||
terminate_ind_rx_enqueue(_radio.conn_curr, reason_peer);
|
||||
|
||||
connection_release(_radio.conn_curr);
|
||||
_radio.conn_curr = NULL;
|
||||
|
@ -3037,8 +3040,8 @@ static inline void isr_close_conn(void)
|
|||
elapsed_event = latency_event + 1;
|
||||
|
||||
/* calculate drift if anchor point sync-ed */
|
||||
if ((_radio.packet_counter != 0) && ((!SILENT_CONNECTION) ||
|
||||
(_radio.packet_counter != 0xFF))) {
|
||||
if (_radio.packet_counter &&
|
||||
(!SILENT_CONNECTION || (_radio.packet_counter != 0xFF))) {
|
||||
if (_radio.role == ROLE_SLAVE) {
|
||||
u32_t start_to_address_expected_us;
|
||||
u32_t start_to_address_actual_us;
|
||||
|
@ -3092,23 +3095,14 @@ static inline void isr_close_conn(void)
|
|||
_radio.conn_curr->latency_event =
|
||||
_radio.conn_curr->latency;
|
||||
}
|
||||
} else if (reason_peer) {
|
||||
_radio.conn_curr->master.terminate_ack = 1;
|
||||
}
|
||||
|
||||
/* Reset connection failed to establish procedure */
|
||||
_radio.conn_curr->connect_expire = 0;
|
||||
}
|
||||
|
||||
/* Remote Initiated terminate happened in previous event for Master */
|
||||
else if (_radio.conn_curr->llcp_terminate.reason_peer) {
|
||||
terminate_ind_rx_enqueue(_radio.conn_curr,
|
||||
_radio.conn_curr->llcp_terminate.reason_peer);
|
||||
|
||||
connection_release(_radio.conn_curr);
|
||||
_radio.conn_curr = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* check connection failed to establish */
|
||||
else if (_radio.conn_curr->connect_expire) {
|
||||
if (_radio.conn_curr->connect_expire > elapsed_event) {
|
||||
|
@ -7504,8 +7498,7 @@ static void terminate_ind_rx_enqueue(struct connection *conn, u8_t reason)
|
|||
void *link;
|
||||
|
||||
/* Prepare the rx packet structure */
|
||||
radio_pdu_node_rx =
|
||||
(struct radio_pdu_node_rx *)&conn->llcp_terminate.radio_pdu_node_rx;
|
||||
radio_pdu_node_rx = (void *)&conn->llcp_terminate.radio_pdu_node_rx;
|
||||
LL_ASSERT(radio_pdu_node_rx->hdr.onion.link);
|
||||
|
||||
radio_pdu_node_rx->hdr.handle = conn->handle;
|
||||
|
@ -8765,6 +8758,7 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval,
|
|||
|
||||
conn->role = 0;
|
||||
conn->connect_expire = 6;
|
||||
conn->master.terminate_ack = 0;
|
||||
conn_interval_us =
|
||||
(u32_t)_radio.scanner.conn_interval * 1250;
|
||||
conn->supervision_reload =
|
||||
|
|
|
@ -90,19 +90,25 @@ struct connection {
|
|||
u16_t apto_expire;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_PING */
|
||||
|
||||
struct {
|
||||
u8_t latency_enabled:1;
|
||||
u8_t latency_cancel:1;
|
||||
u8_t sca:3;
|
||||
u32_t window_widening_periodic_us;
|
||||
u32_t window_widening_max_us;
|
||||
u32_t window_widening_prepare_us;
|
||||
u32_t window_widening_event_us;
|
||||
u32_t window_size_prepare_us;
|
||||
u32_t window_size_event_us;
|
||||
u32_t force;
|
||||
u32_t ticks_to_offset;
|
||||
} slave;
|
||||
union {
|
||||
struct {
|
||||
u8_t terminate_ack:1;
|
||||
} master;
|
||||
|
||||
struct {
|
||||
u8_t latency_enabled:1;
|
||||
u8_t latency_cancel:1;
|
||||
u8_t sca:3;
|
||||
u32_t window_widening_periodic_us;
|
||||
u32_t window_widening_max_us;
|
||||
u32_t window_widening_prepare_us;
|
||||
u32_t window_widening_event_us;
|
||||
u32_t window_size_prepare_us;
|
||||
u32_t window_size_event_us;
|
||||
u32_t force;
|
||||
u32_t ticks_to_offset;
|
||||
} slave;
|
||||
};
|
||||
|
||||
u8_t llcp_req;
|
||||
u8_t llcp_ack;
|
||||
|
@ -174,10 +180,10 @@ struct connection {
|
|||
} llcp_version;
|
||||
|
||||
struct {
|
||||
u8_t req;
|
||||
u8_t ack;
|
||||
u8_t reason_own;
|
||||
u8_t reason_peer;
|
||||
u8_t req;
|
||||
u8_t ack;
|
||||
u8_t reason_own;
|
||||
u8_t reason_peer;
|
||||
struct {
|
||||
struct radio_pdu_node_rx_hdr hdr;
|
||||
u8_t reason;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue