aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2024-01-14 15:04:00 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2024-01-19 18:23:01 +0100
commitd397129ebafc4b23f26f5537b0e5dce2a9b481eb (patch)
treecbbd0abe143cc51455794b290f500348a87c0ce6 /src
parentd5b99eb1bdccc6373cad430bd69a2bfb67ea91e6 (diff)
Add command and client function to change transmitted Sa bits
Diffstat (limited to 'src')
-rw-r--r--src/ctl.c37
-rw-r--r--src/e1d.h2
-rw-r--r--src/intf_line.c1
-rw-r--r--src/mux_demux.c11
-rw-r--r--src/proto_clnt.c28
5 files changed, 77 insertions, 2 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 8ed4a69..331f2ad 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -430,6 +430,37 @@ _e1d_ctl_ts_open(void *data, struct msgb *msgb, struct msgb *rmsgb, int *rfd)
return 0;
}
+static int
+_e1d_ctl_sabits(void *data, struct msgb *msgb, struct msgb *rmsgb, int *rfd)
+{
+ struct e1_daemon *e1d = (struct e1_daemon *)data;
+ struct osmo_e1dp_msg_hdr *hdr = msgb_l1(msgb);
+ uint8_t sa_bits = *(uint8_t *)msgb_l2(msgb);
+ struct e1_intf *intf = NULL;
+ struct e1_line *line = NULL;
+
+ /* Process query and find timeslot */
+ intf = e1d_find_intf(e1d, hdr->intf);
+ if (!intf) {
+ LOGP(DE1D, LOGL_NOTICE, "Client request for non-existant Interface %u\n", hdr->intf);
+ return 0;
+ }
+
+ line = e1_intf_find_line(intf, hdr->line);
+ if (!line) {
+ LOGPIF(intf, DE1D, LOGL_NOTICE, "Client request for non-existant line %u\n", hdr->line);
+ return 0;
+ }
+
+ line->ts0.tx_frame = ((sa_bits & 0x80) >> 7) | /* Bit 7 -> Sa8 */
+ ((sa_bits & 0x40) >> 5) | /* Bit 6 -> Sa7 */
+ ((sa_bits & 0x01) << 2) | /* Bit 0 -> Sa6 */
+ ((sa_bits & 0x20) >> 2) | /* Bit 5 -> Sa5 */
+ (sa_bits & 0x10); /* Bit 4 -> Sa4 */
+
+ return 0;
+}
+
struct osmo_e1dp_server_handler e1d_ctl_handlers[] = {
{
@@ -462,5 +493,11 @@ struct osmo_e1dp_server_handler e1d_ctl_handlers[] = {
.payload_len = sizeof(struct osmo_e1dp_ts_config),
.fn = _e1d_ctl_ts_open,
},
+ {
+ .type = E1DP_CMD_SABITS,
+ .flags = E1DP_SF_INTF_REQ | E1DP_SF_LINE_REQ,
+ .payload_len = sizeof(uint8_t),
+ .fn = _e1d_ctl_sabits,
+ },
{ /* guard */ },
};
diff --git a/src/e1d.h b/src/e1d.h
index 4b70c0f..bf1cbdf 100644
--- a/src/e1d.h
+++ b/src/e1d.h
@@ -148,6 +148,8 @@ struct e1_line {
uint8_t prev_errmask;
/*! timer to re-set the rx_crc4_err and rx_alarm above */
struct osmo_timer_list timer;
+ /*! current transmitting frame with Sa bits */
+ uint8_t tx_frame;
/*! last received frame with Sa bits */
uint8_t rx_frame;
} ts0;
diff --git a/src/intf_line.c b/src/intf_line.c
index b3dafff..8eac84d 100644
--- a/src/intf_line.c
+++ b/src/intf_line.c
@@ -272,6 +272,7 @@ e1_line_new(struct e1_intf *intf, int line_id, void *drv_data)
line->intf = intf;
line->drv_data = drv_data;
line->mode = E1_LINE_MODE_CHANNELIZED;
+ line->ts0.tx_frame = 0xff;
line->ts0.rx_frame = 0xff;
for (int i = 0; i < 32; i++)
diff --git a/src/mux_demux.c b/src/mux_demux.c
index 71374ef..dd8ca45 100644
--- a/src/mux_demux.c
+++ b/src/mux_demux.c
@@ -149,11 +149,18 @@ _e1_ts_read(struct e1_ts *ts, uint8_t *buf, size_t len)
static void
_e1_line_mux_out_channelized(struct e1_line *line, uint8_t *buf, int fts)
{
+ struct e1_ts *ts;
+
OSMO_ASSERT(line->mode == E1_LINE_MODE_CHANNELIZED);
- /* Scan timeslots */
+ /* Fill timeslot 0 */
+ ts = &line->ts[0];
+ for (int i = 0; i < fts; i++)
+ buf[(i*32)] = line->ts0.tx_frame;
+
+ /* Scan timeslots 1..31 */
for (int tsn = 1; tsn < 32; tsn++) {
- struct e1_ts *ts = &line->ts[tsn];
+ ts = &line->ts[tsn];
uint8_t buf_ts[fts];
int l;
diff --git a/src/proto_clnt.c b/src/proto_clnt.c
index 99d1cc2..854b958 100644
--- a/src/proto_clnt.c
+++ b/src/proto_clnt.c
@@ -394,6 +394,34 @@ osmo_e1dp_client_line_config(struct osmo_e1dp_client *clnt,
return 0;
}
+/*! Set Sa-bits of a specific E1 line in osmo-e1d.
+ * \param[in] clnt Client previously returned from osmo_e1dp_client_create().
+ * \param[in] intf E1 interface number to configure.
+ * \param[in] line E1 line number (within interface) to configure.
+ * \param[in] sa_bits Sa bits to set on line.
+ * \returns zero in case of success; negative in case of error. */
+int
+osmo_e1dp_client_set_sa_bits(struct osmo_e1dp_client *clnt, uint8_t intf, uint8_t line, uint8_t sa_bits)
+{
+ struct msgb *msgb;
+ struct osmo_e1dp_msg_hdr hdr;
+ int rc;
+
+ memset(&hdr, 0x00, sizeof(struct osmo_e1dp_msg_hdr));
+ hdr.type = E1DP_CMD_SABITS;
+ hdr.intf = intf;
+ hdr.line = line;
+ hdr.ts = E1DP_INVALID;
+
+ rc = _e1dp_client_query_base(clnt, &hdr, &sa_bits, 1, &msgb, NULL);
+ if (rc)
+ return rc;
+
+ msgb_free(msgb);
+
+ return 0;
+}
+
static int
_client_ts_open(struct osmo_e1dp_client *clnt,
uint8_t intf, uint8_t line, uint8_t ts,