This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Harald Welte gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/1102 Add HDLC timeslot mode This is useful for protocols that use HDLC framing for signalling on E1 timeslots, but which don't use LAPD inside (our E1INP_TS_TYPE_SIGN). Examples are particularly a MTP2/MTP3 SS7 stack, like it is used on the A interfaces or on the core network interfaces of classic circuit-switched networks. Change-Id: I2d75801df4d7cbb8dad325f4d6689841f0196fa6 --- M include/osmocom/abis/e1_input.h M src/e1_input.c M src/input/dahdi.c M src/input/misdn.c 4 files changed, 110 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/02/1102/1 diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 7568f19..c99b133 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -65,9 +65,10 @@ E1INP_TS_TYPE_SIGN, E1INP_TS_TYPE_TRAU, E1INP_TS_TYPE_RAW, + E1INP_TS_TYPE_HDLC, }; const char *e1inp_tstype_name(enum e1inp_ts_type tp); -const struct value_string e1inp_ts_type_names[5]; +const struct value_string e1inp_ts_type_names[6]; /* A timeslot in the E1 interface */ struct e1inp_ts { @@ -101,6 +102,12 @@ /* queue of pending to-be-transmitted msgbs */ struct llist_head tx_queue; } raw; + struct { + /* call-back for every received frame */ + void (*recv_cb)(struct e1inp_ts *ts, struct msgb *msg); + /* queue of pending to-be-transmitted msgbs */ + struct llist_head tx_queue; + } hdlc; }; union { struct { @@ -252,6 +259,11 @@ void (*raw_recv_cb)(struct e1inp_ts *ts, struct msgb *msg)); +/* configure and initialize one timeslot dedicated to HDLC frames */ +int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line, + void (*hdlc_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)); + /* Receive a packet from the E1 driver */ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, uint8_t tei, uint8_t sapi); diff --git a/src/e1_input.c b/src/e1_input.c index 75ae36e..970bdb9 100644 --- a/src/e1_input.c +++ b/src/e1_input.c @@ -213,11 +213,12 @@ return get_value_string(e1inp_sign_type_names, tp); } -const struct value_string e1inp_ts_type_names[5] = { +const struct value_string e1inp_ts_type_names[6] = { { E1INP_TS_TYPE_NONE, "None" }, { E1INP_TS_TYPE_SIGN, "Signalling" }, { E1INP_TS_TYPE_TRAU, "TRAU" }, { E1INP_TS_TYPE_RAW, "RAW" }, + { E1INP_TS_TYPE_HDLC, "HDLC" }, { 0, NULL } }; @@ -311,6 +312,21 @@ ts->line = line; ts->raw.recv_cb = raw_recv_cb; INIT_LLIST_HEAD(&ts->raw.tx_queue); + + return 0; +} + +int e1inp_ts_config_hdlc(struct e1inp_ts *ts, struct e1inp_line *line, + void (*hdlc_recv_cb)(struct e1inp_ts *ts, + struct msgb *msg)) +{ + if (ts->type == E1INP_TS_TYPE_HDLC && ts->line && line) + return 0; + + ts->type = E1INP_TS_TYPE_HDLC; + ts->line = line; + ts->hdlc.recv_cb = hdlc_recv_cb; + INIT_LLIST_HEAD(&ts->hdlc.tx_queue); return 0; } @@ -550,6 +566,9 @@ case E1INP_TS_TYPE_RAW: ts->raw.recv_cb(ts, msg); break; + case E1INP_TS_TYPE_HDLC: + ts->hdlc.recv_cb(ts, msg); + break; default: ret = -EINVAL; LOGP(DLMI, LOGL_ERROR, "unknown TS type %u\n", ts->type); @@ -677,6 +696,10 @@ /* Get msgb from tx_queue */ msg = msgb_dequeue(&e1i_ts->raw.tx_queue); break; + case E1INP_TS_TYPE_HDLC: + /* Get msgb from tx_queue */ + msg = msgb_dequeue(&e1i_ts->hdlc.tx_queue); + break; default: LOGP(DLMI, LOGL_ERROR, "unsupported E1 TS type %u\n", e1i_ts->type); return NULL; diff --git a/src/input/dahdi.c b/src/input/dahdi.c index db00f5f..0945daa 100644 --- a/src/input/dahdi.c +++ b/src/input/dahdi.c @@ -259,6 +259,51 @@ return 0; } +static void handle_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; + int ret; + + /* get the next msg for this timeslot */ + msg = e1inp_tx_ts(e1i_ts, NULL); + if (!msg) + return; + + ret = write(bfd->fd, msg->data, msg->len + 2); + msgb_free(msg); + if (ret == -1) + handle_dahdi_exception(e1i_ts); + else if (ret < 0) + LOGP(DLMI, LOGL_NOTICE, "%s write failed %d\n", __func__, ret); +} + +static int handle_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(TS1_ALLOC_SIZE, "DAHDI HDLC Rx"); + int ret; + + if (!msg) + return -ENOMEM; + + ret = read(bfd->fd, msg->data, TS1_ALLOC_SIZE - 16); + if (ret == -1) + handle_dahdi_exception(e1i_ts); + else if (ret < 0) { + perror("read "); + } + msgb_put(msg, ret - 2); + if (ret <= 3) { + perror("read "); + } + + return e1inp_rx_ts(e1i_ts, msg, 0, 0); +} static int invertbits = 1; @@ -451,6 +496,14 @@ if (what & BSC_FD_WRITE) rc = handle_ts1_write(bfd); break; + case E1INP_TS_TYPE_HDLC: + if (what & BSC_FD_EXCEPT) + handle_dahdi_exception(e1i_ts); + if (what & BSC_FD_READ) + rc = handle_hdlc_read(bfd); + if (what & BSC_FD_WRITE) + handle_hdlc_write(bfd); + break; case E1INP_TS_TYPE_TRAU: if (what & BSC_FD_EXCEPT) handle_dahdi_exception(e1i_ts); @@ -620,6 +673,20 @@ dahdi_write_msg, bfd, e1inp_dlsap_up, e1i_ts, &lapd_profile_abis); break; + case E1INP_TS_TYPE_HDLC: + if (!bfd->fd) + bfd->fd = open(openstr, O_RDWR | O_NONBLOCK); + if (bfd->fd == -1) { + LOGP(DLINP, LOGL_ERROR, + "%s could not open %s %s\n", + __func__, openstr, strerror(errno)); + return -EIO; + } + bfd->when = BSC_FD_READ | BSC_FD_EXCEPT; + ret = dahdi_set_bufinfo(bfd->fd, 1); + if (ret < 0) + return ret; + break; case E1INP_TS_TYPE_TRAU: case E1INP_TS_TYPE_RAW: /* close/release LAPD instance, if any */ diff --git a/src/input/misdn.c b/src/input/misdn.c index 391cd18..f72b496 100644 --- a/src/input/misdn.c +++ b/src/input/misdn.c @@ -607,6 +607,11 @@ case E1INP_TS_TYPE_NONE: continue; break; + case E1INP_TS_TYPE_HDLC: + bfd->fd = socket(PF_ISDN, SOCK_DGRAM, + ISDN_P_B_HDLC); + bfd->when = BSC_FD_READ; + break; case E1INP_TS_TYPE_SIGN: if (mline->use_userspace_lapd) bfd->fd = socket(PF_ISDN, SOCK_DGRAM, @@ -650,6 +655,7 @@ addr.tei = GROUP_TEI; } break; + case E1INP_TS_TYPE_HDLC: case E1INP_TS_TYPE_TRAU: addr.channel = ts; break; -- To view, visit https://gerrit.osmocom.org/1102 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2d75801df4d7cbb8dad325f4d6689841f0196fa6 Gerrit-PatchSet: 1 Gerrit-Project: libosmo-abis Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org>