Jolly has uploaded this change for review.

View Change

Fix support for HDLC/RAW type channels at mISDN.c

Change-Id: Ie9a2a3f6ae1ad7da1711b6ff2f0aeda39839a427
---
M include/osmocom/abis/e1_input.h
M src/input/misdn.c
2 files changed, 100 insertions(+), 4 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/46/30446/1
diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h
index 91a71e1..a466ef6 100644
--- a/include/osmocom/abis/e1_input.h
+++ b/include/osmocom/abis/e1_input.h
@@ -116,6 +116,8 @@
void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg);
/* queue of pending to-be-transmitted msgbs */
struct llist_head tx_queue;
+ /* flag to indicate that packet is not yet confirmed by mISDN */
+ int unconfirmed;
} hdlc;
struct {
struct osmo_i460_timeslot i460_ts;
diff --git a/src/input/misdn.c b/src/input/misdn.c
index 874b627..892ff3f 100644
--- a/src/input/misdn.c
+++ b/src/input/misdn.c
@@ -430,7 +430,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 +471,89 @@
return ret;
}

+/* write to a hdlc channel TS */
+static int handle_ts_hdlc_write(struct osmo_fd *bfd)
+{
+ 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;
+ struct mISDNhead *hh;
+ int ret;
+
+ osmo_fd_write_disable(bfd);
+
+ if (e1i_ts->hdlc.unconfirmed)
+ 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_DEBUG, "send returns %d instead of %d\n", ret, msg->len);
+ msgb_free(msg);
+
+ e1i_ts->hdlc.unconfirmed = 1;
+
+ return ret;
+}
+
+static int handle_ts_hdlc_read(struct osmo_fd *bfd)
+{
+ 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 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:
+ e1i_ts->hdlc.unconfirmed = 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 +584,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 +687,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 +739,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 +769,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 change 30446. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: Ie9a2a3f6ae1ad7da1711b6ff2f0aeda39839a427
Gerrit-Change-Number: 30446
Gerrit-PatchSet: 1
Gerrit-Owner: Jolly <andreas@eversberg.eu>
Gerrit-MessageType: newchange