pespin has uploaded this change for review.

View Change

WIP: rspro: use osmo_stream to handle IPA connection

Change-Id: I9cba48bf8eba85215acef70eda7bcf8ec13ea49a
---
M configure.ac
M debian/control
M src/Makefile.am
M src/bankd/Makefile.am
M src/client/Makefile.am
M src/rspro_client_fsm.c
M src/rspro_client_fsm.h
M src/server/Makefile.am
8 files changed, 135 insertions(+), 52 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-remsim refs/changes/23/39023/1
diff --git a/configure.ac b/configure.ac
index 0529ff2..0296197 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,7 +35,8 @@

PKG_CHECK_MODULES(OSMOCORE, libosmocore >= 1.6.0)
PKG_CHECK_MODULES(OSMOGSM, libosmogsm >= 0.11.0)
-PKG_CHECK_MODULES(OSMOABIS, libosmoabis >= 0.8.0)
+PKG_CHECK_MODULES(OSMONETIF, libosmo-netif >= 1.5.0)
+PKG_CHECK_MODULES(OSMOABIS, libosmoabis >= 1.6.0)

AC_ARG_ENABLE([remsim-server],[AS_HELP_STRING([--disable-remsim-server], [Build osmo-remsim-server])],
[osmo_ac_build_server="$enableval"],[osmo_ac_build_server="yes"])
diff --git a/debian/control b/debian/control
index b3204fc..01d4776 100644
--- a/debian/control
+++ b/debian/control
@@ -10,7 +10,8 @@
osmo-gsm-manuals-dev,
libcsv-dev,
libosmocore-dev (>= 1.6.0),
- libosmo-abis-dev,
+ libosmo-abis-dev (>= 1.6.0),
+ libosmonetif-dev (>= 1.5.0),
libosmo-simtrace2-dev (>= 0.8.0),
libpcsclite-dev,
libusb-1.0-0-dev,
diff --git a/src/Makefile.am b/src/Makefile.am
index 5c10373..ef3474a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@

AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_builddir)/include \
$(OSMOABIS_CFLAGS) \
+ $(OSMONETIF_CFLAGS) \
$(OSMOGSM_CFLAGS) \
$(OSMOCORE_CFLAGS) \
-I$(top_srcdir)/include/osmocom/rspro
@@ -16,7 +17,7 @@
RSPRO_LIBVERSION=2:0:0
lib_LTLIBRARIES = libosmo-rspro.la
libosmo_rspro_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(RSPRO_LIBVERSION)
-# OSMOGSM_LIBS, OSMOABIS_LIBS not needed, we don't use any of its symbols, only the header above
+# OSMOABIS_LIBS, OSMONETIF_LIBS, OSMOGSM_LIBS not needed, we don't use any of its symbols, only the header above
libosmo_rspro_la_LIBADD = $(OSMOCORE_LIBS) \
rspro/libosmo-asn1-rspro.la
libosmo_rspro_la_SOURCES = rspro_util.c asn1c_helpers.c
diff --git a/src/bankd/Makefile.am b/src/bankd/Makefile.am
index 937464b..9ba306a 100644
--- a/src/bankd/Makefile.am
+++ b/src/bankd/Makefile.am
@@ -1,6 +1,7 @@
AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src \
-I$(top_srcdir)/include/osmocom/rspro \
$(OSMOABIS_CFLAGS) \
+ $(OSMONETIF_CFLAGS) \
$(OSMOGSM_CFLAGS) \
$(OSMOCORE_CFLAGS) \
$(PCSC_CFLAGS)
@@ -17,6 +18,7 @@
osmo_remsim_bankd_SOURCES = ../slotmap.c ../rspro_client_fsm.c ../debug.c \
bankd_main.c bankd_pcsc.c gsmtap.c
osmo_remsim_bankd_LDADD = $(OSMOABIS_LIBS) \
+ $(OSMONETIF_LIBS) \
$(OSMOGSM_LIBS) \
$(OSMOCORE_LIBS) \
$(PCSC_LIBS) \
diff --git a/src/client/Makefile.am b/src/client/Makefile.am
index 069206e..3f86a8a 100644
--- a/src/client/Makefile.am
+++ b/src/client/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = -Wall -I$(top_srcdir)/include -I/$(top_builddir)/include -I$(top_srcdir)/src \
$(OSMOABIS_CFLAGS) \
+ $(OSMONETIF_CFLAGS) \
$(OSMOGSM_CFLAGS) \
$(OSMOCORE_CFLAGS) \
$(PCSC_CFLAGS) $(USB_CFLAGS) \
@@ -12,6 +13,7 @@
remsim_client.c main_fsm.c ../rspro_client_fsm.c ../debug.c
osmo_remsim_client_shell_CFLAGS = $(AM_CFLAGS)
osmo_remsim_client_shell_LDADD = $(OSMOABIS_LIBS) \
+ $(OSMONETIF_LIBS) \
$(OSMOGSM_LIBS) \
$(OSMOCORE_LIBS) \
$(top_builddir)/src/libosmo-rspro.la
@@ -29,6 +31,7 @@
libifd_remsim_client_la_CPPFLAGS = $(PCSC_CFLAGS)
libifd_remsim_client_la_LDFLAGS = -no-undefined
libifd_remsim_client_la_LIBADD = $(OSMOABIS_LIBS) \
+ $(OSMONETIF_LIBS) \
$(OSMOGSM_LIBS) \
$(OSMOCORE_LIBS) \
$(top_builddir)/src/libosmo-rspro.la
@@ -41,6 +44,7 @@
osmo_remsim_client_st2_CPPFLAGS = -DUSB_SUPPORT -DSIMTRACE_SUPPORT
osmo_remsim_client_st2_CFLAGS = $(AM_CFLAGS)
osmo_remsim_client_st2_LDADD = $(OSMOABIS_LIBS) \
+ $(OSMONETIF_LIBS) \
$(OSMOGSM_LIBS) \
$(OSMOCORE_LIBS) \
$(OSMOUSB_LIBS) $(OSMOSIMTRACE2_LIBS) \
diff --git a/src/rspro_client_fsm.c b/src/rspro_client_fsm.c
index 351c642..45a8e99 100644
--- a/src/rspro_client_fsm.c
+++ b/src/rspro_client_fsm.c
@@ -28,9 +28,9 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/fsm.h>
-
-#include <osmocom/abis/ipa.h>
#include <osmocom/gsm/protocol/ipaccess.h>
+#include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>

#include "debug.h"
#include "asn1c_helpers.h"
@@ -73,15 +73,15 @@
* remsim-bankd for their RSPRO control connection to remsim-server.
***********************************************************************/

-static void push_and_send(struct ipa_client_conn *ipa, struct msgb *msg_tx)
+static void push_and_send(struct osmo_stream_cli *cli, struct msgb *msg_tx)
{
ipa_prepend_header_ext(msg_tx, IPAC_PROTO_EXT_RSPRO);
ipa_prepend_header(msg_tx, IPAC_PROTO_OSMO);
- ipa_client_conn_send(ipa, msg_tx);
+ osmo_stream_cli_send(cli, msg_tx);
/* msg_tx is now queued and will be freed. */
}

-static int ipa_client_conn_send_rspro(struct ipa_client_conn *ipa, RsproPDU_t *rspro)
+static int cli_conn_send_rspro(struct osmo_stream_cli *cli, RsproPDU_t *rspro)
{
struct msgb *msg = rspro_enc_msg(rspro);
if (!msg) {
@@ -90,14 +90,14 @@
ASN_STRUCT_FREE(asn_DEF_RsproPDU, rspro);
return -1;
}
- push_and_send(ipa, msg);
+ push_and_send(cli, msg);
return 0;
}

static int _server_conn_send_rspro(struct rspro_server_conn *srvc, RsproPDU_t *rspro)
{
LOGPFSML(srvc->fi, LOGL_DEBUG, "Tx RSPRO %s\n", rspro_msgt_name(rspro));
- return ipa_client_conn_send_rspro(srvc->conn, rspro);
+ return cli_conn_send_rspro(srvc->conn, rspro);
}

int server_conn_send_rspro(struct rspro_server_conn *srvc, RsproPDU_t *rspro)
@@ -139,35 +139,102 @@
{ 0, NULL }
};

-static void srvc_updown_cb(struct ipa_client_conn *conn, int up)
+static int srvc_connect_cb(struct osmo_stream_cli *cli)
{
- struct rspro_server_conn *srvc = conn->data;
-
- LOGPFSML(srvc->fi, LOGL_NOTICE, "RSPRO link to %s:%d %s\n",
- conn->addr, conn->port, up ? "UP" : "DOWN");
-
- osmo_fsm_inst_dispatch(srvc->fi, up ? SRVC_E_TCP_UP: SRVC_E_TCP_DOWN, 0);
+ struct rspro_server_conn *srvc = osmo_stream_cli_get_data(cli);
+ LOGPFSML(srvc->fi, LOGL_NOTICE, "RSPRO link to %s:%d UP\n", srvc->server_host, srvc->server_port);
+ osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_TCP_UP, 0);
+ return 0;
}

-static int srvc_read_cb(struct ipa_client_conn *conn, struct msgb *msg)
+static int srvc_disconnect_cb(struct osmo_stream_cli *cli)
{
- struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
- struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg);
- struct rspro_server_conn *srvc = conn->data;
+ struct rspro_server_conn *srvc = osmo_stream_cli_get_data(cli);
+
+ LOGPFSML(srvc->fi, LOGL_NOTICE, "RSPRO link to %s:%d DOWN\n", srvc->server_host, srvc->server_port);
+ osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_TCP_DOWN, 0);
+ return 0;
+}
+
+static struct msgb *ipa_bts_id_ack(void)
+{
+ struct msgb *nmsg2;
+ nmsg2 = ipa_msg_alloc(0);
+ if (!nmsg2)
+ return NULL;
+ msgb_v_put(nmsg2, IPAC_MSGT_ID_ACK);
+ ipa_prepend_header(nmsg2, IPAC_PROTO_IPACCESS);
+ return nmsg2;
+}
+
+static int _ipaccess_bts_handle_ccm(struct osmo_stream_cli *cli, struct rspro_server_conn *srvc, struct msgb *msg)
+{
+ /* special handling for IPA CCM. */
+ if (osmo_ipa_msgb_cb_proto(msg) != IPAC_PROTO_IPACCESS)
+ return 0;
+
+ int ret = 0;
+ const uint8_t *data = msgb_l2(msg);
+ int len = msgb_l2len(msg);
+ OSMO_ASSERT(len > 0);
+ uint8_t msg_type = *data;
+
+ /* ping, pong and acknowledgment cases. */
+ struct osmo_fd tmp_ofd = { .fd = osmo_stream_cli_get_fd(cli) };
+ OSMO_ASSERT(tmp_ofd.fd >= 0);
+ ret = ipa_ccm_rcvmsg_bts_base(msg, &tmp_ofd);
+ if (ret < 0)
+ goto err;
+
+ /* this is a request for identification from the BSC. */
+ if (msg_type == IPAC_MSGT_ID_GET) {
+ struct msgb *rmsg;
+ LOGPFSML(srvc->fi, LOGL_NOTICE, "received ID_GET for unit ID %u/%u/%u\n",
+ srvc->ipa_dev.site_id, srvc->ipa_dev.bts_id, srvc->ipa_dev.trx_id);
+ rmsg = ipa_ccm_make_id_resp_from_req(&srvc->ipa_dev, data + 1, len - 1);
+ if (!rmsg) {
+ LOGPFSML(srvc->fi, LOGL_ERROR, "Failed parsing ID_GET message.\n");
+ goto err;
+ }
+ osmo_stream_cli_send(cli, rmsg);
+
+ /* send ID_ACK. */
+ rmsg = ipa_bts_id_ack();
+ if (!rmsg) {
+ LOGPFSML(srvc->fi, LOGL_ERROR, "Failed allocating ID_ACK message.\n");
+ goto err;
+ }
+ osmo_stream_cli_send(cli, rmsg);
+ }
+ return 1;
+
+err:
+ return -1;
+}
+
+static int srvc_read_cb(struct osmo_stream_cli *cli, int res, struct msgb *msg)
+{
+ enum ipaccess_proto ipa_proto = osmo_ipa_msgb_cb_proto(msg);
+ struct rspro_server_conn *srvc = osmo_stream_cli_get_data(cli);
RsproPDU_t *pdu;
int rc;

- if (msgb_length(msg) < sizeof(*hh))
- goto invalid;
- msg->l2h = &hh->data[0];
- switch (hh->proto) {
+ if (res <= 0) {
+ LOGPFSML(srvc->fi, LOGL_NOTICE, "failed reading from socket: %d\n", res);
+ goto err;
+ }
+
+
+ switch (ipa_proto) {
case IPAC_PROTO_IPACCESS:
- rc = ipaccess_bts_handle_ccm(srvc->conn, &srvc->ipa_dev, msg);
+ OSMO_ASSERT(msgb_l2len(msg) > 0);
+ uint8_t msg_type = msg->l2h[0];
+ rc = _ipaccess_bts_handle_ccm(srvc->conn, srvc, msg);
if (rc < 0) {
msgb_free(msg);
break;
}
- switch (hh->data[0]) {
+ switch (msg_type) {
case IPAC_MSGT_PONG:
ipa_keepalive_fsm_pong_received(srvc->keepalive_fi);
rc = 0;
@@ -177,10 +244,7 @@
}
break;
case IPAC_PROTO_OSMO:
- if (!he || msgb_l2len(msg) < sizeof(*he))
- goto invalid;
- msg->l2h = &he->data[0];
- switch (he->proto) {
+ switch (osmo_ipa_msgb_cb_proto_ext(msg)) {
case IPAC_PROTO_EXT_RSPRO:
LOGPFSML(srvc->fi, LOGL_DEBUG, "Received RSPRO %s\n", msgb_hexdump(msg));
pdu = rspro_dec_msg(msg);
@@ -192,20 +256,20 @@
ASN_STRUCT_FREE(asn_DEF_RsproPDU, pdu);
break;
default:
- goto invalid;
+ goto err;
}
break;
default:
- goto invalid;
+ goto err;
}

msgb_free(msg);
return rc;

-invalid:
- LOGPFSML(srvc->fi, LOGL_ERROR, "Error decoding PDU\n");
+err:
msgb_free(msg);
- return -1;
+ osmo_stream_cli_close(cli);
+ return -EBADF;
}

static const struct ipa_keepalive_params ka_params = {
@@ -294,8 +358,7 @@
if (res != ResultCode_ok) {
LOGPFSML(fi, LOGL_ERROR, "Rx RSPRO connectClientRes(result=%s), closing\n",
asn_enum_name(&asn_DEF_ResultCode, res));
- ipa_client_conn_close(srvc->conn);
- osmo_fsm_inst_dispatch(fi, SRVC_E_TCP_DOWN, NULL);
+ osmo_stream_cli_close(srvc->conn);
} else {
/* somehow notify the main code? */
osmo_fsm_inst_state_chg(fi, SRVC_ST_CONNECTED, 0, 0);
@@ -360,8 +423,7 @@

if (srvc->conn) {
LOGPFSML(fi, LOGL_INFO, "Destroying existing connection to server\n");
- ipa_client_conn_close(srvc->conn);
- ipa_client_conn_destroy(srvc->conn);
+ osmo_stream_cli_destroy(srvc->conn);
srvc->conn = NULL;
}

@@ -387,14 +449,28 @@

LOGPFSML(fi, LOGL_INFO, "Creating TCP connection to server at %s:%u\n",
srvc->server_host, srvc->server_port);
- srvc->conn = ipa_client_conn_create2(fi, NULL, 0, NULL, 0, srvc->server_host, srvc->server_port,
- srvc_updown_cb, srvc_read_cb, NULL, srvc);
+ srvc->conn = osmo_stream_cli_create(fi);
if (!srvc->conn) {
LOGPFSML(fi, LOGL_FATAL, "Unable to create socket: %s\n", strerror(errno));
exit(1);
}

- srvc->keepalive_fi = ipa_client_conn_alloc_keepalive_fsm(srvc->conn, &ka_params, fi->id);
+ osmo_stream_cli_set_name(srvc->conn, osmo_fsm_inst_name(fi));
+ osmo_stream_cli_set_data(srvc->conn, srvc);
+ osmo_stream_cli_set_addr(srvc->conn, srvc->server_host);
+ osmo_stream_cli_set_port(srvc->conn, srvc->server_port);
+ osmo_stream_cli_set_proto(srvc->conn, IPPROTO_TCP);
+ osmo_stream_cli_set_nodelay(srvc->conn, true);
+
+ /* Reconnect is handled by upper layers: */
+ osmo_stream_cli_set_reconnect_timeout(srvc->conn, -1);
+
+ osmo_stream_cli_set_segmentation_cb(srvc->conn, osmo_ipa_segmentation_cb);
+ osmo_stream_cli_set_connect_cb(srvc->conn, srvc_connect_cb);
+ osmo_stream_cli_set_disconnect_cb(srvc->conn, srvc_disconnect_cb);
+ osmo_stream_cli_set_read_cb2(srvc->conn, srvc_read_cb);
+
+ srvc->keepalive_fi = ipa_generic_conn_alloc_keepalive_fsm(srvc->conn, srvc->conn, &ka_params, fi->id);
if (!srvc->keepalive_fi) {
LOGPFSM(fi, "Unable to create keepalive FSM\n");
exit(1);
@@ -404,7 +480,7 @@
osmo_fsm_inst_change_parent(srvc->keepalive_fi, srvc->fi, SRVC_E_KA_TERMINATED);

/* Attempt to connect TCP socket */
- rc = ipa_client_conn_open(srvc->conn);
+ rc = osmo_stream_cli_open(srvc->conn);
if (rc < 0) {
LOGPFSML(fi, LOGL_FATAL, "Unable to connect RSPRO to %s:%u - %s\n",
srvc->server_host, srvc->server_port, strerror(errno));
@@ -446,8 +522,7 @@
}
if (srvc->conn) {
LOGPFSML(fi, LOGL_INFO, "Destroying existing connection to server\n");
- ipa_client_conn_close(srvc->conn);
- ipa_client_conn_destroy(srvc->conn);
+ osmo_stream_cli_destroy(srvc->conn);
srvc->conn = NULL;
}
osmo_fsm_inst_state_chg(fi, SRVC_ST_INIT, 0, 0);
@@ -472,8 +547,7 @@
break;
case 1:
/* no ClientConnectRes received: disconnect + reconnect */
- ipa_client_conn_close(srvc->conn);
- osmo_fsm_inst_dispatch(fi, SRVC_E_TCP_DOWN, NULL);
+ osmo_stream_cli_close(srvc->conn);
break;
default:
OSMO_ASSERT(0);
diff --git a/src/rspro_client_fsm.h b/src/rspro_client_fsm.h
index adf56af..a8a4965 100644
--- a/src/rspro_client_fsm.h
+++ b/src/rspro_client_fsm.h
@@ -18,12 +18,10 @@
SRVC_E_RSPRO_TX /* transmit a RSPRO PDU to the peer */
};

-struct ipa_client_conn;
-
struct osmo_rspro_client {
const char *unit_name;

- struct ipa_client_conn *link;
+ struct osmo_stream_cli *link;
osmo_rspro_client_read_cb_t read_cb;
void *data;

@@ -36,7 +34,7 @@
/* representing a client-side connection to a RSPRO server */
struct rspro_server_conn {
/* state */
- struct ipa_client_conn *conn;
+ struct osmo_stream_cli *conn;
struct osmo_fsm_inst *fi;
struct osmo_fsm_inst *keepalive_fi;
int (*handle_rx)(struct rspro_server_conn *conn, const RsproPDU_t *pdu);
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index b51ea94..eaf89bc 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -2,6 +2,7 @@
AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src \
-I$(top_srcdir)/include/osmocom/rspro \
$(OSMOABIS_CFLAGS) \
+ $(OSMONETIF_CFLAGS) \
$(OSMOGSM_CFLAGS) \
$(OSMOCORE_CFLAGS) \
$(ULFIUS_CFLAGS) \
@@ -15,6 +16,7 @@
osmo_remsim_server_SOURCES = remsim_server.c rspro_server.c rest_api.c \
../rspro_util.c ../slotmap.c ../debug.c
osmo_remsim_server_LDADD = $(OSMOABIS_LIBS) \
+ $(OSMONETIF_LIBS) \
$(OSMOGSM_LIBS) \
$(OSMOCORE_LIBS) \
$(ULFIUS_LIBS) \

To view, visit change 39023. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-remsim
Gerrit-Branch: master
Gerrit-Change-Id: I9cba48bf8eba85215acef70eda7bcf8ec13ea49a
Gerrit-Change-Number: 39023
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>