FreeCalypso > hg > themwi-system-sw
diff sip-in/mgw_ops.c @ 141:e499e8db8b82
sip-in: handle call hold and retrieve
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 08 Oct 2022 13:28:30 -0800 |
parents | 5685412bd6aa |
children | 0ecbc3dc8f93 |
line wrap: on
line diff
--- a/sip-in/mgw_ops.c Sat Oct 08 11:48:26 2022 -0800 +++ b/sip-in/mgw_ops.c Sat Oct 08 13:28:30 2022 -0800 @@ -14,6 +14,7 @@ #include <strings.h> #include <syslog.h> #include "../include/gsm48_const.h" +#include "../include/mncc.h" #include "../include/tmgw_ctrl.h" #include "../include/tmgw_const.h" #include "call.h" @@ -87,6 +88,42 @@ } void +tmgw_send_mdcx_hold(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_MDCX; + req.transact_ref = get_new_tmgw_xact_id(); + req.ep_id = call->mgw_ep_id; + req.setup_mask = TMGW_CTRL_MASK_FWD_MODE; + req.fwd_mode = TMGW_FWD_MODE_INACTIVE; + send_req_to_tmgw(&req); + call->mgw_state = MGW_STATE_HOLD_OP; + call->mgw_xact = TMGW_CTRL_OP_MDCX; + call->mgw_xact_id = req.transact_ref; +} + +void +tmgw_send_mdcx_retrieve(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_MDCX; + req.transact_ref = get_new_tmgw_xact_id(); + req.ep_id = call->mgw_ep_id; + req.setup_mask = TMGW_CTRL_MASK_FWD_MODE; + req.fwd_mode = TMGW_FWD_MODE_SENDRECV; + send_req_to_tmgw(&req); + call->mgw_state = MGW_STATE_RETRIEVE_OP; + call->mgw_xact = TMGW_CTRL_OP_MDCX; + call->mgw_xact_id = req.transact_ref; +} + +void tmgw_send_dlcx(call) struct call *call; { @@ -186,7 +223,7 @@ } static void -handle_mdcx_fail(call, msg) +handle_mdcx_connect_fail(call, msg) struct call *call; struct tmgw_ctrl_resp *msg; { @@ -212,7 +249,7 @@ } static void -mdcx_response(call, msg) +mdcx_connect_response(call, msg) struct call *call; struct tmgw_ctrl_resp *msg; { @@ -236,7 +273,7 @@ tmgw_send_dlcx(call); switch (call->overall_state) { case OVERALL_STATE_ANSWERED: - handle_mdcx_fail(call, msg); + handle_mdcx_connect_fail(call, msg); return; case OVERALL_STATE_TEARDOWN: return; @@ -246,6 +283,77 @@ } } +static struct gsm_mncc_cause mgw_hold_retrieve_error = { + .coding = GSM48_CAUSE_CODING_GSM, + .location = GSM48_CAUSE_LOC_PRN_S_LU, + .value = GSM48_CC_CAUSE_NETWORK_OOO, +}; + +static void +mdcx_hold_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + if (call->overall_state == OVERALL_STATE_TEARDOWN) { + tmgw_send_dlcx(call); + return; + } + if (msg->res == TMGW_RESP_OK) { + call->mgw_state = MGW_STATE_HELD; + mncc_send_hold_ack(call); + } else { + call->overall_state = OVERALL_STATE_TEARDOWN; + tmgw_send_dlcx(call); + disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_NETWORK_OOO); + disconnect_sip(call, &mgw_hold_retrieve_error); + } +} + +static void +mdcx_retrieve_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + if (call->overall_state == OVERALL_STATE_TEARDOWN) { + tmgw_send_dlcx(call); + return; + } + if (msg->res == TMGW_RESP_OK) { + call->mgw_state = MGW_STATE_COMPLETE; + mncc_send_retrieve_ack(call); + } else { + call->overall_state = OVERALL_STATE_TEARDOWN; + tmgw_send_dlcx(call); + disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_NETWORK_OOO); + disconnect_sip(call, &mgw_hold_retrieve_error); + } +} + +static void +mdcx_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + switch (call->mgw_state) { + case MGW_STATE_CONNECTING: + mdcx_connect_response(call, msg); + return; + case MGW_STATE_HOLD_OP: + mdcx_hold_response(call, msg); + return; + case MGW_STATE_RETRIEVE_OP: + mdcx_retrieve_response(call, msg); + return; + default: + syslog(LOG_CRIT, + "FATAL: invalid MGW state 0x%x on MDCX response", + call->mgw_state); + exit(1); + } +} + static void dlcx_response(call, msg) struct call *call;