summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-12-30 22:35:26 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2024-01-06 01:03:19 +0700
commit5f447e5e639b14a5153fd087b56c9ae75239a49b (patch)
tree0a19a120d1cef3f72a67451840075c4c741e4d78
parent0dc976377f75376d52a4b11cf64c8398e3dd3d78 (diff)
[WIP] mobile: integrate V.110 TA from libosmoisdnfixeria/csd_demo
-rw-r--r--src/host/layer23/configure.ac1
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/tch.h7
-rw-r--r--src/host/layer23/src/mobile/Makefile.am2
-rw-r--r--src/host/layer23/src/mobile/tch.c5
-rw-r--r--src/host/layer23/src/mobile/tch_csd.c88
-rw-r--r--src/host/layer23/src/mobile/tch_csd_sock.c3
6 files changed, 83 insertions, 23 deletions
diff --git a/src/host/layer23/configure.ac b/src/host/layer23/configure.ac
index b4eb8604..7fb8bf16 100644
--- a/src/host/layer23/configure.ac
+++ b/src/host/layer23/configure.ac
@@ -45,6 +45,7 @@ dnl checks for libraries
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.10.0)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm)
+PKG_CHECK_MODULES(LIBOSMOISDN, libosmoisdn)
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec)
PKG_CHECK_MODULES(LIBOSMOGPRSRLCMAC, libosmo-gprs-rlcmac)
PKG_CHECK_MODULES(LIBOSMOGPRSLLC, libosmo-gprs-llc)
diff --git a/src/host/layer23/include/osmocom/bb/mobile/tch.h b/src/host/layer23/include/osmocom/bb/mobile/tch.h
index 4963f174..820f0fb4 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/tch.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/tch.h
@@ -9,12 +9,15 @@ int tch_send_voice_msg(struct osmocom_ms *ms, struct msgb *msg);
int tch_send_voice_frame(struct osmocom_ms *ms, const struct gsm_data_frame *frame);
int tch_soft_uart_alloc(struct osmocom_ms *ms);
-int tch_soft_uart_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg);
-int tch_soft_uart_tx_to_l1(struct osmocom_ms *ms);
+int tch_v110_ta_alloc(struct osmocom_ms *ms);
+
+int tch_csd_rx_from_l1(struct osmocom_ms *ms, struct msgb *msg);
+int tch_csd_tx_to_l1(struct osmocom_ms *ms);
struct tch_csd_sock_state;
struct tch_csd_sock_state *tch_csd_sock_init(void *ctx, const char *sock_path);
void tch_csd_sock_exit(struct tch_csd_sock_state *state);
+void tch_csd_sock_conn_cb(struct tch_csd_sock_state *state, bool connected);
int tch_csd_sock_send(struct tch_csd_sock_state *state, struct msgb *msg);
int tch_csd_sock_recv(struct tch_csd_sock_state *state, struct msgb *msg);
diff --git a/src/host/layer23/src/mobile/Makefile.am b/src/host/layer23/src/mobile/Makefile.am
index 3583aef2..ddfa13e6 100644
--- a/src/host/layer23/src/mobile/Makefile.am
+++ b/src/host/layer23/src/mobile/Makefile.am
@@ -8,6 +8,7 @@ AM_CFLAGS = \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOVTY_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOISDN_CFLAGS) \
$(LIBOSMOGPRSRLCMAC_CFLAGS) \
$(LIBOSMOGPRSLLC_CFLAGS) \
$(LIBOSMOGPRSSNDCP_CFLAGS) \
@@ -46,6 +47,7 @@ mobile_LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOVTY_LIBS) \
$(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOISDN_LIBS) \
$(LIBOSMOGPRSRLCMAC_LIBS) \
$(LIBOSMOGPRSLLC_LIBS) \
$(LIBOSMOGPRSSNDCP_LIBS) \
diff --git a/src/host/layer23/src/mobile/tch.c b/src/host/layer23/src/mobile/tch.c
index 4e366327..7ea7f638 100644
--- a/src/host/layer23/src/mobile/tch.c
+++ b/src/host/layer23/src/mobile/tch.c
@@ -45,8 +45,8 @@ static int tch_recv_data(struct osmocom_ms *ms, struct msgb *msg)
/* Send data frame back */
return tch_send_voice_msg(ms, msg);
case TCH_DATA_IOH_UNIX_SOCK:
- tch_soft_uart_rx_from_l1(ms, msg);
- tch_soft_uart_tx_to_l1(ms);
+ tch_csd_rx_from_l1(ms, msg);
+ tch_csd_tx_to_l1(ms);
msgb_free(msg);
break;
case TCH_DATA_IOH_NONE:
@@ -173,6 +173,7 @@ int tch_init(struct osmocom_ms *ms)
ms->l1_entity.l1_traffic_ind = &tch_recv_data;
tch_soft_uart_alloc(ms);
+ tch_v110_ta_alloc(ms);
return 0;
}
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() */
diff --git a/src/host/layer23/src/mobile/tch_csd_sock.c b/src/host/layer23/src/mobile/tch_csd_sock.c
index c5cde6cb..fcf95868 100644
--- a/src/host/layer23/src/mobile/tch_csd_sock.c
+++ b/src/host/layer23/src/mobile/tch_csd_sock.c
@@ -90,6 +90,7 @@ static int tch_csd_sock_read(struct osmo_fd *bfd)
close:
msgb_free(msg);
tch_csd_sock_close(state);
+ tch_csd_sock_conn_cb(state, false);
return -1;
}
@@ -175,6 +176,8 @@ static int tch_csd_sock_accept(struct osmo_fd *bfd, unsigned int flags)
LOGP(DMOB, LOGL_NOTICE, "TCH CSD sock got a connection\n");
+ tch_csd_sock_conn_cb(state, true);
+
return 0;
}