diff --git a/op25/gr-op25_repeater/lib/dstar_header.h b/op25/gr-op25_repeater/lib/dstar_header.h new file mode 100644 index 0000000..034bb26 --- /dev/null +++ b/op25/gr-op25_repeater/lib/dstar_header.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010,2011,2015 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; version 2 of the License. + * + * 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. + */ + +/* from OpenDV/DStarRepeater */ + +#ifndef INCLUDED_DSTAR_HEADER_H +#define INCLUDED_DSTAR_HEADER_H + +#include +#include +#include + +#include "CCITTChecksumReverse.h" +#include "bit_utils.h" + +static inline uint8_t rev_byte(const uint8_t b) { + uint8_t rc = 0; + for (int i=0; i<8; i++) { + rc |= ((b >> i) & 1) << (7-i); + } + return(rc); +} + +static inline void make_dstar_header( + uint8_t header_data_buf[480], // result (bits) + const uint8_t flag1, const uint8_t flag2, const uint8_t flag3, + const char RptCall2[], + const char RptCall1[], + const char YourCall[], + const char MyCall1[], + const char MyCall2[]) +{ + uint8_t m_headerData[60]; + static const unsigned int SLOW_DATA_BLOCK_SIZE = 6U; + static const unsigned int SLOW_DATA_FULL_BLOCK_SIZE = SLOW_DATA_BLOCK_SIZE * 10U; + static const unsigned char SLOW_DATA_TYPE_HEADER = 0x50U; + + ::memset(m_headerData, 'f', SLOW_DATA_FULL_BLOCK_SIZE); + + m_headerData[0U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[1U] = flag1; + m_headerData[2U] = flag2; + m_headerData[3U] = flag3; + m_headerData[4U] = RptCall2[0]; + m_headerData[5U] = RptCall2[1]; + + m_headerData[6U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[7U] = RptCall2[2]; + m_headerData[8U] = RptCall2[3]; + m_headerData[9U] = RptCall2[4]; + m_headerData[10U] = RptCall2[5]; + m_headerData[11U] = RptCall2[6]; + + m_headerData[12U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[13U] = RptCall2[7]; + m_headerData[14U] = RptCall1[0]; + m_headerData[15U] = RptCall1[1]; + m_headerData[16U] = RptCall1[2]; + m_headerData[17U] = RptCall1[3]; + + m_headerData[18U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[19U] = RptCall1[4]; + m_headerData[20U] = RptCall1[5]; + m_headerData[21U] = RptCall1[6]; + m_headerData[22U] = RptCall1[7]; + m_headerData[23U] = YourCall[0]; + + m_headerData[24U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[25U] = YourCall[1]; + m_headerData[26U] = YourCall[2]; + m_headerData[27U] = YourCall[3]; + m_headerData[28U] = YourCall[4]; + m_headerData[29U] = YourCall[5]; + + m_headerData[30U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[31U] = YourCall[6]; + m_headerData[32U] = YourCall[7]; + m_headerData[33U] = MyCall1[0]; + m_headerData[34U] = MyCall1[1]; + m_headerData[35U] = MyCall1[2]; + + m_headerData[36U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[37U] = MyCall1[3]; + m_headerData[38U] = MyCall1[4]; + m_headerData[39U] = MyCall1[5]; + m_headerData[40U] = MyCall1[6]; + m_headerData[41U] = MyCall1[7]; + + m_headerData[42U] = SLOW_DATA_TYPE_HEADER | 5U; + m_headerData[43U] = MyCall2[0]; + m_headerData[44U] = MyCall2[1]; + m_headerData[45U] = MyCall2[2]; + m_headerData[46U] = MyCall2[3]; + + CCCITTChecksumReverse cksum; + cksum.update(m_headerData + 1U, 5U); + cksum.update(m_headerData + 7U, 5U); + cksum.update(m_headerData + 13U, 5U); + cksum.update(m_headerData + 19U, 5U); + cksum.update(m_headerData + 25U, 5U); + cksum.update(m_headerData + 31U, 5U); + cksum.update(m_headerData + 37U, 5U); + cksum.update(m_headerData + 43U, 4U); + + unsigned char checkSum[2U]; + cksum.result(checkSum); + + m_headerData[47U] = checkSum[0]; + + m_headerData[48U] = SLOW_DATA_TYPE_HEADER | 1U; + m_headerData[49U] = checkSum[1]; + + for (int i=0; i +#include "dstar_header.h" #include #include @@ -52,6 +53,15 @@ static inline void print_result(char title[], const uint8_t r[], int len) { } #endif +static inline void sstring(const char s[], char dest[8]) { + memset(dest, ' ', 8); + memcpy(dest, s, std::min(strlen(s), (size_t)8)); + for (int i=0; i<8; i++) { + if (dest[i] < ' ') + dest [i] = ' '; + } +} + static const uint8_t FS[24] = { 1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,0,0,1,1,0,1,0,0,0 }; static const uint8_t FS_DUMMY[24] = { 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1 }; @@ -102,8 +112,13 @@ dstar_tx_sb_impl::config() FILE * fp1 = fopen(d_config_file, "r"); char line[256]; char * cp; - // TODO: add code to generate slow speed datastream - return; + int flag1, flag2, flag3; + char rptcall1[8]; + char rptcall2[8]; + char urcall[8]; + char mycall1[8]; + char mycall2[8]; + if (!fp1) { fprintf(stderr, "dstar_tx_sb_impl:config: failed to open %s\n", d_config_file); return; @@ -112,12 +127,25 @@ dstar_tx_sb_impl::config() cp = fgets(line, sizeof(line) - 2, fp1); if (!cp) break; if (line[0] == '#') continue; -#if 0 - if (memcmp(line, "ft=", 3) == 0) - sscanf(&line[3], "%d", &d_ft); -#endif + if (memcmp(line, "flag1=", 6) == 0) + sscanf(&line[6], "%x", &flag1); + else if (memcmp(line, "flag2=", 6) == 0) + sscanf(&line[6], "%x", &flag2); + else if (memcmp(line, "flag3=", 6) == 0) + sscanf(&line[6], "%x", &flag3); + else if (memcmp(line, "rptcall2=", 9) == 0) + sstring(&line[9], rptcall2); + else if (memcmp(line, "rptcall1=", 9) == 0) + sstring(&line[9], rptcall1); + else if (memcmp(line, "urcall=", 7) == 0) + sstring(&line[7], urcall); + else if (memcmp(line, "mycall1=", 8) == 0) + sstring(&line[8], mycall1); + else if (memcmp(line, "mycall2=", 8) == 0) + sstring(&line[8], mycall2); } fclose(fp1); + make_dstar_header(d_dstar_header_data, flag1 & 0xff, flag2 & 0xff, flag3 & 0xff, rptcall2, rptcall1, urcall, mycall1, mycall2); } void @@ -151,7 +179,7 @@ dstar_tx_sb_impl::general_work (int noutput_items, if (d_frame_counter == 0) memcpy(out+72, FS, 24); else - memcpy(out+72, FS_DUMMY, 24); + memcpy(out+72, d_dstar_header_data+((d_frame_counter-1) * 24), 24); d_frame_counter = (d_frame_counter + 1) % 21; in += 160; nconsumed += 160; diff --git a/op25/gr-op25_repeater/lib/dstar_tx_sb_impl.h b/op25/gr-op25_repeater/lib/dstar_tx_sb_impl.h index 4451702..6570161 100644 --- a/op25/gr-op25_repeater/lib/dstar_tx_sb_impl.h +++ b/op25/gr-op25_repeater/lib/dstar_tx_sb_impl.h @@ -60,6 +60,7 @@ namespace gr { const char * d_config_file; ambe_encoder d_encoder; int d_frame_counter; + uint8_t d_dstar_header_data[480]; }; } // namespace op25_repeater