FreeCalypso > hg > themwi-system-sw
view mncc/mncc_recv.c @ 110:c1c94b7fc2e2
sip-in call clearing: DEAD_SIP transition implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 28 Sep 2022 18:37:19 -0800 |
parents | 660126bd5f59 |
children |
line wrap: on
line source
/* * In this module we implement initial handling of MNCC messages * coming from OsmoMSC, dispatching them further as appropriate. */ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <syslog.h> #include "../include/mncc.h" #include "struct.h" #include "gsm_call.h" extern char *mncc_msg_name(); static void report_runt(msg) union mncc_msg *msg; { syslog(LOG_CRIT, "MNCC message type 0x%x from GSM is too short!", msg->msg_type); } static void handle_setup_ind(msg, msglen) struct gsm_mncc *msg; unsigned msglen; { struct gsm_call *call; if (msglen < sizeof(struct gsm_mncc)) { report_runt(msg); return; } syslog(LOG_DEBUG, "Rx MNCC_SETUP_IND from GSM, callref=0x%x", msg->callref); call = find_gsm_callref(msg->callref); if (call) { syslog(LOG_ERR, "duplicate MNCC_SETUP_IND for callref 0x%x", msg->callref); /* drop it like OsmoMSC's mncc_builtin does */ return; } /* further processing */ process_mo_call_setup(msg); } static void handle_signaling_msg(msg, msglen) struct gsm_mncc *msg; unsigned msglen; { struct gsm_call *call; if (msglen < sizeof(struct gsm_mncc)) { report_runt(msg); return; } syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x", mncc_msg_name(msg->msg_type), msg->callref); call = find_gsm_callref(msg->callref); if (!call) { syslog(LOG_ERR, "%s from GSM: callref 0x%x not found", mncc_msg_name(msg->msg_type), msg->callref); /* drop it like OsmoMSC's mncc_builtin does */ return; } if (msg->msg_type == MNCC_SETUP_CNF) preen_connected_number(msg); /* dispatch according to internal switch or socket */ if (call->socket) mncc_signal_to_socket(call, msg); else internal_switch_mncc(call, msg); } static void handle_release_msg(msg, msglen) struct gsm_mncc *msg; unsigned msglen; { struct gsm_call *call; if (msglen < sizeof(struct gsm_mncc)) { report_runt(msg); return; } syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x", mncc_msg_name(msg->msg_type), msg->callref); call = find_gsm_callref(msg->callref); if (!call) { syslog(LOG_ERR, "%s from GSM: callref 0x%x not found", mncc_msg_name(msg->msg_type), msg->callref); /* drop it like OsmoMSC's mncc_builtin does */ return; } /* dispatch according to internal switch or socket */ if (call->socket) { mncc_signal_to_socket(call, msg); syslog(LOG_DEBUG, "clearing socket call: GSM callref 0x%x, socket ref 0x%x", call->callref, call->socket_ref); extsock_dec_refcount(call->socket); call->gc_flag = 1; } else internal_switch_mncc(call, msg); } static void handle_rtp_msg(msg, msglen) struct gsm_mncc_rtp *msg; unsigned msglen; { struct gsm_call *call; if (msglen < sizeof(struct gsm_mncc_rtp)) { report_runt(msg); return; } syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x", mncc_msg_name(msg->msg_type), msg->callref); call = find_gsm_callref(msg->callref); if (!call) { syslog(LOG_ERR, "%s from GSM: callref 0x%x not found", mncc_msg_name(msg->msg_type), msg->callref); /* drop it like OsmoMSC's mncc_builtin does */ return; } /* only for socket connections - no RTP handling for internal */ if (call->socket) mncc_rtp_to_socket(call, msg); } static void handle_mncc_hello(msg, msglen) struct gsm_mncc_hello *msg; unsigned msglen; { if (msglen < sizeof(struct gsm_mncc_hello)) { syslog(LOG_CRIT, "MNCC_SOCKET_HELLO message is too short!"); exit(1); } if (msg->version != MNCC_SOCK_VERSION) { syslog(LOG_CRIT, "MNCC hello error: version number mismatch"); exit(1); } if (msg->mncc_size != sizeof(struct gsm_mncc)) { syslog(LOG_CRIT, "MNCC hello error: mncc_size mismatch"); exit(1); } } void mncc_msg_from_gsm(msg, msglen) union mncc_msg *msg; unsigned msglen; { switch (msg->msg_type) { case MNCC_SETUP_IND: handle_setup_ind(msg, msglen); return; case MNCC_SETUP_CNF: case MNCC_SETUP_COMPL_IND: case MNCC_CALL_CONF_IND: case MNCC_ALERT_IND: case MNCC_NOTIFY_IND: case MNCC_DISC_IND: case MNCC_FACILITY_IND: case MNCC_START_DTMF_IND: case MNCC_STOP_DTMF_IND: case MNCC_MODIFY_IND: case MNCC_MODIFY_CNF: case MNCC_MODIFY_REJ: case MNCC_HOLD_IND: case MNCC_RETRIEVE_IND: case MNCC_USERINFO_IND: handle_signaling_msg(msg, msglen); return; case MNCC_REL_IND: case MNCC_REL_CNF: case MNCC_REJ_IND: handle_release_msg(msg, msglen); return; case MNCC_RTP_CREATE: case MNCC_RTP_CONNECT: case MNCC_RTP_FREE: handle_rtp_msg(msg, msglen); return; case MNCC_SOCKET_HELLO: handle_mncc_hello(msg, msglen); return; default: syslog(LOG_CRIT, "unknown MNCC message type 0x%x from GSM", msg->msg_type); } }