mirror of https://gerrit.osmocom.org/libosmocore
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.
This commit is contained in:
parent
24a655f140
commit
3771d09ec0
|
@ -133,6 +133,16 @@ enum gprs_bssgp_cause {
|
||||||
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
|
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Our implementation */
|
||||||
|
|
||||||
|
#include <osmocore/tlv.h>
|
||||||
|
|
||||||
extern int gprs_bssgp_rcvmsg(struct msgb *msg, u_int16_t bvci);
|
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 */
|
#endif /* _GPRS_BSSGP_H */
|
||||||
|
|
|
@ -73,7 +73,37 @@ enum ns_cause {
|
||||||
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
|
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;
|
struct gprs_ns_inst;
|
||||||
|
|
||||||
enum gprs_ns_evt {
|
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 */
|
/* main function for higher layers (BSSGP) to send NS messages */
|
||||||
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
|
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
|
#endif
|
||||||
|
|
|
@ -74,11 +74,6 @@ static const char *bssgp_cause_str(enum gprs_bssgp_cause cause)
|
||||||
return "undefined";
|
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)
|
static inline struct msgb *bssgp_msgb_alloc(void)
|
||||||
{
|
{
|
||||||
return msgb_alloc_headroom(4096, 128, "BSSGP");
|
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 */
|
/* 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 msgb *msg = bssgp_msgb_alloc();
|
||||||
struct bssgp_normal_hdr *bgph =
|
struct bssgp_normal_hdr *bgph =
|
||||||
|
|
|
@ -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 {
|
enum gprs_ns_ll {
|
||||||
GPRS_NS_LL_UDP,
|
GPRS_NS_LL_UDP,
|
||||||
GPRS_NS_LL_E1,
|
GPRS_NS_LL_E1,
|
||||||
|
@ -474,7 +450,7 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb)
|
||||||
nsi->cb = cb;
|
nsi->cb = cb;
|
||||||
INIT_LLIST_HEAD(&nsi->gprs_nsvcs);
|
INIT_LLIST_HEAD(&nsi->gprs_nsvcs);
|
||||||
|
|
||||||
return NULL;
|
return nsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gprs_ns_destroy(struct gprs_ns_inst *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;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue