Added free-text encoding, fixed minor integer width bugs

This commit is contained in:
Karlis Goba 2018-10-18 18:31:24 +03:00
parent 500c204f4d
commit c122a2b01d

View file

@ -4,8 +4,8 @@
#include "pack.h"
constexpr int NBASE = 37*36*10*27*27*27;
constexpr int NGBASE = 180*180;
constexpr int32_t NBASE = 37*36*10*27*27*27L;
constexpr int32_t NGBASE = 180*180L;
// Utility functions for characters and strings
@ -54,21 +54,26 @@ void fmtmsg(char *msg_out, const char *msg_in) {
// Returns integer encoding of a character (number/digit/space).
// Alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?"
// - Digits are encoded as 0..9
// - Letters a..z are encoded as 10..35 (case insensitive)
// - Space is encoded as 36
uint8_t nchar(char c) {
if (is_digit(c)) {
if (is_digit(c))
return (c - '0');
}
if (is_letter(c)) {
if (is_letter(c))
return (to_upper(c) - 'A') + 10;
switch (c) {
case ' ': return 36;
case '+': return 37;
case '-': return 38;
case '.': return 39;
case '/': return 40;
case '?': return 41;
default: return 36; // Equal to ' '
}
if (c == ' ') {
return 36;
}
// we should never reach here
return 36;
}
@ -327,6 +332,37 @@ int16_t packgrid(const char *grid) {
return ng;
}
// Pack a free-text message into 3 integers (28+28+15 bits)
void packtext(const char *msg, int32_t &nc1, int32_t &nc2, int16_t &ng) {
int32_t nc3;
nc1 = nc2 = ng = 0;
// Pack 5 characters (42^5) into 27 bits
for (int i = 0; i < 5; ++i) { // First 5 characters in nc1
uint8_t j = nchar(msg[i]); // Get character code
nc1 = 42*nc1 + j;
}
// Pack 5 characters (42^5) into 27 bits
for (int i = 5; i < 10; ++i) { // Characters 6-10 in nc2
uint8_t j = nchar(msg[i]); // Get character code
nc2 = 42*nc2 + j;
}
// Pack 3 characters (42^3) into 17 bits
for (int i = 10; i < 13; ++i) { // Characters 11-13 in nc3
uint8_t j = nchar(msg[i]); // Get character code
nc3 = 42*nc3 + j;
}
// We now have used 17 bits in nc3. Must move one each to nc1 and nc2.
nc1 <<= 1;
if (nc3 & 0x08000) nc1 |= 1;
nc2 <<= 1;
if (nc3 & 0x10000) nc2 |= 1;
ng = nc3 & 0x7FFF;
}
int packmsg(const char *msg, uint8_t *dat) { // , itype, bcontest
// TODO: check what is maximum allowed length?
@ -362,20 +398,21 @@ int packmsg(const char *msg, uint8_t *dat) { // , itype, bcontest
}
}
int32_t nc1 = -1;
int32_t nc2 = -1;
int16_t ng = -1;
// Try to split the message into three space-delimited fields
// by locating spaces and changing them to zero terminators
// Locate the first delimiter in the message
char *s1 = strchr(msg2, ' ');
if (s1 == NULL) {
// TODO: handle this (plain text message?)
return -2;
}
char *s1 = (char *)strchr(msg2, ' ');
if (s1 != NULL) {
*s1 = 0; // Separate fields by zero terminator
++s1; // Now s1 points to the second field
++s1; // s1 now points to the second field
// Locate the second delimiter in the message
char *s2 = strchr(s1 + 1, ' ');
char *s2 = (char *)strchr(s1 + 1, ' ');
if (s2 == NULL) {
// If the second space is not found, point to the end of string
// to allow for blank grid (third field)
@ -383,28 +420,29 @@ int packmsg(const char *msg, uint8_t *dat) { // , itype, bcontest
}
else {
*s2 = 0;// Separate fields by zero terminator
++s2; // Now s2 points to the third field
++s2; // s2 now points to the third field
}
// TODO: process callsign prefixes/suffixes
// Pack message fields into integers
int nc1 = packcall(msg2);
int nc2 = packcall(s1);
int ng = packgrid(s2);
// TODO: plain text messages
//call packtext(msg,nc1,nc2,ng)
//ng=ng+32768
if (nc1 < 0 || nc2 < 0 || ng < 0) {
return -3;
nc1 = packcall(msg2);
nc2 = packcall(s1);
ng = packgrid(s2);
}
// Check for success in all three fields
if (nc1 < 0 || nc2 < 0 || ng < 0) {
// Treat as plain text message
packtext(msg2, nc1, nc2, ng);
ng += 0x8000; // Set bit 15 (we abuse signed int here)
}
//LOG("nc1 = %d [%04X], nc2 = %d [%04X], ng = %d\n", nc1, nc1, nc2, nc2, ng);
// Originally the data was packed in bytes of 6 bits.
// This seems to waste memory unnecessary and complicate the code, so we pack it in 8 bit values.
pack3_8bit(nc1, nc2, ng, dat);
pack3_8bit((uint32_t)nc1, (uint32_t)nc2, (uint16_t)ng, dat);
//pack3_6bit(nc1, nc2, ng, dat);
return 0; // Success!