FreeCalypso > hg > themwi-interim
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 } |