FreeCalypso > hg > themwi-system-sw
diff sip-in/mncc_handle.c @ 63:e5aee661e3b2
sip-in: beginning to handle incoming MNCC messages from themwi-mncc
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 18 Sep 2022 15:01:11 -0800 |
parents | |
children | 7c0309df59f8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sip-in/mncc_handle.c Sun Sep 18 15:01:11 2022 -0800 @@ -0,0 +1,174 @@ +/* + * In this module we implement our handling of call control messages + * from OsmoMSC relayed to us via themwi-mncc. + */ + +#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/mncc.h" +#include "../include/gsm48_const.h" +#include "call.h" + +extern struct call *find_call_by_mncc_callref(); + +static void +handle_alerting(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + /* handling to be implemented */ +} + +static void +handle_answer(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + /* handling to be implemented */ +} + +static void +handle_disconnect_ind(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + /* handling to be implemented */ +} + +static void +handle_final_release(call, msg) + struct call *call; + struct gsm_mncc *msg; +{ + /* handling to be implemented */ +} + +static void +handle_signaling_msg(msg, msglen) + struct gsm_mncc *msg; + unsigned msglen; +{ + struct call *call; + + if (msglen != sizeof(struct gsm_mncc)) { + syslog(LOG_CRIT, + "FATAL: Rx MNCC message type 0x%x has wrong length", + msg->msg_type); + exit(1); + } + call = find_call_by_mncc_callref(msg->callref); + if (!call) { + syslog(LOG_CRIT, + "error: Rx MNCC message type 0x%x has invalid callref 0x%x", + msg->msg_type, msg->callref); + exit(1); + } + switch (msg->msg_type) { + case MNCC_SETUP_CNF: + handle_answer(call, msg); + return; + case MNCC_ALERT_IND: + handle_alerting(call, msg); + return; + case MNCC_DISC_IND: + handle_disconnect_ind(call, msg); + return; + case MNCC_REL_IND: + case MNCC_REL_CNF: + case MNCC_REJ_IND: + 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)); + return; + case MNCC_STOP_DTMF_IND: + msg->msg_type = MNCC_STOP_DTMF_RSP; + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + return; + case MNCC_MODIFY_IND: + msg->msg_type = MNCC_MODIFY_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)); + return; + case MNCC_HOLD_IND: + msg->msg_type = MNCC_HOLD_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)); + return; + case MNCC_RETRIEVE_IND: + msg->msg_type = MNCC_RETRIEVE_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)); + return; + } +} + +static void +handle_rtp_create(msg, msglen) + struct gsm_mncc_rtp *msg; + unsigned msglen; +{ + struct call *call; + + if (msglen != sizeof(struct gsm_mncc_rtp)) { + syslog(LOG_CRIT, + "FATAL: Rx MNCC message type 0x%x has wrong length", + msg->msg_type); + exit(1); + } + call = find_call_by_mncc_callref(msg->callref); + if (!call) { + syslog(LOG_CRIT, + "error: Rx MNCC message type 0x%x has invalid callref 0x%x", + msg->msg_type, msg->callref); + exit(1); + } + /* handling to be implemented */ +} + +void +msg_from_mncc(msg, msglen) + union mncc_msg *msg; + unsigned msglen; +{ + switch (msg->msg_type) { + case MNCC_SETUP_CNF: + 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_HOLD_IND: + case MNCC_RETRIEVE_IND: + case MNCC_USERINFO_IND: + case MNCC_REL_IND: + case MNCC_REL_CNF: + case MNCC_REJ_IND: + handle_signaling_msg(msg, msglen); + return; + case MNCC_RTP_CREATE: + handle_rtp_create(msg, msglen); + return; + default: + syslog(LOG_CRIT, + "FATAL: received unexpected MNCC message type 0x%x", + msg->msg_type); + exit(1); + } +}