comparison mncc/mncc_recv.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 implement initial handling of MNCC messages
3 * coming from OsmoMSC, dispatching them further as appropriate.
4 */
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <syslog.h>
12 #include "../include/mncc.h"
13 #include "struct.h"
14 #include "gsm_call.h"
15
16 extern char *mncc_msg_name();
17
18 static void
19 report_runt(msg)
20 union mncc_msg *msg;
21 {
22 syslog(LOG_CRIT, "MNCC message type 0x%x from GSM is too short!",
23 msg->msg_type);
24 }
25
26 static void
27 handle_setup_ind(msg, msglen)
28 struct gsm_mncc *msg;
29 unsigned msglen;
30 {
31 struct gsm_call *call;
32
33 if (msglen < sizeof(struct gsm_mncc)) {
34 report_runt(msg);
35 return;
36 }
37 syslog(LOG_DEBUG, "Rx MNCC_SETUP_IND from GSM, callref=0x%x",
38 msg->callref);
39 call = find_gsm_callref(msg->callref);
40 if (call) {
41 syslog(LOG_ERR, "duplicate MNCC_SETUP_IND for callref 0x%x",
42 msg->callref);
43 /* drop it like OsmoMSC's mncc_builtin does */
44 return;
45 }
46 /* further processing */
47 process_mo_call_setup(msg);
48 }
49
50 static void
51 handle_signaling_msg(msg, msglen)
52 struct gsm_mncc *msg;
53 unsigned msglen;
54 {
55 struct gsm_call *call;
56
57 if (msglen < sizeof(struct gsm_mncc)) {
58 report_runt(msg);
59 return;
60 }
61 syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x",
62 mncc_msg_name(msg->msg_type), msg->callref);
63 call = find_gsm_callref(msg->callref);
64 if (!call) {
65 syslog(LOG_ERR, "%s from GSM: callref 0x%x not found",
66 mncc_msg_name(msg->msg_type), msg->callref);
67 /* drop it like OsmoMSC's mncc_builtin does */
68 return;
69 }
70 if (msg->msg_type == MNCC_SETUP_CNF)
71 preen_connected_number(msg);
72 /* dispatch according to internal switch or socket */
73 if (call->socket)
74 mncc_signal_to_socket(call, msg);
75 else
76 internal_switch_mncc(call, msg);
77 }
78
79 static void
80 handle_release_msg(msg, msglen)
81 struct gsm_mncc *msg;
82 unsigned msglen;
83 {
84 struct gsm_call *call;
85
86 if (msglen < sizeof(struct gsm_mncc)) {
87 report_runt(msg);
88 return;
89 }
90 syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x",
91 mncc_msg_name(msg->msg_type), msg->callref);
92 call = find_gsm_callref(msg->callref);
93 if (!call) {
94 syslog(LOG_ERR, "%s from GSM: callref 0x%x not found",
95 mncc_msg_name(msg->msg_type), msg->callref);
96 /* drop it like OsmoMSC's mncc_builtin does */
97 return;
98 }
99 /* dispatch according to internal switch or socket */
100 if (call->socket) {
101 mncc_signal_to_socket(call, msg);
102 syslog(LOG_DEBUG,
103 "clearing socket call: GSM callref 0x%x, socket ref 0x%x",
104 call->callref, call->socket_ref);
105 extsock_dec_refcount(call->socket);
106 call->gc_flag = 1;
107 } else
108 internal_switch_mncc(call, msg);
109 }
110
111 static void
112 handle_rtp_msg(msg, msglen)
113 struct gsm_mncc_rtp *msg;
114 unsigned msglen;
115 {
116 struct gsm_call *call;
117
118 if (msglen < sizeof(struct gsm_mncc_rtp)) {
119 report_runt(msg);
120 return;
121 }
122 syslog(LOG_DEBUG, "Rx %s from GSM, callref=0x%x",
123 mncc_msg_name(msg->msg_type), msg->callref);
124 call = find_gsm_callref(msg->callref);
125 if (!call) {
126 syslog(LOG_ERR, "%s from GSM: callref 0x%x not found",
127 mncc_msg_name(msg->msg_type), msg->callref);
128 /* drop it like OsmoMSC's mncc_builtin does */
129 return;
130 }
131 /* only for socket connections - no RTP handling for internal */
132 if (call->socket)
133 mncc_rtp_to_socket(call, msg);
134 }
135
136 static void
137 handle_mncc_hello(msg, msglen)
138 struct gsm_mncc_hello *msg;
139 unsigned msglen;
140 {
141 if (msglen < sizeof(struct gsm_mncc_hello)) {
142 syslog(LOG_CRIT, "MNCC_SOCKET_HELLO message is too short!");
143 exit(1);
144 }
145 if (msg->version != MNCC_SOCK_VERSION) {
146 syslog(LOG_CRIT, "MNCC hello error: version number mismatch");
147 exit(1);
148 }
149 if (msg->mncc_size != sizeof(struct gsm_mncc)) {
150 syslog(LOG_CRIT, "MNCC hello error: mncc_size mismatch");
151 exit(1);
152 }
153 }
154
155 void
156 mncc_msg_from_gsm(msg, msglen)
157 union mncc_msg *msg;
158 unsigned msglen;
159 {
160 switch (msg->msg_type) {
161 case MNCC_SETUP_IND:
162 handle_setup_ind(msg, msglen);
163 return;
164 case MNCC_SETUP_CNF:
165 case MNCC_SETUP_COMPL_IND:
166 case MNCC_CALL_CONF_IND:
167 case MNCC_ALERT_IND:
168 case MNCC_NOTIFY_IND:
169 case MNCC_DISC_IND:
170 case MNCC_FACILITY_IND:
171 case MNCC_START_DTMF_IND:
172 case MNCC_STOP_DTMF_IND:
173 case MNCC_MODIFY_IND:
174 case MNCC_MODIFY_CNF:
175 case MNCC_MODIFY_REJ:
176 case MNCC_HOLD_IND:
177 case MNCC_RETRIEVE_IND:
178 case MNCC_USERINFO_IND:
179 handle_signaling_msg(msg, msglen);
180 return;
181 case MNCC_REL_IND:
182 case MNCC_REL_CNF:
183 case MNCC_REJ_IND:
184 handle_release_msg(msg, msglen);
185 return;
186 case MNCC_RTP_CREATE:
187 case MNCC_RTP_CONNECT:
188 case MNCC_RTP_FREE:
189 handle_rtp_msg(msg, msglen);
190 return;
191 case MNCC_SOCKET_HELLO:
192 handle_mncc_hello(msg, msglen);
193 return;
194 default:
195 syslog(LOG_CRIT, "unknown MNCC message type 0x%x from GSM",
196 msg->msg_type);
197 }
198 }