diff --git a/encode_91.cpp b/encode_91.cpp index 624009a..34a0b88 100644 --- a/encode_91.cpp +++ b/encode_91.cpp @@ -95,15 +95,15 @@ const uint8_t G[M][K_BYTES] = { // Column order (permutation) in which the bits in codeword are stored const uint8_t colorder[N] = { - 0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16, - 17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43, - 36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62, - 56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79, - 73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119, - 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,171,172,173 + 0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16, + 17, 18, 36, 29, 43, 19, 20, 42, 21, 40, 30, 37, 22, 47, 61, 45, 44, 23, 41, 39, + 49, 24, 46, 50, 48, 26, 31, 33, 51, 38, 52, 59, 55, 66, 57, 27, 60, 35, 54, 58, + 25, 56, 62, 64, 67, 69, 63, 68, 70, 72, 65, 73, 75, 74, 71, 77, 78, 76, 79, 80, + 53, 81, 83, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119, + 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139, + 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173 }; // Costas 7x7 tone pattern @@ -234,7 +234,7 @@ void genft8(const uint8_t *payload, uint8_t i3, uint8_t *itone) { a91[9] |= (uint8_t)(checksum >> 11); a91[10] = (uint8_t)(checksum >> 3); - // a87 contains 72 bits of payload + 3 bits of i3 + 12 bits of CRC + // a87 contains 77 bits of payload + 14 bits of CRC uint8_t codeword[22]; encode174(a91, codeword); diff --git a/pack_77.cpp b/pack_77.cpp index ff22242..0ddff29 100644 --- a/pack_77.cpp +++ b/pack_77.cpp @@ -3,6 +3,7 @@ #include "text.h" +// TODO: This is wasteful, should figure out something more elegant const char *A0 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?"; const char *A1 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *A2 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -24,13 +25,10 @@ int32_t pack28(const char *callsign) { constexpr int32_t NTOKENS = 2063592L; constexpr int32_t MAX22 = 4194304L; - int length = strlen(callsign); // We will need it later - if (length > 13) return -1; - // Check for special tokens first - if (equals(callsign, "DE")) return 0; - if (equals(callsign, "QRZ")) return 1; - if (equals(callsign, "CQ")) return 2; + if (starts_with(callsign, "DE ")) return 0; + if (starts_with(callsign, "QRZ ")) return 1; + if (starts_with(callsign, "CQ ")) return 2; if (starts_with(callsign, "CQ_")) { int nnum = 0, nlet = 0; @@ -46,6 +44,11 @@ int32_t pack28(const char *callsign) { char c6[6] = {' ', ' ', ' ', ' ', ' ', ' '}; + int length = 0; // strlen(callsign); // We will need it later + while (callsign[length] != ' ' && callsign[length] != 0) { + length++; + } + // Work-around for Swaziland prefix: if (starts_with(callsign, "3DA0") && length <= 7) { memcpy(c6, "3D0", 3); @@ -83,6 +86,8 @@ int32_t pack28(const char *callsign) { //char c13[13]; + //if (length > 13) return -1; + // Treat this as a nonstandard callsign: compute its 22-bit hash // call save_hash_call(c13,n10,n12,n22) !Save callsign in hash table // n28=NTOKENS + n22 @@ -113,27 +118,82 @@ bool chkcall(const char *call, char *bc) { } +uint16_t packgrid(const char *grid4) { + constexpr uint16_t MAXGRID4 = 32400; + + if (grid4 == 0) { + // Two callsigns only, no report/grid + return MAXGRID4 + 1; + } + + // Take care of special cases + if (equals(grid4, "RRR")) return MAXGRID4 + 2; + if (equals(grid4, "RR73")) return MAXGRID4 + 3; + if (equals(grid4, "73")) return MAXGRID4 + 4; + + // Check for standard 4 letter grid + if (in_range(grid4[0], 'A', 'R') && + in_range(grid4[1], 'A', 'R') && + is_digit(grid4[2]) && is_digit(grid4[3])) + { + //if (w(3).eq.'R ') ir=1 + uint16_t igrid4 = (grid4[3] - '0'); + igrid4 = igrid4 * 10 + (grid4[2] - '0'); + igrid4 = igrid4 * 10 + (grid4[1] - 'A'); + igrid4 = igrid4 * 18 + (grid4[0] - 'A'); + return igrid4; + } + + // Parse report: +dd / -dd / R+dd / R-dd + // TODO: check the range of dd + if (grid4[0] == 'R') { + int dd = dd_to_int(grid4 + 1, 3); + uint16_t irpt = 35 + dd; + return (MAXGRID4 + irpt) | 0x8000; // ir = 1 + } + else { + int dd = dd_to_int(grid4, 3); + uint16_t irpt = 35 + dd; + return (MAXGRID4 + irpt); // ir = 0 + } + + return MAXGRID4 + 1; +} + // Pack Type 1 (Standard 77-bit message) and Type 2 (ditto, with a "/P" call) -void pack77_1(const char *msg, uint8_t i3, uint8_t *b77) { +int pack77_1(const char *msg, uint8_t *b77) { + // Locate the first delimiter + const char *s1 = strchr(msg, ' '); + if (s1 == 0) return -1; + + const char *call1 = msg; // 1st call + const char *call2 = s1 + 1; // 2nd call + + int32_t n28a = pack28(call1); + int32_t n28b = pack28(call2); + + uint16_t igrid4; + + // Locate the second delimiter + const char *s2 = strchr(s1 + 1, ' '); + if (s2 != 0) { + igrid4 = packgrid(s2 + 1); + } + else { + // Two callsigns, no grid/report + igrid4 = packgrid(0); + } + + uint8_t i3 = 1; + // if(index(w(1),'/P').ge.4 .or. index(w(2),'/P').ge.4) i3=2 !Type 2, with "/P" // if(index(w(1),'/P').ge.4 .or. index(w(1),'/R').ge.4) ipa=1 // if(index(w(2),'/P').ge.4 .or. index(w(2),'/R').ge.4) ipb=1 - int32_t n28a, n28b; - uint16_t igrid4; - - const char *call1, *call2; - - n28a = pack28(call1); - n28b = pack28(call2); - - // Add ipa and ipb bits to the right + // Shift in ipa and ipb bits into n28a and n28b n28a <<= 1; // ipa = 0 n28b <<= 1; // ipb = 0 - // Add igrid4 bit to the left - //igrid4 |= 0x8000; // ir = 1 - // write(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3 // 1000 format(2(b28.28,b1),b1,b15.15,b3.3) // (28 + 1) + (28 + 1) + (1 + 15) + 3 @@ -148,6 +208,8 @@ void pack77_1(const char *msg, uint8_t i3, uint8_t *b77) { b77[7] = (uint8_t)(n28a << 6) | (uint8_t)(igrid4 >> 10); b77[8] = (igrid4 >> 2); b77[9] = (uint8_t)(igrid4 << 6) | (uint8_t)(i3 << 3); + + return 0; } @@ -182,10 +244,9 @@ void packtext77(const char *c13, uint8_t *b71) { int pack77(const char *msg, uint8_t *c77) { // Check Type 1 (Standard 77-bit message) or Type 2, with optional "/P" - if (starts_with(msg, "CQ ")) { - pack77_1(nwords,w,i3,n3,c77); - return; - } + //if (starts_with(msg, "CQ ")) { + return pack77_1(msg, c77); + //} // Check 0.5 (telemetry) // i3=0 n3=5 write(c77,1006) ntel,n3,i3 1006 format(b23.23,2b24.24,2b3.3)