It seems that 24.008 Section 10.5.7.1 specifies the IE to be encoded in
little endian...
---
openbsc/src/gprs/gprs_gmm.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 098e4c2..f83219f 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -870,6 +870,7 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
uint16_t pdp_status)
{
struct sgsn_pdp_ctx *pdp, *pdp2;
+ uint16_t pdp_status_reordered;
/* 24.008 4.7.5.1.3: If the PDP context status information element is
* included in ROUTING AREA UPDATE REQUEST message, then the network
* shall deactivate all those PDP contexts locally (without peer to
@@ -877,8 +878,13 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
* state PDP-INACTIVE on network side but are indicated by the MS as
* being in state PDP-INACTIVE. */
+ /* 24.008 10.5.7.1 indicates that the byte ordering is in fact
+ * little endian, i.e. the first octet contains NSAPI0..7 and
+ * the second payload octet NSAPI8..15 */
+ pdp_status_reordered = (pdp_status & 0xff << 8) || (pdp_status >> 8);
+
llist_for_each_entry_safe(pdp, pdp2, &mmctx->pdp_list, list) {
- if (!(pdp_status & (1 << pdp->nsapi))) {
+ if (!(pdp_status_reordered & (1 << pdp->nsapi))) {
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
"due to PDP CTX STATUS IE= 0x%04x\n",
pdp->nsapi, pdp_status);
@@ -977,6 +983,10 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct
msgb *msg,
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) {
uint16_t pdp_status = ntohs(*(uint16_t *)
TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS));
+ /* pdp_status is now in big endian, which is the wrong
+ * order. the wire encoding is little endian! We cannot
+ * simply drop the ntohs() above, as we migh be running
+ * on a big endian machine. */
process_ms_ctx_status(mmctx, pdp_status);
}
--
1.7.5.4
--iq/fWD14IMVFWBCD--
Show replies by date