diff options
author | Harald Welte <laforge@gnumonks.org> | 2012-06-17 12:16:31 +0800 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2012-06-17 12:17:22 +0800 |
commit | b1fd9022ebbf8539cbf52d22a7f0723225eefe02 (patch) | |
tree | 1f3c572ba247d74202a75ad86661100a6b6bfcd3 /openbsc | |
parent | faa70ff2c6c3f592b5601aaa73a3a9a851a6d3c1 (diff) |
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()"
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/osmocom/gprs/gprs_bssgp.h | 37 | ||||
-rw-r--r-- | openbsc/src/gprs/gb_proxy.c | 5 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_llc.c | 3 | ||||
-rw-r--r-- | openbsc/src/gprs/sgsn_main.c | 29 | ||||
-rw-r--r-- | openbsc/src/libgb/gprs_bssgp.c | 78 |
5 files changed, 143 insertions, 9 deletions
diff --git a/openbsc/include/osmocom/gprs/gprs_bssgp.h b/openbsc/include/osmocom/gprs/gprs_bssgp.h index 4fcdfb565..e060fc033 100644 --- a/openbsc/include/osmocom/gprs/gprs_bssgp.h +++ b/openbsc/include/osmocom/gprs/gprs_bssgp.h @@ -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 */ diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 87cfa61df..500a1b2f8 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -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) diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index c1327b6cd..be5fe52bf 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -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 */ diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index a579e7e83..55588797b 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -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); diff --git a/openbsc/src/libgb/gprs_bssgp.c b/openbsc/src/libgb/gprs_bssgp.c index ca99dd527..47750483e 100644 --- a/openbsc/src/libgb/gprs_bssgp.c +++ b/openbsc/src/libgb/gprs_bssgp.c @@ -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, |