FreeCalypso > hg > themwi-system-sw
comparison sip-in/mgw_ops.c @ 60:02761f1ae5e5
sip-in INVITE processing: got as far as CRCX completion
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 11 Sep 2022 15:42:54 -0800 |
parents | |
children | e12036337412 |
comparison
equal
deleted
inserted
replaced
59:bea761629c5b | 60:02761f1ae5e5 |
---|---|
1 /* | |
2 * In this module we implement all transactions from themwi-sip-in | |
3 * toward themwi-mgw. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <sys/socket.h> | |
8 #include <netinet/in.h> | |
9 #include <stdio.h> | |
10 #include <stdint.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <strings.h> | |
14 #include <syslog.h> | |
15 #include "../include/tmgw_ctrl.h" | |
16 #include "../include/tmgw_const.h" | |
17 #include "call.h" | |
18 | |
19 extern struct call *call_list; | |
20 | |
21 struct call * | |
22 find_call_with_mgw_xact(xact_id) | |
23 uint32_t xact_id; | |
24 { | |
25 struct call *call; | |
26 | |
27 for (call = call_list; call; call = call->next) | |
28 if (call->mgw_xact && call->mgw_xact_id == xact_id) | |
29 return call; | |
30 return 0; | |
31 } | |
32 | |
33 uint32_t | |
34 get_new_tmgw_xact_id() | |
35 { | |
36 static uint32_t next_xact_id; | |
37 | |
38 for (;;) { | |
39 next_xact_id++; | |
40 if (!find_call_with_mgw_xact(next_xact_id)) | |
41 return next_xact_id; | |
42 } | |
43 } | |
44 | |
45 void | |
46 tmgw_send_crcx(call) | |
47 struct call *call; | |
48 { | |
49 struct tmgw_ctrl_req req; | |
50 | |
51 bzero(&req, sizeof req); | |
52 req.opcode = TMGW_CTRL_OP_CRCX; | |
53 req.transact_ref = get_new_tmgw_xact_id(); | |
54 req.ep_id = TMGW_EP_TYPE_GATEWAY; | |
55 req.setup_mask = TMGW_CTRL_MASK_PSTN_CONN; | |
56 bcopy(&call->pstn_rtp_remote, &req.pstn_addr, | |
57 sizeof(struct sockaddr_in)); | |
58 req.pstn_payload_type = | |
59 call->use_pcma ? PSTN_CODEC_PCMA : PSTN_CODEC_PCMU; | |
60 send_req_to_tmgw(&req); | |
61 call->mgw_xact = TMGW_CTRL_OP_CRCX; | |
62 call->mgw_xact_id = req.transact_ref; | |
63 } | |
64 | |
65 void | |
66 tmgw_send_mdcx_gsm_rtp(call) | |
67 struct call *call; | |
68 { | |
69 struct tmgw_ctrl_req req; | |
70 | |
71 bzero(&req, sizeof req); | |
72 req.opcode = TMGW_CTRL_OP_MDCX; | |
73 req.transact_ref = get_new_tmgw_xact_id(); | |
74 req.ep_id = call->mgw_ep_id;; | |
75 req.setup_mask = TMGW_CTRL_MASK_GSM_CONN; | |
76 bcopy(&call->gsm_rtp_osmo, &req.gsm_addr, | |
77 sizeof(struct sockaddr_storage)); | |
78 req.gsm_payload_type = call->gsm_payload_type; | |
79 req.gsm_payload_msg_type = call->gsm_payload_msg_type; | |
80 send_req_to_tmgw(&req); | |
81 call->mgw_state = MGW_STATE_CONNECTING; | |
82 call->mgw_xact = TMGW_CTRL_OP_MDCX; | |
83 call->mgw_xact_id = req.transact_ref; | |
84 } | |
85 | |
86 void | |
87 tmgw_send_dlcx(call) | |
88 struct call *call; | |
89 { | |
90 struct tmgw_ctrl_req req; | |
91 | |
92 bzero(&req, sizeof req); | |
93 req.opcode = TMGW_CTRL_OP_DLCX; | |
94 req.transact_ref = get_new_tmgw_xact_id(); | |
95 req.ep_id = call->mgw_ep_id;; | |
96 send_req_to_tmgw(&req); | |
97 call->mgw_state = MGW_STATE_DELETING; | |
98 call->mgw_xact = TMGW_CTRL_OP_DLCX; | |
99 call->mgw_xact_id = req.transact_ref; | |
100 } | |
101 | |
102 static void | |
103 handle_crcx_fail(call, msg) | |
104 struct call *call; | |
105 struct tmgw_ctrl_resp *msg; | |
106 { | |
107 call->overall_state = OVERALL_STATE_TEARDOWN; | |
108 strcpy(call->invite_fail, "503 Gateway resource allocation failure"); | |
109 signal_invite_error(call); | |
110 } | |
111 | |
112 static void | |
113 crcx_response(call, msg) | |
114 struct call *call; | |
115 struct tmgw_ctrl_resp *msg; | |
116 { | |
117 if (msg->res == TMGW_RESP_OK) { | |
118 call->mgw_state = MGW_STATE_ALLOCATED; | |
119 call->mgw_ep_id = msg->ep_id; | |
120 bcopy(&msg->gsm_addr, &call->gsm_rtp_tmgw, | |
121 sizeof(struct sockaddr_storage)); | |
122 bcopy(&msg->pstn_addr, &call->pstn_rtp_local, | |
123 sizeof(struct sockaddr_in)); | |
124 switch (call->overall_state) { | |
125 case OVERALL_STATE_CRCX: | |
126 /* proceed_with_call_setup(call); */ | |
127 return; | |
128 case OVERALL_STATE_TEARDOWN: | |
129 tmgw_send_dlcx(call); | |
130 return; | |
131 default: | |
132 bad_state: | |
133 syslog(LOG_CRIT, | |
134 "FATAL: invalid overall state 0x%x on CRCX response", | |
135 call->overall_state); | |
136 exit(1); | |
137 } | |
138 } else { | |
139 switch (call->overall_state) { | |
140 case OVERALL_STATE_CRCX: | |
141 handle_crcx_fail(call, msg); | |
142 return; | |
143 case OVERALL_STATE_TEARDOWN: | |
144 return; | |
145 default: | |
146 goto bad_state; | |
147 } | |
148 } | |
149 } | |
150 | |
151 static void | |
152 mdcx_response(call, msg) | |
153 struct call *call; | |
154 struct tmgw_ctrl_resp *msg; | |
155 { | |
156 /* will be handled later */ | |
157 } | |
158 | |
159 static void | |
160 dlcx_response(call, msg) | |
161 struct call *call; | |
162 struct tmgw_ctrl_resp *msg; | |
163 { | |
164 if (msg->res != TMGW_RESP_OK) { | |
165 syslog(LOG_CRIT, "FATAL: TMGW DLCX failed with code 0x%x", | |
166 msg->res); | |
167 exit(1); | |
168 } | |
169 call->mgw_state = MGW_STATE_NO_EXIST; | |
170 /* TODO: transition from TEARDOWN to DEAD_SIP */ | |
171 } | |
172 | |
173 void | |
174 process_tmgw_response(msg) | |
175 struct tmgw_ctrl_resp *msg; | |
176 { | |
177 struct call *call; | |
178 unsigned opc; | |
179 | |
180 call = find_call_with_mgw_xact(msg->transact_ref); | |
181 if (!call) { | |
182 syslog(LOG_CRIT, | |
183 "FATAL: response from TMGW xact 0x%x does not match any call", | |
184 msg->transact_ref); | |
185 exit(1); | |
186 } | |
187 opc = call->mgw_xact; | |
188 call->mgw_xact = 0; | |
189 switch (opc) { | |
190 case TMGW_CTRL_OP_CRCX: | |
191 crcx_response(call, msg); | |
192 return; | |
193 case TMGW_CTRL_OP_MDCX: | |
194 mdcx_response(call, msg); | |
195 return; | |
196 case TMGW_CTRL_OP_DLCX: | |
197 dlcx_response(call, msg); | |
198 return; | |
199 default: | |
200 syslog(LOG_CRIT, | |
201 "FATAL: invalid opcode 0x%x in call->msg_xact", opc); | |
202 exit(1); | |
203 } | |
204 } |