diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2017-07-24 19:18:01 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2017-08-08 12:53:48 +0200 |
commit | 0cbd9657d20fb300d4fc2039ec137988eb40d21a (patch) | |
tree | 6fc80af8fb3f701eca4a4b98b8b851eaa599ac20 | |
parent | 6c6402571758340c640bd2350599ff6a9e5ffeb6 (diff) |
Move Hagelbarger error correction code from NMT to common code
It will be used by Radiocom 2000 also.
Some minor fixes and improvements apply.
-rw-r--r-- | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/hagelbarger.c (renamed from src/nmt/hagelbarger.c) | 26 | ||||
-rw-r--r-- | src/common/hagelbarger.h (renamed from src/nmt/hagelbarger.h) | 0 | ||||
-rw-r--r-- | src/nmt/Makefile.am | 1 | ||||
-rw-r--r-- | src/nmt/frame.c | 4 | ||||
-rw-r--r-- | src/test/Makefile.am | 2 | ||||
-rw-r--r-- | src/test/test_hagelbarger.c | 12 |
7 files changed, 32 insertions, 14 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index f719c6e..92447dc 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -25,6 +25,7 @@ libcommon_a_SOURCES = \ fft.c \ fm_modulation.c \ ffsk.c \ + hagelbarger.c \ sender.c \ display_wave.c \ display_status.c \ diff --git a/src/nmt/hagelbarger.c b/src/common/hagelbarger.c index f6ac2cd..7d42bbc 100644 --- a/src/nmt/hagelbarger.c +++ b/src/common/hagelbarger.c @@ -27,10 +27,13 @@ #include "stdint.h" +/* enable to debug the process of parity check */ +//#define DEBUG_HAGEL + /* To encode NMT message: (MSB first) * Use input with 9 bytes, the last byte must be 0x00. * Use output with 18 bytes, ignore the last four (lower) bits of last byte. - * Use length of 72. + * Use length of 70. */ void hagelbarger_encode(const uint8_t *input, uint8_t *output, int length) { @@ -49,6 +52,9 @@ void hagelbarger_encode(const uint8_t *input, uint8_t *output, int length) /* put check bit and data bit to output (MSB first) */ output[i / 4] = (output[i / 4] << 2) | (check << 1) | data; } + /* shift last output byte all the way to MSB */ + while ((i % 4)) + output[i++ / 4] <<= 2; } /* To decode NMT message: (MSB first) @@ -58,12 +64,12 @@ void hagelbarger_encode(const uint8_t *input, uint8_t *output, int length) */ void hagelbarger_decode(const uint8_t *input, uint8_t *output, int length) { - uint16_t reg_data = 0x00, reg_check = 0x00, data, check, r_parity, s_parity; - int i; + uint16_t reg_data = 0x00, reg_check = 0xff, data, check, r_parity, s_parity; + int i, o; length += 10; - for (i = 0; i < length; i++) { + for (i = 0, o = 0; i < length; i++) { /* get check bit from input (MSB first) */ check = (input[i / 4] >> (7 - (i & 3) * 2)) & 1; /* get data bit from input (MSB first) */ @@ -75,13 +81,21 @@ void hagelbarger_decode(const uint8_t *input, uint8_t *output, int length) /* calculate parity */ r_parity = (reg_data + (reg_data >> 3) + (reg_check >> 6) + 1) & 1; s_parity = ((reg_data >> 3) + (reg_data >> 6) + (reg_check >> 9) + 1) & 1; +#ifdef DEBUG_HAGEL + printf("#%d: r=%d s=%d\n", i - 10, r_parity, s_parity); +#endif /* flip message bit, if both parity checks fail */ /* use 4th bit that will be shifted to 5th bit next loop */ if (r_parity && s_parity) reg_data ^= 0x0008; /* put message bit to output (MSB first) */ - if (i >= 10) - output[(i - 10) / 8] = (output[(i - 10) / 8] << 1) | ((reg_data >> 4) & 1); + if (i >= 10) { + output[o / 8] = (output[o / 8] << 1) | ((reg_data >> 4) & 1); + o++; + } } + /* shift last output byte all the way to MSB */ + while ((o % 8)) + output[o++ / 8] <<= 1; } diff --git a/src/nmt/hagelbarger.h b/src/common/hagelbarger.h index 9076afc..9076afc 100644 --- a/src/nmt/hagelbarger.h +++ b/src/common/hagelbarger.h diff --git a/src/nmt/Makefile.am b/src/nmt/Makefile.am index 1f738b9..91d5cff 100644 --- a/src/nmt/Makefile.am +++ b/src/nmt/Makefile.am @@ -8,7 +8,6 @@ nmt_SOURCES = \ countries.c \ transaction.c \ dsp.c \ - hagelbarger.c \ frame.c \ dms.c \ sms.c \ diff --git a/src/nmt/frame.c b/src/nmt/frame.c index b64a37c..fc9ae47 100644 --- a/src/nmt/frame.c +++ b/src/nmt/frame.c @@ -25,9 +25,9 @@ #include "../common/sample.h" #include "../common/debug.h" #include "../common/timer.h" +#include "../common/hagelbarger.h" #include "nmt.h" #include "frame.h" -#include "hagelbarger.h" uint64_t nmt_encode_channel(int nmt_system, int channel, int power) { @@ -1146,7 +1146,7 @@ const char *encode_frame(int nmt_system, frame_t *frame, int debug) message[8] = 0x00; for (i = 0; i < 8; i++) message[i] = (digits[i * 2] << 4) | digits[i * 2 + 1]; - hagelbarger_encode(message, code, 72); + hagelbarger_encode(message, code, 70); memcpy(bits, "10101010101010111100010010", 26); for (i = 0; i < 140; i++) bits[i + 26] = ((code[i / 8] >> (7 - (i & 7))) & 1) + '0'; diff --git a/src/test/Makefile.am b/src/test/Makefile.am index dbe6c73..d9f0de9 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -79,7 +79,7 @@ test_performance_LDADD = \ -lm test_hagelbarger_SOURCES = \ - $(top_builddir)/src/nmt/hagelbarger.c \ + $(top_builddir)/src/common/hagelbarger.c \ test_hagelbarger.c test_hagelbarger_LDADD = \ diff --git a/src/test/test_hagelbarger.c b/src/test/test_hagelbarger.c index d4117e3..1e0838a 100644 --- a/src/test/test_hagelbarger.c +++ b/src/test/test_hagelbarger.c @@ -1,7 +1,7 @@ #include "stdio.h" #include "stdint.h" #include "string.h" -#include "../nmt/hagelbarger.h" +#include "../common/hagelbarger.h" int main(void) { @@ -9,11 +9,15 @@ int main(void) printf("Message: %s\n", message); - /* clean tail at code bit 72 and above */ + /* clean tail at code bit 70 and above */ memset(code, 0, sizeof(code)); /* encode message */ - hagelbarger_encode(message, code, 72); + hagelbarger_encode(message, code, 70); + + /* decode */ + hagelbarger_decode(code, message, 64); + printf("Decoded without corruption: %s (must be the same as above)\n", message); /* corrupt data */ code[0] ^= 0xfc; @@ -22,7 +26,7 @@ int main(void) /* decode */ hagelbarger_decode(code, message, 64); - printf("Decoded: %s (must be the same as above)\n", message); + printf("Decoded with corruption: %s (must be the same as above)\n", message); return 0; } |