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)