On Tue, Jul 30, 2013 at 09:20:38AM +0200, Holger Hans Peter Freyther wrote:

> Or shall we do this... "oh we know this subscriber already" at a
> higher level in GMM? E.g. notice that it is a routing area update...
> and then free the new llme and do a tlli assignment for the foreign
> tlli?

The patch is not enough.. I ran into the newly added ASSERT about the
TLLI.

1.) E71 attach to a network and create a PDP context..
2.) Restart SGSN/GGSN
3.) Phone tries Activate/Deactivate PDP Context.. we send a GMM status
    with impl. detached.. E71 sends a SM Status for protocol error
4.) Re-open the browser app... it tries GPRS Attach for a foreign tlli
    (based on the old one).. we find it.. the state doesn't match so
    there is re-transmission going on.. once we have the righ seq. number
    the RX will find the 'right' LLME.. but on TX for the foreign TLLI
    we create a LLME on the fly and run into the assert...

I can now extend the second phase of look-ups and soften the assert a
bit but I do wonder if that is the correct thing to do.


I added the below diff.. but it is probably better to check if one could
combine these llme's at a higher level? Or at least free the old LLME
and use the new one? My last problem right now is that LLC data is not
sent to the GGSN.. :}


<0012> gprs_llc.c:543 LLC SAPI=1 C   FCS=0xd85a2cCMD=UI DATA 
<0012> gprs_llc.c:194 TLLI 0xa44240f7 is foreign, converting to local TLLI 
0xe44240f7
<0012> gprs_llc.c:409 LLC TX: unknown TLLI 0xa44240f7, creating LLME on the fly
Assert failed msgb_tlli(msg) == mmctx->llme->tlli || msgb_tlli(msg) == 
mmctx->llme->old_tlli gprs_llc.c:106
backtrace() returned 20 addresses
/home/ich/install/openbsc/lib/libosmocore.so.4(osmo_generate_backtrace+0x16) 
[0xb7bb6a36]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8049dc5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8052085]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804a326]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804a8ff]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804ac42]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804b3e5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804bd9f]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804d23c]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8052a24]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn(bssgp_prim_cb+0x55) 
[0x804f5d4]
/home/ich/install/openbsc/lib/libosmogb.so.2(bssgp_rcvmsg+0x3b8) [0xb7b626b8]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804f521]
/home/ich/install/openbsc/lib/libosmogb.so.2(gprs_ns_rcvmsg+0x8c7) [0xb7b5ecf7]
/home/ich/install/openbsc/lib/libosmogb.so.2(+0x4311) [0xb7b5f311]
/home/ich/install/openbsc/lib/libosmocore.so.4(osmo_select_main+0x192) 
[0xb7bb2ed2]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x804fbfd]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5) [0xb796a8f5]
/home/ich/source/gsm/openbsc/openbsc/src/gprs/osmo-sgsn() [0x8049ded]

Program received signal SIGABRT, Aborted.
0xb7fde424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fde424 in __kernel_vsyscall ()
#1  0xb797f83f in __GI_raise (sig=sig@entry=6) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2  0xb7982cf3 in __GI_abort () at abort.c:90
#3  0x08049dca in _bssgp_tx_dl_ud (mmctx=<optimized out>, msg=<optimized out>)
    at gprs_llc.c:105
#4  0x08052085 in gprs_llc_tx_ui (msg=0x8092ba8, sapi=1 '\001', command=1, 
mmctx=0x8092700)
    at gprs_llc.c:417
#5  0x0804a326 in gsm48_gmm_sendmsg (msg=0x8092ba8, command=1, mm=0x8092700) at 
gprs_gmm.c:241
#6  0x0804a8ff in gsm48_tx_gmm_id_req (mm=0x8092700, id_type=2 '\002') at 
gprs_gmm.c:454
#7  0x0804ac42 in gsm48_gmm_authorize (ctx=0x8092700, 
t3350_mode=GMM_T3350_MODE_ATT)
    at gprs_gmm.c:560
#8  0x0804b3e5 in gsm48_rx_gmm_att_req (ctx=0x8092700, msg=0x8090f98, 
llme=0x8091ce8)
    at gprs_gmm.c:765
#9  0x0804bd9f in gsm0408_rcv_gmm (mmctx=0x0, msg=0x8090f98, llme=0x8091ce8)
    at gprs_gmm.c:1039
#10 0x0804d23c in gsm0408_gprs_rcvmsg (msg=msg@entry=0x8090f98, llme=0x8091ce8)
    at gprs_gmm.c:1566
#11 0x08052a24 in gprs_llc_rcvmsg (msg=0x8090f98, tv=0xbfffdcb0) at 
gprs_llc.c:874
#12 0x0804f5d4 in bssgp_prim_cb (oph=oph@entry=0xbfffdc8c, ctx=ctx@entry=0x0)
    at sgsn_main.c:114
#13 0xb7b626b8 in bssgp_rx_ul_ud (tp=0xbfffdcb0, msg=0x8090f98, ctx=<optimized 
out>)
    at gprs_bssgp.c:398
#14 bssgp_rx_ptp (bctx=0x8091a08, tp=0xbfffdcb0, msg=0x8090f98) at 
gprs_bssgp.c:820
#15 bssgp_rcvmsg (msg=0x8090f98) at gprs_bssgp.c:1016
#16 0x0804f521 in sgsn_ns_cb (event=GPRS_NS_EVT_UNIT_DATA, nsvc=0x8090740, 
msg=0x8090f98, 
    bvci=1801) at sgsn_main.c:92
#17 0xb7b5ecf7 in gprs_ns_rx_unitdata (msg=0x8090f98, nsvc=0x8090740) at 
gprs_ns.c:616
#18 gprs_ns_rcvmsg (nsi=nsi@entry=0x807fd38, msg=msg@entry=0x8090f98, 
    saddr=saddr@entry=0xbfffedc0, ll=ll@entry=GPRS_NS_LL_UDP) at gprs_ns.c:841
#19 0xb7b5f311 in handle_nsip_read (bfd=0x807fd58) at gprs_ns.c:991

diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index b637acb..f0930f6 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -84,6 +84,22 @@ struct gprs_llc_hdr_parsed {
 
 static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
 
+/* If the TLLI is foreign, return its local version */
+static inline uint32_t tlli_foreign2local(uint32_t tlli)
+{
+       uint32_t new_tlli;
+
+       if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
+               new_tlli = tlli | 0x40000000;
+               DEBUGP(DLLC, "TLLI 0x%08x is foreign, converting to "
+                       "local TLLI 0x%08x\n", tlli, new_tlli);
+       } else
+               new_tlli = tlli;
+
+       return new_tlli;
+}
+
+
 /* 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 */
 static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
@@ -103,7 +119,8 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct 
sgsn_mm_ctx *mmctx)
 
                /* make sure we only send it to the right llme */
                OSMO_ASSERT(msgb_tlli(msg) == mmctx->llme->tlli
-                               || msgb_tlli(msg) == mmctx->llme->old_tlli);
+                               || msgb_tlli(msg) == mmctx->llme->old_tlli
+                               || tlli_foreign2local(msgb_tlli(msg)) == 
mmctx->llme->tlli);
        }
        memcpy(&dup.qos_profile, qos_profile_default,
                sizeof(qos_profile_default));
@@ -183,21 +200,6 @@ static const struct gprs_llc_params llc_default_params[] = 
{
 LLIST_HEAD(gprs_llc_llmes);
 void *llc_tall_ctx;
 
-/* If the TLLI is foreign, return its local version */
-static inline uint32_t tlli_foreign2local(uint32_t tlli)
-{
-       uint32_t new_tlli;
-
-       if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
-               new_tlli = tlli | 0x40000000;
-               DEBUGP(DLLC, "TLLI 0x%08x is foreign, converting to "
-                       "local TLLI 0x%08x\n", tlli, new_tlli);
-       } else
-               new_tlli = tlli;
-
-       return new_tlli;
-}
-
 /* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */
 static struct gprs_llc_lle *lle_by_tlli_sapi(const uint32_t tlli, uint8_t sapi)
 {
@@ -224,8 +226,12 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const 
uint32_t tlli,
        /* Maybe it is a routing area update but we already know this sapi? */
        if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
                lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
-               if (lle)
+               if (lle) {
+                       LOGP(DLLC, LOGL_NOTICE,
+                               "LLC RX: Found a local entry for TLLI 0x%08x\n",
+                               tlli);
                        return lle;
+               }
        }
 
        /* 7.2.1.1 LLC belonging to unassigned TLLI+SAPI shall be discarded,
@@ -403,6 +409,8 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int 
command,
 
        /* look-up or create the LL Entity for this (TLLI, SAPI) tuple */
        lle = lle_by_tlli_sapi(msgb_tlli(msg), sapi);
+       if (!lle) 
+               lle = lle_by_tlli_sapi(tlli_foreign2local(msgb_tlli(msg)), 
sapi);
        if (!lle) {
                struct gprs_llc_llme *llme;
                LOGP(DLLC, LOGL_ERROR, "LLC TX: unknown TLLI 0x%08x, "

Reply via email to