pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-remsim/+/39023?usp=email )
Change subject: WIP: rspro: use osmo_stream to handle IPA connection ......................................................................
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) \