summaryrefslogtreecommitdiffstats
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
commit3771d09ec01581e50253dce4dc5ec0abba9a1e35 (patch)
tree8bd7c1b89f802232ca18a4cce18a03fd84c3a848
parent24a655f1406f53ce54802e72f72b6bf19394672e (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.
-rw-r--r--openbsc/include/openbsc/gprs_bssgp.h10
-rw-r--r--openbsc/include/openbsc/gprs_ns.h39
-rw-r--r--openbsc/src/gprs_bssgp.c7
-rw-r--r--openbsc/src/gprs_ns.c47
4 files changed, 71 insertions, 32 deletions
diff --git a/openbsc/include/openbsc/gprs_bssgp.h b/openbsc/include/openbsc/gprs_bssgp.h
index f85ac48e..3040e6a0 100644
--- a/openbsc/include/openbsc/gprs_bssgp.h
+++ b/openbsc/include/openbsc/gprs_bssgp.h
@@ -133,6 +133,16 @@ enum gprs_bssgp_cause {
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
};
+/* Our implementation */
+
+#include <osmocore/tlv.h>
+
extern int gprs_bssgp_rcvmsg(struct msgb *msg, u_int16_t bvci);
+/* Wrapper around TLV parser to parse BSSGP IEs */
+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);
+}
+
#endif /* _GPRS_BSSGP_H */
diff --git a/openbsc/include/openbsc/gprs_ns.h b/openbsc/include/openbsc/gprs_ns.h
index 34a3e581..dd10d333 100644
--- a/openbsc/include/openbsc/gprs_ns.h
+++ b/openbsc/include/openbsc/gprs_ns.h
@@ -73,7 +73,37 @@ enum ns_cause {
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
};
-struct gprs_nsvc;
+
+/* Our Implementation */
+#include <netinet/in.h>
+
+#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;
+
+ int remote_end_is_sgsn;
+
+ union {
+ struct {
+ struct sockaddr_in bts_addr;
+ } ip;
+ };
+};
+
+
struct gprs_ns_inst;
enum gprs_ns_evt {
@@ -101,4 +131,11 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
+
+/* Listen for incoming GPRS packets */
+int nsip_listen(struct gprs_ns_inst *nsi, uint16_t udp_port);
+
+/* 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);
#endif
diff --git a/openbsc/src/gprs_bssgp.c b/openbsc/src/gprs_bssgp.c
index 650d7d45..a2181b12 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 6c495b01..3bb0bf94 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;
+}