blob: 07bf58747fe68f80fcefe788e4980a28def83ea2 [file] [log] [blame]
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +01001/* Relay UDT/all SCCP messages */
2/*
3 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2010 by On-Waves
5 * All Rights Reserved
6 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +01007 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010010 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010015 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010016 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010017 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010019 *
20 */
21
22#include <mtp_data.h>
Holger Hans Peter Freyther396282e2010-12-08 10:08:14 +010023#include <mtp_level3.h>
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010024#include <mtp_pcap.h>
25#include <thread.h>
26#include <bsc_data.h>
27#include <snmp_mtp.h>
28#include <cellmgr_debug.h>
29
30#include <osmocore/talloc.h>
31
32#include <osmocom/vty/vty.h>
33#include <osmocom/vty/telnet_interface.h>
34
35#include <sys/stat.h>
36#include <sys/types.h>
37
38#include <fcntl.h>
39#include <signal.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <assert.h>
44#include <unistd.h>
45
46#ifndef _GNU_SOURCE
47#define _GNU_SOURCE
48#endif
49#include <getopt.h>
50
51#undef PACKAGE_NAME
52#undef PACKAGE_VERSION
53#undef PACKAGE_BUGREPORT
54#undef PACKAGE_TARNAME
55#undef PACKAGE_STRING
56#include <cellmgr_config.h>
57
58static struct log_target *stderr_target;
59
60static char *config = "udt_relay.cfg";
61
62struct bsc_data bsc;
63extern void cell_vty_init(void);
64
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010065/*
66 * methods called from the MTP Level3 part
67 */
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +010068void mtp_link_sccp_down(struct mtp_link *link)
69{
70 msc_clear_queue(&bsc);
71}
72
73void mtp_link_forward_sccp(struct mtp_link *link, struct msgb *_msg, int sls)
74{
75 msc_send_direct(&bsc, _msg);
76}
77
78void bsc_link_down(struct link_data *data)
79{
80 int was_up;
81 struct mtp_link *link = data->the_link;
82
83 link->available = 0;
84 was_up = link->sccp_up;
85 mtp_link_stop(link);
86
87 data->clear_queue(data);
88
89 /* clear pending messages from the MSC */
90 msc_clear_queue(data->bsc);
91
92 /* If we have an A link send a reset to the MSC */
93 msc_send_reset(data->bsc);
94}
95
96void bsc_link_up(struct link_data *data)
97{
98 data->the_link->available = 1;
99 mtp_link_reset(data->the_link);
100}
101
102static void print_usage()
103{
104 printf("Usage: cellmgr_ng\n");
105}
106
107static void sigint()
108{
109 static pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
110 static int handled = 0;
111
112 /* failed to lock */
113 if (pthread_mutex_trylock(&exit_mutex) != 0)
114 return;
115 if (handled)
116 goto out;
117
118 printf("Terminating.\n");
119 handled = 1;
120 if (bsc.setup)
121 bsc.link.shutdown(&bsc.link);
122 exit(0);
123
124out:
125 pthread_mutex_unlock(&exit_mutex);
126}
127
128static void sigusr2()
129{
130 printf("Closing the MSC connection on demand.\n");
131 msc_close_connection(&bsc);
132}
133
134static void print_help()
135{
136 printf(" Some useful help...\n");
137 printf(" -h --help this text\n");
138 printf(" -c --config=CFG The config file to use.\n");
139 printf(" -p --pcap=FILE. Write MSUs to the PCAP file.\n");
140 printf(" -c --once. Send the SLTM msg only once.\n");
141 printf(" -v --version. Print the version number\n");
142}
143
144static void handle_options(int argc, char **argv)
145{
146 while (1) {
147 int option_index = 0, c;
148 static struct option long_options[] = {
149 {"help", 0, 0, 'h'},
150 {"config", 1, 0, 'c'},
151 {"pcap", 1, 0, 'p'},
152 {"version", 0, 0, 0},
153 {0, 0, 0, 0},
154 };
155
156 c = getopt_long(argc, argv, "hc:p:v",
157 long_options, &option_index);
158 if (c == -1)
159 break;
160
161 switch (c) {
162 case 'h':
163 print_usage();
164 print_help();
165 exit(0);
166 case 'p':
167 if (bsc.link.pcap_fd >= 0)
168 close(bsc.link.pcap_fd);
169 bsc.link.pcap_fd = open(optarg, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH);
170 if (bsc.link.pcap_fd < 0) {
171 fprintf(stderr, "Failed to open PCAP file.\n");
172 exit(0);
173 }
174 mtp_pcap_write_header(bsc.link.pcap_fd);
175 break;
176 case 'c':
177 config = optarg;
178 break;
179 case 'v':
180 printf("This is %s version %s.\n", PACKAGE, VERSION);
181 exit(0);
182 break;
183 default:
184 fprintf(stderr, "Unknown option.\n");
185 break;
186 }
187 }
188}
189
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100190int main(int argc, char **argv)
191{
192 int rc;
193 INIT_LLIST_HEAD(&bsc.sccp_connections);
194
195 bsc.dpc = 1;
196 bsc.opc = 0;
Holger Hans Peter Freyther7a725562011-01-01 13:34:58 +0100197 bsc.sccp_opc = -1;
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100198 bsc.udp_port = 3456;
199 bsc.udp_ip = NULL;
200 bsc.src_port = 1313;
Holger Hans Peter Freyther396282e2010-12-08 10:08:14 +0100201 bsc.ni_ni = MTP_NI_NATION_NET;
202 bsc.ni_spare = 0;
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100203
204 mtp_link_init();
205 thread_init();
206
207 log_init(&log_info);
208 stderr_target = log_target_create_stderr();
209 log_add_target(stderr_target);
210
211 /* enable filters */
212 log_set_all_filter(stderr_target, 1);
213 log_set_category_filter(stderr_target, DINP, 1, LOGL_INFO);
214 log_set_category_filter(stderr_target, DSCCP, 1, LOGL_INFO);
215 log_set_category_filter(stderr_target, DMSC, 1, LOGL_INFO);
216 log_set_category_filter(stderr_target, DMGCP, 1, LOGL_INFO);
217 log_set_print_timestamp(stderr_target, 1);
218 log_set_use_color(stderr_target, 0);
219
220 sccp_set_log_area(DSCCP);
221
222 bsc.setup = 0;
223 bsc.msc_address = "127.0.0.1";
224 bsc.link.pcap_fd = -1;
225 bsc.link.udp.reset_timeout = 180;
226 bsc.ping_time = 20;
227 bsc.pong_time = 5;
228 bsc.msc_time = 20;
Holger Hans Peter Freyther76943812010-11-16 11:14:34 +0100229 bsc.forward_only = 1;
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100230
231 handle_options(argc, argv);
232
233 signal(SIGPIPE, SIG_IGN);
234 signal(SIGINT, sigint);
235 signal(SIGUSR2, sigusr2);
236 srand(time(NULL));
237
238 cell_vty_init();
239 if (vty_read_config_file(config, NULL) < 0) {
240 fprintf(stderr, "Failed to read the VTY config.\n");
241 return -1;
242 }
243
244 rc = telnet_init(NULL, NULL, 4242);
245 if (rc < 0)
246 return rc;
247
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100248 if (link_init(&bsc) != 0)
249 return -1;
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100250
251 while (1) {
252 bsc_select_main(0);
253 }
254
255 return 0;
256}
257
258void release_bsc_resources(struct bsc_data *bsc)
259{
260 /* clear pending messages from the MSC */
261 msc_clear_queue(bsc);
262}
263
264struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref,
265 struct sccp_source_reference *dst)
266{
Holger Hans Peter Freyther8220b942010-12-08 10:08:40 +0100267 LOGP(DMSC, LOGL_NOTICE, "Refusing to create connection handling.\n");
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100268 return NULL;
269}
270
271struct msgb *create_reset()
272{
Holger Hans Peter Freyther8220b942010-12-08 10:08:40 +0100273 LOGP(DMSC, LOGL_NOTICE, "Refusing to create a GSM0808 reset message.\n");
Holger Hans Peter Freyther594ee9a2010-11-16 11:03:19 +0100274 return NULL;
275}
276
277void update_con_state(struct mtp_link *link, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
278{
279 LOGP(DMSC, LOGL_ERROR, "Should not be called.\n");
280 return;
281}
282
283unsigned int sls_for_src_ref(struct sccp_source_reference *ref)
284{
285 return 13;
286}
287
288int bsc_ussd_handle_in_msg(struct bsc_data *bsc, struct sccp_parse_result *res, struct msgb *msg)
289{
290 return 0;
291}
292
293int bsc_ussd_handle_out_msg(struct bsc_data *bsc, struct sccp_parse_result *res, struct msgb *msg)
294{
295 return 0;
296}