FreeCalypso > hg > themwi-system-sw
comparison sip-in/mgw_ops.c @ 141:e499e8db8b82
sip-in: handle call hold and retrieve
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 08 Oct 2022 13:28:30 -0800 |
parents | 5685412bd6aa |
children | 0ecbc3dc8f93 |
comparison
equal
deleted
inserted
replaced
140:01fe81914bd6 | 141:e499e8db8b82 |
---|---|
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" | 16 #include "../include/gsm48_const.h" |
17 #include "../include/mncc.h" | |
17 #include "../include/tmgw_ctrl.h" | 18 #include "../include/tmgw_ctrl.h" |
18 #include "../include/tmgw_const.h" | 19 #include "../include/tmgw_const.h" |
19 #include "call.h" | 20 #include "call.h" |
20 | 21 |
21 extern struct call *call_list; | 22 extern struct call *call_list; |
80 req.gsm_payload_type = call->gsm_payload_type; | 81 req.gsm_payload_type = call->gsm_payload_type; |
81 req.gsm_payload_msg_type = call->gsm_payload_msg_type; | 82 req.gsm_payload_msg_type = call->gsm_payload_msg_type; |
82 req.fwd_mode = TMGW_FWD_MODE_SENDRECV; | 83 req.fwd_mode = TMGW_FWD_MODE_SENDRECV; |
83 send_req_to_tmgw(&req); | 84 send_req_to_tmgw(&req); |
84 call->mgw_state = MGW_STATE_CONNECTING; | 85 call->mgw_state = MGW_STATE_CONNECTING; |
86 call->mgw_xact = TMGW_CTRL_OP_MDCX; | |
87 call->mgw_xact_id = req.transact_ref; | |
88 } | |
89 | |
90 void | |
91 tmgw_send_mdcx_hold(call) | |
92 struct call *call; | |
93 { | |
94 struct tmgw_ctrl_req req; | |
95 | |
96 bzero(&req, sizeof req); | |
97 req.opcode = TMGW_CTRL_OP_MDCX; | |
98 req.transact_ref = get_new_tmgw_xact_id(); | |
99 req.ep_id = call->mgw_ep_id; | |
100 req.setup_mask = TMGW_CTRL_MASK_FWD_MODE; | |
101 req.fwd_mode = TMGW_FWD_MODE_INACTIVE; | |
102 send_req_to_tmgw(&req); | |
103 call->mgw_state = MGW_STATE_HOLD_OP; | |
104 call->mgw_xact = TMGW_CTRL_OP_MDCX; | |
105 call->mgw_xact_id = req.transact_ref; | |
106 } | |
107 | |
108 void | |
109 tmgw_send_mdcx_retrieve(call) | |
110 struct call *call; | |
111 { | |
112 struct tmgw_ctrl_req req; | |
113 | |
114 bzero(&req, sizeof req); | |
115 req.opcode = TMGW_CTRL_OP_MDCX; | |
116 req.transact_ref = get_new_tmgw_xact_id(); | |
117 req.ep_id = call->mgw_ep_id; | |
118 req.setup_mask = TMGW_CTRL_MASK_FWD_MODE; | |
119 req.fwd_mode = TMGW_FWD_MODE_SENDRECV; | |
120 send_req_to_tmgw(&req); | |
121 call->mgw_state = MGW_STATE_RETRIEVE_OP; | |
85 call->mgw_xact = TMGW_CTRL_OP_MDCX; | 122 call->mgw_xact = TMGW_CTRL_OP_MDCX; |
86 call->mgw_xact_id = req.transact_ref; | 123 call->mgw_xact_id = req.transact_ref; |
87 } | 124 } |
88 | 125 |
89 void | 126 void |
184 } | 221 } |
185 } | 222 } |
186 } | 223 } |
187 | 224 |
188 static void | 225 static void |
189 handle_mdcx_fail(call, msg) | 226 handle_mdcx_connect_fail(call, msg) |
190 struct call *call; | 227 struct call *call; |
191 struct tmgw_ctrl_resp *msg; | 228 struct tmgw_ctrl_resp *msg; |
192 { | 229 { |
193 call->overall_state = OVERALL_STATE_TEARDOWN; | 230 call->overall_state = OVERALL_STATE_TEARDOWN; |
194 switch (msg->res) { | 231 switch (msg->res) { |
210 } | 247 } |
211 signal_invite_error(call); | 248 signal_invite_error(call); |
212 } | 249 } |
213 | 250 |
214 static void | 251 static void |
215 mdcx_response(call, msg) | 252 mdcx_connect_response(call, msg) |
216 struct call *call; | 253 struct call *call; |
217 struct tmgw_ctrl_resp *msg; | 254 struct tmgw_ctrl_resp *msg; |
218 { | 255 { |
219 if (msg->res == TMGW_RESP_OK) { | 256 if (msg->res == TMGW_RESP_OK) { |
220 call->mgw_state = MGW_STATE_COMPLETE; | 257 call->mgw_state = MGW_STATE_COMPLETE; |
234 } | 271 } |
235 } else { | 272 } else { |
236 tmgw_send_dlcx(call); | 273 tmgw_send_dlcx(call); |
237 switch (call->overall_state) { | 274 switch (call->overall_state) { |
238 case OVERALL_STATE_ANSWERED: | 275 case OVERALL_STATE_ANSWERED: |
239 handle_mdcx_fail(call, msg); | 276 handle_mdcx_connect_fail(call, msg); |
240 return; | 277 return; |
241 case OVERALL_STATE_TEARDOWN: | 278 case OVERALL_STATE_TEARDOWN: |
242 return; | 279 return; |
243 default: | 280 default: |
244 goto bad_state; | 281 goto bad_state; |
245 } | 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); | |
246 } | 354 } |
247 } | 355 } |
248 | 356 |
249 static void | 357 static void |
250 dlcx_response(call, msg) | 358 dlcx_response(call, msg) |