Hi!

On Tue, Aug 02, 2011 at 02:30:14AM +0900, Seungju Kim wrote:
> Hello,I got everything up and running. Including EDGE data.
> 
> The throughput of the data from the osmo-sgsn is pretty good. But recently I
> have spotted a problem with the SGSN.
> 
> The sgsn loses the phones SNDCP entity after idling or making a phone call.
> http://pastebin.com/2W9dZdvW

Interesting.  I have not yet observed this, as most likely my phones
don't include the "PDP Context Status IE" (TS 24.008 / 10.5.7.1).

Using this IE, the phone can tell the network "I think I still have PDP
contexts for the following NSAPIs active".  The network  then checks if
it has the smae view, and silently deletes all PDP contexts for other
NSAPIs.

It seems that the current code is interpreting the IE the wrong way.

We interpret it as an uint16_t, do ntohs() and it is 0x2000.
Apparently NSAPI 5 was active befor (your log snippet is a bit short):

<0002> gprs_gmm.c:884 Dropping PDP context for NSAPI=5 due to PDP CTX STATUS 
IE= 0x2000
<0014> sgsn_libgtp.c:212 Delete PDP Context
<0014> sgsn_libgtp.c:389 PDP Context was deleted

If I'm looking at Chapter 10.5.7.1, it seems the encoding is a bit odd,
i.e. actually the byte ordering is little endian!

Can you try the patch below and see if the problem is fixed?

-- 
- Harald Welte <[email protected]>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)
>From aa5621cd1336fddf24b994cef86c5863ff204c06 Mon Sep 17 00:00:00 2001
From: Harald Welte <[email protected]>
Date: Thu, 4 Aug 2011 13:11:18 +0200
Subject: [PATCH] GPRS: Fix the byte ordering of the PDP context status IE

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

Reply via email to