FreeCalypso > hg > themwi-system-sw
comparison sip-in/mgw_resp.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 | sip-in/mgw_ops.c@e499e8db8b82 |
children | 7176dc850d7a |
comparison
equal
deleted
inserted
replaced
150:529906fddcfa | 151:0ecbc3dc8f93 |
---|---|
1 /* | |
2 * In this module we implement our handling of all responses | |
3 * from themwi-mgw. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <sys/socket.h> | |
8 #include <sys/time.h> | |
9 #include <netinet/in.h> | |
10 #include <stdio.h> | |
11 #include <stdint.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <strings.h> | |
15 #include <syslog.h> | |
16 #include "../include/gsm48_const.h" | |
17 #include "../include/mncc.h" | |
18 #include "../include/tmgw_ctrl.h" | |
19 #include "../include/tmgw_const.h" | |
20 #include "call.h" | |
21 | |
22 extern struct call *find_call_with_mgw_xact(); | |
23 | |
24 static void | |
25 handle_crcx_fail(call, msg) | |
26 struct call *call; | |
27 struct tmgw_ctrl_resp *msg; | |
28 { | |
29 call->overall_state = OVERALL_STATE_TEARDOWN; | |
30 strcpy(call->invite_fail, "503 Gateway resource allocation failure"); | |
31 signal_invite_error(call); | |
32 } | |
33 | |
34 static void | |
35 crcx_response(call, msg) | |
36 struct call *call; | |
37 struct tmgw_ctrl_resp *msg; | |
38 { | |
39 if (msg->res == TMGW_RESP_OK) { | |
40 call->mgw_state = MGW_STATE_ALLOCATED; | |
41 call->mgw_ep_id = msg->ep_id; | |
42 bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw, | |
43 sizeof(struct sockaddr_storage)); | |
44 bcopy(&msg->pstn_addr, &call->pstn_rtp_local, | |
45 sizeof(struct sockaddr_in)); | |
46 switch (call->overall_state) { | |
47 case OVERALL_STATE_CRCX: | |
48 proceed_with_call_setup(call); | |
49 return; | |
50 case OVERALL_STATE_TEARDOWN: | |
51 tmgw_send_dlcx(call); | |
52 return; | |
53 default: | |
54 bad_state: | |
55 syslog(LOG_CRIT, | |
56 "FATAL: invalid overall state 0x%x on CRCX response", | |
57 call->overall_state); | |
58 exit(1); | |
59 } | |
60 } else { | |
61 switch (call->overall_state) { | |
62 case OVERALL_STATE_CRCX: | |
63 handle_crcx_fail(call, msg); | |
64 return; | |
65 case OVERALL_STATE_TEARDOWN: | |
66 transition_dead_sip(call); | |
67 return; | |
68 default: | |
69 goto bad_state; | |
70 } | |
71 } | |
72 } | |
73 | |
74 static void | |
75 handle_mdcx_connect_fail(call, msg) | |
76 struct call *call; | |
77 struct tmgw_ctrl_resp *msg; | |
78 { | |
79 call->overall_state = OVERALL_STATE_TEARDOWN; | |
80 switch (msg->res) { | |
81 case TMGW_RESP_ERR_RSRC: | |
82 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
83 GSM48_CC_CAUSE_RESOURCE_UNAVAIL); | |
84 strcpy(call->invite_fail, | |
85 "503 Gateway resource allocation failure"); | |
86 break; | |
87 case TMGW_RESP_ERR_NOTSUP: | |
88 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
89 GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); | |
90 strcpy(call->invite_fail, "502 Gateway internal error"); | |
91 break; | |
92 default: | |
93 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
94 GSM48_CC_CAUSE_PROTO_ERR); | |
95 strcpy(call->invite_fail, "502 Gateway internal error"); | |
96 } | |
97 signal_invite_error(call); | |
98 } | |
99 | |
100 static void | |
101 mdcx_connect_response(call, msg) | |
102 struct call *call; | |
103 struct tmgw_ctrl_resp *msg; | |
104 { | |
105 if (msg->res == TMGW_RESP_OK) { | |
106 call->mgw_state = MGW_STATE_COMPLETE; | |
107 switch (call->overall_state) { | |
108 case OVERALL_STATE_ANSWERED: | |
109 signal_invite_200(call); | |
110 return; | |
111 case OVERALL_STATE_TEARDOWN: | |
112 tmgw_send_dlcx(call); | |
113 return; | |
114 default: | |
115 bad_state: | |
116 syslog(LOG_CRIT, | |
117 "FATAL: invalid overall state 0x%x on MDCX response", | |
118 call->overall_state); | |
119 exit(1); | |
120 } | |
121 } else { | |
122 tmgw_send_dlcx(call); | |
123 switch (call->overall_state) { | |
124 case OVERALL_STATE_ANSWERED: | |
125 handle_mdcx_connect_fail(call, msg); | |
126 return; | |
127 case OVERALL_STATE_TEARDOWN: | |
128 return; | |
129 default: | |
130 goto bad_state; | |
131 } | |
132 } | |
133 } | |
134 | |
135 static struct gsm_mncc_cause mgw_hold_retrieve_error = { | |
136 .coding = GSM48_CAUSE_CODING_GSM, | |
137 .location = GSM48_CAUSE_LOC_PRN_S_LU, | |
138 .value = GSM48_CC_CAUSE_NETWORK_OOO, | |
139 }; | |
140 | |
141 static void | |
142 mdcx_hold_response(call, msg) | |
143 struct call *call; | |
144 struct tmgw_ctrl_resp *msg; | |
145 { | |
146 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
147 tmgw_send_dlcx(call); | |
148 return; | |
149 } | |
150 if (msg->res == TMGW_RESP_OK) { | |
151 call->mgw_state = MGW_STATE_HELD; | |
152 mncc_send_hold_ack(call); | |
153 } else { | |
154 call->overall_state = OVERALL_STATE_TEARDOWN; | |
155 tmgw_send_dlcx(call); | |
156 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
157 GSM48_CC_CAUSE_NETWORK_OOO); | |
158 disconnect_sip(call, &mgw_hold_retrieve_error); | |
159 } | |
160 } | |
161 | |
162 static void | |
163 mdcx_retrieve_response(call, msg) | |
164 struct call *call; | |
165 struct tmgw_ctrl_resp *msg; | |
166 { | |
167 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
168 tmgw_send_dlcx(call); | |
169 return; | |
170 } | |
171 if (msg->res == TMGW_RESP_OK) { | |
172 call->mgw_state = MGW_STATE_COMPLETE; | |
173 mncc_send_retrieve_ack(call); | |
174 } else { | |
175 call->overall_state = OVERALL_STATE_TEARDOWN; | |
176 tmgw_send_dlcx(call); | |
177 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
178 GSM48_CC_CAUSE_NETWORK_OOO); | |
179 disconnect_sip(call, &mgw_hold_retrieve_error); | |
180 } | |
181 } | |
182 | |
183 static void | |
184 mdcx_response(call, msg) | |
185 struct call *call; | |
186 struct tmgw_ctrl_resp *msg; | |
187 { | |
188 switch (call->mgw_state) { | |
189 case MGW_STATE_CONNECTING: | |
190 mdcx_connect_response(call, msg); | |
191 return; | |
192 case MGW_STATE_HOLD_OP: | |
193 mdcx_hold_response(call, msg); | |
194 return; | |
195 case MGW_STATE_RETRIEVE_OP: | |
196 mdcx_retrieve_response(call, msg); | |
197 return; | |
198 default: | |
199 syslog(LOG_CRIT, | |
200 "FATAL: invalid MGW state 0x%x on MDCX response", | |
201 call->mgw_state); | |
202 exit(1); | |
203 } | |
204 } | |
205 | |
206 static void | |
207 dlcx_response(call, msg) | |
208 struct call *call; | |
209 struct tmgw_ctrl_resp *msg; | |
210 { | |
211 if (msg->res != TMGW_RESP_OK) { | |
212 syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x", | |
213 msg->res); | |
214 exit(1); | |
215 } | |
216 call->mgw_state = MGW_STATE_NO_EXIST; | |
217 transition_dead_sip(call); | |
218 } | |
219 | |
220 static void | |
221 dtmf_start_response(call, msg) | |
222 struct call *call; | |
223 struct tmgw_ctrl_resp *msg; | |
224 { | |
225 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
226 tmgw_send_dlcx(call); | |
227 return; | |
228 } | |
229 if (msg->res == TMGW_RESP_OK) | |
230 mncc_dtmf_start_ok(call); | |
231 else | |
232 mncc_dtmf_start_err(call); | |
233 if (call->dtmf_pending_stop) | |
234 tmgw_send_dtmf_stop(call); | |
235 else | |
236 call->mgw_state = MGW_STATE_COMPLETE; | |
237 } | |
238 | |
239 static void | |
240 dtmf_stop_response(call, msg) | |
241 struct call *call; | |
242 struct tmgw_ctrl_resp *msg; | |
243 { | |
244 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
245 tmgw_send_dlcx(call); | |
246 return; | |
247 } | |
248 mncc_dtmf_stop_ok(call); | |
249 call->mgw_state = MGW_STATE_COMPLETE; | |
250 call->dtmf_pending_stop = 0; | |
251 } | |
252 | |
253 void | |
254 process_tmgw_response(msg) | |
255 struct tmgw_ctrl_resp *msg; | |
256 { | |
257 struct call *call; | |
258 unsigned opc; | |
259 | |
260 call = find_call_with_mgw_xact(msg->transact_ref); | |
261 if (!call) { | |
262 syslog(LOG_CRIT, | |
263 "FATAL: response from TMGW xact 0x%x does not match any call", | |
264 msg->transact_ref); | |
265 exit(1); | |
266 } | |
267 opc = call->mgw_xact; | |
268 call->mgw_xact = 0; | |
269 switch (opc) { | |
270 case TMGW_CTRL_OP_CRCX: | |
271 crcx_response(call, msg); | |
272 return; | |
273 case TMGW_CTRL_OP_MDCX: | |
274 mdcx_response(call, msg); | |
275 return; | |
276 case TMGW_CTRL_OP_DLCX: | |
277 dlcx_response(call, msg); | |
278 return; | |
279 case TMGW_CTRL_OP_DTMF_START: | |
280 dtmf_start_response(call, msg); | |
281 return; | |
282 case TMGW_CTRL_OP_DTMF_STOP: | |
283 dtmf_stop_response(call, msg); | |
284 return; | |
285 default: | |
286 syslog(LOG_CRIT, | |
287 "FATAL: invalid opcode 0x%x in call->msg_xact", opc); | |
288 exit(1); | |
289 } | |
290 } |