From e48b825741b3a5b40f65bbf096c9aa65a7b5c7c9 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 10 Apr 2016 23:36:03 +0200 Subject: [PATCH] DSDplus library: basic implementation with DMR and DSTAR --- dsdplus/CMakeLists.txt | 2 + dsdplus/dstar.cpp | 164 +++++++++++++++++++++++++++++++++++++++++ dsdplus/dstar.h | 5 +- 3 files changed, 170 insertions(+), 1 deletion(-) diff --git a/dsdplus/CMakeLists.txt b/dsdplus/CMakeLists.txt index 8d6e1b2ce..baa3b579b 100644 --- a/dsdplus/CMakeLists.txt +++ b/dsdplus/CMakeLists.txt @@ -1,6 +1,7 @@ project(dsdplus) set(dsdplus_SOURCES + descramble.cpp dmr_voice.cpp dsd_decoder.cpp dsd_filters.cpp @@ -11,6 +12,7 @@ set(dsdplus_SOURCES ) set(dsdplus_HEADERS + descramble.h dmr_voice.h dsd_decoder.h dsd_filters.h diff --git a/dsdplus/dstar.cpp b/dsdplus/dstar.cpp index a638e2ace..70c69cc77 100644 --- a/dsdplus/dstar.cpp +++ b/dsdplus/dstar.cpp @@ -17,6 +17,7 @@ #include #include "dstar.h" #include "dsd_decoder.h" +#include "descramble.h" namespace DSDplus { @@ -151,6 +152,7 @@ void DSDDstar::init() sync_missed = 0; bitbuffer = 0; m_symbolIndex = 0; + m_symbolIndexHD = 0; } void DSDDstar::initVoiceFrame() @@ -160,6 +162,9 @@ void DSDDstar::initVoiceFrame() w = dW; x = dX; } +void DSDDstar::initDataFrame() +{ +} void DSDDstar::process() { @@ -173,7 +178,15 @@ void DSDDstar::process() } else if (m_symbolIndex < 97) // data frame { + if (m_symbolIndex == 72) { + initDataFrame(); + } + processData(); + } + else + { + m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end } m_symbolIndex++; @@ -181,6 +194,16 @@ void DSDDstar::process() void DSDDstar::processHD() { + int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in HD cache + radioheaderbuffer[m_symbolIndexHD] = dibit; + + if (m_symbolIndexHD == 660-1) + { + dstar_header_decode(); + m_dsdDecoder->m_fsmState = DSDDecoder::DSDprocessDSTAR; // go to DSTAR + } + + m_symbolIndexHD++; } void DSDDstar::processVoice() @@ -223,7 +246,148 @@ void DSDDstar::processVoice() void DSDDstar::processData() { + bool terminate = false; + int dibit = m_dsdDecoder->getDibit(); // get dibit from symbol and store it in cache + m_dibitCache[m_symbolIndex] = dibit; + if (m_symbolIndex == 97-1) // last dibit in data frame + { + for (int i = 73; i < 97; i++) + { + int dibit = m_dibitCache[i]; + + bitbuffer <<= 1; + + if (dibit == 1) { + bitbuffer |= 0x01; + } + + if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) + { + // looking if we're slipping bits + if (i != 96) + { + fprintf(m_dsdDecoder->m_state.logfile, "sync after i=%d\n", i); + break; + } + } + } + + slowdata[0] = (bitbuffer >> 16) & 0x000000FF; + slowdata[1] = (bitbuffer >> 8) & 0x000000FF; + slowdata[2] = (bitbuffer) & 0x000000FF; + slowdata[3] = 0; + + if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) + { + //We got sync! + //printf("Sync on framecount = %d\n", framecount); + sync_missed = 0; + } + else if ((bitbuffer & 0x00FFFFFF) == 0xAAAAAA) + { + //End of transmission + printf("End of transmission\n"); + terminate = true; + } + else if (framecount % 21 == 0) + { + printf("Missed sync on framecount = %d, value = %x/%x/%x\n", + framecount, slowdata[0], slowdata[1], slowdata[2]); + sync_missed++; + } + else if (framecount != 0 && (bitbuffer & 0x00FFFFFF) != 0x000000) + { + slowdata[0] ^= 0x70; + slowdata[1] ^= 0x4f; + slowdata[2] ^= 0x93; + //printf("unscrambled- %s",slowdata); + } + else if (framecount == 0) + { + //printf("never scrambled-%s\n",slowdata); + } + + + if (terminate) + { + m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end + } + else if (sync_missed < 3) + { + m_symbolIndex = 0; // restart a frame sequence + framecount++; + } + else + { + m_dsdDecoder->m_fsmState = DSDDecoder::DSDLookForSync; // end + } + } +} + +void DSDDstar::dstar_header_decode() +{ + int radioheaderbuffer2[660]; + unsigned char radioheader[41]; + int octetcount, bitcount, loop; + unsigned char bit2octet[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + unsigned int FCSinheader; + unsigned int FCScalculated; + int len; + + Descramble::scramble(radioheaderbuffer, radioheaderbuffer2); + Descramble::deinterleave(radioheaderbuffer2, radioheaderbuffer); + len = Descramble::FECdecoder(radioheaderbuffer, radioheaderbuffer2); + memset(radioheader, 0, 41); + + // note we receive 330 bits, but we only use 328 of them (41 octets) + // bits 329 and 330 are unused + octetcount = 0; + bitcount = 0; + + for (loop = 0; loop < 328; loop++) + { + if (radioheaderbuffer2[loop]) + { + radioheader[octetcount] |= bit2octet[bitcount]; + }; + + bitcount++; + + // increase octetcounter and reset bitcounter every 8 bits + if (bitcount >= 8) + { + octetcount++; + bitcount = 0; + } + } + + // print header + printf("\nDSTAR HEADER: "); + //printf("FLAG1: %02X - FLAG2: %02X - FLAG3: %02X\n", radioheader[0], + // radioheader[1], radioheader[2]); + printf("RPT 2: %c%c%c%c%c%c%c%c ", radioheader[3], radioheader[4], + radioheader[5], radioheader[6], radioheader[7], radioheader[8], + radioheader[9], radioheader[10]); + printf("RPT 1: %c%c%c%c%c%c%c%c ", radioheader[11], radioheader[12], + radioheader[13], radioheader[14], radioheader[15], radioheader[16], + radioheader[17], radioheader[18]); + printf("YOUR: %c%c%c%c%c%c%c%c ", radioheader[19], radioheader[20], + radioheader[21], radioheader[22], radioheader[23], radioheader[24], + radioheader[25], radioheader[26]); + printf("MY: %c%c%c%c%c%c%c%c/%c%c%c%c\n", radioheader[27], radioheader[28], + radioheader[29], radioheader[30], radioheader[31], radioheader[32], + radioheader[33], radioheader[34], radioheader[35], radioheader[36], + radioheader[37], radioheader[38]); + + //FCSinheader = ((radioheader[39] << 8) | radioheader[40]) & 0xFFFF; + //FCScalculated = calc_fcs((unsigned char*) radioheader, 39); + //printf("Check sum = %04X ", FCSinheader); + //if (FCSinheader == FCScalculated) { + // printf("(OK)\n"); + //} else { + // printf("(NOT OK- Calculated FCS = %04X)\n", FCScalculated); + //}; // end else - if } } // namespace DSDplus diff --git a/dsdplus/dstar.h b/dsdplus/dstar.h index b5f50143e..ebf56ad66 100644 --- a/dsdplus/dstar.h +++ b/dsdplus/dstar.h @@ -34,11 +34,14 @@ public: private: void initVoiceFrame(); + void initDataFrame(); void processVoice(); void processData(); + void dstar_header_decode(); DSDDecoder *m_dsdDecoder; - int m_symbolIndex; //!< Current symbol index + int m_symbolIndex; //!< Current symbol index in non HD sequence + int m_symbolIndexHD; //!< Current symbol index in HD sequence int m_dibitCache[97]; // has to handle a voice + data frame (97 dibits) int m_dibitIndex; // index in dibit cache