comparison mncc/extsock.c @ 2:053f04687106

mncc: initial import from old ThemWi
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 08 Jun 2024 23:12:12 +0000
parents
children
comparison
equal deleted inserted replaced
1:b161dbfffdaa 2:053f04687106
1 /*
2 * In this module we gather functions that deal with external
3 * socket connections, both externally-originating MT calls
4 * and outbound MO calls.
5 */
6
7 #include <sys/types.h>
8 #include <sys/socket.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/mncc.h"
16 #include "../include/gsm48_const.h"
17 #include "struct.h"
18 #include "gsm_call.h"
19
20 extern char *mncc_msg_name();
21
22 void
23 extsock_dec_refcount(conn)
24 struct socket_conn *conn;
25 {
26 if (!conn->ncalls) {
27 syslog(LOG_CRIT, "FATAL BUG: ncalls=0 on socket call clearing");
28 exit(1);
29 }
30 conn->ncalls--;
31 }
32
33 static void
34 send_rel_on_broken_socket(call)
35 struct gsm_call *call;
36 {
37 struct gsm_mncc msg;
38
39 bzero(&msg, sizeof(struct gsm_mncc));
40 msg.msg_type = MNCC_REL_REQ;
41 msg.callref = call->callref;
42 mncc_set_cause(&msg, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_DEST_OOO);
43 send_mncc_to_gsm(&msg, sizeof(struct gsm_mncc));
44 }
45
46 static void
47 broken_socket_clear_calls(conn)
48 struct socket_conn *conn;
49 {
50 extern struct gsm_call *call_list_head;
51 struct gsm_call *call;
52
53 for (call = call_list_head; call; call = call->next) {
54 if (call->gc_flag)
55 continue;
56 if (call->socket == conn) {
57 syslog(LOG_WARNING,
58 "clearing broken socket call: GSM callref 0x%x, socket ref 0x%x",
59 call->callref, call->socket_ref);
60 send_rel_on_broken_socket(call);
61 extsock_dec_refcount(conn);
62 call->gc_flag = 1;
63 }
64 }
65 if (conn->ncalls) {
66 syslog(LOG_CRIT,
67 "FATAL BUG: ncalls!=0 after broken socket call clearing");
68 exit(1);
69 }
70 }
71
72 static void
73 report_runt(msg)
74 union mncc_msg *msg;
75 {
76 syslog(LOG_CRIT,
77 "MNCC message type 0x%x from ThemWi call socket is too short!",
78 msg->msg_type);
79 }
80
81 static void
82 handle_setup_req(conn, msg, msglen)
83 struct socket_conn *conn;
84 struct gsm_mncc *msg;
85 unsigned msglen;
86 {
87 struct gsm_call *call;
88
89 if (msglen < sizeof(struct gsm_mncc)) {
90 report_runt(msg);
91 return;
92 }
93 syslog(LOG_DEBUG, "Rx MNCC_SETUP_REQ from socket, callref=0x%x",
94 msg->callref);
95 call = find_socket_call(conn, msg->callref);
96 if (call) {
97 syslog(LOG_ERR,
98 "duplicate MNCC_SETUP_REQ from socket for callref 0x%x",
99 msg->callref);
100 /* drop it like OsmoMSC's mncc_builtin does */
101 return;
102 }
103 /* further processing */
104 process_ext_mtcall_setup(conn, msg);
105 }
106
107 static void
108 handle_signaling_msg(conn, msg, msglen)
109 struct socket_conn *conn;
110 struct gsm_mncc *msg;
111 unsigned msglen;
112 {
113 struct gsm_call *call;
114
115 if (msglen < sizeof(struct gsm_mncc)) {
116 report_runt(msg);
117 return;
118 }
119 syslog(LOG_DEBUG, "Rx %s from socket, callref=0x%x",
120 mncc_msg_name(msg->msg_type), msg->callref);
121 call = find_socket_call(conn, msg->callref);
122 if (!call) {
123 syslog(LOG_ERR,
124 "MNCC message from ThemWi call socket: callref 0x%x not found",
125 msg->callref);
126 /* drop it like OsmoMSC's mncc_builtin does */
127 return;
128 }
129 /* forward to GSM MNCC interface */
130 msg->callref = call->callref;
131 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc));
132 if (msg->msg_type == MNCC_REJ_REQ) {
133 extsock_dec_refcount(conn);
134 call->gc_flag = 1;
135 }
136 }
137
138 static void
139 handle_rtp_msg(conn, msg, msglen)
140 struct socket_conn *conn;
141 struct gsm_mncc_rtp *msg;
142 unsigned msglen;
143 {
144 struct gsm_call *call;
145
146 if (msglen < sizeof(struct gsm_mncc_rtp)) {
147 report_runt(msg);
148 return;
149 }
150 syslog(LOG_DEBUG, "Rx %s from socket, callref=0x%x",
151 mncc_msg_name(msg->msg_type), msg->callref);
152 call = find_socket_call(conn, msg->callref);
153 if (!call) {
154 syslog(LOG_ERR,
155 "MNCC message from ThemWi call socket: callref 0x%x not found",
156 msg->callref);
157 /* drop it like OsmoMSC's mncc_builtin does */
158 return;
159 }
160 /* forward to GSM MNCC interface */
161 msg->callref = call->callref;
162 send_mncc_to_gsm(msg, sizeof(struct gsm_mncc_rtp));
163 }
164
165 void
166 extsock_read_select(conn)
167 struct socket_conn *conn;
168 {
169 union mncc_msg msg;
170 int rc;
171
172 rc = recv(conn->fd, &msg, sizeof msg, 0);
173 if (rc < 4) {
174 if (conn->ncalls) {
175 syslog(LOG_ERR, "ext socket broken with calls present");
176 broken_socket_clear_calls(conn);
177 } else
178 syslog(LOG_INFO, "normal closing of ext socket");
179 close(conn->fd);
180 conn->fd = -1;
181 return;
182 }
183 switch (msg.msg_type) {
184 case MNCC_SETUP_REQ:
185 handle_setup_req(conn, &msg, rc);
186 return;
187 case MNCC_SETUP_RSP:
188 case MNCC_SETUP_COMPL_REQ:
189 case MNCC_CALL_PROC_REQ:
190 case MNCC_PROGRESS_REQ:
191 case MNCC_ALERT_REQ:
192 case MNCC_NOTIFY_REQ:
193 case MNCC_DISC_REQ:
194 case MNCC_REL_REQ:
195 case MNCC_FACILITY_REQ:
196 case MNCC_START_DTMF_RSP:
197 case MNCC_START_DTMF_REJ:
198 case MNCC_STOP_DTMF_RSP:
199 case MNCC_MODIFY_REQ:
200 case MNCC_MODIFY_RSP:
201 case MNCC_MODIFY_REJ:
202 case MNCC_HOLD_CNF:
203 case MNCC_HOLD_REJ:
204 case MNCC_RETRIEVE_CNF:
205 case MNCC_RETRIEVE_REJ:
206 case MNCC_USERINFO_REQ:
207 case MNCC_REJ_REQ:
208 handle_signaling_msg(conn, &msg, rc);
209 return;
210 case MNCC_RTP_CREATE:
211 case MNCC_RTP_CONNECT:
212 case MNCC_RTP_FREE:
213 handle_rtp_msg(conn, &msg, rc);
214 return;
215 default:
216 syslog(LOG_CRIT,
217 "unknown MNCC message type 0x%x from ThemWi call socket",
218 msg.msg_type);
219 }
220 }
221
222 mncc_signal_to_socket(call, msg)
223 struct gsm_call *call;
224 struct gsm_mncc *msg;
225 {
226 msg->callref = call->socket_ref;
227 return send(call->socket->fd, msg, sizeof(struct gsm_mncc), 0);
228 }
229
230 mncc_signal_to_socket_nocall(conn, msg)
231 struct socket_conn *conn;
232 struct gsm_mncc *msg;
233 {
234 return send(conn->fd, msg, sizeof(struct gsm_mncc), 0);
235 }
236
237 mncc_rtp_to_socket(call, msg)
238 struct gsm_call *call;
239 struct gsm_mncc_rtp *msg;
240 {
241 msg->callref = call->socket_ref;
242 return send(call->socket->fd, msg, sizeof(struct gsm_mncc_rtp), 0);
243 }