summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/src/mobile/tch_csd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/layer23/src/mobile/tch_csd.c')
-rw-r--r--src/host/layer23/src/mobile/tch_csd.c88
1 files changed, 69 insertions, 19 deletions
diff --git a/src/host/layer23/src/mobile/tch_csd.c b/src/host/layer23/src/mobile/tch_csd.c
index 1e7ddf6c..7c8914c5 100644
--- a/src/host/layer23/src/mobile/tch_csd.c
+++ b/src/host/layer23/src/mobile/tch_csd.c
@@ -25,7 +25,9 @@
#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmocom/gsm/gsm44021.h>
+
#include <osmocom/isdn/v110.h>
+#include <osmocom/isdn/v110_ta.h>
#include <osmocom/bb/common/logging.h>
#include <osmocom/bb/common/osmocom_data.h>
@@ -71,6 +73,7 @@ const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
/* FIXME: store this in struct osmocom_ms */
static struct tch_csd_sock_state *g_sock_state;
static struct osmo_soft_uart *g_suart;
+static struct osmo_v110_ta *g_ta;
static void tch_soft_uart_rx_cb(void *priv, struct msgb *msg, unsigned int flags)
{
@@ -118,6 +121,46 @@ int tch_soft_uart_alloc(struct osmocom_ms *ms)
return 0;
}
+/*************************************************************************************/
+
+static void tch_v110_ta_rx_cb(void *priv, const ubit_t *buf, size_t buf_size)
+{
+ /* XXX: we're assuming async call here */
+ osmo_soft_uart_rx_ubits(g_suart, buf, buf_size);
+}
+
+static void tch_v110_ta_tx_cb(void *priv, ubit_t *buf, size_t buf_size)
+{
+ /* XXX: we're assuming async call here */
+ osmo_soft_uart_tx_ubits(g_suart, buf, buf_size);
+}
+
+static void tch_v110_ta_status_update_cb(void *priv, unsigned int status)
+{
+ LOGP(DL1C, LOGL_DEBUG, "%s(): [status=0x%08x]\n", __func__, status);
+ /* TODO: update status lines of the soft-UART */
+}
+
+int tch_v110_ta_alloc(struct osmocom_ms *ms)
+{
+ const struct osmo_v110_ta_cfg cfg = {
+ /* FIXME: take the exact rate from BCap */
+ .rate = OSMO_V110_SYNC_RA1_9600,
+ .priv = ms,
+ .rx_cb = &tch_v110_ta_rx_cb,
+ .tx_cb = &tch_v110_ta_tx_cb,
+ .status_update_cb = &tch_v110_ta_status_update_cb,
+ };
+
+ g_ta = osmo_v110_ta_alloc(ms, "csd_v110_ta", &cfg);
+ if (g_ta == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/*************************************************************************************/
+
static void swap_words(uint8_t *data, size_t data_len)
{
/* swap bytes in words */
@@ -130,7 +173,7 @@ static void swap_words(uint8_t *data, size_t data_len)
}
}
-int tch_soft_uart_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg)
+int tch_csd_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg)
{
const struct gsm48_rr_cd *cd = &ms->rrlayer.cd_now;
const struct csd_v110_frame_desc *desc;
@@ -161,17 +204,17 @@ int tch_soft_uart_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg)
for (unsigned int i = 0; i < desc->num_blocks; i++) {
struct osmo_v110_decoded_frame df;
- if (desc->num_bits == 60) {
+ if (desc->num_bits == 60)
osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
- /* feed D-bits (D1..D48) into the soft-UART */
- osmo_soft_uart_rx_ubits(g_suart, &df.d_bits[0], 48);
- } else { /* desc->num_bits == 36 */
+ else /* desc->num_bits == 36 */
osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
- /* feed D-bits (D1..D24) into the soft-UART */
- osmo_soft_uart_rx_ubits(g_suart, &df.d_bits[0], 24);
- }
- /* XXX: what do we do with S-/X-/E-bits? */
+ /* FIXME: properly set E1/E2/E3 depending on data rate */
+ df.e_bits[0] = 0;
+ df.e_bits[1] = 1;
+ df.e_bits[2] = 1;
+
+ osmo_v110_ta_frame_in(g_ta, &df);
}
osmo_soft_uart_flush_rx(g_suart);
@@ -179,7 +222,7 @@ int tch_soft_uart_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
-int tch_soft_uart_tx_to_l1(struct osmocom_ms *ms)
+int tch_csd_tx_to_l1(struct osmocom_ms *ms)
{
const struct gsm48_rr_cd *cd = &ms->rrlayer.cd_now;
const struct csd_v110_frame_desc *desc;
@@ -196,18 +239,18 @@ int tch_soft_uart_tx_to_l1(struct osmocom_ms *ms)
for (unsigned int i = 0; i < desc->num_blocks; i++) {
struct osmo_v110_decoded_frame df;
- /* init all bits to 1 */
- memset(&df, 0x01, sizeof(df));
+ if (osmo_v110_ta_frame_out(g_ta, &df) != 0)
+ memset(&df, 0x01, sizeof(df));
+
+ /* set E7 to binary 0 in every 4-th frame
+ * (as per 3GPP TS 44.021, subclause 10.2.1)
+ * FIXME: properly handle desc->num_blocks == 2 */
+ df.e_bits[6] = (i > 0);
- if (desc->num_bits == 60) {
- /* pull D-bits (D1..D48) out of the soft-UART */
- osmo_soft_uart_tx_ubits(g_suart, &df.d_bits[0], 48);
+ if (desc->num_bits == 60)
osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
- } else { /* desc->num_bits == 36 */
- /* pull D-bits (D1..D24) out of the soft-UART */
- osmo_soft_uart_tx_ubits(g_suart, &df.d_bits[0], 24);
+ else /* desc->num_bits == 36 */
osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
- }
}
nmsg = msgb_alloc_headroom(33 + 64, 64, __func__);
@@ -229,3 +272,10 @@ int tch_soft_uart_tx_to_l1(struct osmocom_ms *ms)
return gsm48_rr_tx_traffic(ms, nmsg);
}
+
+void tch_csd_sock_conn_cb(struct tch_csd_sock_state *state, bool connected)
+{
+ osmo_v110_ta_set_circuit(g_ta, OSMO_V110_TA_C_108, connected);
+}
+
+/* TODO: call osmo_v110_ta_sync_ind() */