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