Move BSSGP/NS instances creation and desctruction to gprs_bssgp_pcu.cpp
This commit is contained in:
parent
81e895b619
commit
bf5a0f6e2c
|
@ -24,6 +24,8 @@
|
|||
struct sgsn_instance *sgsn;
|
||||
void *tall_bsc_ctx;
|
||||
struct bssgp_bvc_ctx *bctx = btsctx_alloc(BVCI, NSEI);
|
||||
struct gprs_nsvc *nsvc = NULL;
|
||||
extern uint16_t spoof_mcc, spoof_mnc;
|
||||
|
||||
int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp)
|
||||
{
|
||||
|
@ -284,3 +286,128 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
|
||||
{
|
||||
int rc = 0;
|
||||
switch (event) {
|
||||
case GPRS_NS_EVT_UNIT_DATA:
|
||||
/* hand the message into the BSSGP implementation */
|
||||
rc = gprs_bssgp_pcu_rcvmsg(msg);
|
||||
break;
|
||||
default:
|
||||
LOGP(DPCU, LOGL_ERROR, "RLCMAC: Unknown event %u from NS\n", event);
|
||||
if (msg)
|
||||
talloc_free(msg);
|
||||
rc = -EIO;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nsvc_unblocked = 0;
|
||||
|
||||
static int nsvc_signal_cb(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct ns_signal_data *nssd;
|
||||
|
||||
if (subsys != SS_L_NS)
|
||||
return -EINVAL;
|
||||
|
||||
nssd = (struct ns_signal_data *)signal_data;
|
||||
if (nssd->nsvc != nsvc) {
|
||||
LOGP(DPCU, LOGL_ERROR, "Signal received of unknown NSVC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (signal) {
|
||||
case S_NS_UNBLOCK:
|
||||
if (!nsvc_unblocked) {
|
||||
nsvc_unblocked = 1;
|
||||
LOGP(DPCU, LOGL_NOTICE, "NS-VC is unblocked.\n");
|
||||
bssgp_tx_bvc_reset(bctx, bctx->bvci,
|
||||
BSSGP_CAUSE_PROTO_ERR_UNSPEC);
|
||||
}
|
||||
break;
|
||||
case S_NS_BLOCK:
|
||||
if (nsvc_unblocked) {
|
||||
nsvc_unblocked = 0;
|
||||
LOGP(DPCU, LOGL_NOTICE, "NS-VC is blocked.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create BSSGP/NS layer instances */
|
||||
int gprs_bssgp_create(uint32_t sgsn_ip, uint16_t sgsn_port, uint16_t nsei,
|
||||
uint16_t nsvci, uint16_t bvci, uint16_t mcc, uint16_t mnc, uint16_t lac,
|
||||
uint16_t rac, uint16_t cell_id)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
|
||||
if (bctx)
|
||||
return 0; /* if already created, must return 0: no error */
|
||||
|
||||
bssgp_nsi = gprs_ns_instantiate(&sgsn_ns_cb, NULL);
|
||||
if (!bssgp_nsi) {
|
||||
LOGP(DBSSGP, LOGL_NOTICE, "Failed to create NS instance\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
gprs_ns_nsip_listen(bssgp_nsi);
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(sgsn_port);
|
||||
dest.sin_addr.s_addr = htonl(sgsn_ip);
|
||||
|
||||
nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
|
||||
if (!nsvc) {
|
||||
LOGP(DBSSGP, LOGL_NOTICE, "Failed to create NSVCt\n");
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bctx = btsctx_alloc(bvci, nsei);
|
||||
if (!bctx) {
|
||||
LOGP(DBSSGP, LOGL_NOTICE, "Failed to create BSSGP context\n");
|
||||
nsvc = NULL;
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
bctx->ra_id.mcc = spoof_mcc ? : mcc;
|
||||
bctx->ra_id.mnc = spoof_mnc ? : mnc;
|
||||
bctx->ra_id.lac = lac;
|
||||
bctx->ra_id.rac = rac;
|
||||
bctx->cell_id = cell_id;
|
||||
|
||||
osmo_signal_register_handler(SS_L_NS, nsvc_signal_cb, NULL);
|
||||
|
||||
// bssgp_tx_bvc_reset(bctx, bctx->bvci, BSSGP_CAUSE_PROTO_ERR_UNSPEC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gprs_bssgp_destroy(void)
|
||||
{
|
||||
if (!bssgp_nsi)
|
||||
return;
|
||||
|
||||
osmo_signal_unregister_handler(SS_L_NS, nsvc_signal_cb, NULL);
|
||||
|
||||
nsvc = NULL;
|
||||
|
||||
/* FIXME: move this to libgb: btsctx_free() */
|
||||
llist_del(&bctx->list);
|
||||
talloc_free(bctx);
|
||||
bctx = NULL;
|
||||
|
||||
/* FIXME: blocking... */
|
||||
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,4 +67,10 @@ int gprs_bssgp_pcu_rx_sign(struct msgb *msg, struct tlv_parsed *tp, struct bssgp
|
|||
|
||||
int gprs_bssgp_pcu_rcvmsg(struct msgb *msg);
|
||||
|
||||
int gprs_bssgp_create(uint32_t sgsn_ip, uint16_t sgsn_port, uint16_t nsei,
|
||||
uint16_t nsvci, uint16_t bvci, uint16_t mcc, uint16_t mnc, uint16_t lac,
|
||||
uint16_t rac, uint16_t cell_id);
|
||||
|
||||
void gprs_bssgp_destroy(void);
|
||||
|
||||
#endif // GPRS_BSSGP_PCU_H
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <gprs_rlcmac.h>
|
||||
#include <gprs_bssgp_pcu.h>
|
||||
#include <pcu_l1_if.h>
|
||||
#include <gprs_debug.h>
|
||||
#include <bitvector.h>
|
||||
#include <gsmL1prim.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/in.h>
|
||||
#include <arpa/inet.h>
|
||||
extern "C" {
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
|
@ -279,12 +280,40 @@ static int udp_write_cb(struct osmo_fd *ofd, struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: We should move this parameters to config file.
|
||||
#define SGSN_IP 127.0.0.1
|
||||
#define SGSN_PORT 23000
|
||||
#define NSEI 3
|
||||
#define NSVCI 4
|
||||
|
||||
#define BVCI 7
|
||||
|
||||
#define MAX_LEN_PDU 60
|
||||
#define IE_LLC_PDU 14
|
||||
#define BLOCK_DATA_LEN 20
|
||||
#define BLOCK_LEN 23
|
||||
|
||||
#define CELL_ID 0
|
||||
#define MNC 2
|
||||
#define MCC 262
|
||||
#define PCU_LAC 1
|
||||
#define PCU_RAC 0
|
||||
|
||||
int pcu_l1if_open()
|
||||
{
|
||||
//struct l1fwd_hdl *l1fh;
|
||||
struct femtol1_hdl *fl1h;
|
||||
int rc;
|
||||
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(SGSN_PORT);
|
||||
inet_aton(SGSN_IP, &dest.sin_addr);
|
||||
|
||||
rc = gprs_bssgp_create(ntohl(dest.sin_addr.s_addr), SGSN_PORT, NSEI, NSVCI, BVCI, MCC, MNC, PCU_LAC, PCU_RAC, CELL_ID);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* allocate new femtol1_handle */
|
||||
fl1h = talloc_zero(NULL, struct femtol1_hdl);
|
||||
INIT_LLIST_HEAD(&fl1h->wlc_list);
|
||||
|
@ -318,3 +347,10 @@ int pcu_l1if_open()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void pcu_l1if_close(void)
|
||||
{
|
||||
gprs_bssgp_destroy();
|
||||
|
||||
/* FIXME: cleanup l1if */
|
||||
talloc_free(fl1h);
|
||||
}
|
||||
|
|
|
@ -255,6 +255,7 @@ bssgp_failed:
|
|||
}
|
||||
}
|
||||
}
|
||||
gprs_bssgp_destroy();
|
||||
return 0;
|
||||
}
|
||||
LOGP(DL1IF, LOGL_INFO, "BTS available\n");
|
||||
|
@ -305,6 +306,15 @@ bssgp_failed:
|
|||
LOGP(DL1IF, LOGL_INFO, " remote_port=%d\n", info_ind->remote_port[0]);
|
||||
LOGP(DL1IF, LOGL_INFO, " remote_ip=%d\n", info_ind->remote_ip[0]);
|
||||
|
||||
rc = gprs_bssgp_create(info_ind->remote_ip[0], info_ind->remote_port[0],
|
||||
info_ind->nsei, info_ind->nsvci[0], info_ind->bvci,
|
||||
info_ind->mcc, info_ind->mnc, info_ind->lac, info_ind->rac,
|
||||
info_ind->cell_id);
|
||||
if (rc < 0) {
|
||||
LOGP(DL1IF, LOGL_NOTICE, "SGSN not available\n");
|
||||
goto bssgp_failed;
|
||||
}
|
||||
|
||||
bts->cs1 = !!(info_ind->flags & PCU_IF_FLAG_CS1);
|
||||
bts->cs2 = !!(info_ind->flags & PCU_IF_FLAG_CS2);
|
||||
bts->cs3 = !!(info_ind->flags & PCU_IF_FLAG_CS3);
|
||||
|
@ -484,6 +494,8 @@ static void pcu_sock_close(struct pcu_sock_state *state)
|
|||
}
|
||||
}
|
||||
|
||||
gprs_bssgp_destroy();
|
||||
|
||||
state->timer.cb = pcu_sock_timeout;
|
||||
osmo_timer_schedule(&state->timer, 5, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue