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 }