laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/30446 )
Change subject: Fix support for HDLC/RAW type channels at mISDN.c ...................................................................... Fix support for HDLC/RAW type channels at mISDN.c Change-Id: Ie9a2a3f6ae1ad7da1711b6ff2f0aeda39839a427 --- M src/input/misdn.c 1 file changed, 102 insertions(+), 4 deletions(-) Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved diff --git a/src/input/misdn.c b/src/input/misdn.c index 874b627..5f6dd62 100644 --- a/src/input/misdn.c +++ b/src/input/misdn.c @@ -69,6 +69,7 @@ /*! \brief driver-specific data for \ref e1inp_line::driver_data */ struct misdn_line { int use_userspace_lapd; + int unconfirmed_ts[NUM_E1_TS]; int dummy_dchannel; }; @@ -430,7 +431,7 @@ struct e1inp_line *line = bfd->data; unsigned int ts_nr = bfd->priv_nr; struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; - struct msgb *msg = msgb_alloc(TSX_ALLOC_SIZE, "mISDN Tx RAW"); + struct msgb *msg = msgb_alloc(TSX_ALLOC_SIZE, "mISDN TS RAW"); struct mISDNhead *hh; int ret; @@ -471,6 +472,92 @@ return ret; } +/* write to a hdlc channel TS */ +static int handle_ts_hdlc_write(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + struct misdn_line *mline = line->driver_data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg; + struct mISDNhead *hh; + int ret; + + osmo_fd_write_disable(bfd); + + if (mline->unconfirmed_ts[ts_nr-1]) + return 0; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, NULL); + if (!msg) + return 0; + + LOGPITS(e1i_ts, DLMIB, LOGL_DEBUG, "HDLC CHAN TX: %s\n", osmo_hexdump(msg->data, msg->len)); + + hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh)); + hh->prim = PH_DATA_REQ; + hh->id = 0; + + ret = write(bfd->fd, msg->data, msg->len); + if (ret < msg->len) + LOGPITS(e1i_ts, DLINP, LOGL_NOTICE, "send returns %d instead of %d\n", ret, msg->len); + else + mline->unconfirmed_ts[ts_nr-1] = 1; + msgb_free(msg); + + + return ret; +} + +static int handle_ts_hdlc_read(struct osmo_fd *bfd) +{ + struct e1inp_line *line = bfd->data; + struct misdn_line *mline = line->driver_data; + unsigned int ts_nr = bfd->priv_nr; + struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; + struct msgb *msg = msgb_alloc(TSX_ALLOC_SIZE, "mISDN TS HDLC"); + struct mISDNhead *hh; + int ret; + + if (!msg) + return -ENOMEM; + + hh = (struct mISDNhead *) msg->data; + + ret = recv(bfd->fd, msg->data, TSX_ALLOC_SIZE, 0); + if (ret < 0) { + fprintf(stderr, "recvfrom error %s\n", strerror(errno)); + return ret; + } + + msgb_put(msg, ret); + + if (hh->prim != PH_CONTROL_IND) + LOGPITS(e1i_ts, DLMIB, LOGL_DEBUG, "<= HDLC CHAN len = %d, prim(0x%x) id(0x%x): %s\n", + ret, hh->prim, hh->id, get_value_string(prim_names, hh->prim)); + + switch (hh->prim) { + case PH_DATA_IND: + msg->l2h = msg->data + MISDN_HEADER_LEN; + LOGPITS(e1i_ts, DLMIB, LOGL_DEBUG, "HDLC CHAN RX: %s\n", + osmo_hexdump(msgb_l2(msg), ret - MISDN_HEADER_LEN)); + return e1inp_rx_ts(e1i_ts, msg, 0, 0); + case PH_ACTIVATE_IND: + break; + case PH_DATA_CNF: + mline->unconfirmed_ts[ts_nr-1] = 0; + osmo_fd_write_enable(bfd); + break; + default: + break; + } + /* FIXME: why do we free signalling msgs in the caller, and trau not? */ + msgb_free(msg); + + return ret; +} + /* callback from select.c in case one of the fd's can be read/written */ static int misdn_fd_cb(struct osmo_fd *bfd, unsigned int what) { @@ -501,6 +588,12 @@ * writeset, since it doesn't support poll() based * write flow control */ break; + case E1INP_TS_TYPE_HDLC: + if (what & OSMO_FD_READ) + rc = handle_ts_hdlc_read(bfd); + if (what & OSMO_FD_WRITE) + rc = handle_ts_hdlc_write(bfd); + break; default: fprintf(stderr, "unknown E1 TS type %u\n", e1i_ts->type); break; @@ -598,8 +691,9 @@ continue; break; case E1INP_TS_TYPE_HDLC: + /* TS 16 is the D-channel, so we use D-channel proto */ bfd->fd = socket(PF_ISDN, SOCK_DGRAM, - ISDN_P_B_HDLC); + (ts == 16) ? ISDN_P_NT_E1 : ISDN_P_B_HDLC); bfd->when = OSMO_FD_READ; break; case E1INP_TS_TYPE_SIGN: @@ -649,8 +743,10 @@ } break; case E1INP_TS_TYPE_HDLC: + case E1INP_TS_TYPE_RAW: case E1INP_TS_TYPE_TRAU: - addr.channel = ts; + /* TS 16 is D-channel, so we use channel 0 */ + addr.channel = (ts == 16) ? 0 : ts; break; default: LOGPITS(e1i_ts, DLMI, LOGL_ERROR, "unsupported E1 TS type: %u\n", e1i_ts->type); @@ -677,7 +773,9 @@ /* FIXME: only activate B-Channels once we start to * use them to conserve CPU power */ - if (e1i_ts->type == E1INP_TS_TYPE_TRAU) + if (e1i_ts->type == E1INP_TS_TYPE_HDLC + || e1i_ts->type == E1INP_TS_TYPE_RAW + || e1i_ts->type == E1INP_TS_TYPE_TRAU) activate_bchan(line, ts, 1); osmo_fd_setup(bfd, bfd->fd, bfd->when, misdn_fd_cb, line, ts); -- To view, visit https://gerrit.osmocom.org/c/libosmo-abis/+/30446 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Change-Id: Ie9a2a3f6ae1ad7da1711b6ff2f0aeda39839a427 Gerrit-Change-Number: 30446 Gerrit-PatchSet: 2 Gerrit-Owner: jolly <andr...@eversberg.eu> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: pespin <pes...@sysmocom.de> Gerrit-MessageType: merged