comparison mtctest/setup.c @ 21:cc0e1c6e33c3

themwi-test-mtc utility written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 28 Jun 2022 18:25:28 -0800
parents
children 08d7794cdd0a
comparison
equal deleted inserted replaced
20:b13acb024fc6 21:cc0e1c6e33c3
1 /*
2 * In this module we compose the MNCC_SETUP_REQ message
3 * initiating our test MT call.
4 */
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <ctype.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <strings.h>
14 #include "../include/mncc.h"
15 #include "../include/gsm48_const.h"
16
17 struct gsm_mncc setup_msg;
18
19 static void
20 set_called_number(arg)
21 char *arg;
22 {
23 int rc, ndig;
24 char short_num[5], long_num[12];
25
26 if (!strncmp(arg, "imsi:", 5)) {
27 rc = grok_imsi_user_arg(arg, setup_msg.imsi);
28 if (rc < 0) {
29 fprintf(stderr,
30 "error: call-by-IMSI destination \"%s\" is invalid\n",
31 arg);
32 exit(1);
33 }
34 return;
35 }
36 if (arg[0] == '+') {
37 if (arg[1] != '1') {
38 fprintf(stderr,
39 "error: plus-format call destination number must begin with 1\n");
40 exit(1);
41 }
42 if (grok_number_string(arg+1, 1) != 11) {
43 bad_plus1: fprintf(stderr,
44 "error: malformed +1 call destination number\n");
45 exit(1);
46 }
47 dehyphen_number_string(arg+1, setup_msg.called.number);
48 if (!is_nanp_valid_prefix(setup_msg.called.number+1))
49 goto bad_plus1;
50 setup_msg.called.type = GSM48_TON_INTERNATIONAL;
51 setup_msg.called.plan = GSM48_NPI_ISDN_E164;
52 setup_msg.fields |= MNCC_F_CALLED;
53 return;
54 }
55 ndig = grok_number_string(arg);
56 switch (ndig) {
57 case 4:
58 dehyphen_number_string(arg, short_num);
59 if (read_number_db() < 0) {
60 fprintf(stderr, "error reading number database\n");
61 exit(1);
62 }
63 rc = lookup_short_dial_number(short_num, long_num);
64 if (!rc) {
65 fprintf(stderr,
66 "error: short dial number %s is not valid\n",
67 short_num);
68 exit(1);
69 }
70 if (long_num[0]) {
71 setup_msg.called.type = GSM48_TON_INTERNATIONAL;
72 setup_msg.called.plan = GSM48_NPI_ISDN_E164;
73 setup_msg.called.number[0] = '1';
74 strcpy(setup_msg.called.number+1, long_num);
75 } else {
76 setup_msg.called.type = GSM48_TON_NET_SPEC;
77 setup_msg.called.plan = GSM48_NPI_PRIVATE;
78 strcpy(setup_msg.called.number, short_num);
79 }
80 setup_msg.fields |= MNCC_F_CALLED;
81 return;
82 case 10:
83 dehyphen_number_string(arg, long_num);
84 if (!is_nanp_valid_prefix(long_num))
85 break;
86 setup_msg.called.type = GSM48_TON_INTERNATIONAL;
87 setup_msg.called.plan = GSM48_NPI_ISDN_E164;
88 setup_msg.called.number[0] = '1';
89 strcpy(setup_msg.called.number+1, long_num);
90 setup_msg.fields |= MNCC_F_CALLED;
91 return;
92 case 11:
93 dehyphen_number_string(arg, long_num);
94 if (long_num[0] != '1')
95 break;
96 if (!is_nanp_valid_prefix(long_num+1))
97 break;
98 setup_msg.called.type = GSM48_TON_INTERNATIONAL;
99 setup_msg.called.plan = GSM48_NPI_ISDN_E164;
100 strcpy(setup_msg.called.number, long_num);
101 setup_msg.fields |= MNCC_F_CALLED;
102 return;
103 }
104 fprintf(stderr, "error: call destination number \"%s\" is invalid\n",
105 arg);
106 exit(1);
107 }
108
109 static void
110 set_calling_number(arg)
111 char *arg;
112 {
113 unsigned ndig;
114 int c;
115
116 if (!strcmp(arg, "unavail")) {
117 setup_msg.calling.present = GSM48_PRES_UNAVAIL;
118 return;
119 }
120 if (!strcmp(arg, "blocked")) {
121 setup_msg.calling.present = GSM48_PRES_RESTR;
122 return;
123 }
124 if (*arg == '+') {
125 setup_msg.calling.type = GSM48_TON_INTERNATIONAL;
126 arg++;
127 }
128 for (ndig = 0; *arg; ) {
129 c = *arg++;
130 if (c == ',')
131 break;
132 if (c == '-')
133 continue;
134 if (!is_valid_ext_digit(c)) {
135 fprintf(stderr,
136 "error: calling number argument contains invalid digit \'%c\'\n",
137 c);
138 exit(1);
139 }
140 if (ndig >= 32) {
141 fprintf(stderr,
142 "error: calling number argument is too long\n");
143 exit(1);
144 }
145 setup_msg.calling.number[ndig] = c;
146 ndig++;
147 }
148 if (!ndig) {
149 fprintf(stderr,
150 "error: calling number argument has no digits\n");
151 exit(1);
152 }
153 setup_msg.calling.plan = GSM48_NPI_ISDN_E164;
154 for (;;) {
155 while (*arg == ',')
156 arg++;
157 if (!*arg)
158 return;
159 if (!strncmp(arg, "ton=", 4)) {
160 arg += 4;
161 if (arg[0] >= '0' && arg[1] <= '7' && !isdigit(arg[1])){
162 setup_msg.calling.type = *arg - '0';
163 arg++;
164 } else {
165 fprintf(stderr,
166 "error: calling number argument contains invalid ton= part\n");
167 exit(1);
168 }
169 } else if (!strncmp(arg, "npi=", 4)) {
170 arg += 4;
171 if (arg[0] >= '0' && arg[1] <= '9' && !isdigit(arg[1])){
172 setup_msg.calling.plan = *arg - '0';
173 arg++;
174 } else if (arg[0] == '1' && arg[1] >= '0' &&
175 arg[1] <= '5' && !isdigit(arg[2])) {
176 setup_msg.calling.plan = atoi(arg);
177 arg += 2;
178 } else {
179 fprintf(stderr,
180 "error: calling number argument contains invalid npi= part\n");
181 exit(1);
182 }
183 } else if (!strncmp(arg, "restr", 5)) {
184 arg += 5;
185 setup_msg.calling.present = GSM48_PRES_RESTR;
186 } else if (!strncmp(arg, "vp", 2)) {
187 arg += 2;
188 setup_msg.calling.screen = GSM48_SCRN_USER_PASS;
189 } else if (!strncmp(arg, "vf", 2)) {
190 arg += 2;
191 setup_msg.calling.screen = GSM48_SCRN_USER_FAIL;
192 } else if (!strncmp(arg, "net", 3)) {
193 arg += 3;
194 setup_msg.calling.screen = GSM48_SCRN_NETWORK;
195 } else {
196 inv_qual: fprintf(stderr,
197 "error: calling number argument contains invalid qualifier\n");
198 exit(1);
199 }
200 if (!*arg)
201 return;
202 if (*arg != ',')
203 goto inv_qual;
204 }
205 }
206
207 void
208 init_setup_msg(from, to)
209 char *from, *to;
210 {
211 setup_msg.msg_type = MNCC_SETUP_REQ;
212 setup_msg.callref = 1;
213 set_called_number(to);
214 if (from) {
215 set_calling_number(from);
216 setup_msg.fields |= MNCC_F_CALLING;
217 }
218 }
219
220 void
221 send_setup_msg()
222 {
223 if (setup_msg.imsi[0])
224 printf("Calling IMSI %s\n", setup_msg.imsi);
225 else
226 printf("Calling %s%s\n",
227 setup_msg.called.type == GSM48_TON_INTERNATIONAL ? "+"
228 : "",
229 setup_msg.called.number);
230 send_mncc_to_gsm(&setup_msg, sizeof(struct gsm_mncc));
231 }