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 ticks_drift_minus;
|
||||||
u16_t latency_event;
|
u16_t latency_event;
|
||||||
u16_t elapsed_event;
|
u16_t elapsed_event;
|
||||||
|
u8_t reason_peer;
|
||||||
u16_t lazy;
|
u16_t lazy;
|
||||||
u8_t force;
|
u8_t force;
|
||||||
|
|
||||||
|
@ -3019,11 +3020,13 @@ static inline void isr_close_conn(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remote Initiated terminate happened in this event for Slave */
|
/* Master transmitted ack for the received terminate ind or
|
||||||
if ((_radio.role == ROLE_SLAVE) &&
|
* Slave received terminate ind.
|
||||||
_radio.conn_curr->llcp_terminate.reason_peer) {
|
*/
|
||||||
terminate_ind_rx_enqueue(_radio.conn_curr,
|
reason_peer = _radio.conn_curr->llcp_terminate.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);
|
connection_release(_radio.conn_curr);
|
||||||
_radio.conn_curr = NULL;
|
_radio.conn_curr = NULL;
|
||||||
|
@ -3037,8 +3040,8 @@ static inline void isr_close_conn(void)
|
||||||
elapsed_event = latency_event + 1;
|
elapsed_event = latency_event + 1;
|
||||||
|
|
||||||
/* calculate drift if anchor point sync-ed */
|
/* calculate drift if anchor point sync-ed */
|
||||||
if ((_radio.packet_counter != 0) && ((!SILENT_CONNECTION) ||
|
if (_radio.packet_counter &&
|
||||||
(_radio.packet_counter != 0xFF))) {
|
(!SILENT_CONNECTION || (_radio.packet_counter != 0xFF))) {
|
||||||
if (_radio.role == ROLE_SLAVE) {
|
if (_radio.role == ROLE_SLAVE) {
|
||||||
u32_t start_to_address_expected_us;
|
u32_t start_to_address_expected_us;
|
||||||
u32_t start_to_address_actual_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_event =
|
||||||
_radio.conn_curr->latency;
|
_radio.conn_curr->latency;
|
||||||
}
|
}
|
||||||
|
} else if (reason_peer) {
|
||||||
|
_radio.conn_curr->master.terminate_ack = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset connection failed to establish procedure */
|
/* Reset connection failed to establish procedure */
|
||||||
_radio.conn_curr->connect_expire = 0;
|
_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 */
|
/* check connection failed to establish */
|
||||||
else if (_radio.conn_curr->connect_expire) {
|
else if (_radio.conn_curr->connect_expire) {
|
||||||
if (_radio.conn_curr->connect_expire > elapsed_event) {
|
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;
|
void *link;
|
||||||
|
|
||||||
/* Prepare the rx packet structure */
|
/* Prepare the rx packet structure */
|
||||||
radio_pdu_node_rx =
|
radio_pdu_node_rx = (void *)&conn->llcp_terminate.radio_pdu_node_rx;
|
||||||
(struct radio_pdu_node_rx *)&conn->llcp_terminate.radio_pdu_node_rx;
|
|
||||||
LL_ASSERT(radio_pdu_node_rx->hdr.onion.link);
|
LL_ASSERT(radio_pdu_node_rx->hdr.onion.link);
|
||||||
|
|
||||||
radio_pdu_node_rx->hdr.handle = conn->handle;
|
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->role = 0;
|
||||||
conn->connect_expire = 6;
|
conn->connect_expire = 6;
|
||||||
|
conn->master.terminate_ack = 0;
|
||||||
conn_interval_us =
|
conn_interval_us =
|
||||||
(u32_t)_radio.scanner.conn_interval * 1250;
|
(u32_t)_radio.scanner.conn_interval * 1250;
|
||||||
conn->supervision_reload =
|
conn->supervision_reload =
|
||||||
|
|
|
@ -90,19 +90,25 @@ struct connection {
|
||||||
u16_t apto_expire;
|
u16_t apto_expire;
|
||||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_PING */
|
#endif /* CONFIG_BLUETOOTH_CONTROLLER_LE_PING */
|
||||||
|
|
||||||
struct {
|
union {
|
||||||
u8_t latency_enabled:1;
|
struct {
|
||||||
u8_t latency_cancel:1;
|
u8_t terminate_ack:1;
|
||||||
u8_t sca:3;
|
} master;
|
||||||
u32_t window_widening_periodic_us;
|
|
||||||
u32_t window_widening_max_us;
|
struct {
|
||||||
u32_t window_widening_prepare_us;
|
u8_t latency_enabled:1;
|
||||||
u32_t window_widening_event_us;
|
u8_t latency_cancel:1;
|
||||||
u32_t window_size_prepare_us;
|
u8_t sca:3;
|
||||||
u32_t window_size_event_us;
|
u32_t window_widening_periodic_us;
|
||||||
u32_t force;
|
u32_t window_widening_max_us;
|
||||||
u32_t ticks_to_offset;
|
u32_t window_widening_prepare_us;
|
||||||
} slave;
|
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_req;
|
||||||
u8_t llcp_ack;
|
u8_t llcp_ack;
|
||||||
|
@ -174,10 +180,10 @@ struct connection {
|
||||||
} llcp_version;
|
} llcp_version;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8_t req;
|
u8_t req;
|
||||||
u8_t ack;
|
u8_t ack;
|
||||||
u8_t reason_own;
|
u8_t reason_own;
|
||||||
u8_t reason_peer;
|
u8_t reason_peer;
|
||||||
struct {
|
struct {
|
||||||
struct radio_pdu_node_rx_hdr hdr;
|
struct radio_pdu_node_rx_hdr hdr;
|
||||||
u8_t reason;
|
u8_t reason;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue