aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-05-11 21:04:03 +0200
committerHarald Welte <laforge@gnumonks.org>2018-05-11 22:00:18 +0200
commit8a95fd5481afa321914b4c06bb953efd59256a9b (patch)
treed29d9eddb7296d245fcdaf1eacd93c68fd3d2c97
parent37e237454589bafd7e78ea634a5df5e53f92b5fe (diff)
osmo_e1: Add HDLC framing/deframing
-rw-r--r--src/e1_test.c2
-rw-r--r--src/osmo_e1.c55
-rw-r--r--src/osmo_e1.h14
3 files changed, 61 insertions, 10 deletions
diff --git a/src/e1_test.c b/src/e1_test.c
index 5fd416f..c6d0e22 100644
--- a/src/e1_test.c
+++ b/src/e1_test.c
@@ -119,7 +119,7 @@ int main(int argc, char **argv)
osmo_e1_instance_init(&inst, "e1_test", &notify_cb, true, NULL);
for (i = 1; i < 32; i++) {
struct osmo_e1_instance_ts *e1t = osmo_e1_instance_ts(&inst, i);
- osmo_e1_ts_config(e1t, &data_cb, 40, true);
+ osmo_e1_ts_config(e1t, &data_cb, 40, true, OSMO_E1_TS_RAW);
}
printf("\nRx Random...\n");
diff --git a/src/osmo_e1.c b/src/osmo_e1.c
index ecf0cab..a328eb1 100644
--- a/src/osmo_e1.c
+++ b/src/osmo_e1.c
@@ -91,6 +91,10 @@ void osmo_e1_ts_reset(struct osmo_e1_instance_ts *e1t)
e1t->rx.enabled = false;
msgb_free(e1t->rx.msg);
e1t->rx.msg = NULL;
+
+ osmo_isdnhdlc_rcv_init(&e1t->rx.hdlc, OSMO_HDLC_F_BITREVERSE);
+ //osmo_isdnhdlc_rcv_init(&e1t->rx.hdlc, 0);
+ osmo_isdnhdlc_out_init(&e1t->tx.hdlc, 0);
}
/*! stop E1 instance; stops all timeslots and releases any pending rx/tx buffers
@@ -136,13 +140,15 @@ struct osmo_e1_instance_ts *osmo_e1_instance_ts(struct osmo_e1_instance *e1i, ui
* \param[in] e1t Timeslot which we are to configure
* \param[in] granularity granularity (buffer size) to use on Rx
* \param[in] enable enable (true) or disalble (false) receiving on this TS
+ * \param[in] mode the mode for this timeslot (raw or hdlc)
* \return 0 on success; negative on error */
int osmo_e1_ts_config(struct osmo_e1_instance_ts *e1t, e1_data_cb cb, unsigned int granularity,
- bool enable)
+ bool enable, enum osmo_e1_ts_mode mode)
{
e1t->rx.data_cb = cb;
e1t->rx.enabled = enable;
e1t->rx.granularity = granularity;
+ e1t->mode = mode;
return 0;
}
@@ -611,6 +617,7 @@ static void e1_rx_ts0(struct osmo_e1_instance *e1i, uint8_t inb)
static void e1_rx_tsN(struct osmo_e1_instance_ts *e1t, uint8_t inb)
{
struct msgb *msg;
+ int count, rc;
if (!e1t->rx.enabled)
return;
@@ -620,14 +627,46 @@ static void e1_rx_tsN(struct osmo_e1_instance_ts *e1t, uint8_t inb)
msg = e1t->rx.msg;
OSMO_ASSERT(msg);
- msgb_put_u8(msg, inb);
- if (msgb_tailroom(msg) <= 0) {
- if (!e1t->rx.data_cb)
- msgb_free(msg);
- else
- e1t->rx.data_cb(e1t, msg);
- e1t->rx.msg = NULL;
+ switch (e1t->mode) {
+ case OSMO_E1_TS_RAW:
+ /* append byte at end of msgb */
+ msgb_put_u8(msg, inb);
+ /* flush msgb, if full */
+ if (msgb_tailroom(msg) <= 0) {
+ goto flush;
+ }
+ break;
+ case OSMO_E1_TS_HDLC_CRC:
+ rc = osmo_isdnhdlc_decode(&e1t->rx.hdlc, &inb, 1, &count,
+ msgb_data(msg), msgb_tailroom(msg));
+ switch (rc) {
+ case -OSMO_HDLC_FRAMING_ERROR:
+ fprintf(stdout, "Framing Error\n");
+ break;
+ case -OSMO_HDLC_CRC_ERROR:
+ fprintf(stdout, "CRC Error\n");
+ break;
+ case -OSMO_HDLC_LENGTH_ERROR:
+ fprintf(stdout, "Length Error\n");
+ break;
+ case 0:
+ /* no output yet */
+ break;
+ default:
+ msgb_put(msg, rc);
+ goto flush;
+ }
+ break;
}
+
+ return;
+flush:
+
+ if (!e1t->rx.data_cb)
+ msgb_free(msg);
+ else
+ e1t->rx.data_cb(e1t, msg);
+ e1t->rx.msg = NULL;
}
/*! Receive a single E1 frame of 32x8 (=256) bits
diff --git a/src/osmo_e1.h b/src/osmo_e1.h
index f39a308..4f5a18a 100644
--- a/src/osmo_e1.h
+++ b/src/osmo_e1.h
@@ -5,6 +5,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/fsm.h>
+#include <osmocom/core/isdnhdlc.h>
struct osmo_e1_tx_state {
bool remote_alarm;
@@ -41,6 +42,11 @@ enum osmo_e1_notify_event {
E1_NTFY_EVT_REMOTE_ALARM,
};
+enum osmo_e1_ts_mode {
+ OSMO_E1_TS_RAW,
+ OSMO_E1_TS_HDLC_CRC,
+};
+
struct osmo_e1_instance_ts;
struct osmo_e1_instance;
typedef void (*e1_data_cb)(struct osmo_e1_instance_ts *ts, struct msgb *msg);
@@ -50,14 +56,20 @@ typedef void (*e1_notify_cb)(struct osmo_e1_instance *e1i, enum osmo_e1_notify_e
struct osmo_e1_instance_ts {
/* timeslot number */
uint8_t ts_nr;
+ /* mode in which we operate (RAW/HDLC) */
+ enum osmo_e1_ts_mode mode;
/* back-pointer to e1 instance */
struct osmo_e1_instance *inst;
struct {
+ /* optional HDLC encoder state */
+ struct osmo_isdnhdlc_vars hdlc;
/* queue of pending to-be-transmitted messages */
struct llist_head queue;
unsigned long underruns;
} tx;
struct {
+ /* optional HDLC decoder state */
+ struct osmo_isdnhdlc_vars hdlc;
bool enabled;
/* how many bytes to buffer before calling call-back */
unsigned int granularity;
@@ -101,7 +113,7 @@ int osmo_e1_instance_init(struct osmo_e1_instance *e1i, const char *name, e1_not
bool crc4_enabled, void *priv);
void osmo_e1_instance_reset(struct osmo_e1_instance *e1i);
int osmo_e1_ts_config(struct osmo_e1_instance_ts *e1t, e1_data_cb cb, unsigned int granularity,
- bool enable);
+ bool enable, enum osmo_e1_ts_mode mode);
void osmo_e1_ts_reset(struct osmo_e1_instance_ts *e1t);