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