FreeCalypso > hg > themwi-system-sw
view mgw/mdcx.c @ 150:529906fddcfa
mgw DTMF timing fix in the corner case of no speech
arriving between the end of one DTMF and the start of next
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 14:10:29 -0800 |
parents | f062c32a5116 |
children | a6eb2de277f6 |
line wrap: on
line source
/* * In this module we implement our MDCX operation. */ #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/tmgw_ctrl.h" #include "../include/tmgw_const.h" #include "struct.h" #include "int_defs.h" extern struct endpoint *find_ep_by_id(); static void gsm_vars_init(ep) struct endpoint *ep; { switch (ep->gsm_payload_msg_type) { case GSM_TCHF_FRAME: ep->gsm_rtp_pkt_size = RTP_PACKET_SIZE_GSM_FR; ep->gsm_payload_magic = 0xD0; return; case GSM_TCHF_FRAME_EFR: ep->gsm_rtp_pkt_size = RTP_PACKET_SIZE_GSM_EFR; ep->gsm_payload_magic = 0xC0; return; } } mdcx_operation(ep, req) struct endpoint *ep; struct tmgw_ctrl_req *req; { int rc; if (req->setup_mask & TMGW_CTRL_MASK_GSM_CONN) { if (ep->ep_type != TMGW_EP_TYPE_GATEWAY) return TMGW_RESP_ERR_PROT; if (req->gsm_addr.ss_family != AF_INET) return TMGW_RESP_ERR_PARAM; if (req->gsm_payload_type > 0x7F) return TMGW_RESP_ERR_PARAM; switch (req->gsm_payload_msg_type) { case GSM_TCHF_FRAME: break; case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: case GSM_TCH_FRAME_AMR: return TMGW_RESP_ERR_NOTSUP; default: return TMGW_RESP_ERR_PARAM; } if (ep->gsm_payload_msg_type && ep->gsm_payload_msg_type != req->gsm_payload_msg_type) return TMGW_RESP_ERR_PROT; bcopy(&req->gsm_addr, &ep->rtp_gsm.remote_addr, sizeof(struct sockaddr_in)); ep->gsm_payload_type = req->gsm_payload_type; ep->gsm_payload_msg_type = req->gsm_payload_msg_type; gsm_vars_init(ep); } if (req->setup_mask & TMGW_CTRL_MASK_PSTN_CONN) { if (ep->ep_type != TMGW_EP_TYPE_GATEWAY) return TMGW_RESP_ERR_PROT; if (req->pstn_addr.ss_family != AF_INET) return TMGW_RESP_ERR_PARAM; switch (req->pstn_payload_type) { case PSTN_CODEC_PCMU: case PSTN_CODEC_PCMA: break; default: return TMGW_RESP_ERR_PARAM; } bcopy(&req->pstn_addr, &ep->rtp_pstn.remote_addr, sizeof(struct sockaddr_in)); ep->pstn_payload_type = req->pstn_payload_type; } if (req->setup_mask & TMGW_CTRL_MASK_FWD_MODE) { if (ep->ep_type != TMGW_EP_TYPE_GATEWAY || ep->rtp_gsm.remote_addr.sin_family != AF_INET || ep->rtp_pstn.remote_addr.sin_family != AF_INET) return TMGW_RESP_ERR_PROT; if (req->fwd_mode & TMGW_FWD_ENABLE_GSM2PSTN) { rc = gsm2pstn_init(ep); if (rc != TMGW_RESP_OK) return rc; } else if (ep->dtmf_pp) dtmf_stop_immediate(ep); if (req->fwd_mode & TMGW_FWD_ENABLE_PSTN2GSM) { rc = pstn2gsm_init(ep); if (rc != TMGW_RESP_OK) return rc; } ep->fwd_mode = req->fwd_mode; } return TMGW_RESP_OK; } void process_mdcx(conn, req, resp) struct ctrl_conn *conn; struct tmgw_ctrl_req *req; struct tmgw_ctrl_resp *resp; { struct endpoint *ep; ep = find_ep_by_id(conn, req->ep_id); if (!ep) { resp->res = TMGW_RESP_ERR_PROT; return; } resp->res = mdcx_operation(ep, req); }