From 03fcc91aad671d6e0b5c849d1ae8cf7c64d1d4c9 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Thu, 15 Jul 2021 02:09:42 +0200 Subject: [PATCH] mgcp_client_endpoint_fsm: on term, still let conns wait for DLCX OK When the mgcp_client_endpoint_fsm terminates, do not directly pull each conn FSM instance (mgcp_client_fsm) into oblivion as well. Those should emit a DLCX and wait for the "OK" response before deallocating. In programs using the mgcp client endpoint FSM (osmo-bsc, osmo-msc), this gets rid of false LMGCP ERROR logging related to DLCX like this: Cannot find matching MGCP transaction for trans_id 71998 Related: SYS#5529 Change-Id: I8fbfec5533e9be9cc7ea550df1e6639a0a215973 --- .../mgcp_client_endpoint_fsm.c | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c b/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c index 7175c1875..0613e17f3 100644 --- a/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c +++ b/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c @@ -990,6 +990,34 @@ static int osmo_mgcpc_ep_fsm_timer_cb(struct osmo_fsm_inst *fi) return 0; } +void osmo_mgcpc_ep_fsm_pre_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + int i; + struct osmo_mgcpc_ep *ep = osmo_mgcpc_ep_fi_mgwep(fi); + + /* We want the mgcp_client_fsm to still stick around until it received the DLCX "OK" responses from the MGW. So + * it should not dealloc along with this ep_fsm instance. Instead, signal DLCX for each conn on the endpoint, + * and detach the mgcp_client_fsm from being a child-fsm. + * + * After mgcp_conn_delete(), an mgcp_client_fsm instance goes into ST_DLCX_RESP, which waits up to 4 seconds for + * a DLCX OK. If none is received in that time, the instance terminates. So cleanup of the instance is + * guaranteed. */ + + for (i = 0; i < ARRAY_SIZE(ep->ci); i++) { + struct osmo_mgcpc_ep_ci *ci = &ep->ci[i]; + + if (!ci->occupied || !ci->mgcp_client_fi) + continue; + + /* mgcp_conn_delete() unlinks itself from this parent FSM implicitly and waits for the DLCX OK. */ + mgcp_conn_delete(ci->mgcp_client_fi); + /* Forget all about this ci */ + *ci = (struct osmo_mgcpc_ep_ci){ + .ep = ep, + }; + } +} + static struct osmo_fsm osmo_mgcpc_ep_fsm = { .name = "mgw-endp", .states = osmo_mgcpc_ep_fsm_states, @@ -997,5 +1025,5 @@ static struct osmo_fsm osmo_mgcpc_ep_fsm = { .log_subsys = DLMGCP, .event_names = osmo_mgcpc_ep_fsm_event_names, .timer_cb = osmo_mgcpc_ep_fsm_timer_cb, - /* The FSM termination will automatically trigger any mgcp_client_fsm instances to DLCX. */ + .pre_term = osmo_mgcpc_ep_fsm_pre_term, };