summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/src/mobile/voice.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/layer23/src/mobile/voice.c')
-rw-r--r--src/host/layer23/src/mobile/voice.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/src/host/layer23/src/mobile/voice.c b/src/host/layer23/src/mobile/voice.c
index 76c116cd..ddecb82a 100644
--- a/src/host/layer23/src/mobile/voice.c
+++ b/src/host/layer23/src/mobile/voice.c
@@ -1,5 +1,6 @@
/*
* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ * (C) 2017-2018 by Vadim Yanitskiy <axilirator@gmail.com>
*
* All Rights Reserved
*
@@ -19,39 +20,75 @@
*
*/
-#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
#include <osmocom/core/msgb.h>
#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/mobile/settings.h>
+#include <osmocom/bb/mobile/gapk_io.h>
#include <osmocom/bb/mobile/mncc.h>
#include <osmocom/bb/mobile/voice.h>
-
/*
- * receive voice
+ * TCH frame (voice) router
*/
-
static int gsm_recv_voice(struct osmocom_ms *ms, struct msgb *msg)
{
- struct gsm_data_frame *mncc;
+ struct gsm_data_frame *frame;
+
+ /* Make sure that a MNCC handler is set */
+ if (!ms->mncc_entity.mncc_recv) {
+ msgb_free(msg);
+ return -ENOTSUP;
+ }
- /* distribute and then free */
- if (ms->mncc_entity.mncc_recv && ms->mncc_entity.ref) {
- /* push mncc header in front of data */
- mncc = (struct gsm_data_frame *)
+ /* TODO: Make sure there is an active call */
+
+ /* Route a frame according to settings */
+ switch (ms->settings.audio.io_target) {
+ /* External MNCC application (e.g. LCR) */
+ case AUDIO_IO_SOCKET:
+ /* Push MNCC header in front of data */
+ frame = (struct gsm_data_frame *)
msgb_push(msg, sizeof(struct gsm_data_frame));
- mncc->msg_type = GSM_TCHF_FRAME;
- mncc->callref = ms->mncc_entity.ref;
- ms->mncc_entity.mncc_recv(ms, mncc->msg_type, mncc);
+
+ /* FIXME: set proper msg_type */
+ frame->msg_type = GSM_TCHF_FRAME;
+ frame->callref = ms->mncc_entity.ref;
+
+ /* Forward to an MNCC-handler */
+ ms->mncc_entity.mncc_recv(ms, frame->msg_type, frame);
+
+ /* Release memory */
+ msgb_free(msg);
+ break;
+
+ /* Build-in GAPK-based audio back-end */
+ case AUDIO_IO_GAPK:
+ /* Prevent null pointer dereference */
+ if (!ms->gapk_io) {
+ msgb_free(msg);
+ break;
+ }
+
+ /* Push a frame to the DL frame buffer */
+ msgb_enqueue(&ms->gapk_io->tch_fb_dl, msg);
+ break;
+
+ /* Drop frame and release memory */
+ case AUDIO_IO_HARDWARE:
+ case AUDIO_IO_NONE:
+ default:
+ msgb_free(msg);
}
- msgb_free(msg);
return 0;
}
/*
- * send voice
+ * Send voice to the lower layers
*/
int gsm_send_voice(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -78,12 +115,10 @@ int gsm_send_voice_mncc(struct osmocom_ms *ms, struct gsm_data_frame *frame)
}
/*
- * init
+ * Init TCH frame (voice) router
*/
-
int gsm_voice_init(struct osmocom_ms *ms)
{
ms->l1_entity.l1_traffic_ind = gsm_recv_voice;
-
return 0;
}