Hi LAPDm guys,
while I was digging into the LAPDm code to find out, why a broken SABM
message is sent on a SAPI3 establish SACCH request during an active
call (leading to a delay of 3s between RSL EST request and response), I
stumbled over the following:
The initial SABM message (not the retransmitted one after T200) has a
non-zero length and ends with 3 bytes that have been taken from the end
of the RSL EST REQ message. The MS does not answer to this.
Interestingly the second SABM message that gets sent after T200 (2s) has
a length field of 0 and no trailing garbage.
The difference lies in the way the msgb is handled. In
rslms_rx_rll_est_req() the msg buffer passed from RSL is being used.
In the case of IPA, the l2h is prepended by the 3 byte IPA header.
Since all code in lapdm.c that handles RSL message seem to assume,
that msg->data == msg->l2h, length computation is done based on that
assumption in some places. In addition, msgb_pull() is used in a way
that would also lead to undefined results in this case, e.g. in
msgb_pull_l2h() just the difference between l2h and l3h is pulled from
the beginning (msg->data).
The main difficulty to find this, was that much msgb handling is done
by manual access to the msgb fields. I'd really favor the use of the
predefined macros/inlines instead of meddling around with the fields.
I've added a function msgb_pull_to_l3() to msgb.h which just skips over
everything in front of l3 (and therefore invalidates l2h and l1h) and
replaced all calls to msgb_pull_l2h() by calls to msgb_pull_to_l3().
In addition, I replaced manual l3 length adjustment by calls to
msgb_trim(). That alone fixed the SABM issue described above. See the
jerlbeck/fixes/lapd-sms branch for details.
But AFAICS there is still something to do:
- The remaining msgb_pull() need to be checked (at least the one in
l2_ph_data_ind() looks suspicious to me.
- L3 length computation should be done with the macros, how it is done
in lapdm_send_ph_data_req() is broken.
- Why does lapd_msg_ctx have a length field that is not used?
- ladp_test.c should be extended to check other execution paths, too.
I've tried it for dummy packets and I didn't get it working without
failing assertions (see below)
- How l2/data/.. in a msg are expected to be used/set should be
documented somewhere.
- It should be clarified, whether all abis driver should reset the msg
to start with l2.
Cheers
Jacob
======
The following patch still breaks the assertions, at least changing the
l3len computation in lapdm_send_ph_data_req() influences but doesn't fix
it.
--- a/tests/lapd/lapd_test.c
+++ b/tests/lapd/lapd_test.c
@@ -123,8 +123,10 @@ static struct msgb *create_empty_msg(void)
static struct msgb *create_dummy_data_req(void)
{
struct msgb *msg;
+ const int dummy_l1len = 3;
msg = msgb_from_array(dummy1, sizeof(dummy1));
+ msgb_push(msg, dummy_l1len);
rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1);
return msg;
}
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hi everybody,
I know that's a bit late, but... I'm part of the Rhizomatica project,
we're currently building a GSM/SIP hybrid network in Mexico.
I'll be around Europe at the time of the conference, and I was
wondering if there is still space available to attend.
I'm not a developer of Osmocom, but we're patching OpenBSC here and
there to make it fit our platform. I could come and present what is
the current status, the code we wrote to manage the network from a
user perspective, and where we're going in the near future.
Could that be of any interest to the Osmocom crew?
Cheers
Ciaby
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iF4EAREKAAYFAlMCef8ACgkQC30ZhxNccpHkggD+M4Sn1Zakc+1oDilvm0dkfY3P
2LidV/BIiTM7P/rgXmEA/29U6I+BhvqIyFcj0ICdZkJoB66aYc70Zk5VOhtv/92f
=tvJk
-----END PGP SIGNATURE-----
Hi all,
I've recently played with Docker [1] and OpenBSC (osmo-nitb). The
result is osmonitb-docker:
https://github.com/shamrin/osmonitb-docker
What you can do with it? You can use it to hack on OpenBSC under Mac
or even Windows (there's Vagrant+VirtualBox config). Or you can try to
streamline deployment and testing on production hardware. I've tested
it under Mac working together with Fairwaves UmSITE hardware (running
OsmoBTS). SMS and phone calls all work.
Does it make sense to submit osmonitb-docker as a patch to OpenBSC?
Quick start, under real or virtual Ubuntu 12.04, with Docker installed:
git clone https://github.com/shamrin/osmonitb-docker.git
cd osmonitb-docker
docker build -rm -t shamrin/osmonitb .
docker run -v $HOME/db:/var/db -i -t -p 3002:3002 -p 3003:3003 -p
30000:30000/udp -p 30001:30001/udp -p 30002:30002/udp -p
30003:30003/udp -p 30004:30004/udp -p 30005:30005/udp -p
30006:30006/udp shamrin/osmonitb start-nitb -i 10.0.0.10 GSM1800 10 20
(replace last 4 arguments as necessary)
[1]: https://www.docker.io/
Alexey
Hi all,
We're moving this discussion to the mailing list, as it seems it is
more generic and complex than we've thought initially.
The issue arose when I started doing load testing of the OsmoTRX
transceiver and disabled all gating in it. As a result, all incoming
noise was processed as valid Normal Bursts and Access Bursts and sent
up to OsmoBTS. This leads to a situation, similar to a RACH flood,
when there are more RACH requests coming, than a BTS could reasonably
process. And this leads to an unbounded increase of the AGCH queue in
the BTS - it consumes a few Mb per minute.
I think that this is the root cause of the issue we've seen at a
Netherlands festival installation, when 20K phones suddenly started
connecting to our station after official networks went down. When the
amount of RACH requests exceeded available CCCH capacity (took <5
seconds), mobile phones stopped answering out IMM.ASS messages.
Hypothesis is that the AGCH queue became so long, requests were sent
too late for a phone to receive it. And thus no phones answered to our
IMM.ASS messages. Unfortunately, I wasn't able to collect enough data
to check this hypothesis during that time and we don't have another
big festival on hands atm.
An attached is a quick fix for the unbounded queue growth. It uses a
hardcoded value for the maximum queue length, which is fine for our
load testing, but not flexible enough for the real life usage. We
should make the AGCH queue long enough to keep high performance. At
the same time, it must not exceed MS timeout or _all_ IMM.ASS messages
will miss their target MS's.
We could make this parameter user-configurable on a BTS side, but it
seems more reasonable to automatically calculate it, depending on the
channel combination and timeout values. But this should be done on the
BSC side. So the questions are:
1) what is a good way to calculate it?
2) should we configure this queue length over OML, or move the queue
from BTS to BSC?
--
Regards,
Alexander Chemeris.
CEO, Fairwaves LLC / ООО УмРадио
http://fairwaves.ru
From: Álvaro Neira Ayuso <anayuso(a)sysmocom.de>
This patch provide two new functions for reading and writing
from the serial interface. I think this two functions makes it
easy reading and writing from the serial interface.
Signed-off-by: Alvaro Neira Ayuso <anayuso(a)sysmocom.de>
---
v3: Fixed the bug that i send errno when in this case errno don't return anything.
Fixed some format error for having consistency with the others function and now,
I control when read function return the value 0 for saying the end of the file.
v2: Fixed the write function for don't supposing that i will write
all the msg in one time. I have studied the limit in the read function
and i have used the -errno like the other functions inside serial.c for
having consistency. The previous version, i have supposed that we need
to liberate the info in case of error, now if we have a error we can
check the info that we have received or we must to send again.
include/osmocom/core/serial.h | 4 +++
src/serial.c | 53 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h
index 1640a6d..056010b 100644
--- a/include/osmocom/core/serial.h
+++ b/include/osmocom/core/serial.h
@@ -33,10 +33,14 @@
#include <termios.h>
+struct msgb;
+
int osmo_serial_init(const char *dev, speed_t baudrate);
int osmo_serial_set_baudrate(int fd, speed_t baudrate);
int osmo_serial_set_custom_baudrate(int fd, int baudrate);
int osmo_serial_clear_custom_baudrate(int fd);
+int osmo_serial_write(int fd, struct msgb *msg);
+int osmo_serial_read(int fd, struct msgb *msg, int numbytes);
/*! @} */
diff --git a/src/serial.c b/src/serial.c
index 66ee756..8c28e7a 100644
--- a/src/serial.c
+++ b/src/serial.c
@@ -43,6 +43,7 @@
#endif
#include <osmocom/core/serial.h>
+#include <osmocom/core/msgb.h>
#if 0
@@ -226,4 +227,56 @@ osmo_serial_clear_custom_baudrate(int fd)
return 0;
}
+/*! \brief Read data from Serial interface
+ * \param[in] fd File descriptor of the open device
+ * \param[in] msg Struct where we save the info
+ * \param[in] numbytes Number of bytes that we want read
+ * \returns 0 for success or negative errno.
+ */
+int
+osmo_serial_read(int fd, struct msgb *msg, int numbytes)
+{
+ int rc, bread = 0;
+
+ if (numbytes > msg->data_len)
+ return -ENOSPC;
+
+ while (bread < numbytes) {
+ rc = read(fd, msg->tail, numbytes - bread);
+ if (rc < 0)
+ return -errno;
+ if (rc == 0)
+ break;
+
+ bread += rc;
+ msgb_put(msg, rc);
+ }
+
+ return bread;
+}
+
+/*! \brief Write data to Serial interface
+ * \param[in] fd File descriptor of the open device
+ * \param[in] msg Struct where we have the info for writing
+ * \returns 0 for success or negative errno.
+ *
+ * The msgb->data pointer is updated when consuming this message
+ */
+int
+osmo_serial_write(int fd, struct msgb *msg)
+{
+ int rc, bwritten = 0;
+
+ while (msg->len > 0) {
+ rc = write(fd, msg->data, msg->len);
+ if (rc < 0)
+ return -errno;
+
+ msgb_pull(msg, rc);
+ bwritten += rc;
+ }
+
+ return bwritten;
+}
+
/*! @} */
From: Álvaro Neira Ayuso <anayuso(a)sysmocom.de>
This patch provide two new functions for reading and writing
from the serial interface. I think this two functions makes it
easy reading and writing from the serial interface.
Signed-off-by: Alvaro Neira Ayuso <anayuso(a)sysmocom.de>
---
v2: Fixed the write function for don't supposing that i will write
all the msg in one time. I have studied the limit in the read function
and i have used the -errno like the other functions inside serial.c for
having consistency. The previous version, i have supposed that we need
to liberate the info in case of error, now if we have a error we can
check the info that we have received or we must to send again.
include/osmocom/core/serial.h | 4 +++
src/serial.c | 51 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h
index 1640a6d..056010b 100644
--- a/include/osmocom/core/serial.h
+++ b/include/osmocom/core/serial.h
@@ -33,10 +33,14 @@
#include <termios.h>
+struct msgb;
+
int osmo_serial_init(const char *dev, speed_t baudrate);
int osmo_serial_set_baudrate(int fd, speed_t baudrate);
int osmo_serial_set_custom_baudrate(int fd, int baudrate);
int osmo_serial_clear_custom_baudrate(int fd);
+int osmo_serial_write(int fd, struct msgb *msg);
+int osmo_serial_read(int fd, struct msgb *msg, int numbytes);
/*! @} */
diff --git a/src/serial.c b/src/serial.c
index 66ee756..c71ee6a 100644
--- a/src/serial.c
+++ b/src/serial.c
@@ -43,6 +43,7 @@
#endif
#include <osmocom/core/serial.h>
+#include <osmocom/core/msgb.h>
#if 0
@@ -226,4 +227,54 @@ osmo_serial_clear_custom_baudrate(int fd)
return 0;
}
+/*! \brief Read datas from Serial interface
+ * \param[in] fd File descriptor of the open device
+ * \param[in] msg Struct where we save the info
+ * \param[in] numbytes Number of bytes that we want read
+ * \returns 0 for success or negative errno.
+ */
+int
+osmo_serial_read(int fd, struct msgb *msg, int numbytes)
+{
+ int rc, bread = 0;
+
+ if (numbytes > msg->data_len)
+ return -errno;
+
+ while (bread < numbytes) {
+ rc = read(fd, msg->tail, numbytes - bread);
+ if (rc < 0)
+ return -errno;
+
+ bread += rc;
+ msgb_put(msg, rc);
+ }
+
+ return bread;
+}
+
+/*! \brief Write datas to Serial interface
+ * \param[in] fd File descriptor of the open device
+ * \param[in] msg Struct where we have the info for writing
+ * \returns 0 for success or negative errno.
+ *
+ * The msgb->data pointer is updated when consuming this message
+ */
+int
+osmo_serial_write(int fd, struct msgb *msg)
+{
+ int rc, bwritten = 0;
+
+ while (msg->len > 0) {
+ rc = write(fd, msg->data, msg->len);
+ if (rc == -1)
+ return -errno;
+
+ msgb_pull(msg, rc);
+ bwritten += rc;
+ }
+
+ return bwritten;
+}
+
/*! @} */