[gprs] pass BSSGP UL-UNITDATA Cell ID up into GMM layer

BSSGP stores a pointer to the Cell Identifier IE in msgb->cb, which
is later used by the GMM layer to identify the cell that has sent a
given message.

This now also means that the gsm_04_08_gprs.c code is free of any
legacy references to msg->trx or struct gsm_bts.
This commit is contained in:
Harald Welte 2010-05-02 11:54:55 +02:00
parent eaa614cb9e
commit 11d7c105f8
5 changed files with 40 additions and 50 deletions

View File

@ -140,6 +140,7 @@ enum gprs_bssgp_cause {
#include <osmocore/tlv.h>
extern int gprs_bssgp_rcvmsg(struct msgb *msg);
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
/* Wrapper around TLV parser to parse BSSGP IEs */
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)

View File

@ -84,6 +84,9 @@ struct openbsc_msgb_cb {
unsigned char *bssgph;
unsigned char *llch;
/* Cell Identifier */
unsigned char *bssgp_cell_id;
/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
u_int16_t nsei;
u_int16_t bvci;
@ -97,6 +100,7 @@ struct openbsc_msgb_cb {
#define msgb_bvci(__x) OBSC_MSGB_CB(__x)->bvci
#define msgb_gmmh(__x) (__x)->l3h
#define msgb_bssgph(__x) OBSC_MSGB_CB(__x)->bssgph
#define msgb_bcid(__x) OBSC_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) OBSC_MSGB_CB(__x)->llch
struct msgb;

View File

@ -205,13 +205,12 @@ int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg)
return gprs_ns_sendmsg(bssgp_nsi, msg);
}
static void bssgp_parse_cell_id(struct gprs_ra_id *raid, uint16_t *cid,
const uint8_t *buf)
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf)
{
/* 6 octets RAC */
gsm48_parse_ra(raid, buf);
/* 2 octets CID */
*cid = ntohs(*(uint16_t *) (buf+6));
return ntohs(*(uint16_t *) (buf+6));
}
/* Chapter 8.4 BVC-Reset Procedure */
@ -241,8 +240,8 @@ static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
return -EINVAL;
}
/* actually extract RAC / CID */
bssgp_parse_cell_id(&bctx->ra_id, &bctx->cell_id,
TLVP_VAL(tp, BSSGP_IE_CELL_ID));
bctx->cell_id = bssgp_parse_cell_id(&bctx->ra_id,
TLVP_VAL(tp, BSSGP_IE_CELL_ID));
LOGP(DGPRS, LOGL_NOTICE, "Cell %u-%u-%u-%u CI %u on BVCI %u\n",
bctx->ra_id.mcc, bctx->ra_id.mnc, bctx->ra_id.lac,
bctx->ra_id.rac, bctx->cell_id, bvci);
@ -275,7 +274,9 @@ static int bssgp_rx_ul_ud(struct msgb *msg)
/* FIXME: lookup bssgp_bts_ctx based on BVCI + NSEI */
/* store pointer to LLC header and CELL ID in msgb->cb */
msgb_llch(msg) = TLVP_VAL(&tp, BSSGP_IE_LLC_PDU);
msgb_bcid(msg) = TLVP_VAL(&tp, BSSGP_IE_CELL_ID);
return gprs_llc_rcvmsg(msg, &tp);
}

View File

@ -452,6 +452,8 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
struct gprs_llc_entity *lle;
int rc = 0;
/* Identifiers from DOWN: NSEI, BVCI, TLLI */
rc = gprs_llc_hdr_parse(&llhp, lh, TLVP_LEN(tv, BSSGP_IE_LLC_PDU));
/* FIXME */

View File

@ -42,6 +42,7 @@
#include <osmocore/signal.h>
#include <osmocore/talloc.h>
#include <openbsc/transaction.h>
#include <openbsc/gprs_bssgp.h>
#include <openbsc/gprs_llc.h>
#include <openbsc/gprs_sgsn.h>
@ -130,20 +131,30 @@ static const char *upd_name(uint8_t type)
/* Send a message through the underlying layer */
static int gsm48_gmm_sendmsg(struct msgb *msg, int command)
{
/* caller needs to provide TLLI, BVCI and NSEI */
return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command);
}
/* copy identifiers from old message to new message, this
* is required so lower layers can route it correctly */
static void gmm_copy_id(struct msgb *msg, const struct msgb *old)
{
msgb_tlli(msg) = msgb_tlli(old);
msgb_bvci(msg) = msgb_bvci(old);
msgb_nsei(msg) = msgb_nsei(old);
}
/* Chapter 9.4.2: Attach accept */
static int gsm48_tx_gmm_att_ack(struct msgb *old_msg)
{
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
struct gsm48_attach_ack *aa;
struct gprs_ra_id ra_id;
DEBUGP(DMM, "<- GPRS ATTACH ACCEPT\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@ -154,7 +165,8 @@ static int gsm48_tx_gmm_att_ack(struct msgb *old_msg)
aa->att_result = 1; /* GPRS only */
aa->ra_upd_timer = GPRS_TMR_MINUTE | 10;
aa->radio_prio = 4; /* lowest */
//FIXME gsm48_ra_id_by_bts(aa->ra_id.digits, old_msg->trx->bts);
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
gsm48_construct_ra(aa->ra_id.digits, &ra_id);
/* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
return gsm48_gmm_sendmsg(msg, 0);
@ -168,8 +180,7 @@ static int gsm48_tx_gmm_att_rej(struct msgb *old_msg, uint8_t gmm_cause)
DEBUGP(DMM, "<- GPRS ATTACH REJECT\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@ -187,8 +198,7 @@ static int gsm48_tx_gmm_id_req(struct msgb *old_msg, uint8_t id_type)
DEBUGP(DMM, "-> GPRS IDENTITY REQUEST: mi_type=%02x\n", id_type);
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@ -228,7 +238,7 @@ static int gsm48_rx_gmm_id_resp(struct msgb *msg)
DEBUGP(DMM, "GMM IDENTITY RESPONSE: mi_type=0x%02x MI(%s) ",
mi_type, mi_string);
//FIXME gprs_ra_id_by_bts(&ra_id, msg->trx->bts);
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
ctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
if (!ctx) {
DEBUGP(DMM, "from unknown TLLI 0x%08x?!?\n", msgb_tlli(msg));
@ -290,7 +300,7 @@ static int gsm48_rx_gmm_att_req(struct msgb *msg)
* with a foreign TLLI (P-TMSI that was allocated to the MS before),
* or with random TLLI. */
//FIXME gprs_ra_id_by_bts(&ra_id, msg->trx->bts);
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
/* MS network capability 10.5.5.12 */
msnc_len = *cur++;
@ -378,11 +388,11 @@ static int gsm48_tx_gmm_ra_upd_ack(struct msgb *old_msg)
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
struct gsm48_ra_upd_ack *rua;
struct gprs_ra_id ra_id;
DEBUGP(DMM, "<- ROUTING AREA UPDATE ACCEPT\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@ -392,7 +402,9 @@ static int gsm48_tx_gmm_ra_upd_ack(struct msgb *old_msg)
rua->force_stby = 0; /* not indicated */
rua->upd_result = 0; /* RA updated */
rua->ra_upd_timer = GPRS_TMR_MINUTE | 10;
//FIXME gsm48_ra_id_by_bts(rua->ra_id.digits, old_msg->trx->bts);
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
gsm48_construct_ra(rua->ra_id.digits, &ra_id);
/* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
return gsm48_gmm_sendmsg(msg, 0);
@ -406,8 +418,7 @@ static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause)
DEBUGP(DMM, "<- ROUTING AREA UPDATE REJECT\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 2);
gh->proto_discr = GSM48_PDISC_MM_GPRS;
@ -529,8 +540,7 @@ static int gsm48_tx_gsm_act_pdp_acc(struct msgb *old_msg, struct gsm48_act_pdp_c
DEBUGP(DMM, "<- ACTIVATE PDP CONTEXT ACK\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
@ -554,8 +564,7 @@ static int gsm48_tx_gsm_deact_pdp_acc(struct msgb *old_msg)
DEBUGP(DMM, "<- DEACTIVATE PDP CONTEXT ACK\n");
msgb_tlli(msg) = msgb_tlli(old_msg);
msg->trx = old_msg->trx;
gmm_copy_id(msg, old_msg);
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
@ -652,30 +661,3 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg)
return rc;
}
/* Determine the 'struct gsm_bts' from a RA ID */
struct gsm_bts *gsm48_bts_by_ra_id(struct gsm_network *net,
const uint8_t *buf, unsigned int len)
{
struct gprs_ra_id raid;
struct gsm_bts *bts;
if (len < 6)
return NULL;
gsm48_parse_ra(&raid, buf);
if (net->country_code != raid.mcc ||
net->network_code != raid.mnc)
return NULL;
llist_for_each_entry(bts, &net->bts_list, list) {
/* FIXME: we actually also need to check the
* routing area code! */
if (bts->location_area_code == raid.lac)
return bts;
}
return NULL;
}