From fd44a5f2fed648b3d182136d15d89bd6a5fdecf3 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 21 Aug 2011 00:48:54 +0200 Subject: e1_input: move the lapd_instance pointer out of dahdi specifics ... and create a new e1inp_rx_ts_lapd() from dahdi as well --- include/osmocom/abis/e1_input.h | 5 ++- src/e1_input.c | 70 +++++++++++++++++++++++++++++++++++++++++ src/input/dahdi.c | 62 +++--------------------------------- 3 files changed, 78 insertions(+), 59 deletions(-) diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h index 757f3f2..42b1758 100644 --- a/include/osmocom/abis/e1_input.h +++ b/include/osmocom/abis/e1_input.h @@ -70,6 +70,9 @@ struct e1inp_ts { /* to which line do we belong ? */ struct e1inp_line *line; + /* LAPD instance, if any */ + struct lapd_instance *lapd; + union { struct { /* list of all signalling links on this TS */ @@ -98,7 +101,6 @@ struct e1inp_ts { struct { /* DAHDI driver has one fd for each ts */ struct osmo_fd fd; - struct lapd_instance *lapd; } dahdi; struct { struct osmo_fd fd; @@ -229,6 +231,7 @@ int e1inp_update_ts(struct e1inp_ts *ts); /* Receive a packet from the E1 driver */ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, uint8_t tei, uint8_t sapi); +int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg); /* called by driver if it wants to transmit on a given TS */ struct msgb *e1inp_tx_ts(struct e1inp_ts *e1i_ts, diff --git a/src/e1_input.c b/src/e1_input.c index 81c5a99..f9d3477 100644 --- a/src/e1_input.c +++ b/src/e1_input.c @@ -33,6 +33,8 @@ #include #include +#include + //#define AF_COMPATIBILITY_FUNC //#include #ifndef AF_ISDN @@ -523,6 +525,74 @@ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg, return ret; } +/*! \brief Receive some data from the L1/HDLC into LAPD of a timeslot + * \param[in] e1i_ts E1 Timeslot data structure + * \param[in] msg Message buffer containing full LAPD message + * + * This is a wrapper around e1inp_rx_ts(), but feeding the incoming + * message first into our LAPD code. This allows a driver to read raw + * (HDLC decoded) data from the timeslot, instead of a LAPD stack + * present in any underlying driver. + */ +int e1inp_rx_ts_lapd(struct e1inp_ts *e1i_ts, struct msgb *msg) +{ + lapd_mph_type prim; + unsigned int sapi, tei; + int ilen, ret = 0, error = 0; + uint8_t *idata; + + sapi = msg->data[0] >> 2; + tei = msg->data[1] >> 1; + + DEBUGP(DLMI, "<= len = %d, sapi(%d) tei(%d)", msg->len, sapi, tei); + + idata = lapd_receive(e1i_ts->lapd, msg->data, msg->len, &ilen, &prim, &error); + if (!idata) { + switch(error) { + case LAPD_ERR_UNKNOWN_TEI: + /* We don't know about this TEI, probably the BSC + * lost local states (it crashed or it was stopped), + * notify the driver to see if it can do anything to + * recover the existing signalling links with the BTS. + */ + e1inp_event(e1i_ts, S_L_INP_TEI_UNKNOWN, tei, sapi); + return -EIO; + } + if (prim == 0) + return -EIO; + } + + msgb_pull(msg, 2); + + DEBUGP(DLMI, "prim %08x\n", prim); + + switch (prim) { + case 0: + break; + case LAPD_MPH_ACTIVATE_IND: + DEBUGP(DLMI, "MPH_ACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei); + ret = e1inp_event(e1i_ts, S_L_INP_TEI_UP, tei, sapi); + break; + case LAPD_MPH_DEACTIVATE_IND: + DEBUGP(DLMI, "MPH_DEACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei); + ret = e1inp_event(e1i_ts, S_L_INP_TEI_DN, tei, sapi); + break; + case LAPD_DL_DATA_IND: + case LAPD_DL_UNITDATA_IND: + if (prim == LAPD_DL_DATA_IND) + msg->l2h = msg->data + 2; + else + msg->l2h = msg->data + 1; + DEBUGP(DLMI, "RX: %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); + ret = e1inp_rx_ts(e1i_ts, msg, tei, sapi); + break; + default: + printf("ERROR: unknown prim\n"); + break; + } + return ret; +} + #define TSX_ALLOC_SIZE 4096 /* called by driver if it wants to transmit on a given TS */ diff --git a/src/input/dahdi.c b/src/input/dahdi.c index e4e4905..4fd4e61 100644 --- a/src/input/dahdi.c +++ b/src/input/dahdi.c @@ -106,10 +106,7 @@ static int handle_ts1_read(struct osmo_fd *bfd) 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 TS1"); - lapd_mph_type prim; - unsigned int sapi, tei; - int ilen, ret, error = 0; - uint8_t *idata; + int ret; if (!msg) return -ENOMEM; @@ -125,58 +122,7 @@ static int handle_ts1_read(struct osmo_fd *bfd) perror("read "); } - sapi = msg->data[0] >> 2; - tei = msg->data[1] >> 1; - - DEBUGP(DLMI, "<= len = %d, sapi(%d) tei(%d)", ret, sapi, tei); - - idata = lapd_receive(e1i_ts->driver.dahdi.lapd, msg->data, msg->len, &ilen, &prim, &error); - if (!idata) { - switch(error) { - case LAPD_ERR_UNKNOWN_TEI: - /* We don't know about this TEI, probably the BSC - * lost local states (it crashed or it was stopped), - * notify the driver to see if it can do anything to - * recover the existing signalling links with the BTS. - */ - e1inp_event(e1i_ts, S_L_INP_TEI_UNKNOWN, tei, sapi); - return -EIO; - } - if (prim == 0) - return -EIO; - } - - msgb_pull(msg, 2); - - DEBUGP(DLMI, "prim %08x\n", prim); - - switch (prim) { - case 0: - break; - case LAPD_MPH_ACTIVATE_IND: - DEBUGP(DLMI, "MPH_ACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei); - ret = e1inp_event(e1i_ts, S_L_INP_TEI_UP, tei, sapi); - break; - case LAPD_MPH_DEACTIVATE_IND: - DEBUGP(DLMI, "MPH_DEACTIVATE_IND: sapi(%d) tei(%d)\n", sapi, tei); - ret = e1inp_event(e1i_ts, S_L_INP_TEI_DN, tei, sapi); - break; - case LAPD_DL_DATA_IND: - case LAPD_DL_UNITDATA_IND: - if (prim == LAPD_DL_DATA_IND) - msg->l2h = msg->data + 2; - else - msg->l2h = msg->data + 1; - DEBUGP(DLMI, "RX: %s\n", osmo_hexdump(msgb_l2(msg), ret)); - ret = e1inp_rx_ts(e1i_ts, msg, tei, sapi); - break; - default: - printf("ERROR: unknown prim\n"); - break; - } - - DEBUGP(DLMI, "Returned ok\n"); - return ret; + return e1inp_rx_ts_lapd(e1i_ts, msg); } static int ts_want_write(struct e1inp_ts *e1i_ts) @@ -235,7 +181,7 @@ static int handle_ts1_write(struct osmo_fd *bfd) } DEBUGP(DLMI, "TX: %s\n", osmo_hexdump(msg->data, msg->len)); - lapd_transmit(e1i_ts->driver.dahdi.lapd, sign_link->tei, + lapd_transmit(e1i_ts->lapd, sign_link->tei, sign_link->sapi, msg->data, msg->len); msgb_free(msg); @@ -466,7 +412,7 @@ static int dahdi_e1_setup(struct e1inp_line *line) } bfd->when = BSC_FD_READ | BSC_FD_EXCEPT; dahdi_set_bufinfo(bfd->fd, 1); - e1i_ts->driver.dahdi.lapd = lapd_instance_alloc(1, dahdi_write_msg, bfd); + e1i_ts->lapd = lapd_instance_alloc(1, dahdi_write_msg, bfd); break; case E1INP_TS_TYPE_TRAU: bfd->fd = open(openstr, O_RDWR | O_NONBLOCK); -- cgit v1.2.3-55-g7522