<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.2963" name=GENERATOR></HEAD>
<BODY text=#000000 bgColor=#ffffff>
<DIV dir=ltr align=left><FONT face=Arial color=#0000ff 
size=2></FONT> </DIV>
<DIV></DIV><PRE><SMALL><FONT color=#3333ff><BIG><BIG><BIG><FONT face=Arial>hi,

finally i finished my patch about mISDN handling, reversed time slots and other things. here is what i did:


the first part will allow new options for bsc_hack:
- alter LAC (location-area-code)
- select mISDN card number other than 0
- release layer 2 after closing
</FONT></BIG></BIG></BIG></FONT></SMALL>

diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/src/bsc_hack.c openbsc/src/bsc_hack.c
--- openbsc.orig/src/bsc_hack.c 2009-03-28 11:36:37.000000000 +0100
+++ openbsc/src/bsc_hack.c      2009-04-18 06:58:34.000000000 +0200
@@ -53,8 +53,11 @@
 /* MCC and MNC for the Location Area Identifier */
 static int MCC = 1;
 static int MNC = 1;
+static int LAC = 1;
 static int ARFCN = HARDCODED_ARFCN;
 static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
+static int cardnr = 0;
+static int release_l2 = 0;
 static const char *database_name = "hlr.sqlite3";
 
 /* The following definitions are for OM and NM packets that we cannot yet
@@ -901,7 +904,7 @@
        gsmnet->name_long = "OpenBSC";
        gsmnet->name_short = "OpenBSC";
        bts = &gsmnet->bts[0];
-       bts->location_area_code = 1;
+       bts->location_area_code = LAC;
        bts->trx[0].arfcn = ARFCN;
 
        /* Control Channel Description */
@@ -920,7 +923,7 @@
 
        /* E1 mISDN input setup */
        if (BTS_TYPE == GSM_BTS_TYPE_BS11)
-               return e1_config(bts);
+               return e1_config(bts, cardnr, release_l2);
        else
                return ia_config(bts);
 }
@@ -952,14 +955,17 @@
        printf("  Some useful help...\n");
        printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
        printf("  -s --disable-color\n");
-       printf("  -n --network-code number(MNC) \n");
+       printf("  -n --network-code number (MNC) \n");
        printf("  -c --country-code number (MCC) \n");
+       printf("  -L --location-area-code number (LAC) \n");
        printf("  -f --arfcn number The frequency ARFCN\n");
        printf("  -l --database db-name The database to use\n");
        printf("  -a --authorize-everyone Allow everyone into the network.\n");
        printf("  -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
        printf("  -p --pcap file  The filename of the pcap file\n");
        printf("  -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
+       printf("  -C --cardnr number  For bs11 select E1 card number other than 0\n");
+       printf("  -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
        printf("  -h --help this text\n");
 }
 
@@ -973,16 +979,19 @@
                        {"disable-color", 0, 0, 's'},
                        {"network-code", 1, 0, 'n'},
                        {"country-code", 1, 0, 'c'},
+                       {"location-area-code", 1, 0, 'L'},
                        {"database", 1, 0, 'l'},
                        {"authorize-everyone", 0, 0, 'a'},
                        {"reject-cause", 1, 0, 'r'},
                        {"pcap", 1, 0, 'p'},
                        {"arfcn", 1, 0, 'f'},
                        {"bts-type", 1, 0, 't'},
+                       {"cardnr", 1, 0, 'C'},
+                       {"release-l2", 0, 0, 'R'},
                        {0, 0, 0, 0}
                };
 
-               c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:",
+               c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:",
                                long_options, &option_index);
                if (c == -1)
                        break;
@@ -1004,6 +1013,9 @@
                case 'c':
                        MCC = atoi(optarg);
                        break;
+               case 'L':
+                       LAC = atoi(optarg);
+                       break;
                case 'f':
                        ARFCN = atoi(optarg);
                        break;
@@ -1022,6 +1034,12 @@
                case 't':
                        BTS_TYPE = parse_btstype(optarg);
                        break;
+               case 'C':
+                       cardnr = atoi(optarg);
+                       break;
+               case 'R':
+                       release_l2 = 1;
+                       break;
                default:
                        /* ignore */
                        break;


<FONT face=Arial color=#3333ff size=+1>
</FONT></PRE><PRE><FONT face=Arial color=#3333ff size=+1><BIG><BIG>the next part will create both time slots for audio traffic. this is required, because
uninitialized slots cause segementation faults due to invalid structure pointers.</BIG></BIG></FONT>
</PRE><BR><PRE>diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/src/e1_config.c openbsc/src/e1_config.c
--- openbsc.orig/src/e1_config.c        2009-03-28 11:36:37.000000000 +0100
+++ openbsc/src/e1_config.c     2009-04-19 13:24:20.000000000 +0200
@@ -15,7 +15,7 @@
 #define TEI_RSL                1
 
 /* do some compiled-in configuration for our BTS/E1 setup */
-int e1_config(struct gsm_bts *bts)
+int e1_config(struct gsm_bts *bts, int cardnr, int l2_release)
 {
        struct e1inp_line *line;
        struct e1inp_ts *sign_ts;
@@ -29,7 +29,7 @@
        /* create E1 timeslots for signalling and TRAU frames */
        e1inp_ts_config(&line->ts[1-1], line, E1INP_TS_TYPE_SIGN);
        e1inp_ts_config(&line->ts[2-1], line, E1INP_TS_TYPE_TRAU);
-       //e1inp_ts_config(&line->ts[3-1], line, E1INP_TS_TYPE_TRAU);
+       e1inp_ts_config(&line->ts[3-1], line, E1INP_TS_TYPE_TRAU);
 
        /* create signalling links for TS1 */
        sign_ts = &line->ts[1-1];
@@ -47,13 +47,11 @@
        subch_demux_activate(&line->ts[2-1].trau.demux, 2);
        subch_demux_activate(&line->ts[2-1].trau.demux, 3);
 
-#if 0
        /* enable subchannel demuxer on TS3 */
        subch_demux_activate(&line->ts[3-1].trau.demux, 0);
        subch_demux_activate(&line->ts[3-1].trau.demux, 1);
        subch_demux_activate(&line->ts[3-1].trau.demux, 2);
        subch_demux_activate(&line->ts[3-1].trau.demux, 3);
-#endif
 
 #ifdef HAVE_TRX1
        /* create E1 timeslots for TRAU frames of TRX1 */
@@ -68,7 +66,7 @@
        bts->trx[1].rsl_link = rsl_link;
 #endif
 
-       return mi_setup(0, line);
+       return mi_setup(cardnr, line, l2_release);
 }
 
 /* do some compiled-in configuration for our BTS/E1 setup */




<FONT size=+0><BIG><BIG><FONT face=Arial color=#3333ff size=+1><BIG><BIG><SMALL><SMALL>then i changed the inclusion of mISDN headers. the mISDNif.h from /usr/include/mISDNuser must be used.
in e1_input.c is no mISDN header required, so i commented them out.
in misdn.c i changed the definition of AF_ISDN and PF_ISDN. compat_af_isdn.h will provide correct protocol
family. in order to resolve correct protocol family, init_af_isdn() must be called. this will then work with kernel release
and with GIT release. (remember that the current kernel does not have the sapi extension in it, so use GIT.)

in order to solve the transmission delay problem (usleep(100000)) on the timeslot 1, i added a timer to the timeslot. this
timer will be started after a tx-frame is dequeued. the BSC_FD_WRITE flag will be cleared, because we do not require to
write until the timer expires. after timeout event, the BSC_FD_WRITE is set, even if no frame is in the queue. the
subsequent write event will dequeue the frame and restart the timer again (if a frame is in the tx-queue).

the DL_ESTABLISH_IND will tell use when we can use the layer 2 link. i replaced MPH_ACTIVATE_IND.
</SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT><FONT color=#3333ff><FONT size=+1><FONT face=Arial></FONT></FONT></FONT>


diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/src/e1_input.c openbsc/src/e1_input.c
--- openbsc.orig/src/e1_input.c 2009-03-28 11:36:37.000000000 +0100
+++ openbsc/src/e1_input.c      2009-04-19 13:20:00.000000000 +0200
@@ -31,12 +31,10 @@
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
-#include <mISDNif.h>
+//#include <mISDNuser/mISDNif.h>
 
-//#define AF_COMPATIBILITY_FUNC
-//#include <compat_af_isdn.h>
-#define AF_ISDN 34
-#define PF_ISDN AF_ISDN
+//#define MISDN_OLD_AF_COMPATIBILITY
+//#include <mISDNuser/compat_af_isdn.h>
 
 #include <openbsc/select.h>
 #include <openbsc/msgb.h>
@@ -223,6 +221,7 @@
 {
        struct e1inp_sign_link *sign_link;
        struct e1inp_driver *e1inp_driver;
+       struct e1inp_ts *e1i_ts;
 
        msg->l2h = msg->data;
 
@@ -232,11 +231,16 @@
        }
 
        sign_link = msg->trx->rsl_link;
+       e1i_ts = sign_link->ts;
+
+       if (!timer_pending(&e1i_ts->sign.tx_timer)) {
+               /* notify the driver we have something to write */
+               e1inp_driver = sign_link->ts->line->driver;
+               e1inp_driver->want_write(e1i_ts);
+       }
+
        msgb_enqueue(&sign_link->tx_list, msg);
 
-       /* notify the driver we have something to write */
-       e1inp_driver = sign_link->ts->line->driver;
-       e1inp_driver->want_write(sign_link->ts);
 
        return 0;
 }
@@ -245,6 +249,7 @@
 {
        struct e1inp_sign_link *sign_link;
        struct e1inp_driver *e1inp_driver;
+       struct e1inp_ts *e1i_ts;
 
        msg->l2h = msg->data;
 
@@ -254,11 +259,15 @@
        }
 
        sign_link = msg->trx->bts->oml_link;
-       msgb_enqueue(&sign_link->tx_list, msg);
+       e1i_ts = sign_link->ts;
 
-       /* notify the driver we have something to write */
-       e1inp_driver = sign_link->ts->line->driver;
-       e1inp_driver->want_write(sign_link->ts);
+       if (!timer_pending(&e1i_ts->sign.tx_timer)) {
+               /* notify the driver we have something to write */
+               e1inp_driver = sign_link->ts->line->driver;
+               e1inp_driver->want_write(e1i_ts);
+       }
+
+       msgb_enqueue(&sign_link->tx_list, msg);
 
        return 0;
 }
diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/src/input/misdn.c openbsc/src/input/misdn.c
--- openbsc.orig/src/input/misdn.c      2009-03-28 11:36:36.000000000 +0100
+++ openbsc/src/input/misdn.c   2009-04-19 13:20:20.000000000 +0200
@@ -32,12 +32,11 @@
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
-#include <mISDNif.h>
+#include <mISDNuser/mISDNif.h>
 
-//#define AF_COMPATIBILITY_FUNC
-//#include <compat_af_isdn.h>
-#define AF_ISDN 34
-#define PF_ISDN AF_ISDN
+#define MISDN_OLD_AF_COMPATIBILITY
+#define AF_COMPATIBILITY_FUNC
+#include <mISDNuser/compat_af_isdn.h>
 
 #include <openbsc/select.h>
 #include <openbsc/msgb.h>
@@ -114,8 +113,10 @@
                return ret;
        }
 
-       if (alen != sizeof(l2addr))
+       if (alen != sizeof(l2addr)) {
+               fprintf(stderr, "error len\n");
                return -EINVAL;
+       }
 
        msgb_put(msg, ret);
 
@@ -129,7 +130,7 @@
        case DL_INFORMATION_IND:
                /* mISDN tells us which channel number is allocated for this
                 * tuple of (SAPI, TEI). */
-               DEBUGP(DMI, "use channel(%d) sapi(%d) tei(%d) for now\n",
+               DEBUGP(DMI, "DL_INFORMATION_IND: channel(%d) sapi(%d) tei(%d)\n",
                        l2addr.channel, l2addr.sapi, l2addr.tei);
                link = e1inp_lookup_sign_link(e1i_ts, l2addr.tei, l2addr.sapi);
                if (!link) {
@@ -140,10 +141,16 @@
                /* save the channel number in the driver private struct */
                link->driver.misdn.channel = l2addr.channel;
                break;
-       case MPH_ACTIVATE_IND:
+//     case MPH_ACTIVATE_IND:
+       case DL_ESTABLISH_IND:
+               DEBUGP(DMI, "DL_ESTABLISH_IND: channel(%d) sapi(%d) tei(%d)\n",
+               l2addr.channel, l2addr.sapi, l2addr.tei);
                ret = e1inp_event(e1i_ts, EVT_E1_TEI_UP, l2addr.tei, l2addr.sapi);
                break;
-       case MPH_DEACTIVATE_IND:
+//     case MPH_DEACTIVATE_IND:
+       case DL_RELEASE_IND:
+               DEBUGP(DMI, "DL_RELEASE_IND: channel(%d) sapi(%d) tei(%d)\n",
+               l2addr.channel, l2addr.sapi, l2addr.tei);
                ret = e1inp_event(e1i_ts, EVT_E1_TEI_DN, l2addr.tei, l2addr.sapi);
                break;
        case DL_DATA_IND:
@@ -157,6 +164,27 @@
        return ret;
 }
 
+static int ts_want_write(struct e1inp_ts *e1i_ts)
+{
+       /* We never include the mISDN B-Channel FD into the
+        * writeset, since it doesn't support poll() based
+        * write flow control */                
+       if (e1i_ts->type == E1INP_TS_TYPE_TRAU)
+               return 0;
+
+       e1i_ts->driver.misdn.fd.when |= BSC_FD_WRITE;
+
+       return 0;
+}
+
+static void timeout_ts1_write(void *data)
+{
+       struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data;
+
+       /* trigger write of ts1, due to tx delay timer */
+       ts_want_write(e1i_ts);
+}
+
 static int handle_ts1_write(struct bsc_fd *bfd)
 {
        struct e1inp_line *line = bfd->data;
@@ -169,10 +197,12 @@
        u_int8_t *l2_data;
        int ret;
 
+       bfd->when &= ~BSC_FD_WRITE;
+       
        /* get the next msg for this timeslot */
        msg = e1inp_tx_ts(e1i_ts, &sign_link);
        if (!msg) {
-               bfd->when &= ~BSC_FD_WRITE;
+               /* no message after tx delay timer */
                return 0;
        }
 
@@ -182,8 +212,8 @@
        hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh));
        hh->prim = DL_DATA_REQ;
 
-       DEBUGP(DMI, "TX TEI(%d): %s\n", sign_link->tei,
-               hexdump(l2_data, msg->len - MISDN_HEADER_LEN));
+       DEBUGP(DMI, "TX TEI(%d) SAPI(%d): %s\n", sign_link->tei,
+               sign_link->sapi, hexdump(l2_data, msg->len - MISDN_HEADER_LEN));
 
        /* construct the sockaddr */
        sa.family = AF_ISDN;
@@ -193,10 +223,14 @@
 
        ret = sendto(bfd->fd, msg->data, msg->len, 0,
                     (struct sockaddr *)&sa, sizeof(sa));
+       if (ret < 0)
+               fprintf(stderr, "sendto failed %d\n", ret);
        msgb_free(msg);
 
-       /* FIXME: this has to go */
-       usleep(100000);
+       /* set tx delay timer for next event */
+       e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
+       e1i_ts->sign.tx_timer.data = e1i_ts;
+       schedule_timer(&e1i_ts->sign.tx_timer, 0, 50000);
 
        return ret;
 }
@@ -253,8 +287,9 @@
 
        msgb_put(msg, ret);
 
-       DEBUGP(DMIB, "<= BCHAN len = %d, prim(0x%x) id(0x%x): %s\n",
-               ret, hh->prim, hh->id, get_prim_name(hh->prim));
+       if (hh->prim != PH_CONTROL_IND)
+               DEBUGP(DMIB, "<= BCHAN len = %d, prim(0x%x) id(0x%x): %s\n",
+                       ret, hh->prim, hh->id, get_prim_name(hh->prim));
 
        switch (hh->prim) {
        case PH_DATA_IND:
@@ -332,28 +367,16 @@
        return ret;
 }
 
-static int ts_want_write(struct e1inp_ts *e1i_ts)
-{
-       /* We never include the mISDN B-Channel FD into the
-        * writeset, since it doesn't support poll() based
-        * write flow control */                
-       if (e1i_ts->type == E1INP_TS_TYPE_TRAU)
-               return 0;
-
-       e1i_ts->driver.misdn.fd.when |= BSC_FD_WRITE;
-
-       return 0;
-}
-
 struct e1inp_driver misdn_driver = {
        .name = "mISDNuser",
        .want_write = ts_want_write,
 };
 
-static int mi_e1_setup(struct e1inp_line *line)
+static int mi_e1_setup(struct e1inp_line *line, int release_l2)
 {
        struct mi_e1_handle *e1h = line->driver_data;
        int ts, ret;
+       int     clean = 1;
 
        /* TS0 is CRC4, don't need any fd for it */
        for (ts = 1; ts < NUM_E1_TS; ts++) {
@@ -384,8 +407,8 @@
                }
 
                if (bfd->fd < 0) {
-                       fprintf(stderr, "could not open socket %s\n",
-                               strerror(errno));
+                       fprintf(stderr, "%s could not open socket %s\n",
+                               __func__, strerror(errno));
                        return bfd->fd;
                }
 
@@ -395,8 +418,6 @@
                switch (e1i_ts->type) {
                case E1INP_TS_TYPE_SIGN:
                        addr.channel = 0;
-                       /* SAPI not supported yet in kernel */
-                       //addr.sapi = e1inp_ts->sign.sapi;
                        addr.sapi = 0;
                        addr.tei = GROUP_TEI;
                        break;
@@ -415,6 +436,13 @@
                                strerror(errno));
                        return -EIO;
                }
+               if (e1i_ts->type == E1INP_TS_TYPE_SIGN && release_l2) {
+                       ret = ioctl(bfd->fd, IMCLEAR_L2, &clean);
+                               if (ret < 0) {
+                               fprintf(stderr, "could not send IOCTL IMCLEAN_L2 %s\n", strerror(errno));
+                               return -EIO;
+                       }
+               }
 
                /* FIXME: only activate B-Channels once we start to
                 * use them to conserve CPU power */
@@ -432,12 +460,14 @@
        return 0;
 }
 
-int mi_setup(int cardnr,  struct e1inp_line *line)
+int mi_setup(int cardnr,  struct e1inp_line *line, int release_l2)
 {
        struct mi_e1_handle *e1h;
        int sk, ret, cnt;
        struct mISDN_devinfo devinfo;
 
+       init_af_isdn();
+
        /* register the driver with the core */
        /* FIXME: do this in the plugin initializer function */
        ret = e1inp_driver_register(&misdn_driver);
@@ -457,7 +487,7 @@
        /* open the ISDN card device */
        sk = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
        if (sk < 0) {
-               fprintf(stderr, "could not open socket %s\n", strerror(errno));
+               fprintf(stderr, "%s could not open socket %s\n", __func__, strerror(errno));
                return sk;
        }
 
@@ -484,9 +514,20 @@
        fprintf(stdout, "        protocol:       %d\n", devinfo.protocol);
        fprintf(stdout, "        nrbchan:        %d\n", devinfo.nrbchan);
        fprintf(stdout, "        name:           %s\n", devinfo.name);
+#else
+       printf("using device %d\n", e1h->cardnr);
 #endif
 
-       ret = mi_e1_setup(line);
+       if (!(devinfo.Dprotocols & (1 << ISDN_P_NT_E1))) {
+               fprintf(stderr, "error: card is not of type E1 (NT-mode)\n");
+               return -EINVAL;
+       }
+       if (devinfo.nrbchan != 30) {
+               fprintf(stderr, "error: E1 card has no 30 B-channels\n");
+               return -EINVAL;
+       }
+
+       ret = mi_e1_setup(line, release_l2);
        if (ret)
                return ret;
 


<FONT size=+0><BIG><BIG><FONT size=+0><BIG><BIG><SMALL><SMALL><FONT size=+0><BIG><BIG><FONT face=Arial color=#3333ff size=+1><BIG><BIG><SMALL><SMALL>the subchanneling is reversed in my case. maybe we can use "#ifdef" until we know why this works for me and not in the
reverse case: bit order "87654321" work, but "21436587" does not.

here is my theory why this works for others: first i enabled second b-channel, so i expect that others have it disabled.
because we use timeslot 1 of TRX for signalling, others can use just 3 timeslots on TRX for audio, and can make not
more than one call at a time, because two slots are required for a call. in my case, i have the first call on time slot 3 and 4
(channel 2 and 3 on TRX). i did not debug why channel 1 is not selected for first call. if others use time slot 2 and 3
(channel 1 and 2 on TRX), it does not matter if the channel order is swapped, because slot 2 is swapped with slot 3,
and both will not change their position. you will not notice the difference, until slots on different positions are used.

</SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT></SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT> 

diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/src/subchan_demux.c openbsc/src/subchan_demux.c
--- openbsc.orig/src/subchan_demux.c    2009-02-23 17:58:34.000000000 +0100
+++ openbsc/src/subchan_demux.c 2009-04-19 13:30:08.000000000 +0200
@@ -100,7 +100,7 @@
                        if (!(dmx->chan_activ & (1 << c)))
                                continue;
 
-                       inbits = inbyte >> ((3-c)*2);
+                       inbits = inbyte >> (c << 1);
 
                        /* two bits for each subchannel */
                        if (inbits & 0x01)
@@ -230,10 +230,10 @@
        int rc;
 
        /* combine two bits of every subchan */
-       rc = get_subch_bits(mx, 3, &bits[0], 2);
-       rc = get_subch_bits(mx, 2, &bits[2], 2);
-       rc = get_subch_bits(mx, 1, &bits[4], 2);
-       rc = get_subch_bits(mx, 0, &bits[6], 2);
+       rc = get_subch_bits(mx, 0, &bits[0], 2);
+       rc = get_subch_bits(mx, 1, &bits[2], 2);
+       rc = get_subch_bits(mx, 2, &bits[4], 2);
+       rc = get_subch_bits(mx, 3, &bits[6], 2);
 
        *byte = compact_bits(bits);
 
</PRE><BR><PRE><FONT size=+0><BIG><BIG><FONT size=+0><BIG><BIG><SMALL><SMALL><FONT size=+0><BIG><BIG><FONT size=+0><BIG><BIG><SMALL><SMALL><FONT size=+0><BIG><BIG><FONT size=+0><BIG><BIG><SMALL><SMALL><FONT size=+0><BIG><BIG><FONT face=Arial color=#3333ff size=+1><BIG><BIG><SMALL><SMALL>finally the includes:</SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT></SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT></SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT></SMALL></SMALL></BIG></BIG></FONT></BIG></BIG></FONT></PRE><BR><PRE>diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/include/openbsc/e1_input.h openbsc/include/openbsc/e1_input.h
--- openbsc.orig/include/openbsc/e1_input.h     2009-03-28 11:36:36.000000000 +0100
+++ openbsc/include/openbsc/e1_input.h  2009-04-19 12:46:37.000000000 +0200
@@ -63,7 +63,10 @@
 
        union {
                struct {
+                       /* list of all signalling links on this TS */
                        struct llist_head sign_links;
+                       /* timer when to dequeue next frame */
+                       struct timer_list tx_timer;
                } sign;
                struct {
                        /* subchannel demuxer for frames from E1 */
@@ -142,7 +145,7 @@
 struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr);
 
 /* e1_config.c */
-int e1_config(struct gsm_bts *bts);
+int e1_config(struct gsm_bts *bts, int card, int l2_release);
 int ia_config(struct gsm_bts *bts);
 int ipaccess_setup(struct e1inp_line *line);
 
diff -Nur -x '*.Po' -x 'Makefile*' -x '*~' -x '*rej' -x '*.o' openbsc.orig/include/openbsc/misdn.h openbsc/include/openbsc/misdn.h
--- openbsc.orig/include/openbsc/misdn.h        2009-03-28 11:36:36.000000000 +0100
+++ openbsc/include/openbsc/misdn.h     2009-04-19 12:48:28.000000000 +0200
@@ -22,7 +22,7 @@
 
 #include "e1_input.h"
 
-int mi_setup(int cardnr,  struct e1inp_line *line);
+int mi_setup(int cardnr,  struct e1inp_line *line, int l2_release);
 void mi_set_pcap_fd(int fd);
 int _abis_nm_sendmsg(struct msgb *msg);
 
</PRE><BR><PRE></PRE></BODY></HTML>