From 56a0145dd8955b00ef9cff608f5e03912401a0f7 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 31 May 2010 22:12:30 +0200 Subject: [GPRS] Include IMSI and DRX params in BSSGP DL-UD When we send a downlink unit-data request via BSSGP, there is a lot of information that needs to be copied from the mm context, such as the IMSI, DRX parametes, MS radio access parameters, ... This is a quite strange layering violation, since we now need to pass a pointer to the MM ctx from GMM through LLC into BSSGP :( --- openbsc/include/openbsc/gprs_bssgp.h | 3 ++- openbsc/include/openbsc/gprs_llc.h | 3 ++- openbsc/src/gprs/gprs_bssgp.c | 36 ++++++++++++++++++++++++++++++++++-- openbsc/src/gprs/gprs_gmm.c | 27 ++++++++++++++++++--------- openbsc/src/gprs/gprs_llc.c | 7 ++++--- 5 files changed, 60 insertions(+), 16 deletions(-) (limited to 'openbsc') diff --git a/openbsc/include/openbsc/gprs_bssgp.h b/openbsc/include/openbsc/gprs_bssgp.h index 90b945aba..9eaf989af 100644 --- a/openbsc/include/openbsc/gprs_bssgp.h +++ b/openbsc/include/openbsc/gprs_bssgp.h @@ -188,7 +188,8 @@ struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei); int gprs_bssgp_rcvmsg(struct msgb *msg); /* BSSGP-DL-UNITDATA.req */ -int gprs_bssgp_tx_dl_ud(struct msgb *msg); +struct sgsn_mm_ctx; +int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx); uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf); diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h index 4828a8fe9..213ef7bf5 100644 --- a/openbsc/include/openbsc/gprs_llc.h +++ b/openbsc/include/openbsc/gprs_llc.h @@ -103,7 +103,8 @@ extern struct llist_head gprs_llc_lles; int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv); /* LL-UNITDATA.req */ -int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command); +int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, + void *mmctx); int gprs_llc_vty_init(void); diff --git a/openbsc/src/gprs/gprs_bssgp.c b/openbsc/src/gprs/gprs_bssgp.c index f3ce8a9fe..58ade4d21 100644 --- a/openbsc/src/gprs/gprs_bssgp.c +++ b/openbsc/src/gprs/gprs_bssgp.c @@ -39,6 +39,7 @@ #include #include #include +#include void *bssgp_tall_ctx = NULL; @@ -685,7 +686,7 @@ int gprs_bssgp_rcvmsg(struct msgb *msg) /* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU * to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */ -int gprs_bssgp_tx_dl_ud(struct msgb *msg) +int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx) { struct bssgp_bvc_ctx *bctx; struct bssgp_ud_hdr *budh; @@ -696,6 +697,7 @@ int gprs_bssgp_tx_dl_ud(struct msgb *msg) uint16_t msg_len = msg->len; uint16_t bvci = msgb_bvci(msg); uint16_t nsei = msgb_nsei(msg); + uint16_t drx_params; /* Identifiers from UP: TLLI, BVCI, NSEI (all in msgb->cb) */ if (bvci <= BVCI_PTM ) { @@ -724,7 +726,37 @@ int gprs_bssgp_tx_dl_ud(struct msgb *msg) llc_pdu_tlv[1] |= 0x80; } - /* FIXME: optional elements */ + /* FIXME: optional elements: Alignment, UTRAN CCO, LSA, PFI */ + + if (mmctx) { + /* Old TLLI to help BSS map from old->new */ +#if 0 + if (mmctx->tlli_old) + msgb_tvlv_push(msg, BSSGP_IE_TLLI, 4, htonl(*tlli_old)); +#endif + + /* IMSI */ + if (strlen(mmctx->imsi)) { + uint8_t mi[10]; + int imsi_len = gsm48_generate_mid_from_imsi(mi, mmctx->imsi); + if (imsi_len > 2) + msgb_tvlv_push(msg, BSSGP_IE_IMSI, + imsi_len-2, mi+2); + } + + /* DRX parameters */ + drx_params = htons(mmctx->drx_parms); + msgb_tvlv_push(msg, BSSGP_IE_DRX_PARAMS, 2, + (uint8_t *) &drx_params); + + /* FIXME: Priority */ + + /* MS Radio Access Capability */ + if (mmctx->ms_radio_access_capa.len) + msgb_tvlv_push(msg, BSSGP_IE_MS_RADIO_ACCESS_CAP, + mmctx->ms_radio_access_capa.len, + mmctx->ms_radio_access_capa.buf); + } /* prepend the pdu lifetime */ pdu_lifetime = htons(pdu_lifetime); diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 3a6db62b7..95473281f 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -184,7 +184,7 @@ static int gsm48_gmm_sendmsg(struct msgb *msg, int command, rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]); /* caller needs to provide TLLI, BVCI and NSEI */ - return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command); + return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm); } /* copy identifiers from old message to new message, this @@ -278,7 +278,7 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm) /* Optional: MS-identity (combined attach) */ /* Optional: GMM cause (partial attach result for combined attach) */ - return gsm48_gmm_sendmsg(msg, 0, NULL); + return gsm48_gmm_sendmsg(msg, 0, mm); } /* Chapter 9.4.5: Attach reject */ @@ -325,7 +325,7 @@ static int gsm48_tx_gmm_det_ack(struct sgsn_mm_ctx *mm, uint8_t force_stby) gh->msg_type = GSM48_MT_GMM_DETACH_ACK; gh->data[0] = force_stby; - return gsm48_gmm_sendmsg(msg, 0, NULL); + return gsm48_gmm_sendmsg(msg, 0, mm); } /* Transmit Chapter 9.4.12 Identity Request */ @@ -344,7 +344,7 @@ static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type) /* 10.5.5.9 ID type 2 + identity type and 10.5.5.7 'force to standby' IE */ gh->data[0] = id_type & 0xf; - return gsm48_gmm_sendmsg(msg, 0, NULL); + return gsm48_gmm_sendmsg(msg, 0, mm); } /* Check if we can already authorize a subscriber */ @@ -419,8 +419,8 @@ static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg) static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg) { struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); - uint8_t *cur = gh->data, *msnc, *mi, *old_ra_info; - uint8_t msnc_len, att_type, mi_len, mi_type; + uint8_t *cur = gh->data, *msnc, *mi, *old_ra_info, *ms_ra_acc_cap; + uint8_t msnc_len, att_type, mi_len, mi_type, ms_ra_acc_cap_len; uint16_t drx_par; uint32_t tmsi; char mi_string[GSM48_MI_SIZE]; @@ -447,8 +447,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg) att_type = *cur++ & 0x0f; /* DRX parameter 10.5.5.6 */ - drx_par = *cur++; - drx_par |= *cur++ << 8; + drx_par = *cur++ << 8; + drx_par |= *cur++; /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */ mi_len = *cur++; @@ -468,6 +468,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg) cur += 6; /* MS Radio Access Capability 10.5.5.12a */ + ms_ra_acc_cap_len = *cur++; + ms_ra_acc_cap = cur; /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */ @@ -509,6 +511,13 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg) /* Update MM Context with currient RA and Cell ID */ ctx->ra = ra_id; ctx->cell_id = cid; + /* Update MM Context with other data */ + ctx->drx_parms = drx_par; + ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len; + memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, ms_ra_acc_cap_len); + ctx->ms_network_capa.len = msnc_len; + memcpy(ctx->ms_network_capa.buf, msnc, msnc_len); + #ifdef PTMSI_ALLOC /* Allocate a new P-TMSI (+ P-TMSI signature) */ ctx->p_tmsi_old = ctx->p_tmsi; @@ -587,7 +596,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm) #endif /* Option: MS ID, ... */ - return gsm48_gmm_sendmsg(msg, 0, NULL); + return gsm48_gmm_sendmsg(msg, 0, mm); } /* Chapter 9.4.17: Routing area update reject */ diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 68d7d7654..c13f45f07 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -197,7 +197,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 gprs_bssgp_tx_dl_ud(msg); + return gprs_bssgp_tx_dl_ud(msg, NULL); } /* Send XID response to LLE */ @@ -212,7 +212,8 @@ static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg) } /* Transmit a UI frame over the given SAPI */ -int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command) +int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, + void *mmctx) { struct gprs_llc_lle *lle; uint8_t *fcs, *llch; @@ -261,7 +262,7 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command) /* Identifiers passed down: (BVCI, NSEI) */ /* Send BSSGP-DL-UNITDATA.req */ - return gprs_bssgp_tx_dl_ud(msg); + return gprs_bssgp_tx_dl_ud(msg, mmctx); } static void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph) -- cgit v1.2.3