diff --git a/AMBEFEC.cpp b/AMBEFEC.cpp index 32456bc..65303ef 100644 --- a/AMBEFEC.cpp +++ b/AMBEFEC.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "Golay24128.h" #include "AMBEFEC.h" #include diff --git a/AMBEFEC.h b/AMBEFEC.h index cc04cde..99ebd6f 100644 --- a/AMBEFEC.h +++ b/AMBEFEC.h @@ -19,8 +19,6 @@ #ifndef AMBEFEC_H #define AMBEFEC_H -#include "Golay24128.h" - class CAMBEFEC { public: CAMBEFEC(); diff --git a/CRC.cpp b/CRC.cpp index bcf018c..23deca6 100644 --- a/CRC.cpp +++ b/CRC.cpp @@ -26,7 +26,7 @@ #include #include -const uint16_t CCITT16_TABLE[] = { +const uint16_t CCITT16_TABLE1[] = { 0x0000U, 0x1189U, 0x2312U, 0x329bU, 0x4624U, 0x57adU, 0x6536U, 0x74bfU, 0x8c48U, 0x9dc1U, 0xaf5aU, 0xbed3U, 0xca6cU, 0xdbe5U, 0xe97eU, 0xf8f7U, 0x1081U, 0x0108U, 0x3393U, 0x221aU, 0x56a5U, 0x472cU, 0x75b7U, 0x643eU, @@ -60,6 +60,40 @@ const uint16_t CCITT16_TABLE[] = { 0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U, 0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U }; +const uint16_t CCITT16_TABLE2[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 }; + bool CCRC::checkFiveBit(bool* in, unsigned int tcrc) { assert(in != NULL); @@ -144,7 +178,7 @@ void CCRC::addCCITT16(unsigned char *in, unsigned int length) crc16 = 0xFFFFU; for (unsigned int i = 0U; i < (length - 2U); i++) - crc16 = uint16_t(crc8[1U]) ^ CCITT16_TABLE[crc8[0U] ^ in[i]]; + crc16 = uint16_t(crc8[1U]) ^ CCITT16_TABLE1[crc8[0U] ^ in[i]]; crc16 = ~crc16; @@ -168,3 +202,23 @@ unsigned char CCRC::crc8(const unsigned char *in, unsigned int length) return crc >> 8; } + +bool CCRC::crcFICH(const unsigned char* fich) +{ + assert(fich != NULL); + + union { + uint16_t crc16; + uint8_t crc8[2U]; + }; + + crc16 = 0U; + crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ fich[0U]]; + crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ fich[1U]]; + crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ fich[2U]]; + crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ fich[3U]]; + + crc16 = ~crc16; + + return crc8[0U] == fich[5U] && crc8[1U] == fich[4U]; +} diff --git a/CRC.h b/CRC.h index 3fe2df9..f5830b1 100644 --- a/CRC.h +++ b/CRC.h @@ -31,6 +31,8 @@ public: static unsigned char encodeEightBit(const unsigned char* in, unsigned int length); static unsigned char crc8(const unsigned char* in, unsigned int length); + + static bool crcFICH(const unsigned char* fich); }; #endif diff --git a/Golay24128.cpp b/Golay24128.cpp index 60f99c8..417da00 100644 --- a/Golay24128.cpp +++ b/Golay24128.cpp @@ -5,6 +5,9 @@ #include "Golay24128.h" +#include +#include + const unsigned int ENCODING_TABLE_23127[] = { 0x000000U, 0x0018EAU, 0x00293EU, 0x0031D4U, 0x004A96U, 0x00527CU, 0x0063A8U, 0x007B42U, 0x008DC6U, 0x00952CU, 0x00A4F8U, 0x00BC12U, 0x00C750U, 0x00DFBAU, 0x00EE6EU, 0x00F684U, 0x010366U, 0x011B8CU, 0x012A58U, 0x0132B2U, @@ -1090,3 +1093,16 @@ unsigned int CGolay24128::decode24128(unsigned int code) { return decode23127(code >> 1); } + +unsigned int CGolay24128::decode24128(unsigned char* bytes) +{ + assert(bytes != NULL); + + unsigned int code = bytes[0U]; + code <<= 8; + code |= bytes[1U]; + code <<= 8; + code |= bytes[2U]; + + return decode23127(code >> 1); +} diff --git a/Golay24128.h b/Golay24128.h index 9630e50..1ac7852 100644 --- a/Golay24128.h +++ b/Golay24128.h @@ -26,6 +26,7 @@ public: static unsigned int decode23127(unsigned int code); static unsigned int decode24128(unsigned int code); + static unsigned int decode24128(unsigned char* bytes); }; #endif diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index ad43975..0e9805b 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -189,8 +189,10 @@ + + @@ -231,7 +233,9 @@ + + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index 15f9e3e..ca31965 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -146,6 +146,12 @@ Header Files + + Header Files + + + Header Files + @@ -265,5 +271,11 @@ Source Files + + Source Files + + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index c127b94..77ed12a 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,12 @@ all: MMDVMHost MMDVMHost: AMBEFEC.o BPTC19696.o Conf.o CRC.o CSBK.o Display.o DMRControl.o DMRData.o DMRDataHeader.o DMRSlot.o DMRSync.o DStarControl.o DStarHeader.o \ DStarNetwork.o DStarSlowData.o EMB.o EmbeddedLC.o FullLC.o Golay2087.o Golay24128.o Hamming.o HomebrewDMRIPSC.o LC.o Log.o MMDVMHost.o Modem.o \ - NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o ShortLC.o SlotType.o StopWatch.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFEcho.o + NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o ShortLC.o SlotType.o StopWatch.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFConvolution.o \ + YSFEcho.o YSFFICH.o $(CC) $(LDFLAGS) -o MMDVMHost AMBEFEC.o BPTC19696.o Conf.o CRC.o CSBK.o Display.o DMRControl.o DMRData.o DMRDataHeader.o DMRSlot.o DMRSync.o DStarControl.o \ DStarHeader.o DStarNetwork.o DStarSlowData.o EMB.o EmbeddedLC.o FullLC.o Golay2087.o Golay24128.o Hamming.o HomebrewDMRIPSC.o LC.o Log.o MMDVMHost.o \ - Modem.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o ShortLC.o SlotType.o StopWatch.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFEcho.o \ + Modem.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o ShortLC.o SlotType.o StopWatch.o TFTSerial.o Timer.o UDPSocket.o Utils.o \ + YSFConvolution.o YSFEcho.o YSFFICH.o $(LIBS) AMBEFEC.o: AMBEFEC.cpp AMBEFEC.h Golay24128.h @@ -130,8 +132,14 @@ UDPSocket.o: UDPSocket.cpp UDPSocket.h Log.h Utils.o: Utils.cpp Utils.h Log.h $(CC) $(CFLAGS) -c Utils.cpp +YSFConvolution.o: YSFConvolution.cpp YSFConvolution.h + $(CC) $(CFLAGS) -c YSFConvolution.cpp + YSFEcho.o: YSFEcho.cpp YSFEcho.h YSFDefines.h RingBuffer.h Timer.h $(CC) $(CFLAGS) -c YSFEcho.cpp +YSFFICH.o: YSFFICH.cpp YSFFICH.h YSFConvolution.h CRC.h Golay24128.h + $(CC) $(CFLAGS) -c YSFFICH.cpp + clean: $(RM) MMDVMHost *.o *.bak *~ diff --git a/Version.h b/Version.h index 9ce126e..56a183b 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20160203"; +const char* VERSION = "20160204"; #endif diff --git a/YSFConvolution.cpp b/YSFConvolution.cpp new file mode 100644 index 0000000..6633ee3 --- /dev/null +++ b/YSFConvolution.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "YSFConvolution.h" + +#include +#include +#include + +const unsigned int BUFFER_LENGTH = 200U; + +const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; + +#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) +#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) + +const unsigned char BRANCH_TABLE1[] = {0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U}; +const unsigned char BRANCH_TABLE2[] = {0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U}; + +CYSFConvolution::CYSFConvolution() : +m_metrics1(NULL), +m_metrics2(NULL), +m_oldMetrics(NULL), +m_newMetrics(NULL), +m_decisions(NULL), +m_dp(NULL) +{ + m_metrics1 = new unsigned short[16U]; + m_metrics2 = new unsigned short[16U]; + m_decisions = new unsigned long long[100U]; +} + +CYSFConvolution::~CYSFConvolution() +{ + delete[] m_metrics1; + delete[] m_metrics2; + delete[] m_decisions; +} + +const unsigned int NUM_OF_STATES_D2 = 8U; +const unsigned int NUM_OF_STATES = 16U; +const unsigned int M = 3U; +const unsigned int K = 5U; + +void CYSFConvolution::start() +{ + ::memset(m_metrics1, 0x00U, NUM_OF_STATES * sizeof(unsigned short)); + ::memset(m_metrics2, 0x00U, NUM_OF_STATES * sizeof(unsigned short)); + + m_oldMetrics = m_metrics1; + m_newMetrics = m_metrics2; + m_dp = m_decisions; +} + +void CYSFConvolution::decode(unsigned char s0, unsigned char s1) +{ + *m_dp = 0U; + + for (unsigned int i = 0U; i < NUM_OF_STATES_D2; i++) { + unsigned int j = i * 2U; + + unsigned short metric = (BRANCH_TABLE1[i] ^ s0) + (BRANCH_TABLE2[i] ^ s1); + + unsigned short m0 = m_oldMetrics[i] + metric; + unsigned short m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric); + unsigned char decision0 = (m0 >= m1) ? 1U : 0U; + m_newMetrics[j + 0U] = decision0 != 0U ? m1 : m0; + + m0 = m_oldMetrics[i] + (M - metric); + m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + metric; + unsigned char decision1 = (m0 >= m1) ? 1U : 0U; + m_newMetrics[j + 1U] = decision1 != 0U ? m1 : m0; + + *m_dp |= ((unsigned long long)(decision1) << (j + 1U)) | ((unsigned long long)(decision0) << (j + 0U)); + } + + ++m_dp; + + unsigned short* tmp = m_oldMetrics; + m_oldMetrics = m_newMetrics; + m_newMetrics = tmp; +} + +void CYSFConvolution::chainback(unsigned char* out) +{ + assert(out != NULL); + + unsigned int state = 0U; + + unsigned char nbits = 96U; + while (nbits-- > 0) { + --m_dp; + + unsigned int i = state >> (9 - K); + unsigned char bit = (unsigned char)(*m_dp >> i) & 1; + state = (bit << 7) | (state >> 1); + + WRITE_BIT1(out, nbits, bit != 0U); + } +} diff --git a/YSFConvolution.h b/YSFConvolution.h new file mode 100644 index 0000000..4b805b2 --- /dev/null +++ b/YSFConvolution.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(YSFConvolution_H) +#define YSFConvolution_H + +#include "YSFConvolution.h" + +class CYSFConvolution { +public: + CYSFConvolution(); + ~CYSFConvolution(); + + void start(); + void decode(unsigned char s0, unsigned char s1); + void chainback(unsigned char* out); + +private: + unsigned short* m_metrics1; + unsigned short* m_metrics2; + unsigned short* m_oldMetrics; + unsigned short* m_newMetrics; + unsigned long long* m_decisions; + unsigned long long* m_dp; +}; + +#endif + diff --git a/YSFFICH.cpp b/YSFFICH.cpp new file mode 100644 index 0000000..efc4fcf --- /dev/null +++ b/YSFFICH.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "YSFConvolution.h" +#include "Golay24128.h" +#include "YSFFICH.h" +#include "CRC.h" + +#include +#include + + +const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; + +#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) +#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) + +const unsigned int INTERLEAVE_TABLE_RX[] = { + 0U, 40U, 80U, 120U, 160U, + 2U, 42U, 82U, 122U, 162U, + 4U, 44U, 84U, 124U, 164U, + 6U, 46U, 86U, 126U, 166U, + 8U, 48U, 88U, 128U, 168U, + 10U, 50U, 90U, 130U, 170U, + 12U, 52U, 92U, 132U, 172U, + 14U, 54U, 94U, 134U, 174U, + 16U, 56U, 96U, 136U, 176U, + 18U, 58U, 98U, 138U, 178U, + 20U, 60U, 100U, 140U, 180U, + 22U, 62U, 102U, 142U, 182U, + 24U, 64U, 104U, 144U, 184U, + 26U, 66U, 106U, 146U, 186U, + 28U, 68U, 108U, 148U, 188U, + 30U, 70U, 110U, 150U, 190U, + 32U, 72U, 112U, 152U, 192U, + 34U, 74U, 114U, 154U, 194U, + 36U, 76U, 116U, 156U, 196U, + 38U, 78U, 118U, 158U, 198U}; + +CYSFFICH::CYSFFICH() +{ +} + +CYSFFICH::~CYSFFICH() +{ +} + +bool CYSFFICH::decode(const unsigned char* data, unsigned char* fich) const +{ + assert(data != NULL); + assert(fich != NULL); + + CYSFConvolution viterbi; + viterbi.start(); + + // Deinterleave the FICH and send bits to the Viterbi decoder + for (unsigned int i = 0U; i < 100U; i++) { + unsigned int n = INTERLEAVE_TABLE_RX[i]; + unsigned int s0 = READ_BIT1(data, n) ? 1U : 0U; + + n++; + unsigned int s1 = READ_BIT1(data, n) ? 1U : 0U; + + viterbi.decode(s0, s1); + } + + unsigned char output[13U]; + viterbi.chainback(output); + + unsigned int b0 = CGolay24128::decode24128(output + 0U); + unsigned int b1 = CGolay24128::decode24128(output + 3U); + unsigned int b2 = CGolay24128::decode24128(output + 6U); + unsigned int b3 = CGolay24128::decode24128(output + 9U); + + fich[0U] = (b0 >> 16) & 0xFFU; + fich[1U] = ((b0 >> 8) & 0xF0U) | ((b1 >> 20) & 0x0FU); + fich[2U] = (b1 >> 12) & 0xFFU; + fich[3U] = (b2 >> 16) & 0xFFU; + fich[4U] = ((b2 >> 8) & 0xF0U) | ((b3 >> 20) & 0x0FU); + fich[5U] = (b3 >> 12) & 0xFFU; + + return CCRC::crcFICH(fich); +} diff --git a/YSFFICH.h b/YSFFICH.h new file mode 100644 index 0000000..28e50a0 --- /dev/null +++ b/YSFFICH.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(YSFFICH_H) +#define YSFFICH_H + +class CYSFFICH { +public: + CYSFFICH(); + ~CYSFFICH(); + + bool decode(const unsigned char* frame, unsigned char* fich) const; + +private: +}; + +#endif