diff options
-rw-r--r-- | src/host/layer23/configure.ac | 1 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/tch.h | 7 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/Makefile.am | 2 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/tch.c | 5 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/tch_csd.c | 88 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/tch_csd_sock.c | 3 |
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; } |