first patch: mISDN handling

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Andreas.Eversberg Andreas.Eversberg at versatel.de
Sun Apr 19 17:13:58 UTC 2009


hi,

finally i finished my patch about mISDN handling, reversed time slots
and other things.

i sent this mail again, because my last formatting might be detected as
spam by "spam assassin" filters.

you will find documentation text between this patch, so scroll and look.
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


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;



the next part will create both e1 time slots for audio traffic. this is
required, because uninitialized slots cause segementation faults due to
invalid structure pointers.
i tested it, by using making calls on four phones.


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 */




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.



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;
 


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 no 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.

 

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);
 


finally the includes:

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);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: gsm1.patch
Type: application/octet-stream
Size: 16453 bytes
Desc: gsm1.patch
URL: <http://lists.osmocom.org/pipermail/openbsc/attachments/20090419/3870bd6b/attachment.obj>


More information about the OpenBSC mailing list