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