GSM: Add audio frame type for uncompressed 16 bit frame
authorAndreas Eversberg <jolly@eversberg.eu>
Sat, 30 Jan 2016 14:38:02 +0000 (15:38 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Sat, 30 Jan 2016 14:55:55 +0000 (15:55 +0100)
It is usefull for connecting MNCC to other networks than GSM.

gsm.cpp
gsm_bs.cpp
gsm_ms.cpp
message.h
mncc.h

diff --git a/gsm.cpp b/gsm.cpp
index 5ed0f89..b9b88ee 100644 (file)
--- 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;
index 97be942..6d1a122 100644 (file)
@@ -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 */
index 8a314bf..6ef0a82 100644 (file)
@@ -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();
 
index 47952ac..9b8833a 100644 (file)
--- 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 (file)
--- 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 */