Moved layer 1 <-> layer 2 interface from main.c to a seperate file of
authorAndreas.Eversberg <jolly@eversberg.eu>
Sat, 22 May 2010 10:46:20 +0000 (10:46 +0000)
committerAndreas.Eversberg <jolly@eversberg.eu>
Sat, 22 May 2010 10:46:20 +0000 (10:46 +0000)
liblayer23. Other applications using liblayer23 don't need to re-implement it.

Messages from layer 1 are not freed in layer2_read() anymore. They will be
freed by the upper layers. The layers may also decide to queue or to forward
the messages. In general: A message is always discarded by the message handler
and not after calling the message handler.

src/host/layer23/include/osmocom/l1ctl.h
src/host/layer23/include/osmocom/l1l2_interface.h [new file with mode: 0644]
src/host/layer23/src/Makefile.am
src/host/layer23/src/gsm48_rr.c
src/host/layer23/src/l1ctl.c
src/host/layer23/src/l1l2_interface.c [new file with mode: 0644]
src/host/layer23/src/lapdm.c
src/host/layer23/src/main.c
src/host/layer23/src/rslms.c

index c267fa7..48aeaad 100644 (file)
@@ -28,7 +28,4 @@ int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len);
 int l1ctl_tx_pm_req_range(struct osmocom_ms *ms, uint16_t arfcn_from,
                          uint16_t arfcm_to);
 
-extern int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg);
-
-
 #endif
diff --git a/src/host/layer23/include/osmocom/l1l2_interface.h b/src/host/layer23/include/osmocom/l1l2_interface.h
new file mode 100644 (file)
index 0000000..41403d8
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _L1L2_INTERFACE_H
+#define _L1L2_INTERFACE_H
+
+int layer2_open(struct osmocom_ms *ms, const char *socket_path);
+int layer2_close(struct osmocom_ms *ms);
+int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg);
+
+#endif /* _L1L2_INTERFACE_H */
index c63e759..86d86bc 100644 (file)
@@ -3,7 +3,7 @@ AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
 #AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
 
 noinst_LIBRARIES = liblayer23.a libvty.a
-liblayer23_a_SOURCES = l1ctl.c gsmtap_util.c lapdm.c rslms.c \
+liblayer23_a_SOURCES = l1l2_interface.c l1ctl.c gsmtap_util.c lapdm.c rslms.c \
                        layer3.c logging.c bcch_scan.c \
                        gsm48_cc.c transaction.c gsm48_mm.c gsm48_rr.c \
                        gsm322.c support.c subscriber.c sysinfo.c networks.c \
index ca98fb7..9cf5c2c 100644 (file)
@@ -53,8 +53,9 @@
 #include <osmocore/gsm48.h>
 #include <osmocore/bitvec.h>
 
-#include <osmocom/logging.h>
 #include <osmocom/osmocom_data.h>
+#include <osmocom/l1l2_interface.h>
+#include <osmocom/logging.h>
 
 static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg);
 static int gsm48_rr_dl_est(struct osmocom_ms *ms);
@@ -273,8 +274,6 @@ static int gsm48_rx_rll(struct msgb *msg, struct osmocom_ms *ms)
 {
        struct gsm48_rrlayer *rr = &ms->rrlayer;
 
-#warning HACK!!!!!!
-return gsm48_rcv_rsl(ms, msg);
        msgb_enqueue(&rr->rsl_upqueue, msg);
 
        return 0;
@@ -294,6 +293,7 @@ static int gsm48_rx_rsl(struct msgb *msg, struct osmocom_ms *ms)
                /* FIXME: implement this */
                LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
                        rslh->msg_discr);
+               msgb_free(msg);
                rc = -EINVAL;
                break;
        }
@@ -3237,8 +3237,6 @@ static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
 
        /* free msgb unless it is forwarded */
        if (dldatastatelist[i].rout != gsm48_rr_data_ind)
-#warning HACK!!!!!!
-return rc;
                msgb_free(msg);
 
        return rc;
index 8731caf..5cda1f9 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <osmocom/l1ctl.h>
 #include <osmocom/osmocom_data.h>
+#include <osmocom/l1l2_interface.h>
 #include <osmocom/lapdm.h>
 #include <osmocom/logging.h>
 #include <osmocom/gsmtap_util.h>
@@ -142,6 +143,7 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
        if (msgb_l3len(msg) < sizeof(*ccch)) {
                LOGP(DL1C, LOGL_ERROR, "MSG too short Data Ind: %u\n",
                        msgb_l3len(msg));
+               msgb_free(msg);
                return -1;
        }
 
@@ -334,6 +336,8 @@ static int rx_l1_reset(struct osmocom_ms *ms)
 {
        printf("Layer1 Reset.\n");
        dispatch_signal(SS_L1CTL, S_L1CTL_RESET, ms);
+
+       return 0;
 }
 
 /* Receive L1CTL_PM_RESP */
@@ -364,6 +368,7 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
        if (msgb_l2len(msg) < sizeof(*dl)) {
                LOGP(DL1C, LOGL_ERROR, "Short Layer2 message: %u\n",
                        msgb_l2len(msg));
+               msgb_free(msg);
                return -1;
        }
 
@@ -376,20 +381,24 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
        switch (l1h->msg_type) {
        case L1CTL_FBSB_RESP:
                rc = rx_l1_fbsb_resp(ms, msg);
+               msgb_free(msg);
                break;
        case L1CTL_DATA_IND:
                rc = rx_ph_data_ind(ms, msg);
                break;
        case L1CTL_RESET:
                rc = rx_l1_reset(ms);
+               msgb_free(msg);
                break;
        case L1CTL_PM_RESP:
                rc = rx_l1_pm_resp(ms, msg);
+               msgb_free(msg);
                if (l1h->flags & L1CTL_F_DONE)
                        dispatch_signal(SS_L1CTL, S_L1CTL_PM_DONE, ms);
                break;
        default:
                fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type);
+               msgb_free(msg);
                break;
        }
 
diff --git a/src/host/layer23/src/l1l2_interface.c b/src/host/layer23/src/l1l2_interface.c
new file mode 100644 (file)
index 0000000..e49b98a
--- /dev/null
@@ -0,0 +1,161 @@
+/* Layer 1 socket interface of layer2/3 stack */
+
+/* (C) 2010 by Holger Hans Peter Freyther
+ * (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocom/osmocom_data.h>
+#include <osmocom/l1ctl.h>
+#include <osmocom/logging.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <arpa/inet.h>
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#define GSM_L2_LENGTH 256
+
+static int layer2_read(struct bsc_fd *fd)
+{
+       struct msgb *msg;
+       u_int16_t len;
+       int rc;
+
+       msg = msgb_alloc(GSM_L2_LENGTH, "Layer2");
+       if (!msg) {
+               LOGP(DL1C, LOGL_ERROR, "Failed to allocate msg.\n");
+               return -ENOMEM;
+       }
+
+       rc = read(fd->fd, &len, sizeof(len));
+       if (rc < sizeof(len)) {
+               msgb_free(msg);
+               return rc;
+       }
+
+       len = ntohs(len);
+       if (len > GSM_L2_LENGTH) {
+               LOGP(DL1C, LOGL_ERROR, "Length is too big: %u\n", len);
+               msgb_free(msg);
+               return -EINVAL;
+       }
+
+
+       msg->l1h = msgb_put(msg, len);
+       rc = read(fd->fd, msg->l1h, msgb_l1len(msg));
+       if (rc != msgb_l1len(msg)) {
+               LOGP(DL1C, LOGL_ERROR, "Can not read data: len=%d rc=%d "
+                    "errno=%d\n", len, rc, errno);
+               msgb_free(msg);
+               return rc;
+       }
+
+       l1ctl_recv((struct osmocom_ms *) fd->data, msg);
+
+       return 0;
+}
+
+static int layer2_write(struct bsc_fd *fd, struct msgb *msg)
+{
+       int rc;
+
+       rc = write(fd->fd, msg->data, msg->len);
+       if (rc != msg->len) {
+               LOGP(DL1C, LOGL_ERROR, "Failed to write data: rc: %d\n", rc);
+               return rc;
+       }
+
+       return 0;
+}
+
+int layer2_open(struct osmocom_ms *ms, const char *socket_path)
+{
+       int rc;
+       struct sockaddr_un local;
+
+       ms->wq.bfd.fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (ms->wq.bfd.fd < 0) {
+               fprintf(stderr, "Failed to create unix domain socket.\n");
+               return ms->wq.bfd.fd;
+       }
+
+       local.sun_family = AF_UNIX;
+       strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
+       local.sun_path[sizeof(local.sun_path) - 1] = '\0';
+
+       rc = connect(ms->wq.bfd.fd, (struct sockaddr *) &local,
+                    sizeof(local.sun_family) + strlen(local.sun_path));
+       if (rc < 0) {
+               fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
+               close(ms->wq.bfd.fd);
+               return rc;
+       }
+
+       write_queue_init(&ms->wq, 100);
+       ms->wq.bfd.data = ms;
+       ms->wq.bfd.when = BSC_FD_READ;
+       ms->wq.read_cb = layer2_read;
+       ms->wq.write_cb = layer2_write;
+
+       rc = bsc_register_fd(&ms->wq.bfd);
+       if (rc != 0) {
+               fprintf(stderr, "Failed to register fd.\n");
+               return rc;
+       }
+
+       return 0;
+}
+
+int layer2_close(struct osmocom_ms *ms)
+{
+       close(ms->wq.bfd.fd);
+       bsc_unregister_fd(&ms->wq.bfd);
+
+       return 0;
+}
+
+int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg)
+{
+       uint16_t *len;
+
+       DEBUGP(DL1C, "Sending: '%s'\n", hexdump(msg->data, msg->len));
+
+       if (msg->l1h != msg->data)
+               LOGP(DL1C, LOGL_ERROR, "Message L1 header != Message Data\n");
+       
+       /* prepend 16bit length before sending */
+       len = (uint16_t *) msgb_push(msg, sizeof(*len));
+       *len = htons(msg->len - sizeof(*len));
+
+       if (write_queue_enqueue(&ms->wq, msg) != 0) {
+               LOGP(DL1C, LOGL_ERROR, "Failed to enqueue msg.\n");
+               msgb_free(msg);
+               return -1;
+       }
+
+       return 0;
+}
+
+
index d507da8..1d90517 100644 (file)
@@ -305,8 +305,10 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                DEBUGPC(DLAPDM, "SABM ");
                /* Must be Format B */
                rc = check_length_ind(msg->l2h[2]);
-               if (rc < 0)
+               if (rc < 0) {
+                       msgb_free(msg);
                        return rc;
+               }
                length = msg->l2h[2] >> 2;
                /* FIXME: G.4.5 check */
                if (dl->state == LAPDm_STATE_MF_EST) {
@@ -316,6 +318,7 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                                /* FIXME: check for contention resoultion */
                                DEBUGP(DLAPDM, "SABM command, multiple "
                                        "frame established state\n");
+                               msgb_free(msg);
                                return 0;
                        }
                }
@@ -337,23 +340,27 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                DEBUGPC(DLAPDM, "DM ");
                if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
                        /* 5.4.1.2 DM responses with the F bit set to "0" shall be ignored. */
+                       msgb_free(msg);
                        return 0;
                }
                switch (dl->state) {
                case LAPDm_STATE_IDLE:
                        /* 5.4.5 all other frame types shall be discarded */
                        DEBUGPC(DLAPDM, "state=IDLE (discarding) ");
+                       msgb_free(msg);
                        return 0;
                case LAPDm_STATE_MF_EST:
                        if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 1)
                                DEBUGPC(DLAPDM, "unsolicited DM resposne ");
                        else
                                DEBUGPC(DLAPDM, "unsolicited DM resposne, multiple frame established state ");
+                       msgb_free(msg);
                        return 0;
                case LAPDm_STATE_TIMER_RECOV:
                        /* DM is normal in case PF = 1 */
                        if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 0) {
                                DEBUGPC(DLAPDM, "unsolicited DM resposne, multiple frame established state ");
+                               msgb_free(msg);
                                return 0;
                        }
                        break;
@@ -369,8 +376,10 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                        msg->l3h = msg->l2h + 2;
                } else {
                        rc = check_length_ind(msg->l2h[2]);
-                       if (rc < 0)
+                       if (rc < 0) {
+                               msgb_free(msg);
                                return rc;
+                       }
                        length = msg->l2h[2] >> 2;
                        msg->l3h = msg->l2h + 3;
                }
@@ -378,6 +387,7 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                if (length == 0) {
                        /* 5.3.3 UI frames received with the length indicator set to "0" shall be ignored */
                        DEBUGP(DLAPDM, "length=0 (discarding) ");
+                       msgb_free(msg);
                        return 0;
                }
                /* FIXME: G.4.5 check */
@@ -388,6 +398,7 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                default:
                        /* 5.3.3 UI frames with invalid SAPI values shall be discarded */
                        DEBUGP(DLAPDM, "sapi=%u (discarding) ", LAPDm_ADDR_SAPI(mctx->ctrl));
+                       msgb_free(msg);
                        return 0;
                }
                msgb_pull_l2h(msg);
@@ -403,8 +414,10 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                         * parameters" is sent to the mobile management entity. */
                        LOGP(DLAPDM, LOGL_ERROR,
                                "U frame iwth incorrect parameters ");
+                       msgb_free(msg);
                        return -EIO;
                }
+               msgb_free(msg);
                switch (dl->state) {
                case LAPDm_STATE_IDLE:
                        /* FIXME: send DM with F=P */
@@ -420,6 +433,7 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
                        /* 5.4.1.2 A UA response with the F bit set to "0" shall be ignored. */
                        DEBUGP(DLAPDM, "F=0 (discarding) ");
+                       msgb_free(msg);
                        return 0;
                }
                switch (dl->state) {
@@ -430,6 +444,7 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                default:
                        DEBUGP(DLAPDM,
                                "unsolicited UA response! (discarding) ");
+                       msgb_free(msg);
                        return 0;
                }
                /* reset Timer T200 */
@@ -441,6 +456,8 @@ static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                /* send notification to L3 */
                rc = send_rslms_rll_simple(RSL_MT_EST_CONF, mctx);
                break;
+       default:
+               msgb_free(msg);
        }
        return rc;
 }
@@ -457,6 +474,7 @@ static int lapdm_rx_s(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                 * with the M bit set to "1", an MDL-ERROR-INDICATION
                 * primitive with cause "S frame with incorrect
                 * parameters" is sent to the mobile management entity. */
+               msgb_free(msg);
                return -EIO;
        }
        switch (dl->state) {
@@ -476,6 +494,7 @@ static int lapdm_rx_s(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                /* FIXME */
                break;
        }
+       msgb_free(msg);
        return 0;
 }
 
@@ -495,6 +514,7 @@ static int lapdm_rx_i(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                 * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
                 * primitive with cause "I frame with incorrect length"
                 * is sent to the mobile management entity. */
+               msgb_free(msg);
                return -EIO;
        }
        /* FIXME: G.4.2 If the numerical value of L is L<N201 and the M
@@ -522,8 +542,10 @@ static int lapdm_rx_i(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                     "V_recv=%u ", ns, dl->V_recv);
                /* FIXME: 5.7.1: N(s) sequence error */
                /* discard data */
+               msgb_free(msg);
                return -EIO;
        }
+       msgb_free(msg);
 
        /* Check for P bit */
        if (LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
@@ -578,6 +600,7 @@ static int lapdm_ph_data_ind(struct msgb *msg, struct lapdm_msg_ctx *mctx)
                rc = lapdm_rx_i(msg, mctx);
        else {
                LOGP(DLAPDM, LOGL_ERROR, "unknown LAPDm format ");
+               msgb_free(msg);
                rc = -EINVAL;
        }
        return rc;
@@ -626,6 +649,7 @@ int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_
                if (!(mctx.addr & 0x01)) {
                        LOGP(DLAPDM, LOGL_ERROR, "we don't support "
                                "multibyte addresses (discarding)\n");
+                       msgb_free(msg);
                        return -EINVAL;
                }
                mctx.ctrl = msg->l2h[1];
@@ -635,6 +659,7 @@ int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_
                break;
        case LAPDm_FMT_Bter:
                /* FIXME */
+               msgb_free(msg);
                break;
        case LAPDm_FMT_Bbis:
                /* directly pass up to layer3 */
@@ -643,6 +668,8 @@ int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_
                msgb_pull_l2h(msg);
                rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg);
                break;
+       default:
+               msgb_free(msg);
        }
 
        return rc;
@@ -847,8 +874,10 @@ int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms)
 /* input function that L2 calls when sending messages up to L3 */
 int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms)
 {
-       if (!ms->l2_entity.msg_handler)
+       if (!ms->l2_entity.msg_handler) {
+               msgb_free(msg);
                return -EIO;
+       }
 
        /* call the layer2 message handler that is registered */
        return ms->l2_entity.msg_handler(msg, ms);
index 5ec71cc..9c669bb 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <osmocom/osmocom_data.h>
 #include <osmocom/l1ctl.h>
+#include <osmocom/l1l2_interface.h>
 #include <osmocom/layer3.h>
 #include <osmocom/lapdm.h>
 #include <osmocom/gsmtap_util.h>
@@ -36,9 +37,6 @@
 
 #include <arpa/inet.h>
 
-#include <sys/socket.h>
-#include <sys/un.h>
-
 #define _GNU_SOURCE
 #include <getopt.h>
 #include <stdlib.h>
@@ -49,8 +47,6 @@
 
 struct log_target *stderr_target;
 
-#define GSM_L2_LENGTH 256
-
 void *l23_ctx = NULL;
 static char *socket_path = "/tmp/osmocom_l2";
 struct llist_head ms_list;
@@ -59,82 +55,6 @@ static uint32_t gsmtap_ip = 0;
 int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
 int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
 
-static int layer2_read(struct bsc_fd *fd)
-{
-       struct msgb *msg;
-       u_int16_t len;
-       int rc;
-
-       msg = msgb_alloc(GSM_L2_LENGTH, "Layer2");
-       if (!msg) {
-               LOGP(DL1C, LOGL_ERROR, "Failed to allocate msg.\n");
-               return -1;
-       }
-
-       rc = read(fd->fd, &len, sizeof(len));
-       if (rc < sizeof(len)) {
-               LOGP(DL1C, LOGL_ERROR, "Short read. Error.\n");
-               exit(2);
-       }
-
-       len = ntohs(len);
-       if (len > GSM_L2_LENGTH) {
-               LOGP(DL1C, LOGL_ERROR, "Length is too big: %u\n", len);
-               msgb_free(msg);
-               return -1;
-       }
-
-
-       msg->l1h = msgb_put(msg, len);
-       rc = read(fd->fd, msg->l1h, msgb_l1len(msg));
-       if (rc != msgb_l1len(msg)) {
-               LOGP(DL1C, LOGL_ERROR, "Can not read data: len=%d rc=%d "
-                    "errno=%d\n", len, rc, errno);
-               msgb_free(msg);
-               return -1;
-       }
-
-       l1ctl_recv((struct osmocom_ms *) fd->data, msg);
-       msgb_free(msg);
-       return 0;
-}
-
-static int layer2_write(struct bsc_fd *fd, struct msgb *msg)
-{
-       int rc;
-
-       rc = write(fd->fd, msg->data, msg->len);
-       if (rc != msg->len) {
-               LOGP(DL1C, LOGL_ERROR, "Failed to write data: rc: %d\n", rc);
-               return -1;
-       }
-
-       return 0;
-}
-
-
-int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg)
-{
-       uint16_t *len;
-
-       DEBUGP(DL1C, "Sending: '%s'\n", hexdump(msg->data, msg->len));
-
-       if (msg->l1h != msg->data)
-               LOGP(DL1C, LOGL_ERROR, "Message L1 header != Message Data\n");
-       
-       /* prepend 16bit length before sending */
-       len = (uint16_t *) msgb_push(msg, sizeof(*len));
-       *len = htons(msg->len - sizeof(*len));
-
-       if (write_queue_enqueue(&ms->wq, msg) != 0) {
-               LOGP(DL1C, LOGL_ERROR, "Failed to enqueue msg.\n");
-               msgb_free(msg);
-               return -1;
-       }
-
-       return 0;
-}
-
 static void print_usage(const char *app)
 {
        printf("Usage: %s\n", app);
@@ -214,7 +134,6 @@ void sighandler(int sigset)
 int main(int argc, char **argv)
 {
        int rc;
-       struct sockaddr_un local;
 
        INIT_LLIST_HEAD(&ms_list);
        log_init(&log_info);
@@ -237,29 +156,12 @@ int main(int argc, char **argv)
 
        handle_options(argc, argv);
 
-       ms->wq.bfd.fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (ms->wq.bfd.fd < 0) {
-               fprintf(stderr, "Failed to create unix domain socket.\n");
-               exit(1);
-       }
-
-       local.sun_family = AF_UNIX;
-       strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
-       local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
-       rc = connect(ms->wq.bfd.fd, (struct sockaddr *) &local,
-                    sizeof(local.sun_family) + strlen(local.sun_path));
+       rc = layer2_open(ms, socket_path);
        if (rc < 0) {
-               fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
+               fprintf(stderr, "Failed during layer2_open()\n");
                exit(1);
        }
 
-       write_queue_init(&ms->wq, 100);
-       ms->wq.bfd.data = ms;
-       ms->wq.bfd.when = BSC_FD_READ;
-       ms->wq.read_cb = layer2_read;
-       ms->wq.write_cb = layer2_write;
-
        lapdm_init(&ms->l2_entity.lapdm_dcch, ms);
        lapdm_init(&ms->l2_entity.lapdm_acch, ms);
 
@@ -267,11 +169,6 @@ int main(int argc, char **argv)
        if (rc < 0)
                exit(1);
 
-       if (bsc_register_fd(&ms->wq.bfd) != 0) {
-               fprintf(stderr, "Failed to register fd.\n");
-               exit(1);
-       }
-
        if (gsmtap_ip) {
                rc = gsmtap_init(gsmtap_ip);
                if (rc < 0) {
index 63afa77..cb1f9b0 100644 (file)
@@ -122,6 +122,7 @@ static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms)
                rc = -EINVAL;
                break;
        }
+       msgb_free(msg);
        return rc;
 }
 
@@ -139,6 +140,7 @@ static int layer3_from_layer2(struct msgb *msg, struct osmocom_ms *ms)
                /* FIXME: implement this */
                LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
                        rslh->msg_discr);
+               msgb_free(msg);
                rc = -EINVAL;
                break;
        }