FreeCalypso > hg > themwi-system-sw
changeset 128:5685412bd6aa
sip-in: pass DTMF start & stop to themwi-mgw
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 01 Oct 2022 23:07:01 -0800 |
parents | f062c32a5116 |
children | b7cd66acb123 |
files | sip-in/call.h sip-in/disconnect.c sip-in/mgw_ops.c sip-in/mncc_handle.c |
diffstat | 4 files changed, 155 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/sip-in/call.h Sat Oct 01 20:31:15 2022 -0800 +++ b/sip-in/call.h Sat Oct 01 23:07:01 2022 -0800 @@ -42,6 +42,8 @@ char invite_fail[80]; unsigned sip_tx_count; time_t sip_clear_time; + int dtmf_digit; + int dtmf_pending_stop; }; #define OVERALL_STATE_CRCX 1 @@ -75,3 +77,4 @@ #define MGW_STATE_CONNECTING 2 #define MGW_STATE_COMPLETE 3 #define MGW_STATE_DELETING 4 +#define MGW_STATE_DTMF_OP 5
--- a/sip-in/disconnect.c Sat Oct 01 20:31:15 2022 -0800 +++ b/sip-in/disconnect.c Sat Oct 01 23:07:01 2022 -0800 @@ -44,6 +44,7 @@ case MGW_STATE_NO_EXIST: case MGW_STATE_CONNECTING: case MGW_STATE_DELETING: + case MGW_STATE_DTMF_OP: return; case MGW_STATE_ALLOCATED: case MGW_STATE_COMPLETE:
--- a/sip-in/mgw_ops.c Sat Oct 01 20:31:15 2022 -0800 +++ b/sip-in/mgw_ops.c Sat Oct 01 23:07:01 2022 -0800 @@ -102,6 +102,39 @@ call->mgw_xact_id = req.transact_ref; } +void +tmgw_send_dtmf_start(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_DTMF_START; + req.transact_ref = get_new_tmgw_xact_id(); + req.ep_id = call->mgw_ep_id; + req.fwd_mode = call->dtmf_digit; + send_req_to_tmgw(&req); + call->mgw_state = MGW_STATE_DTMF_OP; + call->mgw_xact = TMGW_CTRL_OP_DTMF_START; + call->mgw_xact_id = req.transact_ref; +} + +void +tmgw_send_dtmf_stop(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_DTMF_STOP; + req.transact_ref = get_new_tmgw_xact_id(); + req.ep_id = call->mgw_ep_id; + send_req_to_tmgw(&req); + call->mgw_state = MGW_STATE_DTMF_OP; + 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; @@ -227,6 +260,39 @@ 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; @@ -253,6 +319,12 @@ 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);
--- a/sip-in/mncc_handle.c Sat Oct 01 20:31:15 2022 -0800 +++ b/sip-in/mncc_handle.c Sat Oct 01 23:07:01 2022 -0800 @@ -39,6 +39,46 @@ call->overall_state = OVERALL_STATE_CONNECTED; } +void +mncc_dtmf_start_ok(call) + struct call *call; +{ + struct gsm_mncc msg; + + bzero(&msg, sizeof(struct gsm_mncc)); + msg.msg_type = MNCC_START_DTMF_RSP; + msg.callref = call->mncc_callref; + msg.fields |= MNCC_F_KEYPAD; + msg.keypad = call->dtmf_digit; + send_mncc_to_gsm(&msg, sizeof(struct gsm_mncc)); +} + +void +mncc_dtmf_start_err(call) + struct call *call; +{ + struct gsm_mncc msg; + + bzero(&msg, sizeof(struct gsm_mncc)); + msg.msg_type = MNCC_START_DTMF_REJ; + msg.callref = call->mncc_callref; + mncc_set_cause(&msg, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_PROTO_ERR); + send_mncc_to_gsm(&msg, sizeof(struct gsm_mncc)); +} + +void +mncc_dtmf_stop_ok(call) + struct call *call; +{ + struct gsm_mncc msg; + + bzero(&msg, sizeof(struct gsm_mncc)); + msg.msg_type = MNCC_STOP_DTMF_RSP; + msg.callref = call->mncc_callref; + send_mncc_to_gsm(&msg, sizeof(struct gsm_mncc)); +} + static void handle_alerting(call, msg) struct call *call; @@ -122,6 +162,43 @@ } static void +handle_dtmf_start(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + if (!(msg->fields & MNCC_F_KEYPAD) || + !is_valid_dtmf_digit(msg->keypad)) { + msg->msg_type = MNCC_START_DTMF_REJ; + mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_INVAL_MAND_INF); + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + return; + } + if (call->overall_state != OVERALL_STATE_CONNECTED || + call->mgw_state != MGW_STATE_COMPLETE) { + msg->msg_type = MNCC_START_DTMF_REJ; + mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_MSGTYPE_INCOMPAT); + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + return; + } + call->dtmf_digit = msg->keypad; + tmgw_send_dtmf_start(call); +} + +static void +handle_dtmf_stop(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + if (call->overall_state == OVERALL_STATE_CONNECTED && + call->mgw_state == MGW_STATE_COMPLETE) + tmgw_send_dtmf_stop(call); + else + call->dtmf_pending_stop = 1; +} + +static void handle_signaling_msg(msg, msglen) struct gsm_mncc *msg; unsigned msglen; @@ -157,14 +234,10 @@ handle_final_release(call, msg); return; case MNCC_START_DTMF_IND: - msg->msg_type = MNCC_START_DTMF_REJ; - mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_SERV_OPT_UNIMPL); - send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + handle_dtmf_start(call, msg); return; case MNCC_STOP_DTMF_IND: - msg->msg_type = MNCC_STOP_DTMF_RSP; - send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + handle_dtmf_stop(call, msg); return; case MNCC_MODIFY_IND: msg->msg_type = MNCC_MODIFY_REJ;