FreeCalypso > hg > themwi-system-sw
changeset 151:0ecbc3dc8f93
sip-in: split mgw_resp.c from mgw_ops.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 15:58:42 -0800 |
parents | 529906fddcfa |
children | 7176dc850d7a |
files | sip-in/Makefile sip-in/mgw_ops.c sip-in/mgw_resp.c |
diffstat | 3 files changed, 292 insertions(+), 272 deletions(-) [+] |
line wrap: on
line diff
--- a/sip-in/Makefile Tue Oct 11 14:10:29 2022 -0800 +++ b/sip-in/Makefile Tue Oct 11 15:58:42 2022 -0800 @@ -3,8 +3,8 @@ PROG= themwi-sip-in OBJS= bye_in.o bye_out.o call_clear.o call_list.o call_setup.o cancel.o \ disconnect.o invite_dup.o invite_init.o invite_resp.o main.o mgw_ops.o \ - mgw_sock.o mncc_handle.o mncc_sock.o prack.o readconf.o retrans.o \ - shutdown.o sip_ack.o sip_log.o sip_uas.o sip_udp.o + mgw_resp.o mgw_sock.o mncc_handle.o mncc_sock.o prack.o readconf.o \ + retrans.o shutdown.o sip_ack.o sip_log.o sip_uas.o sip_udp.o LIBS= ../libnumdb/libnumdb.a ../libsip/libsip.a ../libutil/libutil.a INSTBIN=/usr/local/bin
--- a/sip-in/mgw_ops.c Tue Oct 11 14:10:29 2022 -0800 +++ b/sip-in/mgw_ops.c Tue Oct 11 15:58:42 2022 -0800 @@ -13,8 +13,6 @@ #include <string.h> #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" @@ -171,271 +169,3 @@ call->mgw_xact = TMGW_CTRL_OP_DTMF_STOP; call->mgw_xact_id = req.transact_ref; } - -static void -handle_crcx_fail(call, msg) - struct call *call; - struct tmgw_ctrl_resp *msg; -{ - call->overall_state = OVERALL_STATE_TEARDOWN; - strcpy(call->invite_fail, "503 Gateway resource allocation failure"); - signal_invite_error(call); -} - -static void -crcx_response(call, msg) - struct call *call; - struct tmgw_ctrl_resp *msg; -{ - if (msg->res == TMGW_RESP_OK) { - call->mgw_state = MGW_STATE_ALLOCATED; - call->mgw_ep_id = msg->ep_id; - bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw, - sizeof(struct sockaddr_storage)); - bcopy(&msg->pstn_addr, &call->pstn_rtp_local, - sizeof(struct sockaddr_in)); - switch (call->overall_state) { - case OVERALL_STATE_CRCX: - proceed_with_call_setup(call); - return; - case OVERALL_STATE_TEARDOWN: - tmgw_send_dlcx(call); - return; - default: - bad_state: - syslog(LOG_CRIT, - "FATAL: invalid overall state 0x%x on CRCX response", - call->overall_state); - exit(1); - } - } else { - switch (call->overall_state) { - case OVERALL_STATE_CRCX: - handle_crcx_fail(call, msg); - return; - case OVERALL_STATE_TEARDOWN: - transition_dead_sip(call); - return; - default: - goto bad_state; - } - } -} - -static void -handle_mdcx_connect_fail(call, msg) - struct call *call; - struct tmgw_ctrl_resp *msg; -{ - call->overall_state = OVERALL_STATE_TEARDOWN; - switch (msg->res) { - case TMGW_RESP_ERR_RSRC: - disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - strcpy(call->invite_fail, - "503 Gateway resource allocation failure"); - break; - case TMGW_RESP_ERR_NOTSUP: - disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); - strcpy(call->invite_fail, "502 Gateway internal error"); - break; - default: - disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_PROTO_ERR); - strcpy(call->invite_fail, "502 Gateway internal error"); - } - signal_invite_error(call); -} - -static void -mdcx_connect_response(call, msg) - struct call *call; - struct tmgw_ctrl_resp *msg; -{ - if (msg->res == TMGW_RESP_OK) { - call->mgw_state = MGW_STATE_COMPLETE; - switch (call->overall_state) { - case OVERALL_STATE_ANSWERED: - signal_invite_200(call); - return; - case OVERALL_STATE_TEARDOWN: - tmgw_send_dlcx(call); - return; - default: - bad_state: - syslog(LOG_CRIT, - "FATAL: invalid overall state 0x%x on MDCX response", - call->overall_state); - exit(1); - } - } else { - tmgw_send_dlcx(call); - switch (call->overall_state) { - case OVERALL_STATE_ANSWERED: - handle_mdcx_connect_fail(call, msg); - return; - case OVERALL_STATE_TEARDOWN: - return; - default: - goto bad_state; - } - } -} - -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; - struct tmgw_ctrl_resp *msg; -{ - if (msg->res != TMGW_RESP_OK) { - syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x", - msg->res); - exit(1); - } - call->mgw_state = MGW_STATE_NO_EXIST; - transition_dead_sip(call); -} - -static void -dtmf_start_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) - mncc_dtmf_start_ok(call); - else - mncc_dtmf_start_err(call); - if (call->dtmf_pending_stop) - tmgw_send_dtmf_stop(call); - else - call->mgw_state = MGW_STATE_COMPLETE; -} - -static void -dtmf_stop_response(call, msg) - struct call *call; - struct tmgw_ctrl_resp *msg; -{ - if (call->overall_state == OVERALL_STATE_TEARDOWN) { - tmgw_send_dlcx(call); - return; - } - mncc_dtmf_stop_ok(call); - call->mgw_state = MGW_STATE_COMPLETE; - call->dtmf_pending_stop = 0; -} - -void -process_tmgw_response(msg) - struct tmgw_ctrl_resp *msg; -{ - struct call *call; - unsigned opc; - - call = find_call_with_mgw_xact(msg->transact_ref); - if (!call) { - syslog(LOG_CRIT, - "FATAL: response from TMGW xact 0x%x does not match any call", - msg->transact_ref); - exit(1); - } - opc = call->mgw_xact; - call->mgw_xact = 0; - switch (opc) { - case TMGW_CTRL_OP_CRCX: - crcx_response(call, msg); - return; - case TMGW_CTRL_OP_MDCX: - mdcx_response(call, msg); - return; - case TMGW_CTRL_OP_DLCX: - dlcx_response(call, msg); - return; - case TMGW_CTRL_OP_DTMF_START: - dtmf_start_response(call, msg); - return; - case TMGW_CTRL_OP_DTMF_STOP: - dtmf_stop_response(call, msg); - return; - default: - syslog(LOG_CRIT, - "FATAL: invalid opcode 0x%x in call->msg_xact", opc); - exit(1); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sip-in/mgw_resp.c Tue Oct 11 15:58:42 2022 -0800 @@ -0,0 +1,290 @@ +/* + * In this module we implement our handling of all responses + * from themwi-mgw. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#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" + +extern struct call *find_call_with_mgw_xact(); + +static void +handle_crcx_fail(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + call->overall_state = OVERALL_STATE_TEARDOWN; + strcpy(call->invite_fail, "503 Gateway resource allocation failure"); + signal_invite_error(call); +} + +static void +crcx_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + if (msg->res == TMGW_RESP_OK) { + call->mgw_state = MGW_STATE_ALLOCATED; + call->mgw_ep_id = msg->ep_id; + bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw, + sizeof(struct sockaddr_storage)); + bcopy(&msg->pstn_addr, &call->pstn_rtp_local, + sizeof(struct sockaddr_in)); + switch (call->overall_state) { + case OVERALL_STATE_CRCX: + proceed_with_call_setup(call); + return; + case OVERALL_STATE_TEARDOWN: + tmgw_send_dlcx(call); + return; + default: + bad_state: + syslog(LOG_CRIT, + "FATAL: invalid overall state 0x%x on CRCX response", + call->overall_state); + exit(1); + } + } else { + switch (call->overall_state) { + case OVERALL_STATE_CRCX: + handle_crcx_fail(call, msg); + return; + case OVERALL_STATE_TEARDOWN: + transition_dead_sip(call); + return; + default: + goto bad_state; + } + } +} + +static void +handle_mdcx_connect_fail(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + call->overall_state = OVERALL_STATE_TEARDOWN; + switch (msg->res) { + case TMGW_RESP_ERR_RSRC: + disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_RESOURCE_UNAVAIL); + strcpy(call->invite_fail, + "503 Gateway resource allocation failure"); + break; + case TMGW_RESP_ERR_NOTSUP: + disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); + strcpy(call->invite_fail, "502 Gateway internal error"); + break; + default: + disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_PROTO_ERR); + strcpy(call->invite_fail, "502 Gateway internal error"); + } + signal_invite_error(call); +} + +static void +mdcx_connect_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + if (msg->res == TMGW_RESP_OK) { + call->mgw_state = MGW_STATE_COMPLETE; + switch (call->overall_state) { + case OVERALL_STATE_ANSWERED: + signal_invite_200(call); + return; + case OVERALL_STATE_TEARDOWN: + tmgw_send_dlcx(call); + return; + default: + bad_state: + syslog(LOG_CRIT, + "FATAL: invalid overall state 0x%x on MDCX response", + call->overall_state); + exit(1); + } + } else { + tmgw_send_dlcx(call); + switch (call->overall_state) { + case OVERALL_STATE_ANSWERED: + handle_mdcx_connect_fail(call, msg); + return; + case OVERALL_STATE_TEARDOWN: + return; + default: + goto bad_state; + } + } +} + +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; + struct tmgw_ctrl_resp *msg; +{ + if (msg->res != TMGW_RESP_OK) { + syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x", + msg->res); + exit(1); + } + call->mgw_state = MGW_STATE_NO_EXIST; + transition_dead_sip(call); +} + +static void +dtmf_start_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) + mncc_dtmf_start_ok(call); + else + mncc_dtmf_start_err(call); + if (call->dtmf_pending_stop) + tmgw_send_dtmf_stop(call); + else + call->mgw_state = MGW_STATE_COMPLETE; +} + +static void +dtmf_stop_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + if (call->overall_state == OVERALL_STATE_TEARDOWN) { + tmgw_send_dlcx(call); + return; + } + mncc_dtmf_stop_ok(call); + call->mgw_state = MGW_STATE_COMPLETE; + call->dtmf_pending_stop = 0; +} + +void +process_tmgw_response(msg) + struct tmgw_ctrl_resp *msg; +{ + struct call *call; + unsigned opc; + + call = find_call_with_mgw_xact(msg->transact_ref); + if (!call) { + syslog(LOG_CRIT, + "FATAL: response from TMGW xact 0x%x does not match any call", + msg->transact_ref); + exit(1); + } + opc = call->mgw_xact; + call->mgw_xact = 0; + switch (opc) { + case TMGW_CTRL_OP_CRCX: + crcx_response(call, msg); + return; + case TMGW_CTRL_OP_MDCX: + mdcx_response(call, msg); + return; + case TMGW_CTRL_OP_DLCX: + dlcx_response(call, msg); + return; + case TMGW_CTRL_OP_DTMF_START: + dtmf_start_response(call, msg); + return; + case TMGW_CTRL_OP_DTMF_STOP: + dtmf_stop_response(call, msg); + return; + default: + syslog(LOG_CRIT, + "FATAL: invalid opcode 0x%x in call->msg_xact", opc); + exit(1); + } +}