blob: 67db49af814ac8e1e946d9d68428fe5f9855b9ec [file] [log] [blame]
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +08001/* BSC Multiplexer/NAT */
2
3/*
4 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2010 by on-waves.com
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#include <sys/socket.h>
24#include <netinet/in.h>
25#include <arpa/inet.h>
26
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +010027#include <signal.h>
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +080028#include <stdio.h>
29#include <stdlib.h>
30#include <unistd.h>
31
32#define _GNU_SOURCE
33#include <getopt.h>
34
35#include <openbsc/debug.h>
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +010036#include <openbsc/msgb.h>
37#include <openbsc/bsc_msc.h>
38#include <openbsc/ipaccess.h>
39#include <openbsc/abis_nm.h>
40#include <openbsc/talloc.h>
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +080041
42static const char *config_file = "openbsc.cfg";
43static char *msc_address = "127.0.0.1";
44static struct in_addr local_addr;
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +010045static struct bsc_fd msc_connection;
46
47/*
48 * below are stubs we need to link
49 */
50int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
51 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
52{
53 return -1;
54}
55
56void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
57{}
58
59int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
60{
61 return -1;
62}
63
64/*
65 * Below is the handling of messages coming
66 * from the MSC and need to be forwarded to
67 * a real BSC.
68 */
69static void initialize_msc_if_needed()
70{
71 static int init = 0;
72 init = 1;
73
74 /* do we need to send a GSM 08.08 message here? */
75}
76
77static void forward_sccp_to_bts(struct msgb *msg)
78{
79 /* filter, drop, patch the message? */
80}
81
82static int ipaccess_msc_cb(struct bsc_fd *bfd, unsigned int what)
83{
84 int error;
85 struct msgb *msg = ipaccess_read_msg(bfd, &error);
86 struct ipaccess_head *hh;
87
88 if (!msg) {
89 if (error == 0) {
90 fprintf(stderr, "The connection to the MSC was lost, exiting\n");
91 exit(-2);
92 }
93
94 fprintf(stderr, "Failed to parse ip access message: %d\n", error);
95 return -1;
96 }
97
98 DEBUGP(DMSC, "MSG from MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
99
100 /* handle base message handling */
101 hh = (struct ipaccess_head *) msg->data;
102 ipaccess_rcvmsg_base(msg, bfd);
103
104 /* initialize the networking. This includes sending a GSM08.08 message */
105 if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_ID_ACK)
106 initialize_msc_if_needed();
107 else if (hh->proto == IPAC_PROTO_SCCP)
108 forward_sccp_to_bts(msg);
109
110 return 0;
111}
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +0800112
113static void print_usage()
114{
115 printf("Usage: bsc_nat\n");
116}
117
118static void print_help()
119{
120 printf(" Some useful help...\n");
121 printf(" -h --help this text\n");
122 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
123 printf(" -s --disable-color\n");
124 printf(" -c --config-file filename The config file to use.\n");
125 printf(" -m --msc=IP. The address of the MSC.\n");
126 printf(" -l --local=IP. The local address of the MGCP.\n");
127}
128
129static void handle_options(int argc, char** argv)
130{
131 while (1) {
132 int option_index = 0, c;
133 static struct option long_options[] = {
134 {"help", 0, 0, 'h'},
135 {"debug", 1, 0, 'd'},
136 {"config-file", 1, 0, 'c'},
137 {"disable-color", 0, 0, 's'},
138 {"timestamp", 0, 0, 'T'},
139 {"msc", 1, 0, 'm'},
140 {"local", 1, 0, 'l'},
141 {0, 0, 0, 0}
142 };
143
144 c = getopt_long(argc, argv, "hd:sTPc:m:l:",
145 long_options, &option_index);
146 if (c == -1)
147 break;
148
149 switch (c) {
150 case 'h':
151 print_usage();
152 print_help();
153 exit(0);
154 case 's':
155 debug_use_color(0);
156 break;
157 case 'd':
158 debug_parse_category_mask(optarg);
159 break;
160 case 'c':
161 config_file = strdup(optarg);
162 break;
163 case 'T':
164 debug_timestamp(1);
165 break;
166 case 'm':
167 msc_address = strdup(optarg);
168 break;
169 case 'l':
170 inet_aton(optarg, &local_addr);
171 break;
172 default:
173 /* ignore */
174 break;
175 }
176 }
177}
178
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +0100179static void signal_handler(int signal)
180{
181 fprintf(stdout, "signal %u received\n", signal);
182
183 switch (signal) {
184 case SIGABRT:
185 /* in case of abort, we want to obtain a talloc report
186 * and then return to the caller, who will abort the process */
187 case SIGUSR1:
188 talloc_report_full(tall_bsc_ctx, stderr);
189 break;
190 default:
191 break;
192 }
193}
194
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +0800195int main(int argc, char** argv)
196{
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +0100197 int rc;
198
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +0800199 /* parse options */
200 handle_options(argc, argv);
201
202 /* seed the PRNG */
203 srand(time(NULL));
204
Holger Hans Peter Freyther6ace5222010-01-12 21:15:08 +0100205 msc_connection.cb = ipaccess_msc_cb;
206 rc = connect_to_msc(&msc_connection, msc_address, 5000);
207 if (rc < 0) {
208 fprintf(stderr, "Opening the MSC connection failed.\n");
209 exit(1);
210 }
211
212 signal(SIGINT, &signal_handler);
213 signal(SIGABRT, &signal_handler);
214 signal(SIGUSR1, &signal_handler);
215 signal(SIGPIPE, SIG_IGN);
216
217 while (1) {
218 bsc_select_main(0);
219 }
220
Holger Hans Peter Freyther9e2c5f52010-06-15 18:44:42 +0800221 return 0;
222}