comparison mncc/extsock.c @ 15:ccc5ab6d8388

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