From d67fcefab05e9aa89e6e72a5f2aae10a5404c5e5 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 30 Jan 2016 15:38:02 +0100 Subject: [PATCH] GSM: Add audio frame type for uncompressed 16 bit frame It is usefull for connecting MNCC to other networks than GSM. --- gsm.cpp | 15 +++++++++++++++ gsm_bs.cpp | 16 +++++++++++++++- gsm_ms.cpp | 7 +++++++ message.h | 1 + mncc.h | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gsm.cpp b/gsm.cpp index 5ed0f89..b9b88ee 100644 --- a/gsm.cpp +++ b/gsm.cpp @@ -290,6 +290,15 @@ void Pgsm::frame_receive(void *arg) return; switch (frame->msg_type) { + case ANALOG_8000HZ: + if (p_g_media_type != MEDIA_TYPE_ANALOG) { + PERROR("'Analog' frame, but current media type mismatches.\n"); + return; + } + for (i = 0; i < 160; i++) { + data[i] = audio_s16_to_law[((int16_t *)frame->data)[i] & 0xffff]; + } + break; case GSM_TCHF_FRAME: if (p_g_media_type != MEDIA_TYPE_GSM) { PERROR("FR frame, but current media type mismatches.\n"); @@ -450,6 +459,9 @@ int Pgsm::audio_send(unsigned char *data, int len) p_g_rxpos = 0; switch (p_g_media_type) { + case MEDIA_TYPE_ANALOG: + frame_send(p_g_rxdata, 320, ANALOG_8000HZ); + break; case MEDIA_TYPE_GSM: if (!p_g_fr_encoder) { PERROR("FR frame, but encoder not created.\n"); @@ -1254,6 +1266,9 @@ static int mncc_send(struct lcr_gsm *lcr_gsm, int msg_type, void *data) /* FIXME: the caller should provide this */ switch (msg_type) { + case ANALOG_8000HZ: + len = sizeof(struct gsm_data_frame) + 320; + break; case GSM_TCHF_FRAME: len = sizeof(struct gsm_data_frame) + 33; break; diff --git a/gsm_bs.cpp b/gsm_bs.cpp index 97be942..6d1a122 100644 --- a/gsm_bs.cpp +++ b/gsm_bs.cpp @@ -395,6 +395,13 @@ void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_ decoder = p_g_amr_decoder; half = 1; break; + case 0x80: + add_trace("speech", "version", "Analog 8000Hz given"); + media_type = MEDIA_TYPE_ANALOG; + payload_type = dynamic_type++; + encoder = (void *)1; + decoder = (void *)1; + break; default: add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]); media_type = 0; @@ -463,6 +470,7 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ if (p_g_callref) { /* release in case the ID is already in use */ add_trace("error", NULL, "callref already in use"); +reject: end_trace(); mncc = create_mncc(MNCC_REJ_REQ, callref); gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT); @@ -480,6 +488,11 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ trigger_work(&p_g_delete); return; } + if (callref < 0x40000000) { + /* release in case the ID is invalid */ + add_trace("error", NULL, "callref invalid, not of BSC type"); + goto reject; + } p_g_callref = callref; end_trace(); @@ -571,7 +584,7 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN); if (p_callerinfo.id[0]) add_trace("calling", "number", "%s", p_callerinfo.id); - else + else if (p_callerinfo.imsi[0]) SPRINT(p_callerinfo.id, "imsi-%s", p_callerinfo.imsi); add_trace("calling", "imsi", "%s", p_callerinfo.imsi); add_trace("dialing", "number", "%s", p_dialinginfo.id); @@ -677,6 +690,7 @@ int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg) || msg_type == GSM_TCHF_FRAME_EFR || msg_type == GSM_TCHH_FRAME || msg_type == GSM_TCH_FRAME_AMR + || msg_type == ANALOG_8000HZ || msg_type == GSM_BAD_FRAME) { if (port) { /* inject DTMF, if enabled */ diff --git a/gsm_ms.cpp b/gsm_ms.cpp index 8a314bf..6ef0a82 100644 --- a/gsm_ms.cpp +++ b/gsm_ms.cpp @@ -84,6 +84,7 @@ void Pgsm_ms::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ if (p_g_callref) { /* release in case the ID is already in use */ add_trace("error", NULL, "callref already in use"); +reject: end_trace(); mncc = create_mncc(MNCC_REJ_REQ, callref); gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT); @@ -101,6 +102,12 @@ void Pgsm_ms::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ trigger_work(&p_g_delete); return; } + if (callref < 0x40000000) { + /* release in case the ID is invalid */ + add_trace("error", NULL, "callref invalid, not of MS type"); + goto reject; + } + p_g_callref = callref; end_trace(); diff --git a/message.h b/message.h index 47952ac..9b8833a 100644 --- a/message.h +++ b/message.h @@ -145,6 +145,7 @@ enum { MEDIA_TYPE_GSM_EFR, MEDIA_TYPE_AMR, MEDIA_TYPE_GSM_HR, + MEDIA_TYPE_ANALOG, /* just send analog data via MNCC */ }; /* rtp-info structure */ diff --git a/mncc.h b/mncc.h index 1cd45f8..998e91b 100644 --- a/mncc.h +++ b/mncc.h @@ -62,6 +62,7 @@ #define GSM_TCHF_FRAME_EFR 0x0301 #define GSM_TCHH_FRAME 0x0302 #define GSM_TCH_FRAME_AMR 0x0303 +#define ANALOG_8000HZ 0x0380 #define GSM_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 @@ -189,6 +190,7 @@ enum gsm48_bcap_speech_ver { GSM48_BCAP_SV_EFR = 2, GSM48_BCAP_SV_AMR_F = 4, GSM48_BCAP_SV_AMR_H = 5, + BCAP_SV_ANALOG_8000HZ = 0x80, }; /* Expanded fields from GSM TS 04.08, Table 10.5.102 */ -- 2.13.6