libgb: don't call directly into GMM / LLC layer
Instead of direct function calls to individual functions, we now generate primitives (osmo_prim) and send them to one application-provided function "bssgp_prim_cb()"
This commit is contained in:
parent
faa70ff2c6
commit
b1fd9022eb
|
@ -144,6 +144,7 @@ enum gprs_bssgp_cause {
|
|||
/* Our implementation */
|
||||
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/gsm/prim.h>
|
||||
|
||||
/* gprs_bssgp_util.c */
|
||||
extern struct gprs_ns_inst *bssgp_nsi;
|
||||
|
@ -155,6 +156,40 @@ int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
|
|||
/* Chapter 10.4.14: Status */
|
||||
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
|
||||
|
||||
enum bssgp_prim {
|
||||
PRIM_BSSGP_DL_UD,
|
||||
PRIM_BSSGP_UL_UD,
|
||||
PRIM_BSSGP_PTM_UD,
|
||||
|
||||
PRIM_BSSGP_GMM_SUSPEND,
|
||||
PRIM_BSSGP_GMM_RESUME,
|
||||
PRIM_BSSGP_GMM_PAGING,
|
||||
|
||||
PRIM_NM_FLUSH_LL,
|
||||
PRIM_NM_LLC_DISCARDED,
|
||||
PRIM_NM_BVC_RESET,
|
||||
PRIM_NM_BVC_BLOCK,
|
||||
PRIM_NM_BVC_UNBLOCK,
|
||||
};
|
||||
|
||||
struct osmo_bssgp_prim {
|
||||
struct osmo_prim_hdr oph;
|
||||
|
||||
/* common fields */
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
uint32_t tlli;
|
||||
struct tlv_parsed *tp;
|
||||
struct gprs_ra_id *ra_id;
|
||||
|
||||
/* specific fields */
|
||||
union {
|
||||
struct {
|
||||
uint8_t *suspend_ref;
|
||||
} resume;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* gprs_bssgp.c */
|
||||
|
||||
#define BVC_S_BLOCKED 0x0001
|
||||
|
@ -264,4 +299,6 @@ int gprs_bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
|
|||
int gprs_bssgp_vty_init(void);
|
||||
void gprs_bssgp_set_log_ss(int ss);
|
||||
|
||||
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
|
||||
|
||||
#endif /* _GPRS_BSSGP_H */
|
||||
|
|
|
@ -246,6 +246,11 @@ static int gbprox_relay2bvci(struct msgb *msg, uint16_t ptp_bvci,
|
|||
return gbprox_relay2peer(msg, peer, ns_bvci);
|
||||
}
|
||||
|
||||
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
|
|
|
@ -48,7 +48,6 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
|
|||
dup.drx_parms = mmctx->drx_parms;
|
||||
dup.ms_ra_cap.len = mmctx->ms_radio_access_capa.len;
|
||||
dup.ms_ra_cap.v = mmctx->ms_radio_access_capa.buf;
|
||||
dup.pdu_lifetime = 1000; /* centi-seconds */
|
||||
memcpy(&dup.qos_profile, qos_profile_default,
|
||||
sizeof(qos_profile_default));
|
||||
|
||||
|
@ -328,7 +327,7 @@ int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi, int command,
|
|||
/* Identifiers passed down: (BVCI, NSEI) */
|
||||
|
||||
/* Send BSSGP-DL-UNITDATA.req */
|
||||
return _bssgp_tx_dl_ud(msg, 1000, NULL);
|
||||
return _bssgp_tx_dl_ud(msg, NULL);
|
||||
}
|
||||
|
||||
/* Send XID response to LLE */
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <openbsc/vty.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
#include <openbsc/gprs_llc.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
|
||||
#include <gtp.h>
|
||||
|
||||
|
@ -99,6 +100,34 @@ static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* call-back function for the BSSGP protocol */
|
||||
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
|
||||
{
|
||||
struct osmo_bssgp_prim *bp;
|
||||
bp = container_of(oph, struct osmo_bssgp_prim, oph);
|
||||
|
||||
switch (oph->sap) {
|
||||
case SAP_BSSGP_LL:
|
||||
switch (oph->primitive) {
|
||||
case PRIM_BSSGP_UL_UD:
|
||||
return gprs_llc_rcvmsg(oph->msg, bp->tp);
|
||||
}
|
||||
break;
|
||||
case SAP_BSSGP_GMM:
|
||||
switch (oph->primitive) {
|
||||
case PRIM_BSSGP_GMM_SUSPEND:
|
||||
return gprs_gmm_rx_suspend(bp->ra_id, bp->tlli);
|
||||
case PRIM_BSSGP_GMM_RESUME:
|
||||
return gprs_gmm_rx_resume(bp->ra_id, bp->tlli,
|
||||
*bp->u.resume.suspend_ref);
|
||||
}
|
||||
break;
|
||||
case SAP_BSSGP_NM:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
|
|
|
@ -233,6 +233,7 @@ int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
|
|||
static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
|
||||
uint16_t ns_bvci)
|
||||
{
|
||||
struct osmo_bssgp_prim nmp;
|
||||
struct bssgp_bvc_ctx *bctx;
|
||||
uint16_t nsei = msgb_nsei(msg);
|
||||
uint16_t bvci;
|
||||
|
@ -266,6 +267,16 @@ static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
|
|||
bctx->ra_id.rac, bctx->cell_id, bvci);
|
||||
}
|
||||
|
||||
/* Send NM_BVC_RESET.ind to NM */
|
||||
memset(&nmp, 0, sizeof(nmp));
|
||||
nmp.nsei = nsei;
|
||||
nmp.bvci = bvci;
|
||||
nmp.tp = tp;
|
||||
nmp.ra_id = &bctx->ra_id;
|
||||
osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_RESET,
|
||||
PRIM_OP_INDICATION, msg);
|
||||
bssgp_prim_cb(&nmp.oph, NULL);
|
||||
|
||||
/* Acknowledge the RESET to the BTS */
|
||||
rc = bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_RESET_ACK,
|
||||
nsei, bvci, ns_bvci);
|
||||
|
@ -274,6 +285,7 @@ static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
|
|||
|
||||
static int bssgp_rx_bvc_block(struct msgb *msg, struct tlv_parsed *tp)
|
||||
{
|
||||
struct osmo_bssgp_prim nmp;
|
||||
uint16_t bvci;
|
||||
struct bssgp_bvc_ctx *ptp_ctx;
|
||||
|
||||
|
@ -295,7 +307,14 @@ static int bssgp_rx_bvc_block(struct msgb *msg, struct tlv_parsed *tp)
|
|||
ptp_ctx->state |= BVC_S_BLOCKED;
|
||||
rate_ctr_inc(&ptp_ctx->ctrg->ctr[BSSGP_CTR_BLOCKED]);
|
||||
|
||||
/* FIXME: Send NM_BVC_BLOCK.ind to NM */
|
||||
/* Send NM_BVC_BLOCK.ind to NM */
|
||||
memset(&nmp, 0, sizeof(nmp));
|
||||
nmp.nsei = msgb_nsei(msg);
|
||||
nmp.bvci = bvci;
|
||||
nmp.tp = tp;
|
||||
osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_BLOCK,
|
||||
PRIM_OP_INDICATION, msg);
|
||||
bssgp_prim_cb(&nmp.oph, NULL);
|
||||
|
||||
/* We always acknowledge the BLOCKing */
|
||||
return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK_ACK, msgb_nsei(msg),
|
||||
|
@ -304,6 +323,7 @@ static int bssgp_rx_bvc_block(struct msgb *msg, struct tlv_parsed *tp)
|
|||
|
||||
static int bssgp_rx_bvc_unblock(struct msgb *msg, struct tlv_parsed *tp)
|
||||
{
|
||||
struct osmo_bssgp_prim nmp;
|
||||
uint16_t bvci;
|
||||
struct bssgp_bvc_ctx *ptp_ctx;
|
||||
|
||||
|
@ -324,7 +344,14 @@ static int bssgp_rx_bvc_unblock(struct msgb *msg, struct tlv_parsed *tp)
|
|||
|
||||
ptp_ctx->state &= ~BVC_S_BLOCKED;
|
||||
|
||||
/* FIXME: Send NM_BVC_UNBLOCK.ind to NM */
|
||||
/* Send NM_BVC_UNBLOCK.ind to NM */
|
||||
memset(&nmp, 0, sizeof(nmp));
|
||||
nmp.nsei = msgb_nsei(msg);
|
||||
nmp.bvci = bvci;
|
||||
nmp.tp = tp;
|
||||
osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_UNBLOCK,
|
||||
PRIM_OP_INDICATION, msg);
|
||||
bssgp_prim_cb(&nmp.oph, NULL);
|
||||
|
||||
/* We always acknowledge the unBLOCKing */
|
||||
return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_UNBLOCK_ACK, msgb_nsei(msg),
|
||||
|
@ -335,6 +362,7 @@ static int bssgp_rx_bvc_unblock(struct msgb *msg, struct tlv_parsed *tp)
|
|||
static int bssgp_rx_ul_ud(struct msgb *msg, struct tlv_parsed *tp,
|
||||
struct bssgp_bvc_ctx *ctx)
|
||||
{
|
||||
struct osmo_bssgp_prim gbp;
|
||||
struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
|
||||
|
||||
/* extract TLLI and parse TLV IEs */
|
||||
|
@ -354,12 +382,21 @@ static int bssgp_rx_ul_ud(struct msgb *msg, struct tlv_parsed *tp,
|
|||
msgb_llch(msg) = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_LLC_PDU);
|
||||
msgb_bcid(msg) = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_CELL_ID);
|
||||
|
||||
return gprs_llc_rcvmsg(msg, tp);
|
||||
/* Send BSSGP_UL_UD.ind to NM */
|
||||
memset(&gbp, 0, sizeof(gbp));
|
||||
gbp.nsei = ctx->nsei;
|
||||
gbp.bvci = ctx->bvci;
|
||||
gbp.tlli = msgb_tlli(msg);
|
||||
gbp.tp = tp;
|
||||
osmo_prim_init(&gbp.oph, SAP_BSSGP_LL, PRIM_BSSGP_UL_UD,
|
||||
PRIM_OP_INDICATION, msg);
|
||||
return bssgp_prim_cb(&gbp.oph, NULL);
|
||||
}
|
||||
|
||||
static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
|
||||
struct bssgp_bvc_ctx *ctx)
|
||||
{
|
||||
struct osmo_bssgp_prim gbp;
|
||||
struct bssgp_normal_hdr *bgph =
|
||||
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
||||
struct gprs_ra_id raid;
|
||||
|
@ -381,7 +418,15 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
|
|||
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
||||
|
||||
/* Inform GMM about the SUSPEND request */
|
||||
rc = gprs_gmm_rx_suspend(&raid, tlli);
|
||||
memset(&gbp, 0, sizeof(gbp));
|
||||
gbp.nsei = msgb_nsei(msg);
|
||||
gbp.bvci = ctx->bvci;
|
||||
gbp.tlli = tlli;
|
||||
gbp.ra_id = &raid;
|
||||
osmo_prim_init(&gbp.oph, SAP_BSSGP_GMM, PRIM_BSSGP_GMM_SUSPEND,
|
||||
PRIM_OP_REQUEST, msg);
|
||||
|
||||
rc = bssgp_prim_cb(&gbp.oph, NULL);
|
||||
if (rc < 0)
|
||||
return bssgp_tx_suspend_nack(msgb_nsei(msg), tlli, &raid, NULL);
|
||||
|
||||
|
@ -393,6 +438,7 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
|
|||
static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
|
||||
struct bssgp_bvc_ctx *ctx)
|
||||
{
|
||||
struct osmo_bssgp_prim gbp;
|
||||
struct bssgp_normal_hdr *bgph =
|
||||
(struct bssgp_normal_hdr *) msgb_bssgph(msg);
|
||||
struct gprs_ra_id raid;
|
||||
|
@ -416,7 +462,16 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
|
|||
gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
|
||||
|
||||
/* Inform GMM about the RESUME request */
|
||||
rc = gprs_gmm_rx_resume(&raid, tlli, suspend_ref);
|
||||
memset(&gbp, 0, sizeof(gbp));
|
||||
gbp.nsei = msgb_nsei(msg);
|
||||
gbp.bvci = ctx->bvci;
|
||||
gbp.tlli = tlli;
|
||||
gbp.ra_id = &raid;
|
||||
gbp.u.resume.suspend_ref = suspend_ref;
|
||||
osmo_prim_init(&gbp.oph, SAP_BSSGP_GMM, PRIM_BSSGP_GMM_RESUME,
|
||||
PRIM_OP_REQUEST, msg);
|
||||
|
||||
rc = bssgp_prim_cb(&gbp.oph, NULL);
|
||||
if (rc < 0)
|
||||
return bssgp_tx_resume_nack(msgb_nsei(msg), tlli, &raid,
|
||||
NULL);
|
||||
|
@ -429,6 +484,7 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
|
|||
static int bssgp_rx_llc_disc(struct msgb *msg, struct tlv_parsed *tp,
|
||||
struct bssgp_bvc_ctx *ctx)
|
||||
{
|
||||
struct osmo_bssgp_prim nmp;
|
||||
uint32_t tlli = 0;
|
||||
|
||||
if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
|
||||
|
@ -447,8 +503,16 @@ static int bssgp_rx_llc_disc(struct msgb *msg, struct tlv_parsed *tp,
|
|||
|
||||
rate_ctr_inc(&ctx->ctrg->ctr[BSSGP_CTR_DISCARDED]);
|
||||
|
||||
/* FIXME: send NM_LLC_DISCARDED to NM */
|
||||
return 0;
|
||||
/* send NM_LLC_DISCARDED to NM */
|
||||
memset(&nmp, 0, sizeof(nmp));
|
||||
nmp.nsei = msgb_nsei(msg);
|
||||
nmp.bvci = ctx->bvci;
|
||||
nmp.tlli = tlli;
|
||||
nmp.tp = tp;
|
||||
osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_LLC_DISCARDED,
|
||||
PRIM_OP_INDICATION, msg);
|
||||
|
||||
return bssgp_prim_cb(&nmp.oph, NULL);
|
||||
}
|
||||
|
||||
static int bssgp_rx_fc_bvc(struct msgb *msg, struct tlv_parsed *tp,
|
||||
|
|
Loading…
Reference in New Issue