comparison 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
parents
children e8e82a4bf12b
comparison
equal deleted inserted replaced
20:b13acb024fc6 21:cc0e1c6e33c3
1 /*
2 * In this module we handle all incoming messages from MNCC,
3 * printing all of them and generating protocol-required responses
4 * for some.
5 */
6
7 #include <sys/types.h>
8 #include <sys/socket.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 extern int disconnect_mode;
18
19 static void
20 print_bearer_cap(bcap)
21 struct gsm_mncc_bearer_cap *bcap;
22 {
23 int i, sv;
24
25 printf("Bearer cap: itcap=%d tmod=%d coding=%d rrq=%d\n",
26 bcap->transfer, bcap->mode, bcap->coding, bcap->radio);
27 printf(" speech: CTM=%d sv", bcap->speech_ctm);
28 for (i = 0; i < 8; i++) {
29 sv = bcap->speech_ver[i];
30 if (sv < 0)
31 break;
32 printf(" %d", sv);
33 }
34 putchar('\n');
35 printf(" data: ra=%d sig=%d async=%d nstop=%d ndata=%d\n",
36 bcap->data.rate_adaption, bcap->data.sig_access,
37 bcap->data.async, bcap->data.nr_stop_bits,
38 bcap->data.nr_data_bits);
39 printf(" urate=%d par=%d irate=%d transp=%d mtype=%d\n",
40 bcap->data.user_rate, bcap->data.parity,
41 bcap->data.interm_rate, bcap->data.transp,
42 bcap->data.modem_type);
43 }
44
45 static void
46 print_cc_cap(cc)
47 struct gsm_mncc_cccap *cc;
48 {
49 printf("CC capabilities: DTMF=%d PCP=%d\n", cc->dtmf, cc->pcp);
50 }
51
52 static void
53 print_cause(cause)
54 struct gsm_mncc_cause *cause;
55 {
56 int i;
57
58 printf("Cause: loc=%d coding=%d value=%d", cause->location,
59 cause->coding, cause->value);
60 if (cause->rec)
61 printf(" rec=0x%02X", cause->rec_val);
62 for (i = 0; i < cause->diag_len; i++) {
63 if (!(i & 15)) {
64 putchar('\n');
65 putchar(' ');
66 }
67 printf(" %02X", cause->diag[i] & 0xFF);
68 }
69 putchar('\n');
70 }
71
72 static void
73 print_progress(prog)
74 struct gsm_mncc_progress *prog;
75 {
76 printf("Progress: loc=%d coding=%d descr=0x%02X", prog->location,
77 prog->coding, prog->descr);
78 }
79
80 static void
81 print_useruser(uu)
82 struct gsm_mncc_useruser *uu;
83 {
84 printf("User-User IE: proto=0x%02X\n", uu->proto);
85 /* dump to be implemented if and when we actually get a UU somewhere */
86 }
87
88 static void
89 print_keypad(kp)
90 int kp;
91 {
92 if (kp >= '!' && kp <= '~')
93 printf("Keypad code: %c\n", kp);
94 else
95 printf("Keypad code: 0x%02X\n", kp);
96 }
97
98 static void
99 print_facility(fac)
100 struct gsm_mncc_facility *fac;
101 {
102 int i;
103
104 printf("Facility IE: %d byte(s)", fac->len);
105 for (i = 0; i < fac->len; i++) {
106 if (!(i & 15)) {
107 putchar('\n');
108 putchar(' ');
109 }
110 printf(" %02X", fac->info[i] & 0xFF);
111 }
112 putchar('\n');
113 }
114
115 static void
116 print_ssver(ssv)
117 struct gsm_mncc_ssversion *ssv;
118 {
119 int i;
120
121 printf("SS version IE: %d byte(s)", ssv->len);
122 for (i = 0; i < ssv->len; i++) {
123 if (!(i & 15)) {
124 putchar('\n');
125 putchar(' ');
126 }
127 printf(" %02X", ssv->info[i] & 0xFF);
128 }
129 putchar('\n');
130 }
131
132 static void
133 print_fields(msg)
134 struct gsm_mncc *msg;
135 {
136 if (msg->fields & MNCC_F_BEARER_CAP)
137 print_bearer_cap(&msg->bearer_cap);
138 if (msg->fields & MNCC_F_CCCAP)
139 print_cc_cap(&msg->cccap);
140 if (msg->fields & MNCC_F_CAUSE)
141 print_cause(&msg->cause);
142 if (msg->fields & MNCC_F_PROGRESS)
143 print_progress(&msg->progress);
144 if (msg->fields & MNCC_F_USERUSER)
145 print_useruser(&msg->useruser);
146 if (msg->more)
147 printf("More data flag set\n");
148 if (msg->fields & MNCC_F_KEYPAD)
149 print_keypad(msg->keypad);
150 if (msg->fields & MNCC_F_FACILITY)
151 print_facility(&msg->facility);
152 if (msg->fields & MNCC_F_SSVERSION)
153 print_ssver(&msg->ssversion);
154 }
155
156 static void
157 send_connect_ack()
158 {
159 struct gsm_mncc ack;
160
161 printf("Sending connect ack\n");
162 bzero(&ack, sizeof(struct gsm_mncc));
163 ack.msg_type = MNCC_SETUP_COMPL_REQ;
164 ack.callref = 1;
165 send_mncc_to_gsm(&ack, sizeof(struct gsm_mncc));
166 }
167
168 static void
169 handle_signaling_msg(msg, msglen)
170 struct gsm_mncc *msg;
171 unsigned msglen;
172 {
173 if (msglen != sizeof(struct gsm_mncc)) {
174 fprintf(stderr,
175 "error: Rx MNCC message type 0x%x has wrong length\n",
176 msg->msg_type);
177 exit(1);
178 }
179 if (msg->callref != 1) {
180 fprintf(stderr,
181 "error: Rx MNCC message type 0x%x has unexpected callref 0x%x\n",
182 msg->msg_type, msg->callref);
183 exit(1);
184 }
185 switch (msg->msg_type) {
186 case MNCC_SETUP_CNF:
187 printf("MNCC_SETUP_CNF: call is answered\n");
188 print_fields(msg);
189 send_connect_ack();
190 return;
191 case MNCC_CALL_CONF_IND:
192 printf("MNCC_CALL_CONF_IND: call is confirmed\n");
193 print_fields(msg);
194 return;
195 case MNCC_ALERT_IND:
196 printf("MNCC_ALERT_IND: call is alerting\n");
197 print_fields(msg);
198 return;
199 case MNCC_NOTIFY_IND:
200 printf("NNCC_NOTIFY_IND: NOTIFY byte from MS: 0x%02X\n",
201 msg->notify);
202 return;
203 case MNCC_DISC_IND:
204 printf("MNCC_DISC_IND: MS initiates disconnect\n");
205 print_fields(msg);
206 disconnect_mode = 1;
207 printf("Responding with release request\n");
208 msg->msg_type = MNCC_REL_REQ;
209 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
210 return;
211 case MNCC_FACILITY_IND:
212 printf("MNCC_FACILITY_IND: call-related SS from MS\n");
213 print_fields(msg);
214 return;
215 case MNCC_START_DTMF_IND:
216 printf("MNCC_START_DTMF_IND: MS sending DTMF start\n");
217 print_fields(msg);
218 msg->msg_type = MNCC_START_DTMF_REJ;
219 mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
220 GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
221 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
222 return;
223 case MNCC_STOP_DTMF_IND:
224 printf("MNCC_STOP_DTMF_IND: MS sending DTMF stop\n");
225 msg->msg_type = MNCC_STOP_DTMF_RSP;
226 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
227 return;
228 case MNCC_MODIFY_IND:
229 printf("MNCC_MODIFY_IND: MS requests call modification\n");
230 print_fields(msg);
231 msg->msg_type = MNCC_MODIFY_REJ;
232 mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
233 GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
234 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
235 return;
236 case MNCC_HOLD_IND:
237 printf("MNCC_HOLD_IND: MS requests call hold\n");
238 msg->msg_type = MNCC_HOLD_REJ;
239 mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
240 GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
241 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
242 return;
243 case MNCC_RETRIEVE_IND:
244 printf("MNCC_RETRIEVE_IND: MS requests call retrieve\n");
245 msg->msg_type = MNCC_RETRIEVE_REJ;
246 mncc_set_cause(msg, GSM48_CAUSE_LOC_PRN_S_LU,
247 GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
248 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
249 return;
250 case MNCC_USERINFO_IND:
251 printf("MNCC_USERINFO_IND: user-user info\n");
252 print_fields(msg);
253 return;
254 case MNCC_REL_IND:
255 printf("MNCC_REL_IND: final release\n");
256 print_fields(msg);
257 exit(0);
258 case MNCC_REL_CNF:
259 printf("MNCC_REL_CNF: final release in response to request\n");
260 print_fields(msg);
261 exit(0);
262 case MNCC_REJ_IND:
263 printf("MNCC_REJ_IND: MT call rejected\n");
264 print_fields(msg);
265 exit(0);
266 }
267 }
268
269 static void
270 handle_rtp_create(msg, msglen)
271 struct gsm_mncc_rtp *msg;
272 unsigned msglen;
273 {
274 if (msglen != sizeof(struct gsm_mncc_rtp)) {
275 fprintf(stderr,
276 "error: Rx MNCC message type 0x%x has wrong length\n",
277 msg->msg_type);
278 exit(1);
279 }
280 if (msg->callref != 1) {
281 fprintf(stderr,
282 "error: Rx MNCC message type 0x%x has unexpected callref 0x%x\n",
283 msg->msg_type, msg->callref);
284 exit(1);
285 }
286 printf("MNCC_RTP_CREATE: RTP info from MSC\n");
287 printf("payload_type=0x%x payload_msg_type=0x%x\n", msg->payload_type,
288 msg->payload_msg_type);
289 }
290
291 void
292 msg_from_mncc(msg, msglen)
293 union mncc_msg *msg;
294 unsigned msglen;
295 {
296 switch (msg->msg_type) {
297 case MNCC_SETUP_CNF:
298 case MNCC_CALL_CONF_IND:
299 case MNCC_ALERT_IND:
300 case MNCC_NOTIFY_IND:
301 case MNCC_DISC_IND:
302 case MNCC_FACILITY_IND:
303 case MNCC_START_DTMF_IND:
304 case MNCC_STOP_DTMF_IND:
305 case MNCC_MODIFY_IND:
306 case MNCC_HOLD_IND:
307 case MNCC_RETRIEVE_IND:
308 case MNCC_USERINFO_IND:
309 case MNCC_REL_IND:
310 case MNCC_REL_CNF:
311 case MNCC_REJ_IND:
312 handle_signaling_msg(msg, msglen);
313 return;
314 case MNCC_RTP_CREATE:
315 handle_rtp_create(msg, msglen);
316 return;
317 default:
318 fprintf(stderr,
319 "error: received unexpected MNCC message type 0x%x\n",
320 msg->msg_type);
321 exit(1);
322 }
323 }