comparison sip-in/mgw_ops.c @ 151:0ecbc3dc8f93

sip-in: split mgw_resp.c from mgw_ops.c
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 11 Oct 2022 15:58:42 -0800
parents e499e8db8b82
children
comparison
equal deleted inserted replaced
150:529906fddcfa 151:0ecbc3dc8f93
11 #include <stdint.h> 11 #include <stdint.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <string.h> 13 #include <string.h>
14 #include <strings.h> 14 #include <strings.h>
15 #include <syslog.h> 15 #include <syslog.h>
16 #include "../include/gsm48_const.h"
17 #include "../include/mncc.h"
18 #include "../include/tmgw_ctrl.h" 16 #include "../include/tmgw_ctrl.h"
19 #include "../include/tmgw_const.h" 17 #include "../include/tmgw_const.h"
20 #include "call.h" 18 #include "call.h"
21 19
22 extern struct call *call_list; 20 extern struct call *call_list;
169 send_req_to_tmgw(&req); 167 send_req_to_tmgw(&req);
170 call->mgw_state = MGW_STATE_DTMF_OP; 168 call->mgw_state = MGW_STATE_DTMF_OP;
171 call->mgw_xact = TMGW_CTRL_OP_DTMF_STOP; 169 call->mgw_xact = TMGW_CTRL_OP_DTMF_STOP;
172 call->mgw_xact_id = req.transact_ref; 170 call->mgw_xact_id = req.transact_ref;
173 } 171 }
174
175 static void
176 handle_crcx_fail(call, msg)
177 struct call *call;
178 struct tmgw_ctrl_resp *msg;
179 {
180 call->overall_state = OVERALL_STATE_TEARDOWN;
181 strcpy(call->invite_fail, "503 Gateway resource allocation failure");
182 signal_invite_error(call);
183 }
184
185 static void
186 crcx_response(call, msg)
187 struct call *call;
188 struct tmgw_ctrl_resp *msg;
189 {
190 if (msg->res == TMGW_RESP_OK) {
191 call->mgw_state = MGW_STATE_ALLOCATED;
192 call->mgw_ep_id = msg->ep_id;
193 bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw,
194 sizeof(struct sockaddr_storage));
195 bcopy(&msg->pstn_addr, &call->pstn_rtp_local,
196 sizeof(struct sockaddr_in));
197 switch (call->overall_state) {
198 case OVERALL_STATE_CRCX:
199 proceed_with_call_setup(call);
200 return;
201 case OVERALL_STATE_TEARDOWN:
202 tmgw_send_dlcx(call);
203 return;
204 default:
205 bad_state:
206 syslog(LOG_CRIT,
207 "FATAL: invalid overall state 0x%x on CRCX response",
208 call->overall_state);
209 exit(1);
210 }
211 } else {
212 switch (call->overall_state) {
213 case OVERALL_STATE_CRCX:
214 handle_crcx_fail(call, msg);
215 return;
216 case OVERALL_STATE_TEARDOWN:
217 transition_dead_sip(call);
218 return;
219 default:
220 goto bad_state;
221 }
222 }
223 }
224
225 static void
226 handle_mdcx_connect_fail(call, msg)
227 struct call *call;
228 struct tmgw_ctrl_resp *msg;
229 {
230 call->overall_state = OVERALL_STATE_TEARDOWN;
231 switch (msg->res) {
232 case TMGW_RESP_ERR_RSRC:
233 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
234 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
235 strcpy(call->invite_fail,
236 "503 Gateway resource allocation failure");
237 break;
238 case TMGW_RESP_ERR_NOTSUP:
239 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
240 GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
241 strcpy(call->invite_fail, "502 Gateway internal error");
242 break;
243 default:
244 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
245 GSM48_CC_CAUSE_PROTO_ERR);
246 strcpy(call->invite_fail, "502 Gateway internal error");
247 }
248 signal_invite_error(call);
249 }
250
251 static void
252 mdcx_connect_response(call, msg)
253 struct call *call;
254 struct tmgw_ctrl_resp *msg;
255 {
256 if (msg->res == TMGW_RESP_OK) {
257 call->mgw_state = MGW_STATE_COMPLETE;
258 switch (call->overall_state) {
259 case OVERALL_STATE_ANSWERED:
260 signal_invite_200(call);
261 return;
262 case OVERALL_STATE_TEARDOWN:
263 tmgw_send_dlcx(call);
264 return;
265 default:
266 bad_state:
267 syslog(LOG_CRIT,
268 "FATAL: invalid overall state 0x%x on MDCX response",
269 call->overall_state);
270 exit(1);
271 }
272 } else {
273 tmgw_send_dlcx(call);
274 switch (call->overall_state) {
275 case OVERALL_STATE_ANSWERED:
276 handle_mdcx_connect_fail(call, msg);
277 return;
278 case OVERALL_STATE_TEARDOWN:
279 return;
280 default:
281 goto bad_state;
282 }
283 }
284 }
285
286 static struct gsm_mncc_cause mgw_hold_retrieve_error = {
287 .coding = GSM48_CAUSE_CODING_GSM,
288 .location = GSM48_CAUSE_LOC_PRN_S_LU,
289 .value = GSM48_CC_CAUSE_NETWORK_OOO,
290 };
291
292 static void
293 mdcx_hold_response(call, msg)
294 struct call *call;
295 struct tmgw_ctrl_resp *msg;
296 {
297 if (call->overall_state == OVERALL_STATE_TEARDOWN) {
298 tmgw_send_dlcx(call);
299 return;
300 }
301 if (msg->res == TMGW_RESP_OK) {
302 call->mgw_state = MGW_STATE_HELD;
303 mncc_send_hold_ack(call);
304 } else {
305 call->overall_state = OVERALL_STATE_TEARDOWN;
306 tmgw_send_dlcx(call);
307 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
308 GSM48_CC_CAUSE_NETWORK_OOO);
309 disconnect_sip(call, &mgw_hold_retrieve_error);
310 }
311 }
312
313 static void
314 mdcx_retrieve_response(call, msg)
315 struct call *call;
316 struct tmgw_ctrl_resp *msg;
317 {
318 if (call->overall_state == OVERALL_STATE_TEARDOWN) {
319 tmgw_send_dlcx(call);
320 return;
321 }
322 if (msg->res == TMGW_RESP_OK) {
323 call->mgw_state = MGW_STATE_COMPLETE;
324 mncc_send_retrieve_ack(call);
325 } else {
326 call->overall_state = OVERALL_STATE_TEARDOWN;
327 tmgw_send_dlcx(call);
328 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
329 GSM48_CC_CAUSE_NETWORK_OOO);
330 disconnect_sip(call, &mgw_hold_retrieve_error);
331 }
332 }
333
334 static void
335 mdcx_response(call, msg)
336 struct call *call;
337 struct tmgw_ctrl_resp *msg;
338 {
339 switch (call->mgw_state) {
340 case MGW_STATE_CONNECTING:
341 mdcx_connect_response(call, msg);
342 return;
343 case MGW_STATE_HOLD_OP:
344 mdcx_hold_response(call, msg);
345 return;
346 case MGW_STATE_RETRIEVE_OP:
347 mdcx_retrieve_response(call, msg);
348 return;
349 default:
350 syslog(LOG_CRIT,
351 "FATAL: invalid MGW state 0x%x on MDCX response",
352 call->mgw_state);
353 exit(1);
354 }
355 }
356
357 static void
358 dlcx_response(call, msg)
359 struct call *call;
360 struct tmgw_ctrl_resp *msg;
361 {
362 if (msg->res != TMGW_RESP_OK) {
363 syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x",
364 msg->res);
365 exit(1);
366 }
367 call->mgw_state = MGW_STATE_NO_EXIST;
368 transition_dead_sip(call);
369 }
370
371 static void
372 dtmf_start_response(call, msg)
373 struct call *call;
374 struct tmgw_ctrl_resp *msg;
375 {
376 if (call->overall_state == OVERALL_STATE_TEARDOWN) {
377 tmgw_send_dlcx(call);
378 return;
379 }
380 if (msg->res == TMGW_RESP_OK)
381 mncc_dtmf_start_ok(call);
382 else
383 mncc_dtmf_start_err(call);
384 if (call->dtmf_pending_stop)
385 tmgw_send_dtmf_stop(call);
386 else
387 call->mgw_state = MGW_STATE_COMPLETE;
388 }
389
390 static void
391 dtmf_stop_response(call, msg)
392 struct call *call;
393 struct tmgw_ctrl_resp *msg;
394 {
395 if (call->overall_state == OVERALL_STATE_TEARDOWN) {
396 tmgw_send_dlcx(call);
397 return;
398 }
399 mncc_dtmf_stop_ok(call);
400 call->mgw_state = MGW_STATE_COMPLETE;
401 call->dtmf_pending_stop = 0;
402 }
403
404 void
405 process_tmgw_response(msg)
406 struct tmgw_ctrl_resp *msg;
407 {
408 struct call *call;
409 unsigned opc;
410
411 call = find_call_with_mgw_xact(msg->transact_ref);
412 if (!call) {
413 syslog(LOG_CRIT,
414 "FATAL: response from TMGW xact 0x%x does not match any call",
415 msg->transact_ref);
416 exit(1);
417 }
418 opc = call->mgw_xact;
419 call->mgw_xact = 0;
420 switch (opc) {
421 case TMGW_CTRL_OP_CRCX:
422 crcx_response(call, msg);
423 return;
424 case TMGW_CTRL_OP_MDCX:
425 mdcx_response(call, msg);
426 return;
427 case TMGW_CTRL_OP_DLCX:
428 dlcx_response(call, msg);
429 return;
430 case TMGW_CTRL_OP_DTMF_START:
431 dtmf_start_response(call, msg);
432 return;
433 case TMGW_CTRL_OP_DTMF_STOP:
434 dtmf_stop_response(call, msg);
435 return;
436 default:
437 syslog(LOG_CRIT,
438 "FATAL: invalid opcode 0x%x in call->msg_xact", opc);
439 exit(1);
440 }
441 }