FreeCalypso > hg > themwi-system-sw
comparison sip-out/mgw_resp.c @ 154:e54b0a9e322f
beginning of themwi-sip-out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 23:04:01 -0800 |
parents | sip-in/mgw_ops.c@0ecbc3dc8f93 |
children |
comparison
equal
deleted
inserted
replaced
153:99fd4ae573ae | 154:e54b0a9e322f |
---|---|
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/tmgw_ctrl.h" | |
18 #include "../include/tmgw_const.h" | |
19 #include "../include/out_routes.h" | |
20 #include "call.h" | |
21 | |
22 extern struct call *find_call_with_mgw_xact(); | |
23 | |
24 static void | |
25 crcx_response(call, msg) | |
26 struct call *call; | |
27 struct tmgw_ctrl_resp *msg; | |
28 { | |
29 int cause; | |
30 | |
31 if (msg->res == TMGW_RESP_OK) { | |
32 call->mgw_state = MGW_STATE_ALLOCATED; | |
33 call->mgw_ep_id = msg->ep_id; | |
34 bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw, | |
35 sizeof(struct sockaddr_storage)); | |
36 bcopy(&msg->pstn_addr, &call->pstn_rtp_local, | |
37 sizeof(struct sockaddr_in)); | |
38 switch (call->overall_state) { | |
39 case OVERALL_STATE_CRCX: | |
40 send_rtp_connect(call); | |
41 start_sip_out(call); | |
42 return; | |
43 case OVERALL_STATE_TEARDOWN: | |
44 tmgw_send_dlcx(call); | |
45 return; | |
46 default: | |
47 bad_state: | |
48 syslog(LOG_CRIT, | |
49 "FATAL: invalid overall state 0x%x on CRCX response", | |
50 call->overall_state); | |
51 exit(1); | |
52 } | |
53 } else { | |
54 switch (call->overall_state) { | |
55 case OVERALL_STATE_CRCX: | |
56 call->overall_state = OVERALL_STATE_TEARDOWN; | |
57 switch (msg->res) { | |
58 case TMGW_RESP_ERR_RSRC: | |
59 cause = GSM48_CC_CAUSE_RESOURCE_UNAVAIL; | |
60 break; | |
61 case TMGW_RESP_ERR_NOTSUP: | |
62 cause = GSM48_CC_CAUSE_BEARER_CA_UNAVAIL; | |
63 break; | |
64 default: | |
65 cause = GSM48_CC_CAUSE_PROTO_ERR; | |
66 } | |
67 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, cause); | |
68 return; | |
69 case OVERALL_STATE_TEARDOWN: | |
70 check_dead_call(call); | |
71 return; | |
72 default: | |
73 goto bad_state; | |
74 } | |
75 } | |
76 } | |
77 | |
78 static void | |
79 mdcx_response(call, msg) | |
80 struct call *call; | |
81 struct tmgw_ctrl_resp *msg; | |
82 { | |
83 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
84 tmgw_send_dlcx(call); | |
85 return; | |
86 } | |
87 if (msg->res != TMGW_RESP_OK) { | |
88 call->overall_state = OVERALL_STATE_TEARDOWN; | |
89 tmgw_send_dlcx(call); | |
90 if (msg->res == TMGW_RESP_ERR_RSRC && | |
91 (call->mgw_state == MGW_STATE_MDCX_IBT || | |
92 call->mgw_state == MGW_STATE_MDCX_CONN)) | |
93 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
94 GSM48_CC_CAUSE_RESOURCE_UNAVAIL); | |
95 else | |
96 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
97 GSM48_CC_CAUSE_NETWORK_OOO); | |
98 disconnect_sip(call); | |
99 return; | |
100 } | |
101 switch (call->mgw_state) { | |
102 case MGW_STATE_MDCX_IBT: | |
103 call->mgw_state = MGW_STATE_IBT_CONN; | |
104 mncc_signal_ibt_ring(call); | |
105 if (call->sip_state == SIP_STATE_CONNECTED) | |
106 tmgw_send_mdcx_connect(call, 0); | |
107 return; | |
108 case MGW_STATE_MDCX_CONN: | |
109 call->mgw_state = MGW_STATE_COMPLETE; | |
110 mncc_signal_answer_sup(call); | |
111 return; | |
112 case MGW_STATE_MDCX_HOLD: | |
113 call->mgw_state = MGW_STATE_HELD; | |
114 mncc_send_hold_ack(call); | |
115 return; | |
116 case MGW_STATE_MDCX_RETR: | |
117 call->mgw_state = MGW_STATE_COMPLETE; | |
118 mncc_send_retrieve_ack(call); | |
119 return; | |
120 default: | |
121 syslog(LOG_CRIT, | |
122 "FATAL: invalid MGW state 0x%x on MDCX response", | |
123 call->mgw_state); | |
124 exit(1); | |
125 } | |
126 } | |
127 | |
128 static void | |
129 dlcx_response(call, msg) | |
130 struct call *call; | |
131 struct tmgw_ctrl_resp *msg; | |
132 { | |
133 if (msg->res != TMGW_RESP_OK) { | |
134 syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x", | |
135 msg->res); | |
136 exit(1); | |
137 } | |
138 call->mgw_state = MGW_STATE_NO_EXIST; | |
139 check_dead_call(call); | |
140 } | |
141 | |
142 static void | |
143 dtmf_start_response(call, msg) | |
144 struct call *call; | |
145 struct tmgw_ctrl_resp *msg; | |
146 { | |
147 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
148 tmgw_send_dlcx(call); | |
149 return; | |
150 } | |
151 if (msg->res == TMGW_RESP_OK) | |
152 mncc_dtmf_start_ok(call); | |
153 else | |
154 mncc_dtmf_start_err(call); | |
155 if (call->dtmf_pending_stop) | |
156 tmgw_send_dtmf_stop(call); | |
157 else | |
158 call->mgw_state = MGW_STATE_COMPLETE; | |
159 } | |
160 | |
161 static void | |
162 dtmf_stop_response(call, msg) | |
163 struct call *call; | |
164 struct tmgw_ctrl_resp *msg; | |
165 { | |
166 if (call->overall_state == OVERALL_STATE_TEARDOWN) { | |
167 tmgw_send_dlcx(call); | |
168 return; | |
169 } | |
170 mncc_dtmf_stop_ok(call); | |
171 call->mgw_state = MGW_STATE_COMPLETE; | |
172 call->dtmf_pending_stop = 0; | |
173 } | |
174 | |
175 void | |
176 process_tmgw_response(msg) | |
177 struct tmgw_ctrl_resp *msg; | |
178 { | |
179 struct call *call; | |
180 unsigned opc; | |
181 | |
182 call = find_call_with_mgw_xact(msg->transact_ref); | |
183 if (!call) { | |
184 syslog(LOG_CRIT, | |
185 "FATAL: response from TMGW xact 0x%x does not match any call", | |
186 msg->transact_ref); | |
187 exit(1); | |
188 } | |
189 opc = call->mgw_xact; | |
190 call->mgw_xact = 0; | |
191 switch (opc) { | |
192 case TMGW_CTRL_OP_CRCX: | |
193 crcx_response(call, msg); | |
194 return; | |
195 case TMGW_CTRL_OP_MDCX: | |
196 mdcx_response(call, msg); | |
197 return; | |
198 case TMGW_CTRL_OP_DLCX: | |
199 dlcx_response(call, msg); | |
200 return; | |
201 case TMGW_CTRL_OP_DTMF_START: | |
202 dtmf_start_response(call, msg); | |
203 return; | |
204 case TMGW_CTRL_OP_DTMF_STOP: | |
205 dtmf_stop_response(call, msg); | |
206 return; | |
207 default: | |
208 syslog(LOG_CRIT, | |
209 "FATAL: invalid opcode 0x%x in call->msg_xact", opc); | |
210 exit(1); | |
211 } | |
212 } |