aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-04-30 20:26:32 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-04 07:20:42 +0200
commit9f75c35eb3cf796366b7452538a1d3113cd6b546 (patch)
tree73d808204e00b05d87558c4e5982bd053d096bf4 /openbsc/src
parent44f1c27460325924e0391677ca76798951289f53 (diff)
GPRS: Introduce a GPRS Gb Proxy
The ida of the Gb proxy is to aggregate Gb links with a number of BSS and then present all the BSSGP-VC's together inside one NS-VC to the actual SGSN. The code is not yet expected to be complete.
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/Makefile.am9
-rw-r--r--openbsc/src/gb_proxy.c315
-rw-r--r--openbsc/src/gb_proxy_main.c140
-rw-r--r--openbsc/src/gprs_bssgp.c7
-rw-r--r--openbsc/src/gprs_ns.c47
-rw-r--r--openbsc/src/input/ipaccess.c52
-rw-r--r--openbsc/src/socket.c94
7 files changed, 579 insertions, 85 deletions
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index 718252f77..ac418707a 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -3,7 +3,7 @@ AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
- isdnsync bsc_mgcp ipaccess-proxy
+ isdnsync bsc_mgcp ipaccess-proxy osmo-gb_proxy
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a libsgsn.a
noinst_HEADERS = vty/cardshell.h
@@ -11,7 +11,7 @@ bscdir = $(libdir)
bsc_LIBRARIES = libsccp.a
libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
- chan_alloc.c debug.c \
+ chan_alloc.c debug.c socket.c \
gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
input/misdn.c input/ipaccess.c \
@@ -50,3 +50,8 @@ bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgc
bsc_mgcp_LDADD = libvty.a
ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c
+
+osmo_gb_proxy_SOURCES = gb_proxy.c gb_proxy_main.c \
+ gprs_ns.c \
+ socket.c debug.c telnet_interface.c vty_interface_cmds.c
+osmo_gb_proxy_LDADD = libvty.a
diff --git a/openbsc/src/gb_proxy.c b/openbsc/src/gb_proxy.c
new file mode 100644
index 000000000..77cc8caf9
--- /dev/null
+++ b/openbsc/src/gb_proxy.c
@@ -0,0 +1,315 @@
+/* NS-over-IP proxy */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by On Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <osmocore/talloc.h>
+#include <osmocore/select.h>
+
+#include <openbsc/signal.h>
+#include <openbsc/debug.h>
+#include <openbsc/gprs_ns.h>
+#include <openbsc/gprs_bssgp.h>
+
+struct gbprox_peer {
+ struct llist_head list;
+
+ /* NS-VC over which we send/receive data to this BVC */
+ struct gprs_nsvc *nsvc;
+
+ /* BVCI used for Point-to-Point to this peer */
+ uint16_t bvci;
+
+ /* Routeing Area that this peer is part of (raw 04.08 encoding) */
+ uint8_t ra[6];
+};
+
+/* Linked list of all Gb peers (except SGSN) */
+static LLIST_HEAD(gbprox_bts_peers);
+
+/* Pointer to the SGSN peer */
+struct gbprox_peer *gbprox_peer_sgsn;
+
+/* The NS protocol stack instance we're using */
+extern struct gprs_ns_inst *gbprox_nsi;
+
+/* Find the gbprox_peer by its BVCI */
+static struct gbprox_peer *peer_by_bvci(uint16_t bvci)
+{
+ struct gbprox_peer *peer;
+ llist_for_each_entry(peer, &gbprox_bts_peers, list) {
+ if (peer->bvci == bvci)
+ return peer;
+ }
+ return NULL;
+}
+
+static struct gbprox_peer *peer_by_nsvc(struct gprs_nsvc *nsvc)
+{
+ struct gbprox_peer *peer;
+ llist_for_each_entry(peer, &gbprox_bts_peers, list) {
+ if (peer->nsvc == nsvc)
+ return peer;
+ }
+ return NULL;
+}
+
+/* look-up a peer by its Routeing Area Code (RAC) */
+static struct gbprox_peer *peer_by_rac(uint8_t *ra)
+{
+ struct gbprox_peer *peer;
+ llist_for_each_entry(peer, &gbprox_bts_peers, list) {
+ if (!memcmp(&peer->ra, ra, 6))
+ return peer;
+ }
+ return NULL;
+}
+
+/* look-up a peer by its Location Area Code (LAC) */
+static struct gbprox_peer *peer_by_lac(uint8_t *la)
+{
+ struct gbprox_peer *peer;
+ llist_for_each_entry(peer, &gbprox_bts_peers, list) {
+ if (!memcmp(&peer->ra, la, 5))
+ return peer;
+ }
+ return NULL;
+}
+
+static struct gbprox_peer *peer_alloc(uint16_t bvci)
+{
+ struct gbprox_peer *peer;
+
+ peer = talloc_zero(tall_bsc_ctx, struct gbprox_peer);
+ if (!peer)
+ return NULL;
+
+ peer->bvci = bvci;
+ llist_add(&peer->list, &gbprox_bts_peers);
+
+ return peer;
+}
+
+static void peer_free(struct gbprox_peer *peer)
+{
+ llist_del(&peer->list);
+ talloc_free(peer);
+}
+
+/* feed a message down the NS-VC associated with the specified peer */
+static int gbprox_tx2peer(struct msgb *msg, struct gbprox_peer *peer,
+ uint16_t ns_bvci)
+{
+ msgb_bvci(msg) = ns_bvci;
+ msgb_nsei(msg) = peer->nsvc->nsei;
+
+ return gprs_ns_sendmsg(gbprox_nsi, msg);
+}
+
+/* Send a message to a peer identified by ptp_bvci but using ns_bvci
+ * in the NS hdr */
+static int gbprox_tx2bvci(struct msgb *msg, uint16_t ptp_bvci,
+ uint16_t ns_bvci)
+{
+ struct gbprox_peer *peer;
+
+ peer = peer_by_bvci(ptp_bvci);
+ if (!peer)
+ return -ENOENT;
+
+ return gbprox_tx2peer(msg, peer, ns_bvci);
+}
+
+/* Receive an incoming signalling message from a BSS-side NS-VC */
+static int gbprox_rx_sig_from_bss(struct msgb *msg, struct gprs_nsvc *nsvc,
+ uint16_t ns_bvci)
+{
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msg->l3h;
+ struct tlv_parsed tp;
+ uint8_t pdu_type = bgph->pdu_type;
+ int data_len = msgb_l3len(msg) - sizeof(*bgph);
+ struct gbprox_peer *from_peer;
+
+ if (ns_bvci != 0) {
+ LOGP(DGPRS, LOGL_NOTICE, "BVCI %u not signalling\n", ns_bvci);
+ return -EINVAL;
+ }
+
+ /* we actually should never see those two for BVCI == 0, but double-check
+ * just to make sure */
+ if (pdu_type == BSSGP_PDUT_UL_UNITDATA ||
+ pdu_type == BSSGP_PDUT_DL_UNITDATA) {
+ LOGP(DGPRS, LOGL_NOTICE, "UNITDATA not allowed in signalling\n");
+ return -EINVAL;
+ }
+
+ bssgp_tlv_parse(&tp, bgph->data, data_len);
+
+ switch (pdu_type) {
+ case BSSGP_PDUT_SUSPEND:
+ case BSSGP_PDUT_RESUME:
+ /* RAC snooping for SUSPEND/RESUME */
+ if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA))
+ goto err_mand_ie;
+ from_peer = peer_by_nsvc(nsvc);
+ if (!from_peer)
+ goto err_no_peer;
+ memcpy(&from_peer->ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA),
+ sizeof(&from_peer->ra));
+ /* FIXME: This only supports one BSS per RA */
+ break;
+ }
+
+ /* Normally, we can simply pass on all signalling messages from BSS to SGSN */
+ return gbprox_tx2peer(msg, gbprox_peer_sgsn, ns_bvci);
+err_no_peer:
+err_mand_ie:
+ /* FIXME: do something */
+ ;
+}
+
+/* Receive paging request from SGSN, we need to relay to proper BSS */
+static int gbprox_rx_paging(struct msgb *msg, struct tlv_parsed *tp,
+ struct gprs_nsvc *nsvc, uint16_t ns_bvci)
+{
+ struct gbprox_peer *peer;
+
+ if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
+ uint16_t bvci = ntohs(*(uint16_t *)TLVP_VAL(tp, BSSGP_IE_BVCI));
+ return gbprox_tx2bvci(msg, bvci, ns_bvci);
+ } else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
+ peer = peer_by_rac(TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
+ return gbprox_tx2peer(msg, peer, ns_bvci);
+ } else if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) {
+ peer = peer_by_lac(TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA));
+ return gbprox_tx2peer(msg, peer, ns_bvci);
+ } else
+ return -EINVAL;
+}
+
+/* Receive an incoming signalling message from the SGSN-side NS-VC */
+static int gbprox_rx_sig_from_sgsn(struct msgb *msg, struct gprs_nsvc *nsvc,
+ uint16_t ns_bvci)
+{
+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msg->l3h;
+ struct tlv_parsed tp;
+ uint8_t pdu_type = bgph->pdu_type;
+ int data_len = msgb_l3len(msg) - sizeof(*bgph);
+ struct gbprox_peer *peer;
+ uint16_t bvci;
+ int rc = 0;
+
+ if (ns_bvci != 0) {
+ LOGP(DGPRS, LOGL_NOTICE, "BVCI %u not signalling\n", ns_bvci);
+ return -EINVAL;
+ }
+
+ /* we actually should never see those two for BVCI == 0, but double-check
+ * just to make sure */
+ if (pdu_type == BSSGP_PDUT_UL_UNITDATA ||
+ pdu_type == BSSGP_PDUT_DL_UNITDATA) {
+ LOGP(DGPRS, LOGL_NOTICE, "UNITDATA not allowed in signalling\n");
+ return -EINVAL;
+ }
+
+ rc = bssgp_tlv_parse(&tp, bgph->data, data_len);
+
+ switch (pdu_type) {
+ case BSSGP_PDUT_FLUSH_LL:
+ case BSSGP_PDUT_BVC_BLOCK_ACK:
+ case BSSGP_PDUT_BVC_UNBLOCK_ACK:
+ case BSSGP_PDUT_BVC_RESET:
+ case BSSGP_PDUT_BVC_RESET_ACK:
+ /* simple case: BVCI IE is mandatory */
+ if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI))
+ goto err_mand_ie;
+ bvci = ntohs(*(uint16_t *)TLVP_VAL(&tp, BSSGP_IE_BVCI));
+ rc = gbprox_tx2bvci(msg, bvci, ns_bvci);
+ break;
+ case BSSGP_PDUT_PAGING_PS:
+ case BSSGP_PDUT_PAGING_CS:
+ /* process the paging request (LAC/RAC lookup) */
+ rc = gbprox_rx_paging(msg, &tp, nsvc, ns_bvci);
+ break;
+ case BSSGP_PDUT_STATUS:
+ /* FIXME: Some exception has occurred */
+ LOGP(DGPRS, LOGL_NOTICE, "STATUS not implemented yet\n");
+ break;
+ /* those only exist in the SGSN -> BSS direction */
+ case BSSGP_PDUT_SUSPEND_ACK:
+ case BSSGP_PDUT_SUSPEND_NACK:
+ case BSSGP_PDUT_RESUME_ACK:
+ case BSSGP_PDUT_RESUME_NACK:
+ /* RAC IE is mandatory */
+ if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA))
+ goto err_mand_ie;
+ peer = peer_by_rac(TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA));
+ if (!peer)
+ goto err_no_peer;
+ rc = gbprox_tx2peer(msg, peer, ns_bvci);
+ break;
+ case BSSGP_PDUT_SGSN_INVOKE_TRACE:
+ LOGP(DGPRS, LOGL_ERROR, "SGSN INVOKE TRACE not supported\n");
+ break;
+ default:
+ DEBUGP(DGPRS, "BSSGP PDU type 0x%02x unknown\n", pdu_type);
+ break;
+ }
+
+ return rc;
+err_mand_ie:
+ ; /* FIXME: this would pull gprs_bssgp.c in, which in turn has dependencies */
+ //return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
+err_no_peer:
+ ; /* FIXME */
+}
+
+/* Main input function for Gb proxy */
+int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci)
+{
+ struct gbprox_peer *peer;
+
+ /* Only BVCI=0 messages need special treatment */
+ if (ns_bvci == 0 || ns_bvci == 1) {
+ if (nsvc->remote_end_is_sgsn)
+ return gbprox_rx_sig_from_sgsn(msg, nsvc, ns_bvci);
+ else
+ return gbprox_rx_sig_from_bss(msg, nsvc, ns_bvci);
+ }
+
+ /* All other BVCI are PTP and thus can be simply forwarded */
+ peer = peer_by_bvci(ns_bvci);
+ if (!peer) {
+ LOGP(DGPRS, LOGL_ERROR, "Couldn't find peer for BVCI %u\n", ns_bvci);
+ return -EIO;
+ }
+
+ return gbprox_tx2peer(msg, peer, ns_bvci);
+}
diff --git a/openbsc/src/gb_proxy_main.c b/openbsc/src/gb_proxy_main.c
new file mode 100644
index 000000000..c624cf8a4
--- /dev/null
+++ b/openbsc/src/gb_proxy_main.c
@@ -0,0 +1,140 @@
+/* NS-over-IP proxy */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by On Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <osmocore/talloc.h>
+#include <osmocore/select.h>
+
+#include <openbsc/signal.h>
+#include <openbsc/debug.h>
+#include <openbsc/gprs_ns.h>
+#include <openbsc/telnet_interface.h>
+#include <openbsc/vty.h>
+
+#include "../bscconfig.h"
+
+/* this is here for the vty... it will never be called */
+void subscr_put() { abort(); }
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+void *tall_bsc_ctx;
+
+struct gprs_ns_inst *gbprox_nsi;
+static u_int16_t nsip_listen_port;
+
+const char *openbsc_version = "Osmocom NSIP Proxy " PACKAGE_VERSION;
+const char *openbsc_copyright =
+ "Copyright (C) 2010 Harald Welte and On-Waves\n"
+ "Contributions by Daniel Willmann, Jan Lübbe, Stefan Schmidt\n"
+ "Dieter Spaar, Andreas Eversberg, Holger Freyther\n\n"
+ "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n";
+
+static char *config_file = "nsip_proxy.cfg";
+
+/* Pointer to the SGSN peer */
+extern struct gbprox_peer *gbprox_peer_sgsn;
+
+/* call-back function for the NS protocol */
+static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
+ struct msgb *msg, u_int16_t bvci)
+{
+ int rc = 0;
+
+ switch (event) {
+ case GPRS_NS_EVT_UNIT_DATA:
+ rc = gbprox_rcvmsg(msg, nsvc, bvci);
+ break;
+ default:
+ LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event);
+ if (msg)
+ talloc_free(msg);
+ rc = -EIO;
+ break;
+ }
+ return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+ struct gsm_network dummy_network;
+ struct log_target *stderr_target;
+ struct sockaddr_in sin;
+ int rc;
+
+ tall_bsc_ctx = talloc_named_const(NULL, 0, "nsip_proxy");
+
+ log_init(&log_info);
+ stderr_target = log_target_create_stderr();
+ log_add_target(stderr_target);
+ log_set_all_filter(stderr_target, 1);
+
+ telnet_init(&dummy_network, 4244);
+
+ gbprox_nsi = gprs_ns_instantiate(&proxy_ns_cb);
+ if (!gbprox_nsi) {
+ LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
+ exit(1);
+ }
+ nsip_listen(gbprox_nsi, nsip_listen_port);
+
+ /* 'establish' the outgoing connection to the SGSN */
+ sin.sin_port = ntohs(23000);
+ inet_aton("192.168.100.239", &sin.sin_addr);
+ gbprox_peer_sgsn = nsip_connect(gbprox_nsi, &sin, 2342);
+
+ while (1) {
+ rc = bsc_select_main(0);
+ if (rc < 0)
+ exit(3);
+ }
+
+ exit(0);
+}
+
+struct gsm_network;
+int bsc_vty_init(struct gsm_network *dummy)
+{
+ cmd_init(1);
+ vty_init();
+
+ openbsc_vty_add_cmds();
+ //mgcp_vty_init();
+ return 0;
+}
+
diff --git a/openbsc/src/gprs_bssgp.c b/openbsc/src/gprs_bssgp.c
index 650d7d45d..a2181b124 100644
--- a/openbsc/src/gprs_bssgp.c
+++ b/openbsc/src/gprs_bssgp.c
@@ -74,11 +74,6 @@ static const char *bssgp_cause_str(enum gprs_bssgp_cause cause)
return "undefined";
}
-static inline int bssgp_tlv_parse(struct tlv_parsed *tp, u_int8_t *buf, int len)
-{
- return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
-}
-
static inline struct msgb *bssgp_msgb_alloc(void)
{
return msgb_alloc_headroom(4096, 128, "BSSGP");
@@ -120,7 +115,7 @@ static int bssgp_tx_fc_bvc_ack(u_int16_t nsei, u_int8_t tag, u_int16_t ns_bvci)
}
/* Chapter 10.4.14: Status */
-static int bssgp_tx_status(u_int8_t cause, u_int16_t *bvci, struct msgb *orig_msg)
+int bssgp_tx_status(u_int8_t cause, u_int16_t *bvci, struct msgb *orig_msg)
{
struct msgb *msg = bssgp_msgb_alloc();
struct bssgp_normal_hdr *bgph =
diff --git a/openbsc/src/gprs_ns.c b/openbsc/src/gprs_ns.c
index 6c495b01e..3bb0bf94d 100644
--- a/openbsc/src/gprs_ns.c
+++ b/openbsc/src/gprs_ns.c
@@ -72,30 +72,6 @@ static const struct tlv_definition ns_att_tlvdef = {
},
};
-#define NSE_S_BLOCKED 0x0001
-#define NSE_S_ALIVE 0x0002
-
-struct gprs_nsvc {
- struct llist_head list;
- struct gprs_ns_inst *nsi;
-
- u_int16_t nsei; /* end-to-end significance */
- u_int16_t nsvci; /* uniquely identifies NS-VC at SGSN */
-
- u_int32_t state;
- u_int32_t remote_state;
-
- struct timer_list alive_timer;
- int timer_is_tns_alive;
- int alive_retries;
-
- union {
- struct {
- struct sockaddr_in bts_addr;
- } ip;
- };
-};
-
enum gprs_ns_ll {
GPRS_NS_LL_UDP,
GPRS_NS_LL_E1,
@@ -474,7 +450,7 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb)
nsi->cb = cb;
INIT_LLIST_HEAD(&nsi->gprs_nsvcs);
- return NULL;
+ return nsi;
}
void gprs_ns_destroy(struct gprs_ns_inst *nsi)
@@ -586,3 +562,24 @@ int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port)
return ret;
}
+
+/* Establish a connection (from the BSS) to the SGSN */
+struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
+ struct sockaddr_in *dest, uint16_t nsvci)
+{
+ struct gprs_nsvc *nsvc;
+
+ nsvc = nsvc_by_rem_addr(nsi, dest);
+ if (!nsvc) {
+ nsvc = nsvc_create(nsi, nsvci);
+ nsvc->ip.bts_addr = *dest;
+ }
+ nsvc->remote_end_is_sgsn = 1;
+
+ /* Initiate a RESET procedure */
+ if (gprs_ns_tx_simple(nsvc, NS_PDUT_RESET) < 0)
+ return NULL;
+ /* FIXME: should we run a timer and re-transmit the reset request? */
+
+ return nsvc;
+}
diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c
index 2b5bf21a6..721cadd23 100644
--- a/openbsc/src/input/ipaccess.c
+++ b/openbsc/src/input/ipaccess.c
@@ -707,58 +707,6 @@ static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
return 0;
}
-int make_sock(struct bsc_fd *bfd, int proto, u_int16_t port,
- int (*cb)(struct bsc_fd *fd, unsigned int what))
-{
- struct sockaddr_in addr;
- int ret, on = 1;
- int type = SOCK_STREAM;
-
- if (proto == IPPROTO_UDP)
- type = SOCK_DGRAM;
-
- bfd->fd = socket(AF_INET, type, proto);
- bfd->cb = cb;
- bfd->when = BSC_FD_READ;
- //bfd->data = line;
-
- if (bfd->fd < 0) {
- LOGP(DINP, LOGL_ERROR, "could not create TCP socket.\n");
- return -EIO;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = INADDR_ANY;
-
- setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
- if (ret < 0) {
- LOGP(DINP, LOGL_ERROR, "could not bind l2 socket %s\n",
- strerror(errno));
- close(bfd->fd);
- return -EIO;
- }
-
- if (proto != IPPROTO_UDP) {
- ret = listen(bfd->fd, 1);
- if (ret < 0) {
- perror("listen");
- return ret;
- }
- }
-
- ret = bsc_register_fd(bfd);
- if (ret < 0) {
- perror("register_listen_fd");
- close(bfd->fd);
- return ret;
- }
- return 0;
-}
-
/* Actively connect to a BTS. Currently used by ipaccess-config.c */
int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa)
{
diff --git a/openbsc/src/socket.c b/openbsc/src/socket.c
new file mode 100644
index 000000000..3ed4d425a
--- /dev/null
+++ b/openbsc/src/socket.c
@@ -0,0 +1,94 @@
+/* OpenBSC sokcet code, taken from Abis input driver for ip.access */
+
+/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther
+ * (C) 2010 by On-Waves
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+
+#include <osmocore/select.h>
+#include <osmocore/tlv.h>
+#include <osmocore/msgb.h>
+#include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+#include <osmocore/talloc.h>
+
+int make_sock(struct bsc_fd *bfd, int proto, u_int16_t port,
+ int (*cb)(struct bsc_fd *fd, unsigned int what))
+{
+ struct sockaddr_in addr;
+ int ret, on = 1;
+ int type = SOCK_STREAM;
+
+ if (proto == IPPROTO_UDP)
+ type = SOCK_DGRAM;
+
+ bfd->fd = socket(AF_INET, type, proto);
+ bfd->cb = cb;
+ bfd->when = BSC_FD_READ;
+ //bfd->data = line;
+
+ if (bfd->fd < 0) {
+ LOGP(DINP, LOGL_ERROR, "could not create TCP socket.\n");
+ return -EIO;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
+ if (ret < 0) {
+ LOGP(DINP, LOGL_ERROR, "could not bind l2 socket %s\n",
+ strerror(errno));
+ close(bfd->fd);
+ return -EIO;
+ }
+
+ if (proto != IPPROTO_UDP) {
+ ret = listen(bfd->fd, 1);
+ if (ret < 0) {
+ perror("listen");
+ return ret;
+ }
+ }
+
+ ret = bsc_register_fd(bfd);
+ if (ret < 0) {
+ perror("register_listen_fd");
+ close(bfd->fd);
+ return ret;
+ }
+ return 0;
+}