pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-abis/+/38927?usp=email )
Change subject: ipaccess: Convert BTS OML & RSL link to use stream_cli ......................................................................
ipaccess: Convert BTS OML & RSL link to use stream_cli
This in turn allows running BTS Abis interfaces through io-uring backend, which should provide performance improvements when used.
Related: SYS#7063 Related: OS#5756 Depends: libosmo-netif.git Change-Id I952938474fa2780bf3c906cbdffb2d024b03c1b7 Depends: libosmocore.git Change-Id 8bcfe62521a977a05b2498efe906d6db6e2be4e8 Change-Id: I35c214fbe930c695a1475d8b4bc3dc44dff83eea --- M TODO-RELEASE M libosmoabis.pc.in M src/Makefile.am M src/input/ipaccess.c 4 files changed, 355 insertions(+), 148 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/27/38927/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index 06f605a..987d77e 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -9,3 +9,5 @@ #library what description / commit summary line libosmotrau struct osmo_trau2rtp_state extended (ABI break) libosmo-netif >1.5.0 New dependency +libosmo-netif >1.5.0 use osmo_stream_cli_set_priority(), osmo_stream_cli_set_ip_dscp() +libosmocore >1.10.0 bigger iofd tx_queue.max_length default value diff --git a/libosmoabis.pc.in b/libosmoabis.pc.in index da113fc..be727a6 100644 --- a/libosmoabis.pc.in +++ b/libosmoabis.pc.in @@ -9,3 +9,4 @@ Libs: -L${libdir} -losmoabis Cflags: -I${includedir}/ Requires: libosmocore +Requires.private: libosmo-netif diff --git a/src/Makefile.am b/src/Makefile.am index 3a6b83d..724dbd5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,9 +5,21 @@ TRAU_LIBVERSION=10:0:0
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) -AM_CFLAGS= -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOE1D_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(COVERAGE_CFLAGS) +AM_CFLAGS= -Wall \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOE1D_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) AM_LDFLAGS = $(COVERAGE_LDFLAGS) -COMMONLIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOE1D_LIBS) # libosmocodec not [yet] needed here +COMMONLIBS = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOE1D_LIBS) # libosmocodec not [yet] needed here
lib_LTLIBRARIES = libosmoabis.la libosmotrau.la
@@ -15,7 +27,7 @@ -version-info $(ABIS_LIBVERSION) \ -no-undefined \ $(NULL) -libosmoabis_la_LIBADD = $(COMMONLIBS) +libosmoabis_la_LIBADD = $(LIBOSMONETIF_LIBS) $(COMMONLIBS) libosmoabis_la_SOURCES = init.c \ e1_input.c \ e1_input_vty.c \ diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index f322f0f..accdbe4 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -52,6 +52,8 @@ #include <osmocom/gsm/ipa.h> #include <osmocom/core/stats_tcp.h> #include <osmocom/core/fsm.h> +#include <osmocom/netif/stream.h> +#include <osmocom/netif/ipa.h>
/* global parameters of IPA input driver */ struct ipa_pars g_e1inp_ipaccess_pars; @@ -64,6 +66,11 @@ #define DEFAULT_TCP_KEEPALIVE_INTERVAL 3 #define DEFAULT_TCP_KEEPALIVE_RETRY_COUNT 10
+struct ipaccess_line { + bool line_already_initialized; + struct osmo_stream_cli *ipa_cli[NUM_E1_TS]; /* 0=OML, 1+N=TRX_N */ +}; + static inline struct e1inp_ts *ipaccess_line_ts(struct osmo_fd *bfd, struct e1inp_line *line) { if (bfd->priv_nr == E1INP_SIGN_OML) @@ -171,25 +178,27 @@ }
static void ipa_bts_keepalive_write_client_cb(struct osmo_fsm_inst *fi, void *conn, struct msgb *msg) { - struct ipa_client_conn *link = (struct ipa_client_conn *)conn; - int ret = 0; - - ret = ipa_send(link->ofd->fd, msg->data, msg->len); - if (ret != msg->len) { - LOGP(DLINP, LOGL_ERROR, "cannot send message. Reason: %s\n", strerror(errno)); - } - msgb_free(msg); + struct osmo_stream_cli *cli = (struct osmo_stream_cli *)conn; + osmo_stream_cli_send(cli, msg); }
-static void update_fd_settings(struct e1inp_line *line, int fd); -static void ipaccess_bts_updown_cb(struct ipa_client_conn *link, int up); +static void _ipaccess_bts_down_cb(struct osmo_stream_cli *cli) +{ + struct e1inp_ts *e1i_ts = osmo_stream_cli_get_data(cli); + struct e1inp_line *line = e1i_ts->line; + + ipaccess_keepalive_fsm_cleanup(e1i_ts); + if (line->ops->sign_link_down) + line->ops->sign_link_down(line); +}
static int ipa_bts_keepalive_timeout_cb(struct osmo_fsm_inst *fi, void *conn) { - ipaccess_bts_updown_cb(conn, false); + struct osmo_stream_cli *cli = (struct osmo_stream_cli *)conn; + _ipaccess_bts_down_cb(cli); return 1; }
-static void ipaccess_bts_keepalive_fsm_alloc(struct e1inp_ts *e1i_ts, struct ipa_client_conn *client, const char *id) +static void ipaccess_bts_keepalive_fsm_alloc(struct e1inp_ts *e1i_ts, struct osmo_stream_cli *client, const char *id) { struct e1inp_line *line = e1i_ts->line; struct osmo_fsm_inst *ka_fsm; @@ -198,7 +207,7 @@ if (!line->ipa_kap) return;
- ka_fsm = ipa_client_conn_alloc_keepalive_fsm(client, line->ipa_kap, id); + ka_fsm = ipa_generic_conn_alloc_keepalive_fsm(client, client, line->ipa_kap, id); e1i_ts->driver.ipaccess.ka_fsm = ka_fsm; if (!ka_fsm) { LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "Failed to allocate IPA keepalive FSM\n"); @@ -209,6 +218,38 @@ ipa_keepalive_fsm_set_send_cb(ka_fsm, ipa_bts_keepalive_write_client_cb); }
+/* See how ts->num is assigned in e1inp_line_create: line->ts[i].num = i+1; +* As per e1inp_line_ipa_oml_ts(), first TS in line (ts->num=1) is OML. +* As per e1inp_line_ipa_rsl_ts(), second TS in line (ts->num>=2) is RSL. +*/ +static inline enum e1inp_sign_type ipaccess_e1i_ts_sign_type(const struct e1inp_ts *e1i_ts) +{ + OSMO_ASSERT(e1i_ts->num != 0); + if (e1i_ts->num == 1) + return E1INP_SIGN_OML; + return E1INP_SIGN_RSL; +} + +static inline unsigned int ipaccess_e1i_ts_trx_nr(const struct e1inp_ts *e1i_ts) +{ + enum e1inp_sign_type sign_type = ipaccess_e1i_ts_sign_type(e1i_ts); + if (sign_type == E1INP_SIGN_OML) + return 0; /* OML uses trx_nr=0 */ + OSMO_ASSERT(sign_type == E1INP_SIGN_RSL); + /* e1i_ts->num >= 2: */ + return e1i_ts->num - 2; +} + +static inline struct osmo_stream_cli *ipaccess_bts_e1i_ts_stream_cli(const struct e1inp_ts *e1i_ts) +{ + OSMO_ASSERT(e1i_ts); + struct ipaccess_line *il = e1i_ts->line->driver_data; + OSMO_ASSERT(il); + struct osmo_stream_cli *cli = il->ipa_cli[e1i_ts->num - 1]; + OSMO_ASSERT(cli); + return cli; +} + /* Returns -1 on error, and 0 or 1 on success. If -1 or 1 is returned, line has * been released and should not be used anymore by the caller. */ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg, @@ -431,19 +472,13 @@ return -EBADF; }
-static int ts_want_write(struct e1inp_ts *e1i_ts) -{ - osmo_fd_write_enable(&e1i_ts->driver.ipaccess.fd); - - return 0; -} - static void ipaccess_close(struct e1inp_sign_link *sign_link) { struct e1inp_ts *e1i_ts = sign_link->ts; struct osmo_fd *bfd = &e1i_ts->driver.ipaccess.fd; struct e1inp_line *line = e1i_ts->line; struct osmo_fsm_inst *ka_fsm = e1i_ts->driver.ipaccess.ka_fsm; + struct osmo_stream_cli *cli;
/* depending on caller the fsm might be dead */ if (ka_fsm) @@ -451,16 +486,29 @@
e1inp_int_snd_event(e1i_ts, sign_link, S_L_INP_TEI_DN); /* the first e1inp_sign_link_destroy call closes the socket. */ - if (bfd->fd != -1) { - osmo_fd_unregister(bfd); - close(bfd->fd); - bfd->fd = -1; - /* If The bfd holds a reference to e1inp_line in ->data (BSC - * accepted() sockets), then release it */ - if (bfd->data == line) { - bfd->data = NULL; - e1inp_line_put2(line, "ipa_bfd"); + + OSMO_ASSERT(line->ops); + switch (line->ops->cfg.ipa.role) { + case E1INP_LINE_R_BTS: + cli = ipaccess_bts_e1i_ts_stream_cli(e1i_ts); + OSMO_ASSERT(cli); /* May be that it is null, like bfd=-1 in BSC case? then simply skip closing it. */ + osmo_stream_cli_close(cli); + bfd->fd = -1; /* Compatibility with older implementations */ + break; + case E1INP_LINE_R_BSC: + default: + if (bfd->fd != -1) { + osmo_fd_unregister(bfd); + close(bfd->fd); + bfd->fd = -1; + /* If The bfd holds a reference to e1inp_line in ->data (BSC + * accepted() sockets), then release it */ + if (bfd->data == line) { + bfd->data = NULL; + e1inp_line_put2(line, "ipa_bfd"); + } } + break; } }
@@ -475,6 +523,69 @@ return false; }
+static int ipaccess_bts_send_msg(struct e1inp_ts *e1i_ts, + struct e1inp_sign_link *sign_link, + struct osmo_stream_cli *cli, + struct msgb *msg) +{ + switch (sign_link->type) { + case E1INP_SIGN_OML: + case E1INP_SIGN_RSL: + case E1INP_SIGN_OSMO: + break; + default: + msgb_free(msg); + return -EINVAL; + } + + msg->l2h = msg->data; + ipa_prepend_header(msg, sign_link->tei); + + LOGPITS(e1i_ts, DLMI, LOGL_DEBUG, "TX: %s\n", osmo_hexdump(msg->l2h, msgb_l2len(msg))); + osmo_stream_cli_send(cli, msg); + return 0; +} + +/* msg was enqueued in sign_link->tx_list. + * Pop it from that list, submit it to osmo_stream_cli. */ +static int ipaccess_bts_write_cb(struct e1inp_ts *e1i_ts) +{ + int rc = 0; + struct osmo_stream_cli *cli = ipaccess_bts_e1i_ts_stream_cli(e1i_ts); + + /* get the next msg for this timeslot */ + while (e1i_ts_has_pending_tx_msgs(e1i_ts)) { + struct e1inp_sign_link *sign_link = NULL; + struct msgb *msg; + msg = e1inp_tx_ts(e1i_ts, &sign_link); + rc |= ipaccess_bts_send_msg(e1i_ts, sign_link, cli, msg); + } + return rc; +} + +static int ts_want_write(struct e1inp_ts *e1i_ts) +{ + enum e1inp_line_role role = E1INP_LINE_R_NONE; + /* osmo-bts handover_test crashes here because has ops = NULL (doesn't + * call e1inp_line_bind_ops())... keep old behavior compatible. */ + OSMO_ASSERT(e1i_ts->line); + if (e1i_ts->line->ops) + role = e1i_ts->line->ops->cfg.ipa.role; + + switch (role) { + case E1INP_LINE_R_BTS: + /* msg was enqueued in sign_link->tx_list. + * Pop it from that list, submit it to osmo_stream_cli: */ + return ipaccess_bts_write_cb(e1i_ts); + case E1INP_LINE_R_NONE: + case E1INP_LINE_R_BSC: + default: + osmo_fd_write_enable(&e1i_ts->driver.ipaccess.fd); + /* ipaccess_fd_cb will be called from main loop and tx the msgb. */ + return 0; + } +} + static void timeout_ts1_write(void *data) { struct e1inp_ts *e1i_ts = (struct e1inp_ts *)data; @@ -554,12 +665,6 @@ return __handle_ts1_write(bfd, line); }
-static int ipaccess_bts_write_cb(struct ipa_client_conn *link) -{ - struct e1inp_line *line = link->line; - - return __handle_ts1_write(link->ofd, line); -}
/* callback from select.c in case one of the fd's can be read/written */ int ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what) @@ -742,27 +847,6 @@ return ret; }
-static void ipaccess_bts_updown_cb(struct ipa_client_conn *link, int up) -{ - struct e1inp_line *line = link->line; - struct e1inp_ts *e1i_ts = ipaccess_line_ts(link->ofd, line); - - if (up) { - struct osmo_fsm_inst *ka_fsm = e1i_ts->driver.ipaccess.ka_fsm; - - update_fd_settings(line, link->ofd->fd); - if (ka_fsm && line->ipa_kap) - ipa_keepalive_fsm_start(ka_fsm); - return; - } - - ipaccess_keepalive_fsm_cleanup(e1i_ts); - if (line->ops->sign_link_down) - line->ops->sign_link_down(line); -} - -/* handle incoming message to BTS, check if it is an IPA CCM, and if yes, - * handle it accordingly (PING/PONG/ID_REQ/ID_RESP/ID_ACK) */ int ipaccess_bts_handle_ccm(struct ipa_client_conn *link, struct ipaccess_unit *dev, struct msgb *msg) { @@ -835,41 +919,121 @@ return -1; }
-static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg) +static struct msgb *ipa_bts_id_ack(void) { - struct ipaccess_head *hh = (struct ipaccess_head *) msg->data; - struct e1inp_ts *e1i_ts = NULL; - struct e1inp_sign_link *sign_link; - uint8_t msg_type = *(msg->l2h); + struct msgb *nmsg2; + nmsg2 = ipa_msg_alloc(0); + if (!nmsg2) + return NULL; + *msgb_put(nmsg2, 1) = IPAC_MSGT_ID_ACK; + ipa_prepend_header(nmsg2, IPAC_PROTO_IPACCESS); + return nmsg2; +} + +/* Same as ipaccess_bts_handle_ccm(), but using an osmo_stream_cli as backend + * instead of ipa_client_conn. + * The old ipaccess_bts_handle_ccm() needs to be kept as it's a public API. */ +static int _ipaccess_bts_handle_ccm(struct osmo_stream_cli *cli, + struct ipaccess_unit *dev, struct msgb *msg) +{ + /* special handling for IPA CCM. */ + if (osmo_ipa_msgb_cb_proto(msg) != IPAC_PROTO_IPACCESS) + return 0; + int ret = 0; + uint8_t *data = msgb_l2(msg); + int len = msgb_l2len(msg); + OSMO_ASSERT(len > 0); + uint8_t msg_type = *data; + struct e1inp_ts *e1i_ts = osmo_stream_cli_get_data(cli); + /* line might not exist if != bsc||bts */ + struct e1inp_line *line = e1i_ts->line; + + /* peek the pong for our keepalive fsm */ + if (line && msg_type == IPAC_MSGT_PONG) { + struct osmo_fsm_inst *ka_fsm = e1i_ts->driver.ipaccess.ka_fsm; + ipa_keepalive_fsm_pong_received(ka_fsm); + } + + /* ping, pong and acknowledgment cases. */ + struct osmo_fd tmp_ofd = { .fd = osmo_stream_cli_get_fd(cli) }; + 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; + /* The ipaccess_unit dev holds generic identity for the whole + * line, hence no trx_id. Patch ipaccess_unit during call to + * ipa_ccm_make_id_resp_from_req() to identify this TRX: */ + int store_trx_nr = dev->trx_id; + dev->trx_id = ipaccess_e1i_ts_trx_nr(e1i_ts); + LOGP(DLINP, LOGL_NOTICE, "received ID_GET for unit ID %u/%u/%u\n", + dev->site_id, dev->bts_id, dev->trx_id); + rmsg = ipa_ccm_make_id_resp_from_req(dev, data + 1, len - 1); + dev->trx_id = store_trx_nr; + if (!rmsg) { + LOGP(DLINP, 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) { + LOGP(DLINP, LOGL_ERROR, "Failed allocating ID_ACK message.\n"); + goto err; + } + osmo_stream_cli_send(cli, rmsg); + } + return 1; + +err: + return -1; +} + +static int ipaccess_bts_read_cb(struct osmo_stream_cli *cli, int res, struct msgb *msg) +{ + enum ipaccess_proto ipa_proto = osmo_ipa_msgb_cb_proto(msg); + struct e1inp_ts *e1i_ts = osmo_stream_cli_get_data(cli); + struct e1inp_line *line = e1i_ts->line; + struct e1inp_sign_link *sign_link; + int ret; + + if (res <= 0) { + LOGPITS(e1i_ts, DLINP, LOGL_NOTICE, "failed reading from socket: %d\n", res); + goto err; + }
/* special handling for IPA CCM. */ - if (hh->proto == IPAC_PROTO_IPACCESS) { + if (ipa_proto == IPAC_PROTO_IPACCESS) { + uint8_t msg_type = *(msg->l2h); /* this is a request for identification from the BSC. */ if (msg_type == IPAC_MSGT_ID_GET) { - if (!link->line->ops->sign_link_up) { - LOGP(DLINP, LOGL_ERROR, - "Unable to set signal link, " - "closing socket.\n"); + if (!e1i_ts->line->ops->sign_link_up) { + LOGPITS(e1i_ts, DLINP, LOGL_NOTICE, + "Unable to set signal link, closing socket.\n"); goto err; } } }
/* core CCM handling */ - ret = ipaccess_bts_handle_ccm(link, link->line->ops->cfg.ipa.dev, msg); + ret = _ipaccess_bts_handle_ccm(cli, line->ops->cfg.ipa.dev, msg); if (ret < 0) goto err;
- if (ret == 1 && hh->proto == IPAC_PROTO_IPACCESS) { + if (ret == 1 && ipa_proto == IPAC_PROTO_IPACCESS) { + uint8_t msg_type = *(msg->l2h); if (msg_type == IPAC_MSGT_ID_GET) { - sign_link = link->line->ops->sign_link_up(link->line->ops->cfg.ipa.dev, - link->line, - link->ofd->priv_nr); + enum e1inp_sign_type sign_type = ipaccess_e1i_ts_sign_type(e1i_ts); + unsigned int trx_nr = ipaccess_e1i_ts_trx_nr(e1i_ts); + sign_link = line->ops->sign_link_up(line->ops->cfg.ipa.dev, + line, sign_type + trx_nr); if (sign_link == NULL) { - LOGP(DLINP, LOGL_ERROR, - "Unable to set signal link, " - "closing socket.\n"); + LOGPITS(e1i_ts, DLINP, LOGL_NOTICE, + "Unable to set signal link, closing socket.\n"); goto err; } } @@ -877,45 +1041,46 @@ return ret; }
- if (link->port == IPA_TCP_PORT_OML) - e1i_ts = e1inp_line_ipa_oml_ts(link->line); - else if (link->port == IPA_TCP_PORT_RSL) - e1i_ts = e1inp_line_ipa_rsl_ts(link->line, link->ofd->priv_nr - E1INP_SIGN_RSL); - OSMO_ASSERT(e1i_ts != NULL); - - if (e1i_ts->type == E1INP_TS_TYPE_NONE) { - LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "Signalling link not initialized. Discarding." - " port=%u msg_type=%u\n", link->port, msg_type); - goto err; - } - /* look up for some existing signaling link. */ - sign_link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0); + sign_link = e1inp_lookup_sign_link(e1i_ts, ipa_proto, 0); if (sign_link == NULL) { LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "no matching signalling link for " - "hh->proto=0x%02x\n", hh->proto); + "ipa_proto=0x%02x\n", ipa_proto); goto err; } msg->dst = sign_link;
/* XXX better use e1inp_ts_rx? */ - if (!link->line->ops->sign_link) { + if (!line->ops->sign_link) { LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "Fix your application, " "no action set for signalling messages.\n"); goto err; } - return link->line->ops->sign_link(msg); + return line->ops->sign_link(msg);
err: - ipa_client_conn_close(link); msgb_free(msg); + osmo_stream_cli_close(cli); return -EBADF; }
-struct ipaccess_line { - bool line_already_initialized; - struct ipa_client_conn *ipa_cli[NUM_E1_TS]; /* 0=OML, 1+N=TRX_N */ -}; +static int ipaccess_bts_connect_cb(struct osmo_stream_cli *cli) +{ + struct e1inp_ts *e1i_ts = osmo_stream_cli_get_data(cli); + struct e1inp_line *line = e1i_ts->line; + struct osmo_fsm_inst *ka_fsm = e1i_ts->driver.ipaccess.ka_fsm; + + update_fd_settings(line, osmo_stream_cli_get_fd(cli)); + if (ka_fsm && line->ipa_kap) + ipa_keepalive_fsm_start(ka_fsm); + return 0; +} + +static int ipaccess_bts_disconnect_cb(struct osmo_stream_cli *cli) +{ + _ipaccess_bts_down_cb(cli); + return 0; +}
static int ipaccess_line_update(struct e1inp_line *line) { @@ -974,45 +1139,57 @@ break; } case E1INP_LINE_R_BTS: { - struct ipa_client_conn *link; + struct osmo_stream_cli *cli; struct e1inp_ts *e1i_ts = e1inp_line_ipa_oml_ts(line); + char cli_name[128];
LOGPITS(e1i_ts, DLINP, LOGL_NOTICE, "enabling ipaccess BTS mode, " "OML connecting to %s:%u\n", line->ops->cfg.ipa.addr, IPA_TCP_PORT_OML);
/* Drop previous line */ if (il->ipa_cli[0]) { - ipa_client_conn_close(il->ipa_cli[0]); + osmo_stream_cli_close(il->ipa_cli[0]); ipaccess_keepalive_fsm_cleanup(e1i_ts); - ipa_client_conn_destroy(il->ipa_cli[0]); + e1i_ts->driver.ipaccess.fd.fd = -1; + osmo_stream_cli_destroy(il->ipa_cli[0]); il->ipa_cli[0] = NULL; }
- link = ipa_client_conn_create2(tall_ipa_ctx, - e1inp_line_ipa_oml_ts(line), - E1INP_SIGN_OML, - NULL, 0, - line->ops->cfg.ipa.addr, - IPA_TCP_PORT_OML, - ipaccess_bts_updown_cb, - ipaccess_bts_read_cb, - ipaccess_bts_write_cb, - line); - if (link == NULL) { - LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot create OML BTS link: %s\n", strerror(errno)); - return -ENOMEM; - } - link->dscp = g_e1inp_ipaccess_pars.oml.dscp; - link->priority = g_e1inp_ipaccess_pars.oml.priority; - if (ipa_client_conn_open2(link, line->connect_timeout) < 0) { + e1inp_ts_config_sign(e1i_ts, line); + + cli = osmo_stream_cli_create(tall_ipa_ctx); + OSMO_ASSERT(cli); + + snprintf(cli_name, sizeof(cli_name), "ts-%u-%u-oml", line->num, e1i_ts->num); + osmo_stream_cli_set_name(cli, cli_name); + osmo_stream_cli_set_data(cli, e1i_ts); + osmo_stream_cli_set_addr(cli, line->ops->cfg.ipa.addr); + osmo_stream_cli_set_port(cli, IPA_TCP_PORT_OML); + osmo_stream_cli_set_proto(cli, IPPROTO_TCP); + osmo_stream_cli_set_nodelay(cli, true); + osmo_stream_cli_set_priority(cli, g_e1inp_ipaccess_pars.oml.dscp); + osmo_stream_cli_set_ip_dscp(cli, g_e1inp_ipaccess_pars.oml.priority); + + /* Reconnect is handled by upper layers: */ + osmo_stream_cli_set_reconnect_timeout(cli, -1); + + osmo_stream_cli_set_segmentation_cb(cli, osmo_ipa_segmentation_cb); + osmo_stream_cli_set_connect_cb(cli, ipaccess_bts_connect_cb); + osmo_stream_cli_set_disconnect_cb(cli, ipaccess_bts_disconnect_cb); + osmo_stream_cli_set_read_cb2(cli, ipaccess_bts_read_cb); + + if (osmo_stream_cli_open(cli)) { LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot open OML BTS link: %s\n", strerror(errno)); - ipa_client_conn_close(link); - ipa_client_conn_destroy(link); + osmo_stream_cli_destroy(cli); return -EIO; }
- ipaccess_bts_keepalive_fsm_alloc(e1i_ts, link, "oml_bts_to_bsc"); - il->ipa_cli[0] = link; + /* Compatibility with older ofd based implementation. osmo-bts accesses + * this fd directly in get_signlink_remote_ip() and get_rsl_local_ip() */ + e1i_ts->driver.ipaccess.fd.fd = osmo_stream_cli_get_fd(cli); + + ipaccess_bts_keepalive_fsm_alloc(e1i_ts, cli, "oml_bts_to_bsc"); + il->ipa_cli[0] = cli; ret = 0; break; } @@ -1035,9 +1212,10 @@ const char *rem_addr, uint16_t rem_port, uint8_t trx_nr) { - struct ipa_client_conn *rsl_link; + struct osmo_stream_cli *cli; struct e1inp_ts *e1i_ts = e1inp_line_ipa_rsl_ts(line, trx_nr); struct ipaccess_line *il; + char cli_name[128]; int rc;
if (E1INP_SIGN_RSL+trx_nr-1 >= NUM_E1_TS) { @@ -1050,40 +1228,53 @@ if ((rc = e1inp_ipa_bts_rsl_close_n(line, trx_nr)) < 0) return rc;
+ e1inp_ts_config_sign(e1i_ts, line); + if (!line->driver_data) line->driver_data = talloc_zero(line, struct ipaccess_line); il = line->driver_data;
- rsl_link = ipa_client_conn_create2(tall_ipa_ctx, - e1inp_line_ipa_rsl_ts(line, trx_nr), - E1INP_SIGN_RSL+trx_nr, - NULL, 0, - rem_addr, rem_port, - ipaccess_bts_updown_cb, - ipaccess_bts_read_cb, - ipaccess_bts_write_cb, - line); - if (rsl_link == NULL) { - LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot create RSL BTS link: %s\n", strerror(errno)); - return -ENOMEM; - } - rsl_link->dscp = g_e1inp_ipaccess_pars.rsl.dscp; - rsl_link->priority = g_e1inp_ipaccess_pars.rsl.priority; - if (ipa_client_conn_open2(rsl_link, line->connect_timeout) < 0) { + cli = osmo_stream_cli_create(tall_ipa_ctx); + OSMO_ASSERT(cli); + + snprintf(cli_name, sizeof(cli_name), "ts-%u-%u-rsl-trx%u", + line->num, e1i_ts->num, trx_nr); + osmo_stream_cli_set_name(cli, cli_name); + osmo_stream_cli_set_data(cli, e1i_ts); + osmo_stream_cli_set_addr(cli, rem_addr); + osmo_stream_cli_set_port(cli, rem_port); + osmo_stream_cli_set_proto(cli, IPPROTO_TCP); + osmo_stream_cli_set_nodelay(cli, true); + osmo_stream_cli_set_priority(cli, g_e1inp_ipaccess_pars.rsl.dscp); + osmo_stream_cli_set_ip_dscp(cli, g_e1inp_ipaccess_pars.rsl.priority); + + /* Reconnect is handled by upper layers: */ + osmo_stream_cli_set_reconnect_timeout(cli, -1); + + osmo_stream_cli_set_segmentation_cb(cli, osmo_ipa_segmentation_cb); + osmo_stream_cli_set_connect_cb(cli, ipaccess_bts_connect_cb); + osmo_stream_cli_set_disconnect_cb(cli, ipaccess_bts_disconnect_cb); + osmo_stream_cli_set_read_cb2(cli, ipaccess_bts_read_cb); + + if (osmo_stream_cli_open(cli)) { LOGPITS(e1i_ts, DLINP, LOGL_ERROR, "cannot open RSL BTS link: %s\n", strerror(errno)); - ipa_client_conn_close(rsl_link); - ipa_client_conn_destroy(rsl_link); + osmo_stream_cli_destroy(cli); return -EIO; } - ipaccess_bts_keepalive_fsm_alloc(e1i_ts, rsl_link, "rsl_bts_to_bsc"); - il->ipa_cli[1 + trx_nr] = rsl_link; + + /* Compatibility with older ofd based implementation. osmo-bts accesses + * this fd directly in get_signlink_remote_ip() and get_rsl_local_ip() */ + e1i_ts->driver.ipaccess.fd.fd = osmo_stream_cli_get_fd(cli); + + ipaccess_bts_keepalive_fsm_alloc(e1i_ts, cli, "rsl_bts_to_bsc"); + il->ipa_cli[1 + trx_nr] = cli; return 0; }
/* Close the underlying IPA TCP socket of an RSL link */ int e1inp_ipa_bts_rsl_close_n(struct e1inp_line *line, uint8_t trx_nr) { - struct ipa_client_conn *conn; + struct osmo_stream_cli *cli; struct ipaccess_line *il; struct e1inp_ts *e1i_ts;
@@ -1098,11 +1289,12 @@
e1i_ts = e1inp_line_ipa_rsl_ts(line, trx_nr); ipaccess_keepalive_fsm_cleanup(e1i_ts); + /* Compatibility with older implementation: */ + e1i_ts->driver.ipaccess.fd.fd = -1;
- conn = il->ipa_cli[1 + trx_nr]; - if (conn != NULL) { - ipa_client_conn_close(conn); - ipa_client_conn_destroy(conn); + cli = il->ipa_cli[1 + trx_nr]; + if (cli != NULL) { + osmo_stream_cli_destroy(cli); il->ipa_cli[1 + trx_nr] = NULL; } return 0;