FreeCalypso > hg > themwi-system-sw
diff mtctest/sig_handler.c @ 21:cc0e1c6e33c3
themwi-test-mtc utility written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 28 Jun 2022 18:25:28 -0800 (2022-06-29) |
parents | |
children | e8e82a4bf12b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtctest/sig_handler.c Tue Jun 28 18:25:28 2022 -0800 @@ -0,0 +1,323 @@ +/* + * In this module we handle all incoming messages from MNCC, + * printing all of them and generating protocol-required responses + * for some. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "../include/mncc.h" +#include "../include/gsm48_const.h" + +extern int disconnect_mode; + +static void +print_bearer_cap(bcap) + struct gsm_mncc_bearer_cap *bcap; +{ + int i, sv; + + printf("Bearer cap: itcap=%d tmod=%d coding=%d rrq=%d\n", + bcap->transfer, bcap->mode, bcap->coding, bcap->radio); + printf(" speech: CTM=%d sv", bcap->speech_ctm); + for (i = 0; i < 8; i++) { + sv = bcap->speech_ver[i]; + if (sv < 0) + break; + printf(" %d", sv); + } + putchar('\n'); + printf(" data: ra=%d sig=%d async=%d nstop=%d ndata=%d\n", + bcap->data.rate_adaption, bcap->data.sig_access, + bcap->data.async, bcap->data.nr_stop_bits, + bcap->data.nr_data_bits); + printf(" urate=%d par=%d irate=%d transp=%d mtype=%d\n", + bcap->data.user_rate, bcap->data.parity, + bcap->data.interm_rate, bcap->data.transp, + bcap->data.modem_type); +} + +static void +print_cc_cap(cc) + struct gsm_mncc_cccap *cc; +{ + printf("CC capabilities: DTMF=%d PCP=%d\n", cc->dtmf, cc->pcp); +} + +static void +print_cause(cause) + struct gsm_mncc_cause *cause; +{ + int i; + + printf("Cause: loc=%d coding=%d value=%d", cause->location, + cause->coding, cause->value); + if (cause->rec) + printf(" rec=0x%02X", cause->rec_val); + for (i = 0; i < cause->diag_len; i++) { + if (!(i & 15)) { + putchar('\n'); + putchar(' '); + } + printf(" %02X", cause->diag[i] & 0xFF); + } + putchar('\n'); +} + +static void +print_progress(prog) + struct gsm_mncc_progress *prog; +{ + printf("Progress: loc=%d coding=%d descr=0x%02X", prog->location, + prog->coding, prog->descr); +} + +static void +print_useruser(uu) + struct gsm_mncc_useruser *uu; +{ + printf("User-User IE: proto=0x%02X\n", uu->proto); + /* dump to be implemented if and when we actually get a UU somewhere */ +} + +static void +print_keypad(kp) + int kp; +{ + if (kp >= '!' && kp <= '~') + printf("Keypad code: %c\n", kp); + else + printf("Keypad code: 0x%02X\n", kp); +} + +static void +print_facility(fac) + struct gsm_mncc_facility *fac; +{ + int i; + + printf("Facility IE: %d byte(s)", fac->len); + for (i = 0; i < fac->len; i++) { + if (!(i & 15)) { + putchar('\n'); + putchar(' '); + } + printf(" %02X", fac->info[i] & 0xFF); + } + putchar('\n'); +} + +static void +print_ssver(ssv) + struct gsm_mncc_ssversion *ssv; +{ + int i; + + printf("SS version IE: %d byte(s)", ssv->len); + for (i = 0; i < ssv->len; i++) { + if (!(i & 15)) { + putchar('\n'); + putchar(' '); + } + printf(" %02X", ssv->info[i] & 0xFF); + } + putchar('\n'); +} + +static void +print_fields(msg) + struct gsm_mncc *msg; +{ + if (msg->fields & MNCC_F_BEARER_CAP) + print_bearer_cap(&msg->bearer_cap); + if (msg->fields & MNCC_F_CCCAP) + print_cc_cap(&msg->cccap); + if (msg->fields & MNCC_F_CAUSE) + print_cause(&msg->cause); + if (msg->fields & MNCC_F_PROGRESS) + print_progress(&msg->progress); + if (msg->fields & MNCC_F_USERUSER) + print_useruser(&msg->useruser); + if (msg->more) + printf("More data flag set\n"); + if (msg->fields & MNCC_F_KEYPAD) + print_keypad(msg->keypad); + if (msg->fields & MNCC_F_FACILITY) + print_facility(&msg->facility); + if (msg->fields & MNCC_F_SSVERSION) + print_ssver(&msg->ssversion); +} + +static void +send_connect_ack() +{ + struct gsm_mncc ack; + + printf("Sending connect ack\n"); + bzero(&ack, sizeof(struct gsm_mncc)); + ack.msg_type = MNCC_SETUP_COMPL_REQ; + ack.callref = 1; + send_mncc_to_gsm(&ack, sizeof(struct gsm_mncc)); +} + +static void +handle_signaling_msg(msg, msglen) + struct gsm_mncc *msg; + unsigned msglen; +{ + if (msglen != sizeof(struct gsm_mncc)) { + fprintf(stderr, + "error: Rx MNCC message type 0x%x has wrong length\n", + msg->msg_type); + exit(1); + } + if (msg->callref != 1) { + fprintf(stderr, + "error: Rx MNCC message type 0x%x has unexpected callref 0x%x\n", + msg->msg_type, msg->callref); + exit(1); + } + switch (msg->msg_type) { + case MNCC_SETUP_CNF: + printf("MNCC_SETUP_CNF: call is answered\n"); + print_fields(msg); + send_connect_ack(); + return; + case MNCC_CALL_CONF_IND: + printf("MNCC_CALL_CONF_IND: call is confirmed\n"); + print_fields(msg); + return; + case MNCC_ALERT_IND: + printf("MNCC_ALERT_IND: call is alerting\n"); + print_fields(msg); + return; + case MNCC_NOTIFY_IND: + printf("NNCC_NOTIFY_IND: NOTIFY byte from MS: 0x%02X\n", + msg->notify); + return; + case MNCC_DISC_IND: + printf("MNCC_DISC_IND: MS initiates disconnect\n"); + print_fields(msg); + disconnect_mode = 1; + printf("Responding with release request\n"); + msg->msg_type = MNCC_REL_REQ; + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + return; + case MNCC_FACILITY_IND: + printf("MNCC_FACILITY_IND: call-related SS from MS\n"); + print_fields(msg); + return; + case MNCC_START_DTMF_IND: + printf("MNCC_START_DTMF_IND: MS sending DTMF start\n"); + print_fields(msg); + 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: + printf("MNCC_STOP_DTMF_IND: MS sending DTMF stop\n"); + msg->msg_type = MNCC_STOP_DTMF_RSP; + send_mncc_to_gsm(msg, sizeof(struct gsm_mncc)); + return; + case MNCC_MODIFY_IND: + printf("MNCC_MODIFY_IND: MS requests call modification\n"); + print_fields(msg); + 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: + printf("MNCC_HOLD_IND: MS requests call hold\n"); + 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: + printf("MNCC_RETRIEVE_IND: MS requests call retrieve\n"); + 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; + case MNCC_USERINFO_IND: + printf("MNCC_USERINFO_IND: user-user info\n"); + print_fields(msg); + return; + case MNCC_REL_IND: + printf("MNCC_REL_IND: final release\n"); + print_fields(msg); + exit(0); + case MNCC_REL_CNF: + printf("MNCC_REL_CNF: final release in response to request\n"); + print_fields(msg); + exit(0); + case MNCC_REJ_IND: + printf("MNCC_REJ_IND: MT call rejected\n"); + print_fields(msg); + exit(0); + } +} + +static void +handle_rtp_create(msg, msglen) + struct gsm_mncc_rtp *msg; + unsigned msglen; +{ + if (msglen != sizeof(struct gsm_mncc_rtp)) { + fprintf(stderr, + "error: Rx MNCC message type 0x%x has wrong length\n", + msg->msg_type); + exit(1); + } + if (msg->callref != 1) { + fprintf(stderr, + "error: Rx MNCC message type 0x%x has unexpected callref 0x%x\n", + msg->msg_type, msg->callref); + exit(1); + } + printf("MNCC_RTP_CREATE: RTP info from MSC\n"); + printf("payload_type=0x%x payload_msg_type=0x%x\n", msg->payload_type, + msg->payload_msg_type); +} + +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: + fprintf(stderr, + "error: received unexpected MNCC message type 0x%x\n", + msg->msg_type); + exit(1); + } +}