FreeCalypso > hg > themwi-interim
diff mtctest/setup.c @ 5:e7b192a5dee5
mtctest: initial import from old ThemWi
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 09 Jun 2024 00:58:38 +0000 |
parents | |
children | 33d8b3177540 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtctest/setup.c Sun Jun 09 00:58:38 2024 +0000 @@ -0,0 +1,243 @@ +/* + * In this module we compose the MNCC_SETUP_REQ message + * initiating our test MT call. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <ctype.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" +#include "../include/number_db_v2.h" +#include "../libnumdb2/lookup_func.h" + +struct gsm_mncc setup_msg; + +static void +set_called_number(arg) + char *arg; +{ + int rc, ndig; + char short_num[5], long_num[12]; + struct short_number_rec *snum; + + if (!strncmp(arg, "imsi:", 5)) { + rc = grok_imsi_user_arg(arg, setup_msg.imsi); + if (rc < 0) { + fprintf(stderr, + "error: call-by-IMSI destination \"%s\" is invalid\n", + arg); + exit(1); + } + return; + } + if (arg[0] == '+') { + if (arg[1] != '1') { + fprintf(stderr, + "error: plus-format call destination number must begin with 1\n"); + exit(1); + } + if (grok_number_string(arg+1, 1) != 11) { +bad_plus1: fprintf(stderr, + "error: malformed +1 call destination number\n"); + exit(1); + } + dehyphen_number_string(arg+1, setup_msg.called.number); + if (!is_nanp_valid_prefix(setup_msg.called.number+1)) + goto bad_plus1; + setup_msg.called.type = GSM48_TON_INTERNATIONAL; + setup_msg.called.plan = GSM48_NPI_ISDN_E164; + setup_msg.fields |= MNCC_F_CALLED; + return; + } + ndig = grok_number_string(arg, 1); + switch (ndig) { + case 4: + dehyphen_number_string(arg, short_num); + if (read_number_db() < 0) { + fprintf(stderr, "error reading number database\n"); + exit(1); + } + snum = numdb_lookup_short(short_num); + if (!snum) { + fprintf(stderr, + "error: short dial number %s is not valid\n", + short_num); + exit(1); + } + switch (snum->short_num_type) { + case SHORT_NUM_TYPE_ABBREV: + setup_msg.called.type = GSM48_TON_INTERNATIONAL; + setup_msg.called.plan = GSM48_NPI_ISDN_E164; + sprintf(setup_msg.called.number, "1%03u%03u%04u", + snum->fullnum_prefix[0], + snum->fullnum_prefix[1], snum->short_num); + break; + case SHORT_NUM_TYPE_ITN: + setup_msg.called.type = GSM48_TON_NET_SPEC; + setup_msg.called.plan = GSM48_NPI_PRIVATE; + strcpy(setup_msg.called.number, short_num); + break; + default: + fprintf(stderr, + "error: short dial number %s is not abbrev or ITN\n", + short_num); + exit(1); + } + setup_msg.fields |= MNCC_F_CALLED; + return; + case 10: + dehyphen_number_string(arg, long_num); + if (!is_nanp_valid_prefix(long_num)) + break; + setup_msg.called.type = GSM48_TON_INTERNATIONAL; + setup_msg.called.plan = GSM48_NPI_ISDN_E164; + setup_msg.called.number[0] = '1'; + strcpy(setup_msg.called.number+1, long_num); + setup_msg.fields |= MNCC_F_CALLED; + return; + case 11: + dehyphen_number_string(arg, long_num); + if (long_num[0] != '1') + break; + if (!is_nanp_valid_prefix(long_num+1)) + break; + setup_msg.called.type = GSM48_TON_INTERNATIONAL; + setup_msg.called.plan = GSM48_NPI_ISDN_E164; + strcpy(setup_msg.called.number, long_num); + setup_msg.fields |= MNCC_F_CALLED; + return; + } + fprintf(stderr, "error: call destination number \"%s\" is invalid\n", + arg); + exit(1); +} + +static void +set_calling_number(arg) + char *arg; +{ + unsigned ndig; + int c; + + if (!strcmp(arg, "unavail")) { + setup_msg.calling.present = GSM48_PRES_UNAVAIL; + return; + } + if (!strcmp(arg, "blocked")) { + setup_msg.calling.present = GSM48_PRES_RESTR; + return; + } + if (*arg == '+') { + setup_msg.calling.type = GSM48_TON_INTERNATIONAL; + arg++; + } + for (ndig = 0; *arg; ) { + c = *arg++; + if (c == ',') + break; + if (c == '-') + continue; + if (!is_valid_ext_digit(c)) { + fprintf(stderr, + "error: calling number argument contains invalid digit \'%c\'\n", + c); + exit(1); + } + if (ndig >= 32) { + fprintf(stderr, + "error: calling number argument is too long\n"); + exit(1); + } + setup_msg.calling.number[ndig] = c; + ndig++; + } + if (!ndig) { + fprintf(stderr, + "error: calling number argument has no digits\n"); + exit(1); + } + setup_msg.calling.plan = GSM48_NPI_ISDN_E164; + for (;;) { + while (*arg == ',') + arg++; + if (!*arg) + return; + if (!strncmp(arg, "ton=", 4)) { + arg += 4; + if (arg[0] >= '0' && arg[0] <= '7' && !isdigit(arg[1])){ + setup_msg.calling.type = *arg - '0'; + arg++; + } else { + fprintf(stderr, + "error: calling number argument contains invalid ton= part\n"); + exit(1); + } + } else if (!strncmp(arg, "npi=", 4)) { + arg += 4; + if (arg[0] >= '0' && arg[0] <= '9' && !isdigit(arg[1])){ + setup_msg.calling.plan = *arg - '0'; + arg++; + } else if (arg[0] == '1' && arg[1] >= '0' && + arg[1] <= '5' && !isdigit(arg[2])) { + setup_msg.calling.plan = atoi(arg); + arg += 2; + } else { + fprintf(stderr, + "error: calling number argument contains invalid npi= part\n"); + exit(1); + } + } else if (!strncmp(arg, "restr", 5)) { + arg += 5; + setup_msg.calling.present = GSM48_PRES_RESTR; + } else if (!strncmp(arg, "vp", 2)) { + arg += 2; + setup_msg.calling.screen = GSM48_SCRN_USER_PASS; + } else if (!strncmp(arg, "vf", 2)) { + arg += 2; + setup_msg.calling.screen = GSM48_SCRN_USER_FAIL; + } else if (!strncmp(arg, "net", 3)) { + arg += 3; + setup_msg.calling.screen = GSM48_SCRN_NETWORK; + } else { +inv_qual: fprintf(stderr, + "error: calling number argument contains invalid qualifier\n"); + exit(1); + } + if (!*arg) + return; + if (*arg != ',') + goto inv_qual; + } +} + +void +init_setup_msg(from, to) + char *from, *to; +{ + setup_msg.msg_type = MNCC_SETUP_REQ; + setup_msg.callref = 1; + set_called_number(to); + if (from) { + set_calling_number(from); + setup_msg.fields |= MNCC_F_CALLING; + } +} + +void +send_setup_msg() +{ + if (setup_msg.imsi[0]) + printf("Calling IMSI %s\n", setup_msg.imsi); + else + printf("Calling %s%s\n", + setup_msg.called.type == GSM48_TON_INTERNATIONAL ? "+" + : "", + setup_msg.called.number); + send_mncc_to_gsm(&setup_msg, sizeof(struct gsm_mncc)); +}