FreeCalypso > hg > themwi-system-sw
diff sip-in/mgw_ops.c @ 60:02761f1ae5e5
sip-in INVITE processing: got as far as CRCX completion
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 11 Sep 2022 15:42:54 -0800 |
parents | |
children | e12036337412 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sip-in/mgw_ops.c Sun Sep 11 15:42:54 2022 -0800 @@ -0,0 +1,204 @@ +/* + * In this module we implement all transactions from themwi-sip-in + * toward themwi-mgw. + */ + +#include <sys/types.h> +#include <sys/socket.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/tmgw_ctrl.h" +#include "../include/tmgw_const.h" +#include "call.h" + +extern struct call *call_list; + +struct call * +find_call_with_mgw_xact(xact_id) + uint32_t xact_id; +{ + struct call *call; + + for (call = call_list; call; call = call->next) + if (call->mgw_xact && call->mgw_xact_id == xact_id) + return call; + return 0; +} + +uint32_t +get_new_tmgw_xact_id() +{ + static uint32_t next_xact_id; + + for (;;) { + next_xact_id++; + if (!find_call_with_mgw_xact(next_xact_id)) + return next_xact_id; + } +} + +void +tmgw_send_crcx(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_CRCX; + req.transact_ref = get_new_tmgw_xact_id(); + req.ep_id = TMGW_EP_TYPE_GATEWAY; + req.setup_mask = TMGW_CTRL_MASK_PSTN_CONN; + bcopy(&call->pstn_rtp_remote, &req.pstn_addr, + sizeof(struct sockaddr_in)); + req.pstn_payload_type = + call->use_pcma ? PSTN_CODEC_PCMA : PSTN_CODEC_PCMU; + send_req_to_tmgw(&req); + call->mgw_xact = TMGW_CTRL_OP_CRCX; + call->mgw_xact_id = req.transact_ref; +} + +void +tmgw_send_mdcx_gsm_rtp(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_GSM_CONN; + bcopy(&call->gsm_rtp_osmo, &req.gsm_addr, + sizeof(struct sockaddr_storage)); + req.gsm_payload_type = call->gsm_payload_type; + req.gsm_payload_msg_type = call->gsm_payload_msg_type; + send_req_to_tmgw(&req); + call->mgw_state = MGW_STATE_CONNECTING; + call->mgw_xact = TMGW_CTRL_OP_MDCX; + call->mgw_xact_id = req.transact_ref; +} + +void +tmgw_send_dlcx(call) + struct call *call; +{ + struct tmgw_ctrl_req req; + + bzero(&req, sizeof req); + req.opcode = TMGW_CTRL_OP_DLCX; + 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_DELETING; + call->mgw_xact = TMGW_CTRL_OP_DLCX; + 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: + return; + default: + goto bad_state; + } + } +} + +static void +mdcx_response(call, msg) + struct call *call; + struct tmgw_ctrl_resp *msg; +{ + /* will be handled later */ +} + +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; + /* TODO: transition from TEARDOWN to DEAD_SIP */ +} + +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; + default: + syslog(LOG_CRIT, + "FATAL: invalid opcode 0x%x in call->msg_xact", opc); + exit(1); + } +}