osmo_e1: Add HDLC framing/deframing
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 @@
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 @@
* \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_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 @@
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