|
77 | 77 | enum { |
78 | 78 | RP_COMMON_STATE_IDLE, |
79 | 79 | RP_COMMON_STATE_WAIT_RX, |
| 80 | + RP_COMMON_STATE_POSTPONE_TERMINATE, |
80 | 81 | RP_COMMON_STATE_WAIT_TX, |
81 | 82 | RP_COMMON_STATE_WAIT_TX_ACK, |
82 | 83 | RP_COMMON_STATE_WAIT_NTF, |
|
93 | 94 | RP_COMMON_EVT_REQUEST, |
94 | 95 | }; |
95 | 96 |
|
| 97 | + |
96 | 98 | static void lp_comm_ntf(struct ll_conn *conn, struct proc_ctx *ctx); |
97 | 99 | static void lp_comm_terminate_invalid_pdu(struct ll_conn *conn, struct proc_ctx *ctx); |
98 | 100 |
|
@@ -781,8 +783,17 @@ void llcp_lp_comm_init_proc(struct proc_ctx *ctx) |
781 | 783 | void llcp_lp_comm_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param) |
782 | 784 | { |
783 | 785 | lp_comm_execute_fsm(conn, ctx, LP_COMMON_EVT_RUN, param); |
| 786 | + |
784 | 787 | } |
785 | 788 |
|
| 789 | +static void rp_comm_terminate(struct ll_conn *conn, struct proc_ctx *ctx) |
| 790 | +{ |
| 791 | + llcp_rr_complete(conn); |
| 792 | + ctx->state = RP_COMMON_STATE_IDLE; |
| 793 | + |
| 794 | + /* Mark the connection for termination */ |
| 795 | + conn->llcp_terminate.reason_final = ctx->data.term.error_code; |
| 796 | +} |
786 | 797 | /* |
787 | 798 | * LLCP Remote Procedure Common FSM |
788 | 799 | */ |
@@ -821,6 +832,8 @@ static void rp_comm_rx_decode(struct ll_conn *conn, struct proc_ctx *ctx, struct |
821 | 832 | break; |
822 | 833 | case PDU_DATA_LLCTRL_TYPE_TERMINATE_IND: |
823 | 834 | llcp_pdu_decode_terminate_ind(ctx, pdu); |
| 835 | + /* Make sure no data is tx'ed after RX of terminate ind */ |
| 836 | + llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_TERMINATE); |
824 | 837 | break; |
825 | 838 | #if defined(CONFIG_BT_CTLR_DATA_LENGTH) |
826 | 839 | case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ: |
@@ -1051,12 +1064,19 @@ static void rp_comm_send_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t |
1051 | 1064 | break; |
1052 | 1065 | #endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_CENTRAL */ |
1053 | 1066 | case PROC_TERMINATE: |
1054 | | - /* No response */ |
1055 | | - llcp_rr_complete(conn); |
1056 | | - ctx->state = RP_COMMON_STATE_IDLE; |
1057 | | - |
1058 | | - /* Mark the connection for termination */ |
1059 | | - conn->llcp_terminate.reason_final = ctx->data.term.error_code; |
| 1067 | +#if defined(CONFIG_BT_CENTRAL) |
| 1068 | + if (conn->lll.role == BT_HCI_ROLE_CENTRAL) { |
| 1069 | + /* No response, but postpone terminate until next event |
| 1070 | + * to ensure acking the reception of TERMINATE_IND |
| 1071 | + */ |
| 1072 | + ctx->state = RP_COMMON_STATE_POSTPONE_TERMINATE; |
| 1073 | + break; |
| 1074 | + } |
| 1075 | +#endif |
| 1076 | +#if defined(CONFIG_BT_PERIPHERAL) |
| 1077 | + /* Terminate right away */ |
| 1078 | + rp_comm_terminate(conn, ctx); |
| 1079 | +#endif |
1060 | 1080 | break; |
1061 | 1081 | #if defined(CONFIG_BT_CTLR_DATA_LENGTH) |
1062 | 1082 | case PROC_DATA_LENGTH_UPDATE: |
@@ -1102,6 +1122,26 @@ static void rp_comm_st_wait_rx(struct ll_conn *conn, struct proc_ctx *ctx, uint8 |
1102 | 1122 | } |
1103 | 1123 | } |
1104 | 1124 |
|
| 1125 | +static void rp_comm_st_postpone_terminate(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, |
| 1126 | + void *param) |
| 1127 | +{ |
| 1128 | + switch (evt) { |
| 1129 | + case RP_COMMON_EVT_RUN: |
| 1130 | + LL_ASSERT(ctx->proc == PROC_TERMINATE); |
| 1131 | + |
| 1132 | + /* Note: now we terminate, mimicking legacy LLCP behaviour |
| 1133 | + * A check should be added to ensure that the ack of the terminate_ind was |
| 1134 | + * indeed tx'ed and not scheduled out/postponed by LLL |
| 1135 | + */ |
| 1136 | + rp_comm_terminate(conn, ctx); |
| 1137 | + |
| 1138 | + break; |
| 1139 | + default: |
| 1140 | + /* Ignore other evts */ |
| 1141 | + break; |
| 1142 | + } |
| 1143 | +} |
| 1144 | + |
1105 | 1145 | static void rp_comm_st_wait_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) |
1106 | 1146 | { |
1107 | 1147 | switch (evt) { |
@@ -1181,6 +1221,9 @@ static void rp_comm_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint |
1181 | 1221 | case RP_COMMON_STATE_WAIT_RX: |
1182 | 1222 | rp_comm_st_wait_rx(conn, ctx, evt, param); |
1183 | 1223 | break; |
| 1224 | + case RP_COMMON_STATE_POSTPONE_TERMINATE: |
| 1225 | + rp_comm_st_postpone_terminate(conn, ctx, evt, param); |
| 1226 | + break; |
1184 | 1227 | case RP_COMMON_STATE_WAIT_TX: |
1185 | 1228 | rp_comm_st_wait_tx(conn, ctx, evt, param); |
1186 | 1229 | break; |
|
0 commit comments