[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:
parent
eaa614cb9e
commit
11d7c105f8
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue