Fixed free message unpacking, some minor code cleanup
This commit is contained in:
parent
ff7247943c
commit
c727f2b572
3 changed files with 133 additions and 110 deletions
87
ft8/text.cpp
87
ft8/text.cpp
|
@ -3,8 +3,31 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
namespace ft8 {
|
namespace ft8 {
|
||||||
|
|
||||||
|
const char * trim_front(const char *str) {
|
||||||
|
// Skip leading whitespace
|
||||||
|
while (*str == ' ') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
// Utility functions for characters and strings
|
void trim_back(char *str) {
|
||||||
|
// Skip trailing whitespace by replacing it with '\0' characters
|
||||||
|
int idx = strlen(str) - 1;
|
||||||
|
while (idx >= 0 && str[idx] == ' ') {
|
||||||
|
str[idx--] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) trims a string from the back by changing whitespaces to '\0'
|
||||||
|
// 2) trims a string from the front by skipping whitespaces
|
||||||
|
char * trim(char *str) {
|
||||||
|
str = (char *)trim_front(str);
|
||||||
|
trim_back(str);
|
||||||
|
// return a pointer to the first non-whitespace character
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
char to_upper(char c) {
|
char to_upper(char c) {
|
||||||
return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
|
return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
|
||||||
|
@ -118,4 +141,66 @@ void int_to_dd(char *str, int value, int width, bool full_sign) {
|
||||||
*str = 0; // Add zero terminator
|
*str = 0; // Add zero terminator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert integer index to ASCII character according to one of 6 tables:
|
||||||
|
// table 0: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?"
|
||||||
|
// table 1: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
// table 2: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
// table 3: "0123456789"
|
||||||
|
// table 4: " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
// table 5: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/"
|
||||||
|
char charn(int c, int table_idx) {
|
||||||
|
if (table_idx != 2 && table_idx != 3) {
|
||||||
|
if (c == 0) return ' ';
|
||||||
|
c -= 1;
|
||||||
|
}
|
||||||
|
if (table_idx != 4) {
|
||||||
|
if (c < 10) return '0' + c;
|
||||||
|
c -= 10;
|
||||||
|
}
|
||||||
|
if (table_idx != 3) {
|
||||||
|
if (c < 26) return 'A' + c;
|
||||||
|
c -= 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_idx == 0) {
|
||||||
|
if (c < 5) return "+-./?" [c];
|
||||||
|
}
|
||||||
|
else if (table_idx == 5) {
|
||||||
|
if (c == 0) return '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '_'; // unknown character, should never get here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert character to its index (charn in reverse) according to a table
|
||||||
|
int nchar(char c, int table_idx) {
|
||||||
|
int n = 0;
|
||||||
|
if (table_idx != 2 && table_idx != 3) {
|
||||||
|
if (c == ' ') return n + 0;
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
if (table_idx != 4) {
|
||||||
|
if (c >= '0' && c <= '9') return n + (c - '0');
|
||||||
|
n += 10;
|
||||||
|
}
|
||||||
|
if (table_idx != 3) {
|
||||||
|
if (c >= 'A' && c <= 'Z') return n + (c - 'A');
|
||||||
|
n += 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_idx == 0) {
|
||||||
|
if (c == '+') return n + 0;
|
||||||
|
if (c == '-') return n + 1;
|
||||||
|
if (c == '.') return n + 2;
|
||||||
|
if (c == '/') return n + 3;
|
||||||
|
if (c == '?') return n + 4;
|
||||||
|
}
|
||||||
|
else if (table_idx == 5) {
|
||||||
|
if (c == '/') return n + 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Character not found
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
|
@ -1,6 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace ft8 {
|
namespace ft8 {
|
||||||
|
// Utility functions for characters and strings
|
||||||
|
|
||||||
|
const char * trim_front(const char *str);
|
||||||
|
void trim_back(char *str);
|
||||||
|
char * trim(char *str);
|
||||||
|
|
||||||
char to_upper(char c);
|
char to_upper(char c);
|
||||||
bool is_digit(char c);
|
bool is_digit(char c);
|
||||||
|
@ -23,4 +28,6 @@ namespace ft8 {
|
||||||
// Convert a 2 digit integer to string
|
// Convert a 2 digit integer to string
|
||||||
void int_to_dd(char *str, int value, int width, bool full_sign = false);
|
void int_to_dd(char *str, int value, int width, bool full_sign = false);
|
||||||
|
|
||||||
|
char charn(int c, int table_idx);
|
||||||
|
int nchar(char c, int table_idx);
|
||||||
}
|
}
|
149
ft8/unpack.cpp
149
ft8/unpack.cpp
|
@ -11,33 +11,6 @@ const uint32_t NTOKENS = 2063592L;
|
||||||
const uint16_t MAXGRID4 = 32400L;
|
const uint16_t MAXGRID4 = 32400L;
|
||||||
|
|
||||||
|
|
||||||
// convert integer index to ASCII character according to one of 5 tables:
|
|
||||||
// table 0: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?"
|
|
||||||
// table 1: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
// table 2: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
// table 3: "0123456789"
|
|
||||||
// table 4: " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
char charn(int c, int table_idx) {
|
|
||||||
if (table_idx == 0 || table_idx == 1 || table_idx == 4) {
|
|
||||||
if (c == 0) return ' ';
|
|
||||||
c -= 1;
|
|
||||||
}
|
|
||||||
if (table_idx != 4) {
|
|
||||||
if (c < 10) return '0' + c;
|
|
||||||
c -= 10;
|
|
||||||
}
|
|
||||||
if (table_idx != 3) {
|
|
||||||
if (c < 26) return 'A' + c;
|
|
||||||
c -= 26;
|
|
||||||
}
|
|
||||||
if (table_idx == 0) {
|
|
||||||
if (c < 5) return "+-./?" [c];
|
|
||||||
}
|
|
||||||
|
|
||||||
return '_'; // unknown character, should never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// n28 is a 28-bit integer, e.g. n28a or n28b, containing all the
|
// n28 is a 28-bit integer, e.g. n28a or n28b, containing all the
|
||||||
// call sign bits from a packed message.
|
// call sign bits from a packed message.
|
||||||
int unpack28(uint32_t n28, uint8_t ip, uint8_t i3, char *result) {
|
int unpack28(uint32_t n28, uint8_t ip, uint8_t i3, char *result) {
|
||||||
|
@ -61,22 +34,14 @@ int unpack28(uint32_t n28, uint8_t ip, uint8_t i3, char *result) {
|
||||||
char aaaa[5];
|
char aaaa[5];
|
||||||
|
|
||||||
aaaa[4] = '\0';
|
aaaa[4] = '\0';
|
||||||
aaaa[3] = charn(n % 27, 4);
|
for (int i = 3; /* */; --i) {
|
||||||
n /= 27;
|
aaaa[i] = charn(n % 27, 4);
|
||||||
aaaa[2] = charn(n % 27, 4);
|
if (i == 0) break;
|
||||||
n /= 27;
|
n /= 27;
|
||||||
aaaa[1] = charn(n % 27, 4);
|
|
||||||
n /= 27;
|
|
||||||
aaaa[0] = charn(n % 27, 4);
|
|
||||||
|
|
||||||
// Skip leading whitespace
|
|
||||||
int ws_len = 0;
|
|
||||||
while (aaaa[ws_len] == ' ') {
|
|
||||||
ws_len++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(result, "CQ ");
|
strcpy(result, "CQ ");
|
||||||
strcat(result, aaaa + ws_len);
|
strcat(result, trim_front(aaaa));
|
||||||
return 0; // Success
|
return 0; // Success
|
||||||
}
|
}
|
||||||
// ? TODO: unspecified in the WSJT-X code
|
// ? TODO: unspecified in the WSJT-X code
|
||||||
|
@ -110,16 +75,7 @@ int unpack28(uint32_t n28, uint8_t ip, uint8_t i3, char *result) {
|
||||||
callsign[0] = charn(n % 37, 1);
|
callsign[0] = charn(n % 37, 1);
|
||||||
|
|
||||||
// Skip trailing and leading whitespace in case of a short callsign
|
// Skip trailing and leading whitespace in case of a short callsign
|
||||||
int ws_len = 0;
|
strcpy(result, trim(callsign));
|
||||||
while (ws_len <= 5 && callsign[5 - ws_len] == ' ') {
|
|
||||||
callsign[5 - ws_len] = '\0';
|
|
||||||
ws_len++;
|
|
||||||
}
|
|
||||||
ws_len = 0;
|
|
||||||
while (callsign[ws_len] == ' ') {
|
|
||||||
ws_len++;
|
|
||||||
}
|
|
||||||
strcpy(result, callsign + ws_len);
|
|
||||||
|
|
||||||
// Check if we should append /R or /P suffix
|
// Check if we should append /R or /P suffix
|
||||||
if (ip) {
|
if (ip) {
|
||||||
|
@ -176,12 +132,12 @@ int unpack_type1(const uint8_t *a77, uint8_t i3, char *message) {
|
||||||
strcat(message, field_2);
|
strcat(message, field_2);
|
||||||
|
|
||||||
// TODO: add to recent calls
|
// TODO: add to recent calls
|
||||||
if (field_1[0] != '<' && strlen(field_1) >= 4) {
|
// if (field_1[0] != '<' && strlen(field_1) >= 4) {
|
||||||
// add_call_to_recent_calls(field_1)
|
// save_hash_call(field_1)
|
||||||
}
|
// }
|
||||||
if (field_2[0] != '<' && strlen(field_2) >= 4) {
|
// if (field_2[0] != '<' && strlen(field_2) >= 4) {
|
||||||
// add_call_to_recent_calls(field_2)
|
// save_hash_call(field_2)
|
||||||
}
|
// }
|
||||||
|
|
||||||
char field_3[5];
|
char field_3[5];
|
||||||
if (igrid4 <= MAXGRID4) {
|
if (igrid4 <= MAXGRID4) {
|
||||||
|
@ -237,14 +193,16 @@ int unpack_text(const uint8_t *a71, char *text) {
|
||||||
// TODO: test
|
// TODO: test
|
||||||
uint8_t b71[9];
|
uint8_t b71[9];
|
||||||
|
|
||||||
|
uint8_t carry = 0;
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
b71[i] = a71[i];
|
b71[i] = carry | (a71[i] >> 1);
|
||||||
|
carry = (a71[i] & 1) ? 0x80 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx = 0; idx < 13; ++idx) {
|
for (int idx = 12; idx >= 0; --idx) {
|
||||||
// Divide the long integer in b71 by 42
|
// Divide the long integer in b71 by 42
|
||||||
uint16_t rem = 0;
|
uint16_t rem = 0;
|
||||||
for (int i = 8; i >= 0; --i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
rem = (rem << 8) | b71[i];
|
rem = (rem << 8) | b71[i];
|
||||||
b71[i] = rem / 42;
|
b71[i] = rem / 42;
|
||||||
rem = rem % 42;
|
rem = rem % 42;
|
||||||
|
@ -284,7 +242,7 @@ int unpack_telemetry(const uint8_t *a71, char *telemetry) {
|
||||||
|
|
||||||
//none standard for wsjt-x 2.0
|
//none standard for wsjt-x 2.0
|
||||||
//by KD8CEC
|
//by KD8CEC
|
||||||
int unpack_nonestandard(const uint8_t *a77, uint8_t i3, char *message)
|
int unpack_nonstandard(const uint8_t *a77, char *message)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
wsjt-x 2.1.0 rc5
|
wsjt-x 2.1.0 rc5
|
||||||
|
@ -313,52 +271,26 @@ int unpack_nonestandard(const uint8_t *a77, uint8_t i3, char *message)
|
||||||
char c11[12];
|
char c11[12];
|
||||||
c11[11] = '\0';
|
c11[11] = '\0';
|
||||||
|
|
||||||
c11[10] = charn(n58 % 38, 0);
|
for (int i = 10; /* no condition */ ; --i) {
|
||||||
n58 /= 38;
|
c11[i] = charn(n58 % 38, 5);
|
||||||
c11[9] = charn(n58 % 38, 0);
|
if (i == 0) break;
|
||||||
n58 /= 38;
|
n58 /= 38;
|
||||||
c11[8] = charn(n58 % 38, 0);
|
}
|
||||||
n58 /= 38;
|
|
||||||
c11[7] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[6] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[5] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[4] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[3] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[2] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[1] = charn(n58 % 38, 0);
|
|
||||||
n58 /= 38;
|
|
||||||
c11[0] = charn(n58 % 38, 0);
|
|
||||||
|
|
||||||
//StrTrim(c11);
|
|
||||||
|
|
||||||
char call_3[15];
|
char call_3[15];
|
||||||
char *call_1, *call_2;
|
call_3[0] = '<';
|
||||||
|
call_3[1] = '>';
|
||||||
|
call_3[2] = '\0';
|
||||||
//hash12(n12, call_3);
|
//hash12(n12, call_3);
|
||||||
|
|
||||||
if (iflip == 0)
|
char * call_1 = (iflip) ? c11 : call_3;
|
||||||
{
|
char * call_2 = (iflip) ? call_3 : c11;
|
||||||
call_1 = call_3;
|
//save_hash_call(c11_trimmed);
|
||||||
call_2 = c11;
|
|
||||||
//save_hash_call(call_2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
call_1 = c11;
|
|
||||||
call_2 = call_3;
|
|
||||||
//save_hash_call(call_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icq == 0)
|
if (icq == 0) {
|
||||||
{
|
strcpy(message, trim(call_1));
|
||||||
strcpy(message, call_1);
|
|
||||||
strcat(message, " ");
|
strcat(message, " ");
|
||||||
strcat(message, call_1);
|
strcat(message, trim(call_2));
|
||||||
if (nrpt == 1)
|
if (nrpt == 1)
|
||||||
strcat(message, " RRR");
|
strcat(message, " RRR");
|
||||||
else if (nrpt == 2)
|
else if (nrpt == 2)
|
||||||
|
@ -366,11 +298,9 @@ int unpack_nonestandard(const uint8_t *a77, uint8_t i3, char *message)
|
||||||
else if (nrpt == 3)
|
else if (nrpt == 3)
|
||||||
strcat(message, " 73");
|
strcat(message, " 73");
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(message, "CQ ");
|
strcpy(message, "CQ ");
|
||||||
strcat(message, c11);
|
strcat(message, trim(call_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -412,13 +342,14 @@ int unpack77(const uint8_t *a77, char *message) {
|
||||||
// // Type 4: Nonstandard calls, e.g. <WA9XYZ> PJ4/KA1ABC RR73
|
// // Type 4: Nonstandard calls, e.g. <WA9XYZ> PJ4/KA1ABC RR73
|
||||||
// // One hashed call or "CQ"; one compound or nonstandard call with up
|
// // One hashed call or "CQ"; one compound or nonstandard call with up
|
||||||
// // to 11 characters; and (if not "CQ") an optional RRR, RR73, or 73.
|
// // to 11 characters; and (if not "CQ") an optional RRR, RR73, or 73.
|
||||||
return unpack_nonestandard(a77, i3, message);
|
return unpack_nonstandard(a77, message);
|
||||||
}
|
|
||||||
else {
|
|
||||||
// unknown type
|
|
||||||
message[0] = '\0';
|
|
||||||
}
|
}
|
||||||
|
// else if (i3 == 5) {
|
||||||
|
// // Type 5: TU; W9XYZ K1ABC R-09 FN 1 28 28 1 7 9 74 WWROF contest
|
||||||
|
// }
|
||||||
|
|
||||||
|
// unknown type, should never get here
|
||||||
|
message[0] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue