*_smscb_peer_fsm: Immediately NACK if Tx of msg failed

This makes the smscb_message_fsm receive immediate notice that this peer
failed to deliver the message, avoiding need to wait for 10 seconds
timeout.

Change-Id: I1f3911accb327f3378d65902d53d86fb298fd528
This commit is contained in:
Pau Espin 2022-07-29 17:47:04 +02:00
parent 20705a0877
commit a76d15048d
3 changed files with 27 additions and 19 deletions

View File

@ -266,11 +266,9 @@ static void smscb_p_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, void *dat
case SMSCB_PEER_E_CREATE: case SMSCB_PEER_E_CREATE:
/* send it to peer */ /* send it to peer */
rc = peer_new_cbc_message(mp->peer, mp->cbcmsg); rc = peer_new_cbc_message(mp->peer, mp->cbcmsg);
if (rc == 0) { osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_WRITE_ACK, 10, T_WAIT_WRITE_ACK);
/* wait for peers' response */ if (rc != 0) /* Immediately timeout the message */
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_WRITE_ACK, 10, fi->fsm->timer_cb(fi);
T_WAIT_WRITE_ACK);
}
break; break;
default: default:
OSMO_ASSERT(0); OSMO_ASSERT(0);
@ -309,6 +307,7 @@ static void smscb_p_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *d
{ {
struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv; struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv;
struct osmo_cbsp_decoded *cbsp; struct osmo_cbsp_decoded *cbsp;
int rc;
switch (event) { switch (event) {
case SMSCB_PEER_E_REPLACE: /* send WRITE-REPLACE to BSC */ case SMSCB_PEER_E_REPLACE: /* send WRITE-REPLACE to BSC */
@ -320,8 +319,10 @@ static void smscb_p_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *d
/* TODO: we assume that the replace will always affect all original cells */ /* TODO: we assume that the replace will always affect all original cells */
cbsp_append_cell_list(&cbsp->u.write_replace.cell_list, cbsp, mp); cbsp_append_cell_list(&cbsp->u.write_replace.cell_list, cbsp, mp);
// TODO: ALL OTHER DATA // TODO: ALL OTHER DATA
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp); rc = cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_REPLACE_ACK, 10, T_WAIT_REPLACE_ACK); osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_REPLACE_ACK, 10, T_WAIT_REPLACE_ACK);
if (rc != 0) /* Immediately timeout the message */
fi->fsm->timer_cb(fi);
break; break;
case SMSCB_PEER_E_STATUS: /* send MSG-STATUS-QUERY to BSC */ case SMSCB_PEER_E_STATUS: /* send MSG-STATUS-QUERY to BSC */
cbsp = osmo_cbsp_decoded_alloc(mp->peer, CBSP_MSGT_MSG_STATUS_QUERY); cbsp = osmo_cbsp_decoded_alloc(mp->peer, CBSP_MSGT_MSG_STATUS_QUERY);
@ -330,8 +331,10 @@ static void smscb_p_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *d
cbsp->u.msg_status_query.old_serial_nr = mp->cbcmsg->msg.serial_nr; cbsp->u.msg_status_query.old_serial_nr = mp->cbcmsg->msg.serial_nr;
cbsp_append_cell_list(&cbsp->u.msg_status_query.cell_list, cbsp, mp); cbsp_append_cell_list(&cbsp->u.msg_status_query.cell_list, cbsp, mp);
cbsp->u.msg_status_query.channel_ind = CBSP_CHAN_IND_BASIC; cbsp->u.msg_status_query.channel_ind = CBSP_CHAN_IND_BASIC;
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp); rc = cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_STATUS_ACK, 10, T_WAIT_STATUS_ACK); osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_STATUS_ACK, 10, T_WAIT_STATUS_ACK);
if (rc != 0) /* Immediately timeout the message */
fi->fsm->timer_cb(fi);
break; break;
default: default:
OSMO_ASSERT(0); OSMO_ASSERT(0);
@ -423,8 +426,6 @@ static void smscb_p_fsm_wait_delete_ack(struct osmo_fsm_inst *fi, uint32_t event
} }
} }
static int smscb_p_fsm_timer_cb(struct osmo_fsm_inst *fi) static int smscb_p_fsm_timer_cb(struct osmo_fsm_inst *fi)
{ {
switch (fi->T) { switch (fi->T) {
@ -454,6 +455,7 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
{ {
struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv; struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv;
struct osmo_cbsp_decoded *cbsp; struct osmo_cbsp_decoded *cbsp;
int rc;
switch (event) { switch (event) {
case SMSCB_PEER_E_DELETE: /* send KILL to BSC */ case SMSCB_PEER_E_DELETE: /* send KILL to BSC */
@ -478,8 +480,10 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
OSMO_ASSERT(cbsp->u.kill.channel_ind); OSMO_ASSERT(cbsp->u.kill.channel_ind);
*(cbsp->u.kill.channel_ind) = CBSP_CHAN_IND_BASIC; *(cbsp->u.kill.channel_ind) = CBSP_CHAN_IND_BASIC;
} }
cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp); rc = cbc_cbsp_link_tx(mp->peer->link.cbsp, cbsp);
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK); osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK);
if (rc != 0) /* Immediately timeout the message */
fi->fsm->timer_cb(fi);
break; break;
default: default:
OSMO_ASSERT(0); OSMO_ASSERT(0);
@ -497,7 +501,8 @@ static const struct osmo_fsm_state smscb_p_fsm_states[] = {
[SMSCB_S_INIT] = { [SMSCB_S_INIT] = {
.name = "INIT", .name = "INIT",
.in_event_mask = S(SMSCB_PEER_E_CREATE), .in_event_mask = S(SMSCB_PEER_E_CREATE),
.out_state_mask = S(SMSCB_S_WAIT_WRITE_ACK), .out_state_mask = S(SMSCB_S_WAIT_WRITE_ACK) |
S(SMSCB_S_ACTIVE),
.action = smscb_p_fsm_init, .action = smscb_p_fsm_init,
}, },
[SMSCB_S_WAIT_WRITE_ACK] = { [SMSCB_S_WAIT_WRITE_ACK] = {

View File

@ -116,11 +116,9 @@ static void smscb_p_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, void *dat
case SMSCB_PEER_E_CREATE: case SMSCB_PEER_E_CREATE:
/* send it to peer */ /* send it to peer */
rc = peer_new_cbc_message(mp->peer, mp->cbcmsg); rc = peer_new_cbc_message(mp->peer, mp->cbcmsg);
if (rc == 0) { osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_WRITE_ACK, 10, T_WAIT_WRITE_ACK);
/* wait for peers' response */ if (rc != 0) /* Immediately timeout the message */
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_WRITE_ACK, 10, fi->fsm->timer_cb(fi);
T_WAIT_WRITE_ACK);
}
break; break;
default: default:
OSMO_ASSERT(0); OSMO_ASSERT(0);
@ -256,6 +254,7 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
SBcAP_SBC_AP_PDU_t *sbcap; SBcAP_SBC_AP_PDU_t *sbcap;
A_SEQUENCE_OF(void) *as_pdu; A_SEQUENCE_OF(void) *as_pdu;
SBcAP_Write_Replace_Warning_Indication_IEs_t *ie; SBcAP_Write_Replace_Warning_Indication_IEs_t *ie;
int rc;
switch (event) { switch (event) {
case SMSCB_PEER_E_DELETE: /* send Stop-Warning to MME */ case SMSCB_PEER_E_DELETE: /* send Stop-Warning to MME */
@ -269,13 +268,16 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
break; break;
} }
if ((sbcap = sbcap_gen_stop_warning_req(mp->peer, mp->cbcmsg))) { if ((sbcap = sbcap_gen_stop_warning_req(mp->peer, mp->cbcmsg))) {
cbc_sbcap_link_tx(mp->peer->link.sbcap, sbcap); rc = cbc_sbcap_link_tx(mp->peer->link.sbcap, sbcap);
} else { } else {
LOGP(DSBcAP, LOGL_ERROR, LOGP(DSBcAP, LOGL_ERROR,
"[%s] Tx SBc-AP Stop-Warning-Request: msg gen failed\n", "[%s] Tx SBc-AP Stop-Warning-Request: msg gen failed\n",
mp->peer->name); mp->peer->name);
rc = -1;
} }
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK); osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK);
if (rc != 0) /* Immediately timeout the message */
fi->fsm->timer_cb(fi);
break; break;
case SMSCB_PEER_E_SBCAP_WRITE_IND: case SMSCB_PEER_E_SBCAP_WRITE_IND:
sbcap = (SBcAP_SBC_AP_PDU_t *)data; sbcap = (SBcAP_SBC_AP_PDU_t *)data;
@ -305,7 +307,8 @@ static const struct osmo_fsm_state smscb_p_fsm_states[] = {
[SMSCB_S_INIT] = { [SMSCB_S_INIT] = {
.name = "INIT", .name = "INIT",
.in_event_mask = S(SMSCB_PEER_E_CREATE), .in_event_mask = S(SMSCB_PEER_E_CREATE),
.out_state_mask = S(SMSCB_S_WAIT_WRITE_ACK), .out_state_mask = S(SMSCB_S_WAIT_WRITE_ACK) |
S(SMSCB_S_ACTIVE),
.action = smscb_p_fsm_init, .action = smscb_p_fsm_init,
}, },
[SMSCB_S_WAIT_WRITE_ACK] = { [SMSCB_S_WAIT_WRITE_ACK] = {

View File

@ -84,7 +84,7 @@ static void smscb_fsm_wait_write_ack(struct osmo_fsm_inst *fi, uint32_t event, v
/* check if any per-peer children have not yet received the ACK or /* check if any per-peer children have not yet received the ACK or
* timed out */ * timed out */
llist_for_each_entry(peer_fi, &fi->proc.children, proc.child) { llist_for_each_entry(peer_fi, &fi->proc.children, proc.child) {
if (peer_fi->state == SMSCB_S_WAIT_WRITE_ACK) if (peer_fi->state != SMSCB_S_ACTIVE)
return; return;
} }
rest_it_op_set_http_result(cbcmsg->it_op, 201, "Created"); // FIXME: error cases rest_it_op_set_http_result(cbcmsg->it_op, 201, "Created"); // FIXME: error cases