Compare commits
509 commits
Author | SHA1 | Date | |
---|---|---|---|
9a3cfe9fd9 | |||
de6f60ed5d | |||
035dd944ab | |||
0082295493 | |||
575a36e42c | |||
10fe14ab72 | |||
7a551ddf04 | |||
f8ad2e28ca | |||
ca8571c276 | |||
bbd72df6fc | |||
a81c03b0ef | |||
9e7186b9bd | |||
58f9b7388c | |||
31cc01c811 | |||
f26ab797dc | |||
77a9501dc4 | |||
842bb20fbf | |||
|
fe195c4e40 | ||
|
33939d8cf5 | ||
|
60b5e425df | ||
|
3e8cda274d | ||
|
452be45b11 | ||
|
d94043e06d | ||
|
82024fae5f | ||
|
ace0d21975 | ||
|
6290449266 | ||
|
efff4f0dc4 | ||
|
2b34978be1 | ||
|
f81e8fbdf5 | ||
|
4d294fda56 | ||
|
fed4400632 | ||
|
a30ae3af4d | ||
|
a6b05aab5b | ||
|
e0adf4328b | ||
|
20b1367848 | ||
|
4b864661a7 | ||
|
5d9acbae1b | ||
|
572227a073 | ||
|
a26f9af671 | ||
|
a919088f1f | ||
|
18823b6c9c | ||
|
94981664e0 | ||
|
bcc73d87aa | ||
|
8ecc41b0bb | ||
|
af8d1f45ed | ||
|
b1d5973bb0 | ||
|
483a886fa8 | ||
|
204b4140bb | ||
|
8a5f79878e | ||
|
e960b052db | ||
|
2f9b4c120c | ||
|
e6d4bfe61c | ||
|
b57b781ab8 | ||
|
fc836f3812 | ||
|
a9fbbc1d2c | ||
|
186c61a128 | ||
|
116e257f90 | ||
|
c469d31227 | ||
|
12282f709a | ||
|
df12cf1052 | ||
|
2f274d3746 | ||
|
c5c5db39a1 | ||
|
cd7527a3aa | ||
|
8b67d856f7 | ||
|
991fd46cad | ||
|
358adce2c9 | ||
|
54c3584453 | ||
|
d83e06a4ad | ||
|
2b357f79c5 | ||
|
9c297371e6 | ||
|
40620f855c | ||
|
ed541885f6 | ||
|
4b0e016355 | ||
|
45e45da6e6 | ||
|
cdfe3620d5 | ||
|
50a3afd66f | ||
|
8ba7a78a77 | ||
|
cb89b34a39 | ||
|
ded46ebb60 | ||
|
14e682dec4 | ||
|
efb3a24872 | ||
|
6aac9d67b7 | ||
|
0071fce5c0 | ||
|
a173c884e4 | ||
|
11f14465e6 | ||
|
d1dc6bb7a0 | ||
|
b779ea5ae6 | ||
|
37c889c2d9 | ||
|
836bc0dc9b | ||
|
ef6ce0ef88 | ||
|
e966d355cd | ||
|
8e36cd88aa | ||
|
8c31fe6f34 | ||
|
fbb835812d | ||
|
55f4c6ce1a | ||
|
293962a7f7 | ||
|
e1b164de70 | ||
|
8e34cab68b | ||
|
200986b698 | ||
|
4ec4b3dafe | ||
|
2a63f83a9b | ||
|
9cea26ec62 | ||
|
03a4837227 | ||
|
14bf5007d5 | ||
|
e2e5ddf4c8 | ||
|
bfacdee8e2 | ||
|
433cb441be | ||
|
61e5623ad3 | ||
|
dd09c666bb | ||
|
bf3dbdb55d | ||
|
b6ff701c05 | ||
|
bc1b84caef | ||
|
42c53d3c39 | ||
|
926755171f | ||
|
dae05ad58a | ||
|
f7b8448963 | ||
|
8547a210bd | ||
|
50337639b2 | ||
|
a8fe55acc4 | ||
|
3f65200d7d | ||
|
f9e953d687 | ||
|
e344fc5b56 | ||
|
43bfaef117 | ||
|
c7effe5e2d | ||
|
9106fd69d2 | ||
|
deff9910eb | ||
|
7226c6f1f3 | ||
|
5727acceb8 | ||
|
a5639559ff | ||
|
0448a315e9 | ||
|
347fc4bedb | ||
|
bf3bf07747 | ||
|
ccdf708bbd | ||
|
8d6da34b79 | ||
|
8363a72f6a | ||
|
e2d61d1572 | ||
|
21b66d5113 | ||
|
d7c95f05f0 | ||
|
87a447f601 | ||
|
0e39d81797 | ||
|
efabc44189 | ||
|
397e5ff14f | ||
|
19d234a627 | ||
|
f5e3427cd8 | ||
|
c0e3fd0a5b | ||
|
e6fc679502 | ||
|
2d6f601feb | ||
|
4c4ea18319 | ||
|
39620c22bd | ||
|
77741318a0 | ||
|
7008c624d9 | ||
|
8b45e04ea0 | ||
|
db1eef6b0e | ||
|
ec0bc51899 | ||
|
609f1e356a | ||
|
82b5b010eb | ||
|
cfe9e0fba4 | ||
|
a5ee4284f2 | ||
|
3a73a25c1e | ||
|
e6d5ef9055 | ||
|
b30d5465f5 | ||
|
dad34bea98 | ||
|
6ae01af364 | ||
|
ffb4bdb042 | ||
|
c08b41a17a | ||
|
8dc54ed21f | ||
|
389bd3b928 | ||
|
6ac672e106 | ||
|
4422444179 | ||
|
8efd77132f | ||
|
0a94b0deb6 | ||
|
242cf50240 | ||
|
dbf771d80c | ||
|
6b43bce561 | ||
|
b5420fef15 | ||
|
69a4fdd23c | ||
|
d26f3ea567 | ||
|
27b7d3fc41 | ||
|
9373b15e58 | ||
|
0088b0b225 | ||
|
629cdcfb2a | ||
|
95cb575a2e | ||
|
a3e4a250bd | ||
|
42570c905d | ||
|
d0ccc0ee61 | ||
|
75e8e95aad | ||
|
fb0d1ef5e2 | ||
|
7c14a6ec40 | ||
|
69c9500cb1 | ||
|
c2be5ab2f7 | ||
|
f1de23e568 | ||
|
125f21735b | ||
|
5111d16b99 | ||
|
51e74c6182 | ||
|
6f2bd43c53 | ||
|
79fc7623dc | ||
|
39e89584e1 | ||
|
46b8ea56d3 | ||
|
5d8d1a3fb9 | ||
|
5537ebbb65 | ||
|
c6f5a21a27 | ||
|
5c292f77e5 | ||
|
fe3be93a2e | ||
|
e291096d22 | ||
|
279afb75f3 | ||
|
8ace65b86d | ||
|
ff9712b36a | ||
|
6344f8b9ef | ||
|
b64359a157 | ||
|
0e6208cc67 | ||
|
e761e9c083 | ||
|
a209c00479 | ||
|
d07782696c | ||
|
4ec33c86a7 | ||
|
397b10131f | ||
|
9d85b6451c | ||
|
1c3f6ae75e | ||
|
28f2203f5a | ||
|
75a6a67c17 | ||
|
37c298c885 | ||
|
02141f55ff | ||
|
d76d4b063c | ||
|
e086b70526 | ||
|
d77e2a00ce | ||
|
ffc369c3a5 | ||
|
a95389242b | ||
|
135fd04e0d | ||
|
e1427e3e37 | ||
|
bcdba292eb | ||
|
2ad4a2abfc | ||
|
b22d9084c8 | ||
|
9811bb7d4d | ||
|
a027b1f3bd | ||
|
f5449ffc83 | ||
|
77daf86723 | ||
|
99a4d37082 | ||
|
56f361b3e4 | ||
|
4897313fc0 | ||
|
bf5651b7a0 | ||
|
b2844bc0a6 | ||
|
0a7df1758b | ||
|
787393e4c2 | ||
|
9dbe634f08 | ||
|
fcf45d3e4b | ||
|
6e05225522 | ||
|
38f6292e71 | ||
|
99a4257d12 | ||
|
ef6056506c | ||
|
136deac61a | ||
|
efe9b3d459 | ||
|
8874d1262b | ||
|
8656aaedaa | ||
|
1fd1a4f6d1 | ||
|
7aabb96351 | ||
|
821db7910a | ||
|
4f0f0fea66 | ||
|
b8ae0febb0 | ||
|
2d2b736c54 | ||
|
449ca905ee | ||
|
fcad5ee0d2 | ||
|
bbbfbbbfad | ||
|
7ea37fc5e9 | ||
|
c94f4f5d4a | ||
|
a87449bf51 | ||
|
59b8b5d623 | ||
|
da92771afa | ||
|
ef9fedcc01 | ||
|
ec80e9553a | ||
|
67b93d6310 | ||
|
8d31808ae8 | ||
|
3968786044 | ||
|
1b0caaae23 | ||
|
8e857edda2 | ||
|
43733df7a4 | ||
|
302a23b6e6 | ||
|
2618a14ae5 | ||
|
a98f65e3aa | ||
|
021c0fea4d | ||
|
bb5e20538d | ||
|
c1bb4c825e | ||
|
644351db4f | ||
|
ffe0fd0cbb | ||
|
067c1039d1 | ||
|
8c65b1c1d9 | ||
|
a4ba00f567 | ||
|
eece693f05 | ||
|
dbd779a6d3 | ||
|
f89145b772 | ||
|
f1dda251c3 | ||
|
3d489096cd | ||
|
304143d4a6 | ||
|
827a0cb72f | ||
|
d1942fcb43 | ||
|
a57397e274 | ||
|
d8677b4028 | ||
|
18c8b95829 | ||
|
06ba457da2 | ||
|
9559cdb060 | ||
|
ff8c9edb49 | ||
|
08ad50d578 | ||
|
cd5624c2fb | ||
|
098cc74c9e | ||
|
31002c2757 | ||
|
d0e8574187 | ||
|
9c13baef82 | ||
|
2ff0e52558 | ||
|
9688929c3d | ||
|
bab4b50d30 | ||
|
1bb1e9da59 | ||
|
d58a0c53b5 | ||
|
9567ac0b20 | ||
|
28e013acb7 | ||
|
d2bf8eb744 | ||
|
551556b65d | ||
|
b46d2f586c | ||
|
ef07f3c035 | ||
|
5b57557a79 | ||
|
c549cf3594 | ||
|
a00ecbe7d9 | ||
|
521da9b54d | ||
|
48f95be982 | ||
|
9a72e95ec0 | ||
|
8946038e0e | ||
|
b921f99d0a | ||
|
6e9174cf4c | ||
|
e0f4928db5 | ||
|
80a77bd12a | ||
|
8536294b76 | ||
|
e2a4ccfc05 | ||
|
35e9a2a830 | ||
|
2fc62e0e7a | ||
|
7c81128d77 | ||
|
20e8d4079d | ||
|
3f125f055c | ||
|
6d313fce51 | ||
|
c2a1aeb581 | ||
|
5a3c61644c | ||
|
90e7b58b92 | ||
|
98b1e6478b | ||
|
2502ee94d7 | ||
|
d5bbd77304 | ||
|
739550885b | ||
|
97a10c7e30 | ||
|
82ea772269 | ||
|
8a6f14e6e6 | ||
|
3776ed2b1b | ||
|
11c8403829 | ||
|
f35ab6230b | ||
|
efcecd69d3 | ||
|
0579b4387a | ||
|
b4cf7a4ad4 | ||
|
c2c1266233 | ||
|
7aec7eefcb | ||
|
869edd33fd | ||
|
f64371b4c8 | ||
|
d4e6f2cb5e | ||
|
354e808ccb | ||
|
8f59691738 | ||
|
5703758116 | ||
|
15c21de416 | ||
|
da077c73f8 | ||
|
801ba04e0d | ||
|
fa7be67d9c | ||
|
49a4e2ad0d | ||
|
bb1a542fe1 | ||
|
ba9c97289f | ||
|
76033dd301 | ||
|
87b7a7c48a | ||
|
c80894ddaa | ||
|
9c4d2f46bb | ||
|
1e833d78cf | ||
|
e9a128ebdc | ||
|
009f50a913 | ||
|
4d6f64a51e | ||
|
b8f0525dcb | ||
|
40a974d7cb | ||
|
41dc96affe | ||
|
954231ccbc | ||
|
3cc77c5c57 | ||
|
f42f6f07c4 | ||
|
183430593f | ||
|
192e8e2435 | ||
|
ba1b6a8751 | ||
|
8c52246be8 | ||
|
2bc6dd6ca9 | ||
|
fb6fb70ffb | ||
|
4d3869172d | ||
|
e106df3cdf | ||
|
d2be920254 | ||
|
d0fa27bfd1 | ||
|
5f0ee739e1 | ||
|
4ae141f594 | ||
|
22427cd348 | ||
|
aa8b78a311 | ||
|
14413963d9 | ||
|
e339de8fee | ||
|
8383c7d320 | ||
|
5dbf916db0 | ||
|
4ee32a506f | ||
|
8291470698 | ||
|
35a283d7b4 | ||
|
fab4dc227e | ||
|
30098a5d38 | ||
|
d4c7f20696 | ||
|
93a0b9793b | ||
|
648426f44c | ||
|
97f1ebb25f | ||
|
d1a809808b | ||
|
bdb1c49bae | ||
|
f151ca6c1a | ||
|
e164538b09 | ||
|
cb51a14575 | ||
|
371661bd11 | ||
|
6321563496 | ||
|
ab3705e8e0 | ||
|
aec1ae74f7 | ||
|
2953ce85a0 | ||
|
1c6a48a8e1 | ||
|
28d64e7c3d | ||
|
96a8ec0e35 | ||
|
d8716adc43 | ||
|
92ceba052a | ||
|
c026471aec | ||
|
27c9ad43ec | ||
|
38f59236ae | ||
|
692d6519db | ||
|
fe77cbd68c | ||
|
f936a6c5b6 | ||
|
d0878bbf7e | ||
|
e0f800ba98 | ||
|
d9e2940f08 | ||
|
b3398710bc | ||
|
d409700a31 | ||
|
dbe04c3c2f | ||
|
85751e0c51 | ||
|
f01fc3e9fc | ||
|
82c6f717cf | ||
|
f18e253eac | ||
|
17b49fde88 | ||
|
aa5eeb3554 | ||
|
97a35e69a4 | ||
|
af6b7d79da | ||
|
bd1aa20803 | ||
|
015edf9b81 | ||
|
98cd2404f5 | ||
|
eef364b1a9 | ||
|
8d4241d154 | ||
|
409e0de721 | ||
|
c2187fd624 | ||
|
75d5083f8e | ||
|
0b8a9a1a4c | ||
|
a28aa77927 | ||
|
02d1e2f0ef | ||
|
1caffc1dad | ||
|
12e58d5440 | ||
|
8b31cb34ff | ||
|
c0a9bb81a3 | ||
|
3b7d4d486e | ||
|
ed3299a513 | ||
|
ad843e7283 | ||
|
af34d9abc3 | ||
|
0b185a0900 | ||
|
303a0163d3 | ||
|
1290f9c49e | ||
|
9d08f1605c | ||
|
578ef5a3d4 | ||
|
23e92af6fa | ||
|
734af9453c | ||
|
a66f4c6188 | ||
|
283b54c46a | ||
|
dc41acbd21 | ||
|
b5316907ad | ||
|
56619166b6 | ||
|
d96e2204bf | ||
|
2165b38379 | ||
|
c413c3a855 | ||
|
9e52db3ef3 | ||
|
8ac6a1b208 | ||
|
143652b7f2 | ||
|
cbcbe4c56a | ||
|
f9ccb7c876 | ||
|
bc6f832b7d | ||
|
039ef44a63 | ||
|
bc3f98f19c | ||
|
7bca857852 | ||
|
29b36a66f8 | ||
|
6b4fe7dd33 | ||
|
7be89b91ea | ||
|
008bfee6b9 | ||
|
0178ba0aba | ||
|
3299913003 | ||
|
33fedb781d | ||
|
ab437c0866 | ||
|
467140dbf8 | ||
|
2a8e1ce9f4 | ||
|
47862e0682 | ||
|
e28dfe79dd | ||
|
bc22709abb | ||
|
dc9e6ade23 | ||
|
9a2dd6a5e6 | ||
|
c48f45d2da | ||
|
93652c764e | ||
|
8cdc1ffe7f | ||
|
5e887a95c5 | ||
|
7ae77a01a9 | ||
|
51a1e2bb9c | ||
|
c2ca65f889 | ||
|
b3d287965f | ||
|
bc791577e7 |
214 changed files with 4817 additions and 26923 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ RemoteCommand
|
||||||
.vs
|
.vs
|
||||||
*.ambe
|
*.ambe
|
||||||
GitVersion.h
|
GitVersion.h
|
||||||
|
.vscode
|
80
.vscode/settings.json
vendored
Normal file
80
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"fstream": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"any": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"hash_map": "cpp",
|
||||||
|
"strstream": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"cfenv": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"complex": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"source_location": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"future": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeindex": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"valarray": "cpp",
|
||||||
|
"variant": "cpp"
|
||||||
|
}
|
||||||
|
}
|
49
AMBEFEC.cpp
49
AMBEFEC.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010,2014,2016,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2010,2014,2016,2018,2021 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#include "Golay24128.h"
|
#include "Golay24128.h"
|
||||||
#include "Hamming.h"
|
#include "Hamming.h"
|
||||||
#include "AMBEFEC.h"
|
#include "AMBEFEC.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -795,34 +796,31 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
|
||||||
unsigned int orig_a = a;
|
unsigned int orig_a = a;
|
||||||
unsigned int orig_b = b;
|
unsigned int orig_b = b;
|
||||||
|
|
||||||
unsigned int data = CGolay24128::decode24128(a);
|
unsigned int data;
|
||||||
|
bool valid1 = CGolay24128::decode24128(a, data);
|
||||||
a = CGolay24128::encode24128(data);
|
if (!valid1)
|
||||||
|
return 10U;
|
||||||
|
|
||||||
// The PRNG
|
// The PRNG
|
||||||
unsigned int p = PRNG_TABLE[data];
|
unsigned int p = PRNG_TABLE[data];
|
||||||
|
|
||||||
b ^= p;
|
b ^= p;
|
||||||
|
|
||||||
unsigned int datb = CGolay24128::decode24128(b);
|
unsigned int datb;
|
||||||
|
bool valid2 = CGolay24128::decode24128(b, datb);
|
||||||
|
if (!valid2)
|
||||||
|
return 10U;
|
||||||
|
|
||||||
|
a = CGolay24128::encode24128(data);
|
||||||
b = CGolay24128::encode24128(datb);
|
b = CGolay24128::encode24128(datb);
|
||||||
|
|
||||||
b ^= p;
|
b ^= p;
|
||||||
|
|
||||||
unsigned int errsA = 0U, errsB = 0U;
|
|
||||||
|
|
||||||
unsigned int v = a ^ orig_a;
|
unsigned int v = a ^ orig_a;
|
||||||
while (v != 0U) {
|
unsigned int errsA = CUtils::countBits(v);
|
||||||
v &= v - 1U;
|
|
||||||
errsA++;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = b ^ orig_b;
|
v = b ^ orig_b;
|
||||||
while (v != 0U) {
|
unsigned int errsB = CUtils::countBits(v);
|
||||||
v &= v - 1U;
|
|
||||||
errsB++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return errsA + errsB;
|
return errsA + errsB;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +830,14 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
|
||||||
unsigned int orig_a = a;
|
unsigned int orig_a = a;
|
||||||
unsigned int orig_b = b;
|
unsigned int orig_b = b;
|
||||||
|
|
||||||
unsigned int data = CGolay24128::decode24128(a);
|
unsigned int data;
|
||||||
|
bool valid = CGolay24128::decode24128(a, data);
|
||||||
|
if (!valid) {
|
||||||
|
a = 0xF00292U;
|
||||||
|
b = 0x0E0B20U;
|
||||||
|
c = 0x000000U;
|
||||||
|
return 10U; // An invalid A block gives an error count of 10
|
||||||
|
}
|
||||||
|
|
||||||
a = CGolay24128::encode24128(data);
|
a = CGolay24128::encode24128(data);
|
||||||
|
|
||||||
|
@ -847,19 +852,11 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
|
||||||
|
|
||||||
b ^= p;
|
b ^= p;
|
||||||
|
|
||||||
unsigned int errsA = 0U, errsB = 0U;
|
|
||||||
|
|
||||||
unsigned int v = a ^ orig_a;
|
unsigned int v = a ^ orig_a;
|
||||||
while (v != 0U) {
|
unsigned int errsA = CUtils::countBits(v);
|
||||||
v &= v - 1U;
|
|
||||||
errsA++;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = b ^ orig_b;
|
v = b ^ orig_b;
|
||||||
while (v != 0U) {
|
unsigned int errsB = CUtils::countBits(v);
|
||||||
v &= v - 1U;
|
|
||||||
errsB++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) {
|
if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) {
|
||||||
a = 0xF00292U;
|
a = 0xF00292U;
|
||||||
|
|
56
CASTInfo.cpp
56
CASTInfo.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -76,20 +76,6 @@ void CCASTInfo::setQuitInt()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCASTInfo::setFMInt()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
|
||||||
{
|
|
||||||
if (m_modem != NULL)
|
|
||||||
m_modem->writeDStarInfo(my1, my2, your, type, reflector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::clearDStarInt()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
void CCASTInfo::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
{
|
||||||
if (m_modem != NULL)
|
if (m_modem != NULL)
|
||||||
|
@ -100,46 +86,6 @@ void CCASTInfo::clearDMRInt(unsigned int slotNo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCASTInfo::writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin)
|
|
||||||
{
|
|
||||||
if (m_modem != NULL)
|
|
||||||
m_modem->writeYSFInfo(source, dest, dgid, type, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::clearFusionInt()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
if (m_modem != NULL)
|
|
||||||
m_modem->writeP25Info(source, group, dest, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::clearP25Int()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
if (m_modem != NULL)
|
|
||||||
m_modem->writeNXDNInfo(source, group, dest, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::clearNXDNInt()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writePOCSAGInt(uint32_t ric, const std::string& message)
|
|
||||||
{
|
|
||||||
if (m_modem != NULL)
|
|
||||||
m_modem->writePOCSAGInfo(ric, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::clearPOCSAGInt()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCASTInfo::writeCWInt()
|
void CCASTInfo::writeCWInt()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
21
CASTInfo.h
21
CASTInfo.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "NetworkInfo.h"
|
#include "NetworkInfo.h"
|
||||||
#include "Modem.h"
|
#include "Modem.h"
|
||||||
|
|
||||||
class CCASTInfo : public CDisplay
|
class CCASTInfo : public CDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -40,31 +41,15 @@ protected:
|
||||||
virtual void setErrorInt(const char* text);
|
virtual void setErrorInt(const char* text);
|
||||||
virtual void setLockoutInt();
|
virtual void setLockoutInt();
|
||||||
virtual void setQuitInt();
|
virtual void setQuitInt();
|
||||||
virtual void setFMInt();
|
|
||||||
|
|
||||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
|
||||||
virtual void clearDStarInt();
|
|
||||||
|
|
||||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
virtual void clearDMRInt(unsigned int slotNo);
|
virtual void clearDMRInt(unsigned int slotNo);
|
||||||
|
|
||||||
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
|
||||||
virtual void clearFusionInt();
|
|
||||||
|
|
||||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual void clearP25Int();
|
|
||||||
|
|
||||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual void clearNXDNInt();
|
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
|
||||||
virtual void clearPOCSAGInt();
|
|
||||||
|
|
||||||
virtual void writeCWInt();
|
virtual void writeCWInt();
|
||||||
virtual void clearCWInt();
|
virtual void clearCWInt();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CModem* m_modem;
|
CModem* m_modem;
|
||||||
std::string m_ipaddress;
|
std::string m_ipaddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
328
Conf.h
328
Conf.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -42,6 +42,12 @@ public:
|
||||||
unsigned int getRXFrequency() const;
|
unsigned int getRXFrequency() const;
|
||||||
unsigned int getTXFrequency() const;
|
unsigned int getTXFrequency() const;
|
||||||
unsigned int getPower() const;
|
unsigned int getPower() const;
|
||||||
|
float getLatitude() const;
|
||||||
|
float getLongitude() const;
|
||||||
|
int getHeight() const;
|
||||||
|
std::string getLocation() const;
|
||||||
|
std::string getDescription() const;
|
||||||
|
std::string getURL() const;
|
||||||
|
|
||||||
// The Log section
|
// The Log section
|
||||||
unsigned int getLogDisplayLevel() const;
|
unsigned int getLogDisplayLevel() const;
|
||||||
|
@ -59,14 +65,16 @@ public:
|
||||||
std::string getDMRIdLookupFile() const;
|
std::string getDMRIdLookupFile() const;
|
||||||
unsigned int getDMRIdLookupTime() const;
|
unsigned int getDMRIdLookupTime() const;
|
||||||
|
|
||||||
// The NXDN Id section
|
|
||||||
std::string getNXDNIdLookupFile() const;
|
|
||||||
unsigned int getNXDNIdLookupTime() const;
|
|
||||||
|
|
||||||
// The Modem section
|
// The Modem section
|
||||||
std::string getModemPort() const;
|
|
||||||
std::string getModemProtocol() const;
|
std::string getModemProtocol() const;
|
||||||
unsigned int getModemAddress() const;
|
std::string getModemUARTPort() const;
|
||||||
|
unsigned int getModemUARTSpeed() const;
|
||||||
|
std::string getModemI2CPort() const;
|
||||||
|
unsigned int getModemI2CAddress() const;
|
||||||
|
std::string getModemModemAddress() const;
|
||||||
|
unsigned short getModemModemPort() const;
|
||||||
|
std::string getModemLocalAddress() const;
|
||||||
|
unsigned short getModemLocalPort() const;
|
||||||
bool getModemRXInvert() const;
|
bool getModemRXInvert() const;
|
||||||
bool getModemTXInvert() const;
|
bool getModemTXInvert() const;
|
||||||
bool getModemPTTInvert() const;
|
bool getModemPTTInvert() const;
|
||||||
|
@ -84,8 +92,10 @@ public:
|
||||||
float getModemYSFTXLevel() const;
|
float getModemYSFTXLevel() const;
|
||||||
float getModemP25TXLevel() const;
|
float getModemP25TXLevel() const;
|
||||||
float getModemNXDNTXLevel() const;
|
float getModemNXDNTXLevel() const;
|
||||||
|
float getModemM17TXLevel() const;
|
||||||
float getModemPOCSAGTXLevel() const;
|
float getModemPOCSAGTXLevel() const;
|
||||||
float getModemFMTXLevel() const;
|
float getModemFMTXLevel() const;
|
||||||
|
float getModemAX25TXLevel() const;
|
||||||
std::string getModemRSSIMappingFile() const;
|
std::string getModemRSSIMappingFile() const;
|
||||||
bool getModemUseCOSAsLockout() const;
|
bool getModemUseCOSAsLockout() const;
|
||||||
bool getModemTrace() const;
|
bool getModemTrace() const;
|
||||||
|
@ -94,28 +104,11 @@ public:
|
||||||
// The Transparent Data section
|
// The Transparent Data section
|
||||||
bool getTransparentEnabled() const;
|
bool getTransparentEnabled() const;
|
||||||
std::string getTransparentRemoteAddress() const;
|
std::string getTransparentRemoteAddress() const;
|
||||||
unsigned int getTransparentRemotePort() const;
|
unsigned short getTransparentRemotePort() const;
|
||||||
unsigned int getTransparentLocalPort() const;
|
unsigned short getTransparentLocalPort() const;
|
||||||
unsigned int getTransparentSendFrameType() const;
|
unsigned int getTransparentSendFrameType() const;
|
||||||
|
|
||||||
// The UMP section
|
// The DMR section
|
||||||
bool getUMPEnabled() const;
|
|
||||||
std::string getUMPPort() const;
|
|
||||||
|
|
||||||
// The D-Star section
|
|
||||||
bool getDStarEnabled() const;
|
|
||||||
std::string getDStarModule() const;
|
|
||||||
bool getDStarSelfOnly() const;
|
|
||||||
std::vector<std::string> getDStarBlackList() const;
|
|
||||||
std::vector<std::string> getDStarWhiteList() const;
|
|
||||||
bool getDStarAckReply() const;
|
|
||||||
unsigned int getDStarAckTime() const;
|
|
||||||
bool getDStarAckMessage() const;
|
|
||||||
bool getDStarErrorReply() const;
|
|
||||||
bool getDStarRemoteGateway() const;
|
|
||||||
unsigned int getDStarModeHang() const;
|
|
||||||
|
|
||||||
// The DMR section
|
|
||||||
bool getDMREnabled() const;
|
bool getDMREnabled() const;
|
||||||
DMR_BEACONS getDMRBeacons() const;
|
DMR_BEACONS getDMRBeacons() const;
|
||||||
unsigned int getDMRBeaconInterval() const;
|
unsigned int getDMRBeaconInterval() const;
|
||||||
|
@ -135,83 +128,13 @@ public:
|
||||||
unsigned int getDMRModeHang() const;
|
unsigned int getDMRModeHang() const;
|
||||||
DMR_OVCM_TYPES getDMROVCM() const;
|
DMR_OVCM_TYPES getDMROVCM() const;
|
||||||
|
|
||||||
// The System Fusion section
|
// The DMR Network section
|
||||||
bool getFusionEnabled() const;
|
|
||||||
bool getFusionLowDeviation() const;
|
|
||||||
bool getFusionRemoteGateway() const;
|
|
||||||
bool getFusionSelfOnly() const;
|
|
||||||
unsigned int getFusionTXHang() const;
|
|
||||||
unsigned int getFusionModeHang() const;
|
|
||||||
|
|
||||||
// The P25 section
|
|
||||||
bool getP25Enabled() const;
|
|
||||||
unsigned int getP25Id() const;
|
|
||||||
unsigned int getP25NAC() const;
|
|
||||||
bool getP25SelfOnly() const;
|
|
||||||
bool getP25OverrideUID() const;
|
|
||||||
bool getP25RemoteGateway() const;
|
|
||||||
unsigned int getP25TXHang() const;
|
|
||||||
unsigned int getP25ModeHang() const;
|
|
||||||
|
|
||||||
// The NXDN section
|
|
||||||
bool getNXDNEnabled() const;
|
|
||||||
unsigned int getNXDNId() const;
|
|
||||||
unsigned int getNXDNRAN() const;
|
|
||||||
bool getNXDNSelfOnly() const;
|
|
||||||
bool getNXDNRemoteGateway() const;
|
|
||||||
unsigned int getNXDNTXHang() const;
|
|
||||||
unsigned int getNXDNModeHang() const;
|
|
||||||
|
|
||||||
// The POCSAG section
|
|
||||||
bool getPOCSAGEnabled() const;
|
|
||||||
unsigned int getPOCSAGFrequency() const;
|
|
||||||
|
|
||||||
// The FM Section
|
|
||||||
bool getFMEnabled() const;
|
|
||||||
std::string getFMCallsign() const;
|
|
||||||
unsigned int getFMCallsignSpeed() const;
|
|
||||||
unsigned int getFMCallsignFrequency() const;
|
|
||||||
unsigned int getFMCallsignTime() const;
|
|
||||||
unsigned int getFMCallsignHoldoff() const;
|
|
||||||
float getFMCallsignHighLevel() const;
|
|
||||||
float getFMCallsignLowLevel() const;
|
|
||||||
bool getFMCallsignAtStart() const;
|
|
||||||
bool getFMCallsignAtEnd() const;
|
|
||||||
bool getFMCallsignAtLatch() const;
|
|
||||||
std::string getFMRFAck() const;
|
|
||||||
std::string getFMExtAck() const;
|
|
||||||
unsigned int getFMAckSpeed() const;
|
|
||||||
unsigned int getFMAckFrequency() const;
|
|
||||||
unsigned int getFMAckMinTime() const;
|
|
||||||
unsigned int getFMAckDelay() const;
|
|
||||||
float getFMAckLevel() const;
|
|
||||||
unsigned int getFMTimeout() const;
|
|
||||||
float getFMTimeoutLevel() const;
|
|
||||||
float getFMCTCSSFrequency() const;
|
|
||||||
unsigned int getFMCTCSSHighThreshold() const;
|
|
||||||
unsigned int getFMCTCSSLowThreshold() const;
|
|
||||||
float getFMCTCSSLevel() const;
|
|
||||||
unsigned int getFMKerchunkTime() const;
|
|
||||||
unsigned int getFMHangTime() const;
|
|
||||||
unsigned int getFMAccessMode() const;
|
|
||||||
bool getFMCOSInvert() const;
|
|
||||||
unsigned int getFMRFAudioBoost() const;
|
|
||||||
float getFMMaxDevLevel() const;
|
|
||||||
unsigned int getFMExtAudioBoost() const;
|
|
||||||
|
|
||||||
// The D-Star Network section
|
|
||||||
bool getDStarNetworkEnabled() const;
|
|
||||||
std::string getDStarGatewayAddress() const;
|
|
||||||
unsigned int getDStarGatewayPort() const;
|
|
||||||
unsigned int getDStarLocalPort() const;
|
|
||||||
unsigned int getDStarNetworkModeHang() const;
|
|
||||||
bool getDStarNetworkDebug() const;
|
|
||||||
|
|
||||||
// The DMR Network section
|
|
||||||
bool getDMRNetworkEnabled() const;
|
bool getDMRNetworkEnabled() const;
|
||||||
std::string getDMRNetworkAddress() const;
|
std::string getDMRNetworkType() const;
|
||||||
unsigned int getDMRNetworkPort() const;
|
std::string getDMRNetworkRemoteAddress() const;
|
||||||
unsigned int getDMRNetworkLocal() const;
|
unsigned short getDMRNetworkRemotePort() const;
|
||||||
|
std::string getDMRNetworkLocalAddress() const;
|
||||||
|
unsigned short getDMRNetworkLocalPort() const;
|
||||||
std::string getDMRNetworkPassword() const;
|
std::string getDMRNetworkPassword() const;
|
||||||
std::string getDMRNetworkOptions() const;
|
std::string getDMRNetworkOptions() const;
|
||||||
bool getDMRNetworkDebug() const;
|
bool getDMRNetworkDebug() const;
|
||||||
|
@ -220,43 +143,7 @@ public:
|
||||||
bool getDMRNetworkSlot2() const;
|
bool getDMRNetworkSlot2() const;
|
||||||
unsigned int getDMRNetworkModeHang() const;
|
unsigned int getDMRNetworkModeHang() const;
|
||||||
|
|
||||||
// The System Fusion Network section
|
// The TFTSERIAL section
|
||||||
bool getFusionNetworkEnabled() const;
|
|
||||||
std::string getFusionNetworkMyAddress() const;
|
|
||||||
unsigned int getFusionNetworkMyPort() const;
|
|
||||||
std::string getFusionNetworkGatewayAddress() const;
|
|
||||||
unsigned int getFusionNetworkGatewayPort() const;
|
|
||||||
unsigned int getFusionNetworkModeHang() const;
|
|
||||||
bool getFusionNetworkDebug() const;
|
|
||||||
|
|
||||||
// The P25 Network section
|
|
||||||
bool getP25NetworkEnabled() const;
|
|
||||||
std::string getP25GatewayAddress() const;
|
|
||||||
unsigned int getP25GatewayPort() const;
|
|
||||||
unsigned int getP25LocalPort() const;
|
|
||||||
unsigned int getP25NetworkModeHang() const;
|
|
||||||
bool getP25NetworkDebug() const;
|
|
||||||
|
|
||||||
// The NXDN Network section
|
|
||||||
bool getNXDNNetworkEnabled() const;
|
|
||||||
std::string getNXDNNetworkProtocol() const;
|
|
||||||
std::string getNXDNGatewayAddress() const;
|
|
||||||
unsigned int getNXDNGatewayPort() const;
|
|
||||||
std::string getNXDNLocalAddress() const;
|
|
||||||
unsigned int getNXDNLocalPort() const;
|
|
||||||
unsigned int getNXDNNetworkModeHang() const;
|
|
||||||
bool getNXDNNetworkDebug() const;
|
|
||||||
|
|
||||||
// The POCSAG Network section
|
|
||||||
bool getPOCSAGNetworkEnabled() const;
|
|
||||||
std::string getPOCSAGGatewayAddress() const;
|
|
||||||
unsigned int getPOCSAGGatewayPort() const;
|
|
||||||
std::string getPOCSAGLocalAddress() const;
|
|
||||||
unsigned int getPOCSAGLocalPort() const;
|
|
||||||
unsigned int getPOCSAGNetworkModeHang() const;
|
|
||||||
bool getPOCSAGNetworkDebug() const;
|
|
||||||
|
|
||||||
// The TFTSERIAL section
|
|
||||||
std::string getTFTSerialPort() const;
|
std::string getTFTSerialPort() const;
|
||||||
unsigned int getTFTSerialBrightness() const;
|
unsigned int getTFTSerialBrightness() const;
|
||||||
|
|
||||||
|
@ -291,8 +178,8 @@ public:
|
||||||
|
|
||||||
// The LCDproc section
|
// The LCDproc section
|
||||||
std::string getLCDprocAddress() const;
|
std::string getLCDprocAddress() const;
|
||||||
unsigned int getLCDprocPort() const;
|
unsigned short getLCDprocPort() const;
|
||||||
unsigned int getLCDprocLocalPort() const;
|
unsigned short getLCDprocLocalPort() const;
|
||||||
bool getLCDprocDisplayClock() const;
|
bool getLCDprocDisplayClock() const;
|
||||||
bool getLCDprocUTC() const;
|
bool getLCDprocUTC() const;
|
||||||
bool getLCDprocDimOnIdle() const;
|
bool getLCDprocDimOnIdle() const;
|
||||||
|
@ -304,7 +191,7 @@ public:
|
||||||
// The Remote Control section
|
// The Remote Control section
|
||||||
bool getRemoteControlEnabled() const;
|
bool getRemoteControlEnabled() const;
|
||||||
std::string getRemoteControlAddress() const;
|
std::string getRemoteControlAddress() const;
|
||||||
unsigned int getRemoteControlPort() const;
|
unsigned short getRemoteControlPort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_file;
|
std::string m_file;
|
||||||
|
@ -318,6 +205,12 @@ private:
|
||||||
unsigned int m_rxFrequency;
|
unsigned int m_rxFrequency;
|
||||||
unsigned int m_txFrequency;
|
unsigned int m_txFrequency;
|
||||||
unsigned int m_power;
|
unsigned int m_power;
|
||||||
|
float m_latitude;
|
||||||
|
float m_longitude;
|
||||||
|
int m_height;
|
||||||
|
std::string m_location;
|
||||||
|
std::string m_description;
|
||||||
|
std::string m_url;
|
||||||
|
|
||||||
unsigned int m_logDisplayLevel;
|
unsigned int m_logDisplayLevel;
|
||||||
unsigned int m_logFileLevel;
|
unsigned int m_logFileLevel;
|
||||||
|
@ -335,9 +228,15 @@ private:
|
||||||
std::string m_nxdnIdLookupFile;
|
std::string m_nxdnIdLookupFile;
|
||||||
unsigned int m_nxdnIdLookupTime;
|
unsigned int m_nxdnIdLookupTime;
|
||||||
|
|
||||||
std::string m_modemPort;
|
|
||||||
std::string m_modemProtocol;
|
std::string m_modemProtocol;
|
||||||
unsigned int m_modemAddress;
|
std::string m_modemUARTPort;
|
||||||
|
unsigned int m_modemUARTSpeed;
|
||||||
|
std::string m_modemI2CPort;
|
||||||
|
unsigned int m_modemI2CAddress;
|
||||||
|
std::string m_modemModemAddress;
|
||||||
|
unsigned short m_modemModemPort;
|
||||||
|
std::string m_modemLocalAddress;
|
||||||
|
unsigned short m_modemLocalPort;
|
||||||
bool m_modemRXInvert;
|
bool m_modemRXInvert;
|
||||||
bool m_modemTXInvert;
|
bool m_modemTXInvert;
|
||||||
bool m_modemPTTInvert;
|
bool m_modemPTTInvert;
|
||||||
|
@ -350,13 +249,7 @@ private:
|
||||||
float m_modemRFLevel;
|
float m_modemRFLevel;
|
||||||
float m_modemRXLevel;
|
float m_modemRXLevel;
|
||||||
float m_modemCWIdTXLevel;
|
float m_modemCWIdTXLevel;
|
||||||
float m_modemDStarTXLevel;
|
|
||||||
float m_modemDMRTXLevel;
|
float m_modemDMRTXLevel;
|
||||||
float m_modemYSFTXLevel;
|
|
||||||
float m_modemP25TXLevel;
|
|
||||||
float m_modemNXDNTXLevel;
|
|
||||||
float m_modemPOCSAGTXLevel;
|
|
||||||
float m_modemFMTXLevel;
|
|
||||||
std::string m_modemRSSIMappingFile;
|
std::string m_modemRSSIMappingFile;
|
||||||
bool m_modemUseCOSAsLockout;
|
bool m_modemUseCOSAsLockout;
|
||||||
bool m_modemTrace;
|
bool m_modemTrace;
|
||||||
|
@ -364,25 +257,10 @@ private:
|
||||||
|
|
||||||
bool m_transparentEnabled;
|
bool m_transparentEnabled;
|
||||||
std::string m_transparentRemoteAddress;
|
std::string m_transparentRemoteAddress;
|
||||||
unsigned int m_transparentRemotePort;
|
unsigned short m_transparentRemotePort;
|
||||||
unsigned int m_transparentLocalPort;
|
unsigned short m_transparentLocalPort;
|
||||||
unsigned int m_transparentSendFrameType;
|
unsigned int m_transparentSendFrameType;
|
||||||
|
|
||||||
bool m_umpEnabled;
|
|
||||||
std::string m_umpPort;
|
|
||||||
|
|
||||||
bool m_dstarEnabled;
|
|
||||||
std::string m_dstarModule;
|
|
||||||
bool m_dstarSelfOnly;
|
|
||||||
std::vector<std::string> m_dstarBlackList;
|
|
||||||
std::vector<std::string> m_dstarWhiteList;
|
|
||||||
bool m_dstarAckReply;
|
|
||||||
unsigned int m_dstarAckTime;
|
|
||||||
bool m_dstarAckMessage;
|
|
||||||
bool m_dstarErrorReply;
|
|
||||||
bool m_dstarRemoteGateway;
|
|
||||||
unsigned int m_dstarModeHang;
|
|
||||||
|
|
||||||
bool m_dmrEnabled;
|
bool m_dmrEnabled;
|
||||||
DMR_BEACONS m_dmrBeacons;
|
DMR_BEACONS m_dmrBeacons;
|
||||||
unsigned int m_dmrBeaconInterval;
|
unsigned int m_dmrBeaconInterval;
|
||||||
|
@ -402,76 +280,12 @@ private:
|
||||||
unsigned int m_dmrModeHang;
|
unsigned int m_dmrModeHang;
|
||||||
DMR_OVCM_TYPES m_dmrOVCM;
|
DMR_OVCM_TYPES m_dmrOVCM;
|
||||||
|
|
||||||
bool m_fusionEnabled;
|
|
||||||
bool m_fusionLowDeviation;
|
|
||||||
bool m_fusionRemoteGateway;
|
|
||||||
bool m_fusionSelfOnly;
|
|
||||||
unsigned int m_fusionTXHang;
|
|
||||||
unsigned int m_fusionModeHang;
|
|
||||||
|
|
||||||
bool m_p25Enabled;
|
|
||||||
unsigned int m_p25Id;
|
|
||||||
unsigned int m_p25NAC;
|
|
||||||
bool m_p25SelfOnly;
|
|
||||||
bool m_p25OverrideUID;
|
|
||||||
bool m_p25RemoteGateway;
|
|
||||||
unsigned int m_p25TXHang;
|
|
||||||
unsigned int m_p25ModeHang;
|
|
||||||
|
|
||||||
bool m_nxdnEnabled;
|
|
||||||
unsigned int m_nxdnId;
|
|
||||||
unsigned int m_nxdnRAN;
|
|
||||||
bool m_nxdnSelfOnly;
|
|
||||||
bool m_nxdnRemoteGateway;
|
|
||||||
unsigned int m_nxdnTXHang;
|
|
||||||
unsigned int m_nxdnModeHang;
|
|
||||||
|
|
||||||
bool m_pocsagEnabled;
|
|
||||||
unsigned int m_pocsagFrequency;
|
|
||||||
|
|
||||||
bool m_fmEnabled;
|
|
||||||
std::string m_fmCallsign;
|
|
||||||
unsigned int m_fmCallsignSpeed;
|
|
||||||
unsigned int m_fmCallsignFrequency;
|
|
||||||
unsigned int m_fmCallsignTime;
|
|
||||||
unsigned int m_fmCallsignHoldoff;
|
|
||||||
float m_fmCallsignHighLevel;
|
|
||||||
float m_fmCallsignLowLevel;
|
|
||||||
bool m_fmCallsignAtStart;
|
|
||||||
bool m_fmCallsignAtEnd;
|
|
||||||
bool m_fmCallsignAtLatch;
|
|
||||||
std::string m_fmRFAck;
|
|
||||||
std::string m_fmExtAck;
|
|
||||||
unsigned int m_fmAckSpeed;
|
|
||||||
unsigned int m_fmAckFrequency;
|
|
||||||
unsigned int m_fmAckMinTime;
|
|
||||||
unsigned int m_fmAckDelay;
|
|
||||||
float m_fmAckLevel;
|
|
||||||
unsigned int m_fmTimeout;
|
|
||||||
float m_fmTimeoutLevel;
|
|
||||||
float m_fmCTCSSFrequency;
|
|
||||||
unsigned int m_fmCTCSSHighThreshold;
|
|
||||||
unsigned int m_fmCTCSSLowThreshold;
|
|
||||||
float m_fmCTCSSLevel;
|
|
||||||
unsigned int m_fmKerchunkTime;
|
|
||||||
unsigned int m_fmHangTime;
|
|
||||||
unsigned int m_fmAccessMode;
|
|
||||||
bool m_fmCOSInvert;
|
|
||||||
unsigned int m_fmRFAudioBoost;
|
|
||||||
float m_fmMaxDevLevel;
|
|
||||||
unsigned int m_fmExtAudioBoost;
|
|
||||||
|
|
||||||
bool m_dstarNetworkEnabled;
|
|
||||||
std::string m_dstarGatewayAddress;
|
|
||||||
unsigned int m_dstarGatewayPort;
|
|
||||||
unsigned int m_dstarLocalPort;
|
|
||||||
unsigned int m_dstarNetworkModeHang;
|
|
||||||
bool m_dstarNetworkDebug;
|
|
||||||
|
|
||||||
bool m_dmrNetworkEnabled;
|
bool m_dmrNetworkEnabled;
|
||||||
std::string m_dmrNetworkAddress;
|
std::string m_dmrNetworkType;
|
||||||
unsigned int m_dmrNetworkPort;
|
std::string m_dmrNetworkRemoteAddress;
|
||||||
unsigned int m_dmrNetworkLocal;
|
unsigned short m_dmrNetworkRemotePort;
|
||||||
|
std::string m_dmrNetworkLocalAddress;
|
||||||
|
unsigned short m_dmrNetworkLocalPort;
|
||||||
std::string m_dmrNetworkPassword;
|
std::string m_dmrNetworkPassword;
|
||||||
std::string m_dmrNetworkOptions;
|
std::string m_dmrNetworkOptions;
|
||||||
bool m_dmrNetworkDebug;
|
bool m_dmrNetworkDebug;
|
||||||
|
@ -480,39 +294,7 @@ private:
|
||||||
bool m_dmrNetworkSlot2;
|
bool m_dmrNetworkSlot2;
|
||||||
unsigned int m_dmrNetworkModeHang;
|
unsigned int m_dmrNetworkModeHang;
|
||||||
|
|
||||||
bool m_fusionNetworkEnabled;
|
std::string m_tftSerialPort;
|
||||||
std::string m_fusionNetworkMyAddress;
|
|
||||||
unsigned int m_fusionNetworkMyPort;
|
|
||||||
std::string m_fusionNetworkGatewayAddress;
|
|
||||||
unsigned int m_fusionNetworkGatewayPort;
|
|
||||||
unsigned int m_fusionNetworkModeHang;
|
|
||||||
bool m_fusionNetworkDebug;
|
|
||||||
|
|
||||||
bool m_p25NetworkEnabled;
|
|
||||||
std::string m_p25GatewayAddress;
|
|
||||||
unsigned int m_p25GatewayPort;
|
|
||||||
unsigned int m_p25LocalPort;
|
|
||||||
unsigned int m_p25NetworkModeHang;
|
|
||||||
bool m_p25NetworkDebug;
|
|
||||||
|
|
||||||
bool m_nxdnNetworkEnabled;
|
|
||||||
std::string m_nxdnNetworkProtocol;
|
|
||||||
std::string m_nxdnGatewayAddress;
|
|
||||||
unsigned int m_nxdnGatewayPort;
|
|
||||||
std::string m_nxdnLocalAddress;
|
|
||||||
unsigned int m_nxdnLocalPort;
|
|
||||||
unsigned int m_nxdnNetworkModeHang;
|
|
||||||
bool m_nxdnNetworkDebug;
|
|
||||||
|
|
||||||
bool m_pocsagNetworkEnabled;
|
|
||||||
std::string m_pocsagGatewayAddress;
|
|
||||||
unsigned int m_pocsagGatewayPort;
|
|
||||||
std::string m_pocsagLocalAddress;
|
|
||||||
unsigned int m_pocsagLocalPort;
|
|
||||||
unsigned int m_pocsagNetworkModeHang;
|
|
||||||
bool m_pocsagNetworkDebug;
|
|
||||||
|
|
||||||
std::string m_tftSerialPort;
|
|
||||||
unsigned int m_tftSerialBrightness;
|
unsigned int m_tftSerialBrightness;
|
||||||
|
|
||||||
unsigned int m_hd44780Rows;
|
unsigned int m_hd44780Rows;
|
||||||
|
@ -542,8 +324,8 @@ private:
|
||||||
bool m_oledLogoScreensaver;
|
bool m_oledLogoScreensaver;
|
||||||
|
|
||||||
std::string m_lcdprocAddress;
|
std::string m_lcdprocAddress;
|
||||||
unsigned int m_lcdprocPort;
|
unsigned short m_lcdprocPort;
|
||||||
unsigned int m_lcdprocLocalPort;
|
unsigned short m_lcdprocLocalPort;
|
||||||
bool m_lcdprocDisplayClock;
|
bool m_lcdprocDisplayClock;
|
||||||
bool m_lcdprocUTC;
|
bool m_lcdprocUTC;
|
||||||
bool m_lcdprocDimOnIdle;
|
bool m_lcdprocDimOnIdle;
|
||||||
|
@ -553,7 +335,7 @@ private:
|
||||||
|
|
||||||
bool m_remoteControlEnabled;
|
bool m_remoteControlEnabled;
|
||||||
std::string m_remoteControlAddress;
|
std::string m_remoteControlAddress;
|
||||||
unsigned int m_remoteControlPort;
|
unsigned short m_remoteControlPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool CDMRAccessControl::validateSrcId(unsigned int id)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int prefix = id / 10000U;
|
unsigned int prefix = id / 10000U;
|
||||||
if (prefix == 0U || prefix > 999U)
|
if (prefix == 0U || prefix > 9999U)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!m_prefixes.empty()) {
|
if (!m_prefixes.empty()) {
|
||||||
|
|
38
DMRCSBK.cpp
38
DMRCSBK.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2021,2022 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2019 by Patrick Maier DK5MP
|
* Copyright (C) 2019 by Patrick Maier DK5MP
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -34,7 +34,8 @@ m_bsId(0U),
|
||||||
m_srcId(0U),
|
m_srcId(0U),
|
||||||
m_dstId(0U),
|
m_dstId(0U),
|
||||||
m_dataContent(false),
|
m_dataContent(false),
|
||||||
m_CBF(0U)
|
m_CBF(0U),
|
||||||
|
m_OVCM(false)
|
||||||
{
|
{
|
||||||
m_data = new unsigned char[12U];
|
m_data = new unsigned char[12U];
|
||||||
}
|
}
|
||||||
|
@ -81,6 +82,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
m_dataContent = false;
|
m_dataContent = false;
|
||||||
m_CBF = 0U;
|
m_CBF = 0U;
|
||||||
|
m_OVCM = (m_data[2U] & 0x04U) == 0x04U;
|
||||||
CUtils::dump(1U, "Unit to Unit Service Request CSBK", m_data, 12U);
|
CUtils::dump(1U, "Unit to Unit Service Request CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -90,6 +92,7 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
m_dataContent = false;
|
m_dataContent = false;
|
||||||
m_CBF = 0U;
|
m_CBF = 0U;
|
||||||
|
m_OVCM = (m_data[2U] & 0x04U) == 0x04U;
|
||||||
CUtils::dump(1U, "Unit to Unit Service Answer Response CSBK", m_data, 12U);
|
CUtils::dump(1U, "Unit to Unit Service Answer Response CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -129,6 +132,21 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Call Alert Ack CSBK", m_data, 12U);
|
CUtils::dump(1U, "Call Alert Ack CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CSBKO_RADIO_CHECK:
|
||||||
|
m_GI = false;
|
||||||
|
if (m_data[3U] == 0x80) {
|
||||||
|
m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
|
m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
CUtils::dump(1U, "Radio Check Req CSBK", m_data, 12U);
|
||||||
|
} else {
|
||||||
|
m_srcId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U];
|
||||||
|
m_dstId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U];
|
||||||
|
CUtils::dump(1U, "Radio Check Ack CSBK", m_data, 12U);
|
||||||
|
}
|
||||||
|
m_dataContent = false;
|
||||||
|
m_CBF = 0U;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_GI = false;
|
m_GI = false;
|
||||||
m_srcId = 0U;
|
m_srcId = 0U;
|
||||||
|
@ -170,22 +188,18 @@ unsigned char CDMRCSBK::getFID() const
|
||||||
|
|
||||||
bool CDMRCSBK::getOVCM() const
|
bool CDMRCSBK::getOVCM() const
|
||||||
{
|
{
|
||||||
bool bOVCM = false;
|
return m_OVCM;
|
||||||
// Service options informations are only available in
|
|
||||||
// "Unit to Unit Voice Service Request CSBK" and
|
|
||||||
// "Unit to Unit Voice Service Answer Response CSBK"
|
|
||||||
if ((m_CSBKO == CSBKO_UUVREQ) || (m_CSBKO == CSBKO_UUANSRSP))
|
|
||||||
bOVCM = (m_data[2U] & 0x04U) == 0x04U;
|
|
||||||
|
|
||||||
return bOVCM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRCSBK::setOVCM(bool ovcm)
|
void CDMRCSBK::setOVCM(bool ovcm)
|
||||||
{
|
{
|
||||||
// Set OVCM only in CSBKs having the service options information
|
if (m_CSBKO == CSBKO_UUVREQ || m_CSBKO == CSBKO_UUANSRSP) {
|
||||||
if ((m_CSBKO == CSBKO_UUVREQ) || (m_CSBKO == CSBKO_UUANSRSP)) {
|
m_OVCM = ovcm;
|
||||||
|
|
||||||
if (ovcm)
|
if (ovcm)
|
||||||
m_data[2U] |= 0x04U;
|
m_data[2U] |= 0x04U;
|
||||||
|
else
|
||||||
|
m_data[2U] &= 0xFBU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2021,2022 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,6 +28,7 @@ enum CSBKO {
|
||||||
CSBKO_CTCSBK = 0x07,
|
CSBKO_CTCSBK = 0x07,
|
||||||
CSBKO_CALL_ALERT = 0x1F,
|
CSBKO_CALL_ALERT = 0x1F,
|
||||||
CSBKO_CALL_ALERT_ACK = 0x20,
|
CSBKO_CALL_ALERT_ACK = 0x20,
|
||||||
|
CSBKO_RADIO_CHECK = 0x24,
|
||||||
CSBKO_NACKRSP = 0x26,
|
CSBKO_NACKRSP = 0x26,
|
||||||
CSBKO_BSDWNACT = 0x38,
|
CSBKO_BSDWNACT = 0x38,
|
||||||
CSBKO_PRECCSBK = 0x3D
|
CSBKO_PRECCSBK = 0x3D
|
||||||
|
@ -75,6 +76,7 @@ private:
|
||||||
unsigned int m_dstId;
|
unsigned int m_dstId;
|
||||||
bool m_dataContent;
|
bool m_dataContent;
|
||||||
unsigned char m_CBF;
|
unsigned char m_CBF;
|
||||||
|
bool m_OVCM;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2019 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm) :
|
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm) :
|
||||||
m_colorCode(colorCode),
|
m_colorCode(colorCode),
|
||||||
m_modem(modem),
|
m_modem(modem),
|
||||||
m_network(network),
|
m_network(network),
|
||||||
|
@ -38,6 +38,13 @@ m_lookup(lookup)
|
||||||
// Load black and white lists to DMRAccessControl
|
// Load black and white lists to DMRAccessControl
|
||||||
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
|
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
|
||||||
|
|
||||||
|
//Print whitelisted IDs
|
||||||
|
LogMessage("Allowed radio ids: ");
|
||||||
|
for (unsigned int i: whitelist) {
|
||||||
|
std::string id_name = std::to_string(i);
|
||||||
|
LogMessage(id_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, jitter, ovcm);
|
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, jitter, ovcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +70,17 @@ bool CDMRControl::processWakeup(const unsigned char* data)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
|
std::string srcId_name = std::to_string(srcId);
|
||||||
|
LogMessage("Incoming uplink from radio id: %s", srcId_name.c_str());
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
|
|
||||||
bool ret = CDMRAccessControl::validateSrcId(srcId);
|
bool ret = CDMRAccessControl::validateSrcId(srcId);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogMessage("Invalid Downlink Activate received from %s", src.c_str());
|
LogMessage("Blocked downlink activation from %s (%s)", src.c_str(), srcId_name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessage("Downlink Activate received from %s", src.c_str());
|
LogMessage("Downlink request received from %s (%s)", src.c_str(), srcId_name.c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
class CDMRControl {
|
class CDMRControl {
|
||||||
public:
|
public:
|
||||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
||||||
~CDMRControl();
|
~CDMRControl();
|
||||||
|
|
||||||
bool processWakeup(const unsigned char* data);
|
bool processWakeup(const unsigned char* data);
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
private:
|
private:
|
||||||
unsigned int m_colorCode;
|
unsigned int m_colorCode;
|
||||||
CModem* m_modem;
|
CModem* m_modem;
|
||||||
CDMRNetwork* m_network;
|
IDMRNetwork* m_network;
|
||||||
CDMRSlot m_slot1;
|
CDMRSlot m_slot1;
|
||||||
CDMRSlot m_slot2;
|
CDMRSlot m_slot2;
|
||||||
CDMRLookup* m_lookup;
|
CDMRLookup* m_lookup;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
644
DMRDirectNetwork.cpp
Normal file
644
DMRDirectNetwork.cpp
Normal file
|
@ -0,0 +1,644 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DMRDirectNetwork.h"
|
||||||
|
|
||||||
|
#include "SHA256.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
const unsigned int BUFFER_LENGTH = 500U;
|
||||||
|
|
||||||
|
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||||
|
|
||||||
|
|
||||||
|
CDMRDirectNetwork::CDMRDirectNetwork(const std::string& address, unsigned short port, const std::string& localAddress, unsigned short localPort, unsigned int id, const std::string& password, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug) :
|
||||||
|
m_address(address),
|
||||||
|
m_port(port),
|
||||||
|
m_addr(),
|
||||||
|
m_addrLen(0U),
|
||||||
|
m_id(NULL),
|
||||||
|
m_password(password),
|
||||||
|
m_duplex(duplex),
|
||||||
|
m_version(version),
|
||||||
|
m_debug(debug),
|
||||||
|
m_socket(localAddress, localPort),
|
||||||
|
m_enabled(false),
|
||||||
|
m_slot1(slot1),
|
||||||
|
m_slot2(slot2),
|
||||||
|
m_hwType(hwType),
|
||||||
|
m_status(WAITING_CONNECT),
|
||||||
|
m_retryTimer(1000U, 10U),
|
||||||
|
m_timeoutTimer(1000U, 60U),
|
||||||
|
m_buffer(NULL),
|
||||||
|
m_streamId(NULL),
|
||||||
|
m_salt(NULL),
|
||||||
|
m_rxData(1000U, "DMR Network"),
|
||||||
|
m_options(),
|
||||||
|
m_random(),
|
||||||
|
m_callsign(),
|
||||||
|
m_rxFrequency(0U),
|
||||||
|
m_txFrequency(0U),
|
||||||
|
m_power(0U),
|
||||||
|
m_colorCode(0U),
|
||||||
|
m_latitude(0.0F),
|
||||||
|
m_longitude(0.0F),
|
||||||
|
m_height(0),
|
||||||
|
m_location(),
|
||||||
|
m_description(),
|
||||||
|
m_url(),
|
||||||
|
m_beacon(false)
|
||||||
|
{
|
||||||
|
assert(!address.empty());
|
||||||
|
assert(port > 0U);
|
||||||
|
assert(id > 1000U);
|
||||||
|
assert(!password.empty());
|
||||||
|
|
||||||
|
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||||
|
m_salt = new unsigned char[sizeof(uint32_t)];
|
||||||
|
m_id = new uint8_t[4U];
|
||||||
|
m_streamId = new uint32_t[2U];
|
||||||
|
|
||||||
|
m_id[0U] = id >> 24;
|
||||||
|
m_id[1U] = id >> 16;
|
||||||
|
m_id[2U] = id >> 8;
|
||||||
|
m_id[3U] = id >> 0;
|
||||||
|
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 mt(rd());
|
||||||
|
m_random = mt;
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
||||||
|
m_streamId[0U] = dist(m_random);
|
||||||
|
m_streamId[1U] = dist(m_random);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDMRDirectNetwork::~CDMRDirectNetwork()
|
||||||
|
{
|
||||||
|
delete[] m_streamId;
|
||||||
|
delete[] m_buffer;
|
||||||
|
delete[] m_salt;
|
||||||
|
delete[] m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRDirectNetwork::setOptions(const std::string& options)
|
||||||
|
{
|
||||||
|
m_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRDirectNetwork::setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url)
|
||||||
|
{
|
||||||
|
m_callsign = callsign;
|
||||||
|
m_rxFrequency = rxFrequency;
|
||||||
|
m_txFrequency = txFrequency;
|
||||||
|
m_power = power;
|
||||||
|
m_colorCode = colorCode;
|
||||||
|
m_latitude = latitude;
|
||||||
|
m_longitude = longitude;
|
||||||
|
m_height = height;
|
||||||
|
m_location = location;
|
||||||
|
m_description = description;
|
||||||
|
m_url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::open()
|
||||||
|
{
|
||||||
|
if (CUDPSocket::lookup(m_address, m_port, m_addr, m_addrLen) != 0) {
|
||||||
|
LogError("DMR, Could not lookup the address of the DMR Network");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("Opening DMR Network");
|
||||||
|
|
||||||
|
m_status = WAITING_CONNECT;
|
||||||
|
m_timeoutTimer.stop();
|
||||||
|
m_retryTimer.start();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRDirectNetwork::enable(bool enabled)
|
||||||
|
{
|
||||||
|
if (!enabled && m_enabled)
|
||||||
|
m_rxData.clear();
|
||||||
|
|
||||||
|
m_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::read(CDMRData& data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_rxData.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char length = 0U;
|
||||||
|
m_rxData.getData(&length, 1U);
|
||||||
|
m_rxData.getData(m_buffer, length);
|
||||||
|
|
||||||
|
// Is this a data packet?
|
||||||
|
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char seqNo = m_buffer[4U];
|
||||||
|
|
||||||
|
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||||
|
|
||||||
|
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
||||||
|
|
||||||
|
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||||
|
|
||||||
|
// DMO mode slot disabling
|
||||||
|
if (slotNo == 1U && !m_duplex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Individual slot disabling
|
||||||
|
if (slotNo == 1U && !m_slot1)
|
||||||
|
return false;
|
||||||
|
if (slotNo == 2U && !m_slot2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
||||||
|
|
||||||
|
data.setSeqNo(seqNo);
|
||||||
|
data.setSlotNo(slotNo);
|
||||||
|
data.setSrcId(srcId);
|
||||||
|
data.setDstId(dstId);
|
||||||
|
data.setFLCO(flco);
|
||||||
|
|
||||||
|
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
||||||
|
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
||||||
|
|
||||||
|
if (dataSync) {
|
||||||
|
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(dataType);
|
||||||
|
data.setN(0U);
|
||||||
|
} else if (voiceSync) {
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(DT_VOICE_SYNC);
|
||||||
|
data.setN(0U);
|
||||||
|
} else {
|
||||||
|
unsigned char n = m_buffer[15U] & 0x0FU;
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(DT_VOICE);
|
||||||
|
data.setN(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::write(const CDMRData& data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||||
|
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||||
|
|
||||||
|
buffer[0U] = 'D';
|
||||||
|
buffer[1U] = 'M';
|
||||||
|
buffer[2U] = 'R';
|
||||||
|
buffer[3U] = 'D';
|
||||||
|
|
||||||
|
unsigned int srcId = data.getSrcId();
|
||||||
|
buffer[5U] = srcId >> 16;
|
||||||
|
buffer[6U] = srcId >> 8;
|
||||||
|
buffer[7U] = srcId >> 0;
|
||||||
|
|
||||||
|
unsigned int dstId = data.getDstId();
|
||||||
|
buffer[8U] = dstId >> 16;
|
||||||
|
buffer[9U] = dstId >> 8;
|
||||||
|
buffer[10U] = dstId >> 0;
|
||||||
|
|
||||||
|
::memcpy(buffer + 11U, m_id, 4U);
|
||||||
|
|
||||||
|
unsigned int slotNo = data.getSlotNo();
|
||||||
|
|
||||||
|
// Individual slot disabling
|
||||||
|
if (slotNo == 1U && !m_slot1)
|
||||||
|
return false;
|
||||||
|
if (slotNo == 2U && !m_slot2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||||
|
|
||||||
|
FLCO flco = data.getFLCO();
|
||||||
|
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
||||||
|
|
||||||
|
unsigned int slotIndex = slotNo - 1U;
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
||||||
|
unsigned char dataType = data.getDataType();
|
||||||
|
if (dataType == DT_VOICE_SYNC) {
|
||||||
|
buffer[15U] |= 0x10U;
|
||||||
|
} else if (dataType == DT_VOICE) {
|
||||||
|
buffer[15U] |= data.getN();
|
||||||
|
} else {
|
||||||
|
if (dataType == DT_VOICE_LC_HEADER)
|
||||||
|
m_streamId[slotIndex] = dist(m_random);
|
||||||
|
|
||||||
|
if (dataType == DT_CSBK || dataType == DT_DATA_HEADER)
|
||||||
|
m_streamId[slotIndex] = dist(m_random);
|
||||||
|
|
||||||
|
buffer[15U] |= (0x20U | dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[4U] = data.getSeqNo();
|
||||||
|
|
||||||
|
::memcpy(buffer + 16U, m_streamId + slotIndex, 4U);
|
||||||
|
|
||||||
|
data.getData(buffer + 20U);
|
||||||
|
|
||||||
|
buffer[53U] = data.getBER();
|
||||||
|
|
||||||
|
buffer[54U] = data.getRSSI();
|
||||||
|
|
||||||
|
write(buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRG", 4U);
|
||||||
|
|
||||||
|
buffer[4U] = id >> 16;
|
||||||
|
buffer[5U] = id >> 8;
|
||||||
|
buffer[6U] = id >> 0;
|
||||||
|
|
||||||
|
::memcpy(buffer + 7U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 14U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRA", 4U);
|
||||||
|
|
||||||
|
buffer[4U] = id >> 16;
|
||||||
|
buffer[5U] = id >> 8;
|
||||||
|
buffer[6U] = id >> 0;
|
||||||
|
|
||||||
|
buffer[7U] = type;
|
||||||
|
|
||||||
|
::memcpy(buffer + 8U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 15U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::isConnected() const
|
||||||
|
{
|
||||||
|
return (m_status == RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRDirectNetwork::close(bool sayGoodbye)
|
||||||
|
{
|
||||||
|
LogMessage("Closing DMR Network");
|
||||||
|
|
||||||
|
if (sayGoodbye && (m_status == RUNNING)) {
|
||||||
|
unsigned char buffer[9U];
|
||||||
|
::memcpy(buffer + 0U, "RPTCL", 5U);
|
||||||
|
::memcpy(buffer + 5U, m_id, 4U);
|
||||||
|
write(buffer, 9U);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_socket.close();
|
||||||
|
|
||||||
|
m_retryTimer.stop();
|
||||||
|
m_timeoutTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRDirectNetwork::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
m_retryTimer.clock(ms);
|
||||||
|
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
||||||
|
switch (m_status) {
|
||||||
|
case WAITING_CONNECT:
|
||||||
|
if (m_socket.open(m_addr.ss_family)) {
|
||||||
|
if (writeLogin()) {
|
||||||
|
m_status = WAITING_LOGIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WAITING_LOGIN:
|
||||||
|
writeLogin();
|
||||||
|
break;
|
||||||
|
case WAITING_AUTHORISATION:
|
||||||
|
writeAuthorisation();
|
||||||
|
break;
|
||||||
|
case WAITING_OPTIONS:
|
||||||
|
writeOptions();
|
||||||
|
break;
|
||||||
|
case WAITING_CONFIG:
|
||||||
|
writeConfig();
|
||||||
|
break;
|
||||||
|
case RUNNING:
|
||||||
|
writePing();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_retryTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_storage address;
|
||||||
|
unsigned int addrlen;
|
||||||
|
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrlen);
|
||||||
|
if (length < 0) {
|
||||||
|
LogError("DMR, Socket has failed, retrying connection to the master");
|
||||||
|
close(false);
|
||||||
|
open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
if (!CUDPSocket::match(m_addr, address)) {
|
||||||
|
LogMessage("DMR, packet received from an invalid source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "DMR, Network Received", m_buffer, length);
|
||||||
|
|
||||||
|
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||||
|
if (m_enabled) {
|
||||||
|
unsigned char len = length;
|
||||||
|
m_rxData.addData(&len, 1U);
|
||||||
|
m_rxData.addData(m_buffer, len);
|
||||||
|
}
|
||||||
|
} else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) {
|
||||||
|
if (m_status == RUNNING) {
|
||||||
|
LogWarning("DMR, Login to the master has failed, retrying login ...");
|
||||||
|
m_status = WAITING_LOGIN;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
} else {
|
||||||
|
/* Once the modem death spiral has been prevented in Modem.cpp
|
||||||
|
the Network sometimes times out and reaches here.
|
||||||
|
We want it to reconnect so... */
|
||||||
|
LogError("DMR, Login to the master has failed, retrying network ...");
|
||||||
|
close(false);
|
||||||
|
open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
||||||
|
switch (m_status) {
|
||||||
|
case WAITING_LOGIN:
|
||||||
|
LogDebug("DMR, Sending authorisation");
|
||||||
|
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
||||||
|
writeAuthorisation();
|
||||||
|
m_status = WAITING_AUTHORISATION;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
case WAITING_AUTHORISATION:
|
||||||
|
LogDebug("DMR, Sending configuration");
|
||||||
|
writeConfig();
|
||||||
|
m_status = WAITING_CONFIG;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
case WAITING_CONFIG:
|
||||||
|
if (m_options.empty()) {
|
||||||
|
LogMessage("DMR, Logged into the master successfully");
|
||||||
|
m_status = RUNNING;
|
||||||
|
} else {
|
||||||
|
LogDebug("DMR, Sending options");
|
||||||
|
writeOptions();
|
||||||
|
m_status = WAITING_OPTIONS;
|
||||||
|
}
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
case WAITING_OPTIONS:
|
||||||
|
LogMessage("DMR, Logged into the master successfully");
|
||||||
|
m_status = RUNNING;
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
m_retryTimer.start();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (::memcmp(m_buffer, "MSTCL", 5U) == 0) {
|
||||||
|
LogError("DMR, Master is closing down");
|
||||||
|
close(false);
|
||||||
|
open();
|
||||||
|
} else if (::memcmp(m_buffer, "MSTPONG", 7U) == 0) {
|
||||||
|
m_timeoutTimer.start();
|
||||||
|
} else if (::memcmp(m_buffer, "RPTSBKN", 7U) == 0) {
|
||||||
|
m_beacon = true;
|
||||||
|
} else {
|
||||||
|
CUtils::dump("DMR, Unknown packet from the master", m_buffer, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timeoutTimer.clock(ms);
|
||||||
|
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
|
||||||
|
LogError("DMR, Connection to the master has timed out, retrying connection");
|
||||||
|
close(false);
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeLogin()
|
||||||
|
{
|
||||||
|
unsigned char buffer[8U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "RPTL", 4U);
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
|
||||||
|
return write(buffer, 8U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeAuthorisation()
|
||||||
|
{
|
||||||
|
size_t size = m_password.size();
|
||||||
|
|
||||||
|
unsigned char* in = new unsigned char[size + sizeof(uint32_t)];
|
||||||
|
::memcpy(in, m_salt, sizeof(uint32_t));
|
||||||
|
for (size_t i = 0U; i < size; i++)
|
||||||
|
in[i + sizeof(uint32_t)] = m_password.at(i);
|
||||||
|
|
||||||
|
unsigned char out[40U];
|
||||||
|
::memcpy(out + 0U, "RPTK", 4U);
|
||||||
|
::memcpy(out + 4U, m_id, 4U);
|
||||||
|
|
||||||
|
CSHA256 sha256;
|
||||||
|
sha256.buffer(in, (unsigned int)(size + sizeof(uint32_t)), out + 8U);
|
||||||
|
|
||||||
|
delete[] in;
|
||||||
|
|
||||||
|
return write(out, 40U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeOptions()
|
||||||
|
{
|
||||||
|
char buffer[300U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "RPTO", 4U);
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
::strcpy(buffer + 8U, m_options.c_str());
|
||||||
|
|
||||||
|
return write((unsigned char*)buffer, (unsigned int)m_options.length() + 8U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writeConfig()
|
||||||
|
{
|
||||||
|
const char* software;
|
||||||
|
char slots = '0';
|
||||||
|
if (m_duplex) {
|
||||||
|
if (m_slot1 && m_slot2)
|
||||||
|
slots = '3';
|
||||||
|
else if (m_slot1 && !m_slot2)
|
||||||
|
slots = '1';
|
||||||
|
else if (!m_slot1 && m_slot2)
|
||||||
|
slots = '2';
|
||||||
|
|
||||||
|
switch (m_hwType) {
|
||||||
|
case HWT_MMDVM:
|
||||||
|
software = "MMDVM";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS:
|
||||||
|
software = "MMDVM_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_DUAL_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_HOTSPOT:
|
||||||
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
software = "MMDVM_Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slots = '4';
|
||||||
|
|
||||||
|
switch (m_hwType) {
|
||||||
|
case HWT_MMDVM:
|
||||||
|
software = "MMDVM_DMO";
|
||||||
|
break;
|
||||||
|
case HWT_DVMEGA:
|
||||||
|
software = "MMDVM_DVMega";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_ZUMSPOT:
|
||||||
|
software = "MMDVM_ZUMspot";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_DUAL_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_HOTSPOT:
|
||||||
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_DV:
|
||||||
|
software = "MMDVM_Nano_DV";
|
||||||
|
break;
|
||||||
|
case HWT_D2RG_MMDVM_HS:
|
||||||
|
software = "MMDVM_D2RG_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS:
|
||||||
|
software = "MMDVM_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
software = "MMDVM_Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[400U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "RPTC", 4U);
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
|
||||||
|
char latitude[20U];
|
||||||
|
::sprintf(latitude, "%08f", m_latitude);
|
||||||
|
|
||||||
|
char longitude[20U];
|
||||||
|
::sprintf(longitude, "%09f", m_longitude);
|
||||||
|
|
||||||
|
unsigned int power = m_power;
|
||||||
|
if (power > 99U)
|
||||||
|
power = 99U;
|
||||||
|
|
||||||
|
int height = m_height;
|
||||||
|
if (height > 999)
|
||||||
|
height = 999;
|
||||||
|
|
||||||
|
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%8.8s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%-40.40s%-40.40s", m_callsign.c_str(),
|
||||||
|
m_rxFrequency, m_txFrequency, power, m_colorCode, latitude, longitude, height, m_location.c_str(),
|
||||||
|
m_description.c_str(), slots, m_url.c_str(), m_version, software);
|
||||||
|
|
||||||
|
return write((unsigned char*)buffer, 302U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::writePing()
|
||||||
|
{
|
||||||
|
unsigned char buffer[11U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "RPTPING", 7U);
|
||||||
|
::memcpy(buffer + 7U, m_id, 4U);
|
||||||
|
|
||||||
|
return write(buffer, 11U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::wantsBeacon()
|
||||||
|
{
|
||||||
|
bool beacon = m_beacon;
|
||||||
|
|
||||||
|
m_beacon = false;
|
||||||
|
|
||||||
|
return beacon;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRDirectNetwork::write(const unsigned char* data, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(length > 0U);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "DMR Network Transmitted", data, length);
|
||||||
|
|
||||||
|
bool ret = m_socket.write(data, length, m_addr, m_addrLen);
|
||||||
|
if (!ret) {
|
||||||
|
LogError("DMR, Socket has failed when writing data to the master, retrying connection");
|
||||||
|
close(false);
|
||||||
|
open();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
121
DMRDirectNetwork.h
Normal file
121
DMRDirectNetwork.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(DMRDirectNetwork_H)
|
||||||
|
#define DMRDirectNetwork_H
|
||||||
|
|
||||||
|
#include "DMRNetwork.h"
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "DMRData.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
class CDMRDirectNetwork : public IDMRNetwork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDMRDirectNetwork(const std::string& remoteAddress, unsigned short remotePort, const std::string& localAddress, unsigned short localPort, unsigned int id, const std::string& password, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug);
|
||||||
|
virtual ~CDMRDirectNetwork();
|
||||||
|
|
||||||
|
virtual void setOptions(const std::string& options);
|
||||||
|
|
||||||
|
virtual void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url);
|
||||||
|
|
||||||
|
virtual bool open();
|
||||||
|
|
||||||
|
virtual void enable(bool enabled);
|
||||||
|
|
||||||
|
virtual bool read(CDMRData& data);
|
||||||
|
|
||||||
|
virtual bool write(const CDMRData& data);
|
||||||
|
|
||||||
|
virtual bool writeRadioPosition(unsigned int id, const unsigned char* data);
|
||||||
|
|
||||||
|
virtual bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data);
|
||||||
|
|
||||||
|
virtual bool wantsBeacon();
|
||||||
|
|
||||||
|
virtual void clock(unsigned int ms);
|
||||||
|
|
||||||
|
virtual bool isConnected() const;
|
||||||
|
|
||||||
|
virtual void close(bool sayGoodbye);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_address;
|
||||||
|
unsigned short m_port;
|
||||||
|
sockaddr_storage m_addr;
|
||||||
|
unsigned int m_addrLen;
|
||||||
|
uint8_t* m_id;
|
||||||
|
std::string m_password;
|
||||||
|
bool m_duplex;
|
||||||
|
const char* m_version;
|
||||||
|
bool m_debug;
|
||||||
|
CUDPSocket m_socket;
|
||||||
|
bool m_enabled;
|
||||||
|
bool m_slot1;
|
||||||
|
bool m_slot2;
|
||||||
|
HW_TYPE m_hwType;
|
||||||
|
|
||||||
|
enum STATUS {
|
||||||
|
WAITING_CONNECT,
|
||||||
|
WAITING_LOGIN,
|
||||||
|
WAITING_AUTHORISATION,
|
||||||
|
WAITING_CONFIG,
|
||||||
|
WAITING_OPTIONS,
|
||||||
|
RUNNING
|
||||||
|
};
|
||||||
|
|
||||||
|
STATUS m_status;
|
||||||
|
CTimer m_retryTimer;
|
||||||
|
CTimer m_timeoutTimer;
|
||||||
|
unsigned char* m_buffer;
|
||||||
|
uint32_t* m_streamId;
|
||||||
|
unsigned char* m_salt;
|
||||||
|
|
||||||
|
CRingBuffer<unsigned char> m_rxData;
|
||||||
|
|
||||||
|
std::string m_options;
|
||||||
|
|
||||||
|
std::mt19937 m_random;
|
||||||
|
std::string m_callsign;
|
||||||
|
unsigned int m_rxFrequency;
|
||||||
|
unsigned int m_txFrequency;
|
||||||
|
unsigned int m_power;
|
||||||
|
unsigned int m_colorCode;
|
||||||
|
float m_latitude;
|
||||||
|
float m_longitude;
|
||||||
|
int m_height;
|
||||||
|
std::string m_location;
|
||||||
|
std::string m_description;
|
||||||
|
std::string m_url;
|
||||||
|
bool m_beacon;
|
||||||
|
|
||||||
|
bool writeLogin();
|
||||||
|
bool writeAuthorisation();
|
||||||
|
bool writeOptions();
|
||||||
|
bool writeConfig();
|
||||||
|
bool writePing();
|
||||||
|
|
||||||
|
bool write(const unsigned char* data, unsigned int length);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
450
DMRGatewayNetwork.cpp
Normal file
450
DMRGatewayNetwork.cpp
Normal file
|
@ -0,0 +1,450 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2021 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DMRGatewayNetwork.h"
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
const unsigned int BUFFER_LENGTH = 500U;
|
||||||
|
|
||||||
|
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||||
|
|
||||||
|
|
||||||
|
CDMRGatewayNetwork::CDMRGatewayNetwork(const std::string& address, unsigned short port, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug) :
|
||||||
|
m_addressStr(address),
|
||||||
|
m_addr(),
|
||||||
|
m_addrLen(0U),
|
||||||
|
m_port(port),
|
||||||
|
m_id(NULL),
|
||||||
|
m_duplex(duplex),
|
||||||
|
m_version(version),
|
||||||
|
m_debug(debug),
|
||||||
|
m_socket(localAddress, localPort),
|
||||||
|
m_enabled(false),
|
||||||
|
m_slot1(slot1),
|
||||||
|
m_slot2(slot2),
|
||||||
|
m_hwType(hwType),
|
||||||
|
m_buffer(NULL),
|
||||||
|
m_streamId(NULL),
|
||||||
|
m_rxData(1000U, "DMR Network"),
|
||||||
|
m_beacon(false),
|
||||||
|
m_random(),
|
||||||
|
m_callsign(),
|
||||||
|
m_rxFrequency(0U),
|
||||||
|
m_txFrequency(0U),
|
||||||
|
m_power(0U),
|
||||||
|
m_colorCode(0U),
|
||||||
|
m_pingTimer(1000U, 10U)
|
||||||
|
{
|
||||||
|
assert(!address.empty());
|
||||||
|
assert(port > 0U);
|
||||||
|
assert(id > 1000U);
|
||||||
|
|
||||||
|
if (CUDPSocket::lookup(m_addressStr, m_port, m_addr, m_addrLen) != 0)
|
||||||
|
m_addrLen = 0U;
|
||||||
|
|
||||||
|
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||||
|
m_id = new uint8_t[4U];
|
||||||
|
m_streamId = new uint32_t[2U];
|
||||||
|
|
||||||
|
m_id[0U] = id >> 24;
|
||||||
|
m_id[1U] = id >> 16;
|
||||||
|
m_id[2U] = id >> 8;
|
||||||
|
m_id[3U] = id >> 0;
|
||||||
|
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 mt(rd());
|
||||||
|
m_random = mt;
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
||||||
|
m_streamId[0U] = dist(m_random);
|
||||||
|
m_streamId[1U] = dist(m_random);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDMRGatewayNetwork::~CDMRGatewayNetwork()
|
||||||
|
{
|
||||||
|
delete[] m_buffer;
|
||||||
|
delete[] m_streamId;
|
||||||
|
delete[] m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRGatewayNetwork::setConfig(const std::string & callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url)
|
||||||
|
{
|
||||||
|
m_callsign = callsign;
|
||||||
|
m_rxFrequency = rxFrequency;
|
||||||
|
m_txFrequency = txFrequency;
|
||||||
|
m_power = power;
|
||||||
|
m_colorCode = colorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRGatewayNetwork::setOptions(const std::string& options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::open()
|
||||||
|
{
|
||||||
|
if (m_addrLen == 0U) {
|
||||||
|
LogError("Unable to resolve the address of the DMR Network");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("DMR, Opening DMR Network");
|
||||||
|
|
||||||
|
bool ret = m_socket.open(m_addr);
|
||||||
|
if (ret)
|
||||||
|
m_pingTimer.start();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRGatewayNetwork::enable(bool enabled)
|
||||||
|
{
|
||||||
|
if (!enabled && m_enabled)
|
||||||
|
m_rxData.clear();
|
||||||
|
|
||||||
|
m_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::read(CDMRData& data)
|
||||||
|
{
|
||||||
|
if (m_rxData.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char length = 0U;
|
||||||
|
m_rxData.getData(&length, 1U);
|
||||||
|
m_rxData.getData(m_buffer, length);
|
||||||
|
|
||||||
|
// Is this a data packet?
|
||||||
|
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char seqNo = m_buffer[4U];
|
||||||
|
|
||||||
|
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||||
|
|
||||||
|
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
||||||
|
|
||||||
|
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||||
|
|
||||||
|
// DMO mode slot disabling
|
||||||
|
if (slotNo == 1U && !m_duplex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Individual slot disabling
|
||||||
|
if (slotNo == 1U && !m_slot1)
|
||||||
|
return false;
|
||||||
|
if (slotNo == 2U && !m_slot2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
||||||
|
|
||||||
|
data.setSeqNo(seqNo);
|
||||||
|
data.setSlotNo(slotNo);
|
||||||
|
data.setSrcId(srcId);
|
||||||
|
data.setDstId(dstId);
|
||||||
|
data.setFLCO(flco);
|
||||||
|
|
||||||
|
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
||||||
|
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
||||||
|
|
||||||
|
if (dataSync) {
|
||||||
|
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(dataType);
|
||||||
|
data.setN(0U);
|
||||||
|
} else if (voiceSync) {
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(DT_VOICE_SYNC);
|
||||||
|
data.setN(0U);
|
||||||
|
} else {
|
||||||
|
unsigned char n = m_buffer[15U] & 0x0FU;
|
||||||
|
data.setData(m_buffer + 20U);
|
||||||
|
data.setDataType(DT_VOICE);
|
||||||
|
data.setN(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::write(const CDMRData& data)
|
||||||
|
{
|
||||||
|
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||||
|
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||||
|
|
||||||
|
buffer[0U] = 'D';
|
||||||
|
buffer[1U] = 'M';
|
||||||
|
buffer[2U] = 'R';
|
||||||
|
buffer[3U] = 'D';
|
||||||
|
|
||||||
|
unsigned int srcId = data.getSrcId();
|
||||||
|
buffer[5U] = srcId >> 16;
|
||||||
|
buffer[6U] = srcId >> 8;
|
||||||
|
buffer[7U] = srcId >> 0;
|
||||||
|
|
||||||
|
unsigned int dstId = data.getDstId();
|
||||||
|
buffer[8U] = dstId >> 16;
|
||||||
|
buffer[9U] = dstId >> 8;
|
||||||
|
buffer[10U] = dstId >> 0;
|
||||||
|
|
||||||
|
::memcpy(buffer + 11U, m_id, 4U);
|
||||||
|
|
||||||
|
unsigned int slotNo = data.getSlotNo();
|
||||||
|
|
||||||
|
// Individual slot disabling
|
||||||
|
if (slotNo == 1U && !m_slot1)
|
||||||
|
return false;
|
||||||
|
if (slotNo == 2U && !m_slot2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||||
|
|
||||||
|
FLCO flco = data.getFLCO();
|
||||||
|
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
||||||
|
|
||||||
|
unsigned int slotIndex = slotNo - 1U;
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
||||||
|
unsigned char dataType = data.getDataType();
|
||||||
|
if (dataType == DT_VOICE_SYNC) {
|
||||||
|
buffer[15U] |= 0x10U;
|
||||||
|
} else if (dataType == DT_VOICE) {
|
||||||
|
buffer[15U] |= data.getN();
|
||||||
|
} else {
|
||||||
|
if (dataType == DT_VOICE_LC_HEADER)
|
||||||
|
m_streamId[slotIndex] = dist(m_random);
|
||||||
|
|
||||||
|
if (dataType == DT_CSBK || dataType == DT_DATA_HEADER)
|
||||||
|
m_streamId[slotIndex] = dist(m_random);
|
||||||
|
|
||||||
|
buffer[15U] |= (0x20U | dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[4U] = data.getSeqNo();
|
||||||
|
|
||||||
|
::memcpy(buffer + 16U, m_streamId + slotIndex, 4U);
|
||||||
|
|
||||||
|
data.getData(buffer + 20U);
|
||||||
|
|
||||||
|
buffer[53U] = data.getBER();
|
||||||
|
|
||||||
|
buffer[54U] = data.getRSSI();
|
||||||
|
|
||||||
|
write(buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
||||||
|
{
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRG", 4U);
|
||||||
|
|
||||||
|
buffer[4U] = id >> 16;
|
||||||
|
buffer[5U] = id >> 8;
|
||||||
|
buffer[6U] = id >> 0;
|
||||||
|
|
||||||
|
::memcpy(buffer + 7U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 14U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
||||||
|
{
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRA", 4U);
|
||||||
|
|
||||||
|
buffer[4U] = id >> 16;
|
||||||
|
buffer[5U] = id >> 8;
|
||||||
|
buffer[6U] = id >> 0;
|
||||||
|
|
||||||
|
buffer[7U] = type;
|
||||||
|
|
||||||
|
::memcpy(buffer + 8U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 15U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::isConnected() const
|
||||||
|
{
|
||||||
|
return (m_addrLen != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRGatewayNetwork::close(bool sayGoodbye)
|
||||||
|
{
|
||||||
|
LogMessage("DMR, Closing DMR Network");
|
||||||
|
|
||||||
|
m_socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRGatewayNetwork::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
m_pingTimer.clock(ms);
|
||||||
|
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
|
||||||
|
writeConfig();
|
||||||
|
m_pingTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_storage address;
|
||||||
|
unsigned int addrLen;
|
||||||
|
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrLen);
|
||||||
|
if (length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!CUDPSocket::match(m_addr, address)) {
|
||||||
|
LogMessage("DMR, packet received from an invalid source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "DMR Network Received", m_buffer, length);
|
||||||
|
|
||||||
|
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||||
|
if (m_enabled) {
|
||||||
|
unsigned char len = length;
|
||||||
|
m_rxData.addData(&len, 1U);
|
||||||
|
m_rxData.addData(m_buffer, len);
|
||||||
|
}
|
||||||
|
} else if (::memcmp(m_buffer, "DMRP", 4U) == 0) {
|
||||||
|
;
|
||||||
|
} else if (::memcmp(m_buffer, "DMRB", 4U) == 0) {
|
||||||
|
m_beacon = true;
|
||||||
|
} else {
|
||||||
|
CUtils::dump("DMR, unknown packet from the DMR Network", m_buffer, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::writeConfig()
|
||||||
|
{
|
||||||
|
const char* software;
|
||||||
|
char slots = '0';
|
||||||
|
if (m_duplex) {
|
||||||
|
if (m_slot1 && m_slot2)
|
||||||
|
slots = '3';
|
||||||
|
else if (m_slot1 && !m_slot2)
|
||||||
|
slots = '1';
|
||||||
|
else if (!m_slot1 && m_slot2)
|
||||||
|
slots = '2';
|
||||||
|
|
||||||
|
switch (m_hwType) {
|
||||||
|
case HWT_MMDVM:
|
||||||
|
software = "MMDVM";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS:
|
||||||
|
software = "MMDVM_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_DUAL_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_HOTSPOT:
|
||||||
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
software = "MMDVM_Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slots = '4';
|
||||||
|
|
||||||
|
switch (m_hwType) {
|
||||||
|
case HWT_MMDVM:
|
||||||
|
software = "MMDVM_DMO";
|
||||||
|
break;
|
||||||
|
case HWT_DVMEGA:
|
||||||
|
software = "MMDVM_DVMega";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_ZUMSPOT:
|
||||||
|
software = "MMDVM_ZUMspot";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS_DUAL_HAT:
|
||||||
|
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_HOTSPOT:
|
||||||
|
software = "MMDVM_Nano_hotSPOT";
|
||||||
|
break;
|
||||||
|
case HWT_NANO_DV:
|
||||||
|
software = "MMDVM_Nano_DV";
|
||||||
|
break;
|
||||||
|
case HWT_D2RG_MMDVM_HS:
|
||||||
|
software = "MMDVM_D2RG_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
case HWT_MMDVM_HS:
|
||||||
|
software = "MMDVM_MMDVM_HS";
|
||||||
|
break;
|
||||||
|
case HWT_OPENGD77_HS:
|
||||||
|
software = "MMDVM_OpenGD77_HS";
|
||||||
|
break;
|
||||||
|
case HWT_SKYBRIDGE:
|
||||||
|
software = "MMDVM_SkyBridge";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
software = "MMDVM_Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int power = m_power;
|
||||||
|
if (power > 99U)
|
||||||
|
power = 99U;
|
||||||
|
|
||||||
|
char buffer[150U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRC", 4U);
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%c%-40.40s%-40.40s",
|
||||||
|
m_callsign.c_str(), m_rxFrequency, m_txFrequency, power, m_colorCode, slots, m_version,
|
||||||
|
software);
|
||||||
|
|
||||||
|
return write((unsigned char*)buffer, 119U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::wantsBeacon()
|
||||||
|
{
|
||||||
|
bool beacon = m_beacon;
|
||||||
|
|
||||||
|
m_beacon = false;
|
||||||
|
|
||||||
|
return beacon;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRGatewayNetwork::write(const unsigned char* data, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(length > 0U);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "DMR Network Transmitted", data, length);
|
||||||
|
|
||||||
|
bool ret = m_socket.write(data, length, m_addr, m_addrLen);
|
||||||
|
if (!ret) {
|
||||||
|
LogError("DMR, socket error when writing to the DMR Network");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
94
DMRGatewayNetwork.h
Normal file
94
DMRGatewayNetwork.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(DMRGatewayNetwork_H)
|
||||||
|
#define DMRGatewayNetwork_H
|
||||||
|
|
||||||
|
#include "DMRNetwork.h"
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "DMRData.h"
|
||||||
|
#include "Defines.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
class CDMRGatewayNetwork : public IDMRNetwork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDMRGatewayNetwork(const std::string& remoteAddress, unsigned short remotePort, const std::string& localAddress, unsigned short localPort, unsigned int id, bool duplex, const char* version, bool slot1, bool slot2, HW_TYPE hwType, bool debug);
|
||||||
|
virtual ~CDMRGatewayNetwork();
|
||||||
|
|
||||||
|
virtual void setOptions(const std::string& options);
|
||||||
|
|
||||||
|
virtual void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url);
|
||||||
|
|
||||||
|
virtual bool open();
|
||||||
|
|
||||||
|
virtual void enable(bool enabled);
|
||||||
|
|
||||||
|
virtual bool read(CDMRData& data);
|
||||||
|
|
||||||
|
virtual bool write(const CDMRData& data);
|
||||||
|
|
||||||
|
virtual bool writeRadioPosition(unsigned int id, const unsigned char* data);
|
||||||
|
|
||||||
|
virtual bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data);
|
||||||
|
|
||||||
|
virtual bool wantsBeacon();
|
||||||
|
|
||||||
|
virtual void clock(unsigned int ms);
|
||||||
|
|
||||||
|
virtual bool isConnected() const;
|
||||||
|
|
||||||
|
virtual void close(bool sayGoodbye);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_addressStr;
|
||||||
|
sockaddr_storage m_addr;
|
||||||
|
unsigned int m_addrLen;
|
||||||
|
unsigned short m_port;
|
||||||
|
uint8_t* m_id;
|
||||||
|
bool m_duplex;
|
||||||
|
const char* m_version;
|
||||||
|
bool m_debug;
|
||||||
|
CUDPSocket m_socket;
|
||||||
|
bool m_enabled;
|
||||||
|
bool m_slot1;
|
||||||
|
bool m_slot2;
|
||||||
|
HW_TYPE m_hwType;
|
||||||
|
unsigned char* m_buffer;
|
||||||
|
uint32_t* m_streamId;
|
||||||
|
CRingBuffer<unsigned char> m_rxData;
|
||||||
|
bool m_beacon;
|
||||||
|
std::mt19937 m_random;
|
||||||
|
std::string m_callsign;
|
||||||
|
unsigned int m_rxFrequency;
|
||||||
|
unsigned int m_txFrequency;
|
||||||
|
unsigned int m_power;
|
||||||
|
unsigned int m_colorCode;
|
||||||
|
CTimer m_pingTimer;
|
||||||
|
|
||||||
|
bool writeConfig();
|
||||||
|
|
||||||
|
bool write(const unsigned char* data, unsigned int length);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2019 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2019,2021,2022 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -193,6 +193,8 @@ void CDMRLC::setOVCM(bool ovcm)
|
||||||
{
|
{
|
||||||
if (ovcm)
|
if (ovcm)
|
||||||
m_options |= 0x04U;
|
m_options |= 0x04U;
|
||||||
|
else
|
||||||
|
m_options &= 0xFBU;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CDMRLC::getSrcId() const
|
unsigned int CDMRLC::getSrcId() const
|
||||||
|
|
2
DMRLC.h
2
DMRLC.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2019 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2019,2021,2022 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -30,7 +30,8 @@ CThread(),
|
||||||
m_filename(filename),
|
m_filename(filename),
|
||||||
m_reloadTime(reloadTime),
|
m_reloadTime(reloadTime),
|
||||||
m_table(),
|
m_table(),
|
||||||
m_stop(false)
|
m_stop(false),
|
||||||
|
m_reload(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +49,14 @@ bool CDMRLookup::read()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDMRLookup::reload()
|
||||||
|
{
|
||||||
|
if (m_reloadTime == 0U)
|
||||||
|
m_table.load(m_filename);
|
||||||
|
else
|
||||||
|
m_reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CDMRLookup::entry()
|
void CDMRLookup::entry()
|
||||||
{
|
{
|
||||||
LogInfo("Started the DMR Id lookup reload thread");
|
LogInfo("Started the DMR Id lookup reload thread");
|
||||||
|
@ -59,9 +68,10 @@ void CDMRLookup::entry()
|
||||||
sleep(1000U);
|
sleep(1000U);
|
||||||
|
|
||||||
timer.clock();
|
timer.clock();
|
||||||
if (timer.hasExpired()) {
|
if (timer.hasExpired() || m_reload) {
|
||||||
m_table.load(m_filename);
|
m_table.load(m_filename);
|
||||||
timer.start();
|
timer.start();
|
||||||
|
m_reload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +92,7 @@ void CDMRLookup::stop()
|
||||||
|
|
||||||
void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry)
|
void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry)
|
||||||
{
|
{
|
||||||
if (id == 0xFFFFFFU) {
|
if (id == 0xFFFFFFFU) {
|
||||||
entry->clear();
|
entry->clear();
|
||||||
entry->set(keyCALLSIGN, "ALL");
|
entry->set(keyCALLSIGN, "ALL");
|
||||||
return;
|
return;
|
||||||
|
@ -105,7 +115,7 @@ std::string CDMRLookup::find(unsigned int id)
|
||||||
{
|
{
|
||||||
std::string callsign;
|
std::string callsign;
|
||||||
|
|
||||||
if (id == 0xFFFFFFU)
|
if (id == 0xFFFFFFFU)
|
||||||
return std::string("ALL");
|
return std::string("ALL");
|
||||||
|
|
||||||
class CUserDBentry entry;
|
class CUserDBentry entry;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,6 +31,8 @@ public:
|
||||||
|
|
||||||
bool read();
|
bool read();
|
||||||
|
|
||||||
|
void reload();
|
||||||
|
|
||||||
virtual void entry();
|
virtual void entry();
|
||||||
|
|
||||||
std::string find(unsigned int id);
|
std::string find(unsigned int id);
|
||||||
|
@ -45,6 +47,7 @@ private:
|
||||||
unsigned int m_reloadTime;
|
unsigned int m_reloadTime;
|
||||||
class CUserDB m_table;
|
class CUserDB m_table;
|
||||||
bool m_stop;
|
bool m_stop;
|
||||||
|
bool m_reload;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
421
DMRNetwork.cpp
421
DMRNetwork.cpp
|
@ -18,425 +18,6 @@
|
||||||
|
|
||||||
#include "DMRNetwork.h"
|
#include "DMRNetwork.h"
|
||||||
|
|
||||||
#include "StopWatch.h"
|
IDMRNetwork::~IDMRNetwork()
|
||||||
#include "Utils.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 500U;
|
|
||||||
|
|
||||||
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
|
||||||
|
|
||||||
|
|
||||||
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType) :
|
|
||||||
m_addressStr(address),
|
|
||||||
m_addr(),
|
|
||||||
m_addrLen(0U),
|
|
||||||
m_port(port),
|
|
||||||
m_id(NULL),
|
|
||||||
m_duplex(duplex),
|
|
||||||
m_version(version),
|
|
||||||
m_debug(debug),
|
|
||||||
m_socket(local),
|
|
||||||
m_enabled(false),
|
|
||||||
m_slot1(slot1),
|
|
||||||
m_slot2(slot2),
|
|
||||||
m_hwType(hwType),
|
|
||||||
m_buffer(NULL),
|
|
||||||
m_streamId(NULL),
|
|
||||||
m_rxData(1000U, "DMR Network"),
|
|
||||||
m_beacon(false),
|
|
||||||
m_random(),
|
|
||||||
m_callsign(),
|
|
||||||
m_rxFrequency(0U),
|
|
||||||
m_txFrequency(0U),
|
|
||||||
m_power(0U),
|
|
||||||
m_colorCode(0U),
|
|
||||||
m_pingTimer(1000U, 10U)
|
|
||||||
{
|
{
|
||||||
assert(!address.empty());
|
|
||||||
assert(port > 0U);
|
|
||||||
assert(id > 1000U);
|
|
||||||
|
|
||||||
if (CUDPSocket::lookup(m_addressStr, m_port, m_addr, m_addrLen) != 0)
|
|
||||||
m_addrLen = 0U;
|
|
||||||
|
|
||||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
|
||||||
m_id = new uint8_t[4U];
|
|
||||||
m_streamId = new uint32_t[2U];
|
|
||||||
|
|
||||||
m_id[0U] = id >> 24;
|
|
||||||
m_id[1U] = id >> 16;
|
|
||||||
m_id[2U] = id >> 8;
|
|
||||||
m_id[3U] = id >> 0;
|
|
||||||
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 mt(rd());
|
|
||||||
m_random = mt;
|
|
||||||
|
|
||||||
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
|
||||||
m_streamId[0U] = dist(m_random);
|
|
||||||
m_streamId[1U] = dist(m_random);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDMRNetwork::~CDMRNetwork()
|
|
||||||
{
|
|
||||||
delete[] m_buffer;
|
|
||||||
delete[] m_streamId;
|
|
||||||
delete[] m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::setConfig(const std::string & callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode)
|
|
||||||
{
|
|
||||||
m_callsign = callsign;
|
|
||||||
m_rxFrequency = rxFrequency;
|
|
||||||
m_txFrequency = txFrequency;
|
|
||||||
m_power = power;
|
|
||||||
m_colorCode = colorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::open()
|
|
||||||
{
|
|
||||||
if (m_addrLen == 0U) {
|
|
||||||
LogError("Unable to resolve the address of the DMR Gateway");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("DMR, Opening DMR Network");
|
|
||||||
|
|
||||||
bool ret = m_socket.open(m_addr);
|
|
||||||
if (ret)
|
|
||||||
m_pingTimer.start();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::enable(bool enabled)
|
|
||||||
{
|
|
||||||
if (!enabled && m_enabled)
|
|
||||||
m_rxData.clear();
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::read(CDMRData& data)
|
|
||||||
{
|
|
||||||
if (m_rxData.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char length = 0U;
|
|
||||||
m_rxData.getData(&length, 1U);
|
|
||||||
m_rxData.getData(m_buffer, length);
|
|
||||||
|
|
||||||
// Is this a data packet?
|
|
||||||
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char seqNo = m_buffer[4U];
|
|
||||||
|
|
||||||
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
|
||||||
|
|
||||||
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
|
||||||
|
|
||||||
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
|
||||||
|
|
||||||
// DMO mode slot disabling
|
|
||||||
if (slotNo == 1U && !m_duplex)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Individual slot disabling
|
|
||||||
if (slotNo == 1U && !m_slot1)
|
|
||||||
return false;
|
|
||||||
if (slotNo == 2U && !m_slot2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
|
||||||
|
|
||||||
data.setSeqNo(seqNo);
|
|
||||||
data.setSlotNo(slotNo);
|
|
||||||
data.setSrcId(srcId);
|
|
||||||
data.setDstId(dstId);
|
|
||||||
data.setFLCO(flco);
|
|
||||||
|
|
||||||
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
|
||||||
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
|
||||||
|
|
||||||
if (dataSync) {
|
|
||||||
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
|
||||||
data.setData(m_buffer + 20U);
|
|
||||||
data.setDataType(dataType);
|
|
||||||
data.setN(0U);
|
|
||||||
} else if (voiceSync) {
|
|
||||||
data.setData(m_buffer + 20U);
|
|
||||||
data.setDataType(DT_VOICE_SYNC);
|
|
||||||
data.setN(0U);
|
|
||||||
} else {
|
|
||||||
unsigned char n = m_buffer[15U] & 0x0FU;
|
|
||||||
data.setData(m_buffer + 20U);
|
|
||||||
data.setDataType(DT_VOICE);
|
|
||||||
data.setN(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::write(const CDMRData& data)
|
|
||||||
{
|
|
||||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
|
||||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
|
||||||
|
|
||||||
buffer[0U] = 'D';
|
|
||||||
buffer[1U] = 'M';
|
|
||||||
buffer[2U] = 'R';
|
|
||||||
buffer[3U] = 'D';
|
|
||||||
|
|
||||||
unsigned int srcId = data.getSrcId();
|
|
||||||
buffer[5U] = srcId >> 16;
|
|
||||||
buffer[6U] = srcId >> 8;
|
|
||||||
buffer[7U] = srcId >> 0;
|
|
||||||
|
|
||||||
unsigned int dstId = data.getDstId();
|
|
||||||
buffer[8U] = dstId >> 16;
|
|
||||||
buffer[9U] = dstId >> 8;
|
|
||||||
buffer[10U] = dstId >> 0;
|
|
||||||
|
|
||||||
::memcpy(buffer + 11U, m_id, 4U);
|
|
||||||
|
|
||||||
unsigned int slotNo = data.getSlotNo();
|
|
||||||
|
|
||||||
// Individual slot disabling
|
|
||||||
if (slotNo == 1U && !m_slot1)
|
|
||||||
return false;
|
|
||||||
if (slotNo == 2U && !m_slot2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
|
||||||
|
|
||||||
FLCO flco = data.getFLCO();
|
|
||||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
|
||||||
|
|
||||||
unsigned int slotIndex = slotNo - 1U;
|
|
||||||
|
|
||||||
std::uniform_int_distribution<uint32_t> dist(0x00000001, 0xfffffffe);
|
|
||||||
unsigned char dataType = data.getDataType();
|
|
||||||
if (dataType == DT_VOICE_SYNC) {
|
|
||||||
buffer[15U] |= 0x10U;
|
|
||||||
} else if (dataType == DT_VOICE) {
|
|
||||||
buffer[15U] |= data.getN();
|
|
||||||
} else {
|
|
||||||
if (dataType == DT_VOICE_LC_HEADER)
|
|
||||||
m_streamId[slotIndex] = dist(m_random);
|
|
||||||
|
|
||||||
if (dataType == DT_CSBK || dataType == DT_DATA_HEADER)
|
|
||||||
m_streamId[slotIndex] = dist(m_random);
|
|
||||||
|
|
||||||
buffer[15U] |= (0x20U | dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[4U] = data.getSeqNo();
|
|
||||||
|
|
||||||
::memcpy(buffer + 16U, m_streamId + slotIndex, 4U);
|
|
||||||
|
|
||||||
data.getData(buffer + 20U);
|
|
||||||
|
|
||||||
buffer[53U] = data.getBER();
|
|
||||||
|
|
||||||
buffer[54U] = data.getRSSI();
|
|
||||||
|
|
||||||
write(buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
|
||||||
{
|
|
||||||
unsigned char buffer[20U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "DMRG", 4U);
|
|
||||||
|
|
||||||
buffer[4U] = id >> 16;
|
|
||||||
buffer[5U] = id >> 8;
|
|
||||||
buffer[6U] = id >> 0;
|
|
||||||
|
|
||||||
::memcpy(buffer + 7U, data + 2U, 7U);
|
|
||||||
|
|
||||||
return write(buffer, 14U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
|
||||||
{
|
|
||||||
unsigned char buffer[20U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "DMRA", 4U);
|
|
||||||
|
|
||||||
buffer[4U] = id >> 16;
|
|
||||||
buffer[5U] = id >> 8;
|
|
||||||
buffer[6U] = id >> 0;
|
|
||||||
|
|
||||||
buffer[7U] = type;
|
|
||||||
|
|
||||||
::memcpy(buffer + 8U, data + 2U, 7U);
|
|
||||||
|
|
||||||
return write(buffer, 15U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::close()
|
|
||||||
{
|
|
||||||
LogMessage("DMR, Closing DMR Network");
|
|
||||||
|
|
||||||
m_socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
m_pingTimer.clock(ms);
|
|
||||||
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
|
|
||||||
writeConfig();
|
|
||||||
m_pingTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_storage address;
|
|
||||||
unsigned int addrLen;
|
|
||||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrLen);
|
|
||||||
if (length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!CUDPSocket::match(m_addr, address)) {
|
|
||||||
LogMessage("DMR, packet received from an invalid source");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
|
||||||
|
|
||||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
|
||||||
if (m_enabled) {
|
|
||||||
unsigned char len = length;
|
|
||||||
m_rxData.addData(&len, 1U);
|
|
||||||
m_rxData.addData(m_buffer, len);
|
|
||||||
}
|
|
||||||
} else if (::memcmp(m_buffer, "DMRP", 4U) == 0) {
|
|
||||||
;
|
|
||||||
} else if (::memcmp(m_buffer, "DMRB", 4U) == 0) {
|
|
||||||
m_beacon = true;
|
|
||||||
} else {
|
|
||||||
CUtils::dump("DMR, unknown packet from the DMR Gateway", m_buffer, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeConfig()
|
|
||||||
{
|
|
||||||
const char* software;
|
|
||||||
char slots = '0';
|
|
||||||
if (m_duplex) {
|
|
||||||
if (m_slot1 && m_slot2)
|
|
||||||
slots = '3';
|
|
||||||
else if (m_slot1 && !m_slot2)
|
|
||||||
slots = '1';
|
|
||||||
else if (!m_slot1 && m_slot2)
|
|
||||||
slots = '2';
|
|
||||||
|
|
||||||
switch (m_hwType) {
|
|
||||||
case HWT_MMDVM:
|
|
||||||
software = "MMDVM";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_HS:
|
|
||||||
software = "MMDVM_MMDVM_HS";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
|
||||||
break;
|
|
||||||
case HWT_NANO_HOTSPOT:
|
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
software = "MMDVM_Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
slots = '4';
|
|
||||||
|
|
||||||
switch (m_hwType) {
|
|
||||||
case HWT_MMDVM:
|
|
||||||
software = "MMDVM_DMO";
|
|
||||||
break;
|
|
||||||
case HWT_DVMEGA:
|
|
||||||
software = "MMDVM_DVMega";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_ZUMSPOT:
|
|
||||||
software = "MMDVM_ZUMspot";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_HS_HAT:
|
|
||||||
software = "MMDVM_MMDVM_HS_Hat";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_HS_DUAL_HAT:
|
|
||||||
software = "MMDVM_MMDVM_HS_Dual_Hat";
|
|
||||||
break;
|
|
||||||
case HWT_NANO_HOTSPOT:
|
|
||||||
software = "MMDVM_Nano_hotSPOT";
|
|
||||||
break;
|
|
||||||
case HWT_NANO_DV:
|
|
||||||
software = "MMDVM_Nano_DV";
|
|
||||||
break;
|
|
||||||
case HWT_D2RG_MMDVM_HS:
|
|
||||||
software = "MMDVM_D2RG_MMDVM_HS";
|
|
||||||
break;
|
|
||||||
case HWT_MMDVM_HS:
|
|
||||||
software = "MMDVM_MMDVM_HS";
|
|
||||||
break;
|
|
||||||
case HWT_OPENGD77_HS:
|
|
||||||
software = "MMDVM_OpenGD77_HS";
|
|
||||||
break;
|
|
||||||
case HWT_SKYBRIDGE:
|
|
||||||
software = "MMDVM_SkyBridge";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
software = "MMDVM_Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int power = m_power;
|
|
||||||
if (power > 99U)
|
|
||||||
power = 99U;
|
|
||||||
|
|
||||||
char buffer[150U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "DMRC", 4U);
|
|
||||||
::memcpy(buffer + 4U, m_id, 4U);
|
|
||||||
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%c%-40.40s%-40.40s",
|
|
||||||
m_callsign.c_str(), m_rxFrequency, m_txFrequency, power, m_colorCode, slots, m_version,
|
|
||||||
software);
|
|
||||||
|
|
||||||
return write((unsigned char*)buffer, 119U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::wantsBeacon()
|
|
||||||
{
|
|
||||||
bool beacon = m_beacon;
|
|
||||||
|
|
||||||
m_beacon = false;
|
|
||||||
|
|
||||||
return beacon;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::write(const unsigned char* data, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
assert(length > 0U);
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "Network Transmitted", data, length);
|
|
||||||
|
|
||||||
bool ret = m_socket.write(data, length, m_addr, m_addrLen);
|
|
||||||
if (!ret) {
|
|
||||||
LogError("DMR, socket error when writing to the DMR Gateway");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
65
DMRNetwork.h
65
DMRNetwork.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,71 +19,40 @@
|
||||||
#if !defined(DMRNetwork_H)
|
#if !defined(DMRNetwork_H)
|
||||||
#define DMRNetwork_H
|
#define DMRNetwork_H
|
||||||
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "DMRData.h"
|
#include "DMRData.h"
|
||||||
#include "Defines.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
class CDMRNetwork
|
class IDMRNetwork
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType);
|
virtual ~IDMRNetwork() = 0;
|
||||||
~CDMRNetwork();
|
|
||||||
|
|
||||||
void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode);
|
virtual void setOptions(const std::string& options) = 0;
|
||||||
|
|
||||||
bool open();
|
virtual void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url) = 0;
|
||||||
|
|
||||||
void enable(bool enabled);
|
virtual bool open() = 0;
|
||||||
|
|
||||||
bool read(CDMRData& data);
|
virtual void enable(bool enabled) = 0;
|
||||||
|
|
||||||
bool write(const CDMRData& data);
|
virtual bool read(CDMRData& data) = 0;
|
||||||
|
|
||||||
bool writeRadioPosition(unsigned int id, const unsigned char* data);
|
virtual bool write(const CDMRData& data) = 0;
|
||||||
|
|
||||||
bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data);
|
virtual bool writeRadioPosition(unsigned int id, const unsigned char* data) = 0;
|
||||||
|
|
||||||
bool wantsBeacon();
|
virtual bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data) = 0;
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
virtual bool wantsBeacon() = 0;
|
||||||
|
|
||||||
void close();
|
virtual void clock(unsigned int ms) = 0;
|
||||||
|
|
||||||
|
virtual bool isConnected() const = 0;
|
||||||
|
|
||||||
|
virtual void close(bool sayGoodbye) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_addressStr;
|
|
||||||
sockaddr_storage m_addr;
|
|
||||||
unsigned int m_addrLen;
|
|
||||||
unsigned int m_port;
|
|
||||||
uint8_t* m_id;
|
|
||||||
bool m_duplex;
|
|
||||||
const char* m_version;
|
|
||||||
bool m_debug;
|
|
||||||
CUDPSocket m_socket;
|
|
||||||
bool m_enabled;
|
|
||||||
bool m_slot1;
|
|
||||||
bool m_slot2;
|
|
||||||
HW_TYPE m_hwType;
|
|
||||||
unsigned char* m_buffer;
|
|
||||||
uint32_t* m_streamId;
|
|
||||||
CRingBuffer<unsigned char> m_rxData;
|
|
||||||
bool m_beacon;
|
|
||||||
std::mt19937 m_random;
|
|
||||||
std::string m_callsign;
|
|
||||||
unsigned int m_rxFrequency;
|
|
||||||
unsigned int m_txFrequency;
|
|
||||||
unsigned int m_power;
|
|
||||||
unsigned int m_colorCode;
|
|
||||||
CTimer m_pingTimer;
|
|
||||||
|
|
||||||
bool writeConfig();
|
|
||||||
|
|
||||||
bool write(const unsigned char* data, unsigned int length);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
68
DMRSlot.cpp
68
DMRSlot.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2020 Jonathan Naylor, G4KLX
|
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -38,7 +38,7 @@ bool CDMRSlot::m_embeddedLCOnly = false;
|
||||||
bool CDMRSlot::m_dumpTAData = true;
|
bool CDMRSlot::m_dumpTAData = true;
|
||||||
|
|
||||||
CModem* CDMRSlot::m_modem = NULL;
|
CModem* CDMRSlot::m_modem = NULL;
|
||||||
CDMRNetwork* CDMRSlot::m_network = NULL;
|
IDMRNetwork* CDMRSlot::m_network = NULL;
|
||||||
CDisplay* CDMRSlot::m_display = NULL;
|
CDisplay* CDMRSlot::m_display = NULL;
|
||||||
bool CDMRSlot::m_duplex = true;
|
bool CDMRSlot::m_duplex = true;
|
||||||
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
||||||
|
@ -224,16 +224,22 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
delete lc;
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lc->setOVCM(m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
lc->setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_rfLC = lc;
|
m_rfLC = lc;
|
||||||
|
|
||||||
// The standby LC data
|
// The standby LC data
|
||||||
|
@ -378,11 +384,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +445,10 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// set the OVCM bit for the supported csbk
|
// set the OVCM bit for the supported csbk
|
||||||
csbk.setOVCM(m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
csbk.setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
csbk.setOVCM(false);
|
||||||
|
|
||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
|
@ -446,11 +457,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (srcId != 0U || dstId != 0U) {
|
if (srcId != 0U || dstId != 0U) {
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,6 +507,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
case CSBKO_CALL_ALERT_ACK:
|
case CSBKO_CALL_ALERT_ACK:
|
||||||
LogMessage("DMR Slot %u, received RF Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
|
case CSBKO_RADIO_CHECK:
|
||||||
|
LogMessage("DMR Slot %u, received RF Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LogWarning("DMR Slot %u, unhandled RF CSBK type - 0x%02X", m_slotNo, csbko);
|
LogWarning("DMR Slot %u, unhandled RF CSBK type - 0x%02X", m_slotNo, csbko);
|
||||||
break;
|
break;
|
||||||
|
@ -656,7 +672,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
||||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||||
m_rfTalkerAlias.reset();
|
m_rfTalkerAlias.reset();
|
||||||
m_rfTalkerAlias.add(0, data, 7U);
|
m_rfTalkerAlias.add(0, data + 2U, 7U);
|
||||||
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
||||||
|
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
|
@ -675,7 +691,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
||||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||||
m_rfTalkerAlias.reset();
|
m_rfTalkerAlias.reset();
|
||||||
m_rfTalkerAlias.add(1, data, 7U);
|
m_rfTalkerAlias.add(1, data + 2U, 7U);
|
||||||
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
||||||
|
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
|
@ -694,7 +710,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
||||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||||
m_rfTalkerAlias.reset();
|
m_rfTalkerAlias.reset();
|
||||||
m_rfTalkerAlias.add(2, data, 7U);
|
m_rfTalkerAlias.add(2, data + 2U, 7U);
|
||||||
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
||||||
|
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
|
@ -713,7 +729,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
||||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||||
m_rfTalkerAlias.reset();
|
m_rfTalkerAlias.reset();
|
||||||
m_rfTalkerAlias.add(3, data, 7U);
|
m_rfTalkerAlias.add(3, data + 2U, 7U);
|
||||||
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
m_display->writeDMRTA(m_slotNo, (unsigned char*)m_rfTalkerAlias.get(), "R");
|
||||||
|
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
|
@ -785,16 +801,22 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
if (!CDMRAccessControl::validateTGId(m_slotNo, flco == FLCO_GROUP, dstId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||||
delete lc;
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lc->setOVCM(m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_TX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
lc->setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_rfLC = lc;
|
m_rfLC = lc;
|
||||||
|
|
||||||
// The standby LC data
|
// The standby LC data
|
||||||
|
@ -1050,7 +1072,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),
|
dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),
|
||||||
srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
||||||
|
|
||||||
lc->setOVCM(m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
lc->setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
||||||
// The standby LC data
|
// The standby LC data
|
||||||
|
@ -1125,7 +1151,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
unsigned int srcId = lc->getSrcId();
|
unsigned int srcId = lc->getSrcId();
|
||||||
|
|
||||||
lc->setOVCM(m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
lc->setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
||||||
m_lastFrameValid = false;
|
m_lastFrameValid = false;
|
||||||
|
@ -1312,7 +1342,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
unsigned int srcId = lc->getSrcId();
|
unsigned int srcId = lc->getSrcId();
|
||||||
|
|
||||||
lc->setOVCM(m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
lc->setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
lc->setOVCM(false);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
||||||
// The standby LC data
|
// The standby LC data
|
||||||
|
@ -1584,7 +1618,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// set the OVCM bit for the supported csbk
|
// set the OVCM bit for the supported csbk
|
||||||
csbk.setOVCM(m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON);
|
if (m_ovcm == DMR_OVCM_RX_ON || m_ovcm == DMR_OVCM_ON)
|
||||||
|
csbk.setOVCM(true);
|
||||||
|
else if (m_ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
|
csbk.setOVCM(false);
|
||||||
|
|
||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
|
@ -1656,6 +1693,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
case CSBKO_CALL_ALERT_ACK:
|
case CSBKO_CALL_ALERT_ACK:
|
||||||
LogMessage("DMR Slot %u, received network Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network Call Alert Ack CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
|
case CSBKO_RADIO_CHECK:
|
||||||
|
LogMessage("DMR Slot %u, received network Radio Check %s CSBK from %s to %s%s", m_slotNo, /* TBD */ 1 ? "Req" : "Ack", src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LogWarning("DMR Slot %u, unhandled network CSBK type - 0x%02X", m_slotNo, csbko);
|
LogWarning("DMR Slot %u, unhandled network CSBK type - 0x%02X", m_slotNo, csbko);
|
||||||
break;
|
break;
|
||||||
|
@ -1896,7 +1936,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
|
||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm)
|
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm)
|
||||||
{
|
{
|
||||||
assert(modem != NULL);
|
assert(modem != NULL);
|
||||||
assert(display != NULL);
|
assert(display != NULL);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
void enable(bool enabled);
|
void enable(bool enabled);
|
||||||
|
|
||||||
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_slotNo;
|
unsigned int m_slotNo;
|
||||||
|
@ -118,7 +118,7 @@ private:
|
||||||
static bool m_dumpTAData;
|
static bool m_dumpTAData;
|
||||||
|
|
||||||
static CModem* m_modem;
|
static CModem* m_modem;
|
||||||
static CDMRNetwork* m_network;
|
static IDMRNetwork* m_network;
|
||||||
static CDisplay* m_display;
|
static CDisplay* m_display;
|
||||||
static bool m_duplex;
|
static bool m_duplex;
|
||||||
static CDMRLookup* m_lookup;
|
static CDMRLookup* m_lookup;
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
# DMRplus - Startup Options
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
This file is to give an overview over the Options-parameter in MMDVM.ini [DMR Network]-section.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
You can pull some conection-info at startup to the DMRplus-Network to define the behavior of TS1 and TS2 in DMR-mode.
|
|
||||||
An example of such a line would be following:
|
|
||||||
|
|
||||||
Options=StartRef=4013;RelinkTime=15;UserLink=1;TS1_1=262;TS1_2=1;TS1_3=20;TS1_4=110;TS1_5=270;
|
|
||||||
|
|
||||||
If an option is set, it overwrites the setting preset at the master, if an option is empty, it unsets a predefined setting from
|
|
||||||
the master. If an option is not set, the default from the master would be taken over.
|
|
||||||
|
|
||||||
## What the parameters are about?
|
|
||||||
|
|
||||||
Here is a quick explaination about the options to be set:
|
|
||||||
|
|
||||||
* StartRef: This is the default reflector in TS2, in example: Refl. 4013
|
|
||||||
* RelinkTime: This is the time to fall back to the default-reflector if linked to another one and no local traffic is done,
|
|
||||||
not yet implemented, would come next
|
|
||||||
* UserLink: This defines, if users are allowed to link to another reflector (other than defined as startreflector)
|
|
||||||
* 1 = allow
|
|
||||||
* 0 = disallow
|
|
||||||
* TS1_1: This is the first of 5 talkgroups that could be set static, in example: TG262
|
|
||||||
* TS1_2: This is the second of 5 talkgroups that could be set static, in example: TG1
|
|
||||||
* TS1_3: This is the third of 5 talkgroups that could be set static, in example: TG20
|
|
||||||
* TS1_4: This is the fourth of 5 talkgroups that could be set static, in example: TG110
|
|
||||||
* TS1_5: This is the fifth of 5 talkgroups that could be set static, in example: TG270
|
|
||||||
|
|
||||||
---
|
|
||||||
Info created by DG9VH 2016-11-11
|
|
1267
DStarControl.cpp
1267
DStarControl.cpp
File diff suppressed because it is too large
Load diff
129
DStarControl.h
129
DStarControl.h
|
@ -1,129 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015-2019 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(DStarControl_H)
|
|
||||||
#define DStarControl_H
|
|
||||||
|
|
||||||
#include "RSSIInterpolator.h"
|
|
||||||
#include "DStarNetwork.h"
|
|
||||||
#include "DStarSlowData.h"
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "DStarHeader.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "StopWatch.h"
|
|
||||||
#include "AMBEFEC.h"
|
|
||||||
#include "Display.h"
|
|
||||||
#include "Defines.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "Modem.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class CDStarControl {
|
|
||||||
public:
|
|
||||||
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
|
|
||||||
~CDStarControl();
|
|
||||||
|
|
||||||
bool writeModem(unsigned char* data, unsigned int len);
|
|
||||||
|
|
||||||
unsigned int readModem(unsigned char* data);
|
|
||||||
|
|
||||||
void clock();
|
|
||||||
|
|
||||||
bool isBusy() const;
|
|
||||||
|
|
||||||
void enable(bool enabled);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_callsign;
|
|
||||||
unsigned char* m_gateway;
|
|
||||||
bool m_selfOnly;
|
|
||||||
bool m_ackReply;
|
|
||||||
bool m_ackMessage;
|
|
||||||
bool m_errorReply;
|
|
||||||
bool m_remoteGateway;
|
|
||||||
std::vector<std::string> m_blackList;
|
|
||||||
std::vector<std::string> m_whiteList;
|
|
||||||
CDStarNetwork* m_network;
|
|
||||||
CDisplay* m_display;
|
|
||||||
bool m_duplex;
|
|
||||||
CRingBuffer<unsigned char> m_queue;
|
|
||||||
CDStarHeader m_rfHeader;
|
|
||||||
CDStarHeader m_netHeader;
|
|
||||||
RPT_RF_STATE m_rfState;
|
|
||||||
RPT_NET_STATE m_netState;
|
|
||||||
bool m_net;
|
|
||||||
CDStarSlowData m_slowData;
|
|
||||||
unsigned char m_rfN;
|
|
||||||
unsigned char m_netN;
|
|
||||||
CTimer m_networkWatchdog;
|
|
||||||
CTimer m_rfTimeoutTimer;
|
|
||||||
CTimer m_netTimeoutTimer;
|
|
||||||
CTimer m_packetTimer;
|
|
||||||
CTimer m_ackTimer;
|
|
||||||
CTimer m_errTimer;
|
|
||||||
CStopWatch m_interval;
|
|
||||||
CStopWatch m_elapsed;
|
|
||||||
unsigned int m_rfFrames;
|
|
||||||
unsigned int m_netFrames;
|
|
||||||
unsigned int m_netLost;
|
|
||||||
CAMBEFEC m_fec;
|
|
||||||
unsigned int m_rfBits;
|
|
||||||
unsigned int m_netBits;
|
|
||||||
unsigned int m_rfErrs;
|
|
||||||
unsigned int m_netErrs;
|
|
||||||
unsigned char* m_lastFrame;
|
|
||||||
bool m_lastFrameValid;
|
|
||||||
CRSSIInterpolator* m_rssiMapper;
|
|
||||||
unsigned char m_rssi;
|
|
||||||
unsigned char m_maxRSSI;
|
|
||||||
unsigned char m_minRSSI;
|
|
||||||
unsigned int m_aveRSSI;
|
|
||||||
unsigned int m_rssiCount;
|
|
||||||
bool m_enabled;
|
|
||||||
FILE* m_fp;
|
|
||||||
|
|
||||||
void writeNetwork();
|
|
||||||
|
|
||||||
void writeQueueHeaderRF(const unsigned char* data);
|
|
||||||
void writeQueueDataRF(const unsigned char* data);
|
|
||||||
void writeQueueEOTRF();
|
|
||||||
void writeQueueHeaderNet(const unsigned char* data);
|
|
||||||
void writeQueueDataNet(const unsigned char* data);
|
|
||||||
void writeQueueEOTNet();
|
|
||||||
void writeNetworkHeaderRF(const unsigned char* data);
|
|
||||||
void writeNetworkDataRF(const unsigned char* data, unsigned int errors, bool end);
|
|
||||||
|
|
||||||
void writeEndRF();
|
|
||||||
void writeEndNet();
|
|
||||||
|
|
||||||
bool openFile();
|
|
||||||
bool writeFile(const unsigned char* data, unsigned int length);
|
|
||||||
void closeFile();
|
|
||||||
|
|
||||||
bool insertSilence(const unsigned char* data, unsigned char seqNo);
|
|
||||||
void insertSilence(unsigned int count);
|
|
||||||
|
|
||||||
void blankDTMF(unsigned char* data) const;
|
|
||||||
|
|
||||||
void sendAck();
|
|
||||||
void sendError();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015,2016,2018,2019 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(DStarDefines_H)
|
|
||||||
#define DStarDefines_H
|
|
||||||
|
|
||||||
#include "Defines.h"
|
|
||||||
|
|
||||||
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
|
|
||||||
const unsigned int DSTAR_FRAME_LENGTH_BYTES = 12U;
|
|
||||||
|
|
||||||
const unsigned char DSTAR_END_PATTERN_BYTES[] = { TAG_EOT, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A };
|
|
||||||
const unsigned int DSTAR_END_PATTERN_LENGTH_BYTES = 6U;
|
|
||||||
|
|
||||||
const unsigned char DSTAR_NULL_AMBE_DATA_BYTES[] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 };
|
|
||||||
|
|
||||||
const unsigned char DSTAR_NULL_SLOW_SYNC_BYTES[] = { 0x55, 0x2D, 0x16 };
|
|
||||||
// Note that these are already scrambled, 0x66 0x66 0x66 otherwise
|
|
||||||
const unsigned char DSTAR_NULL_SLOW_DATA_BYTES[] = { 0x16, 0x29, 0xF5 };
|
|
||||||
|
|
||||||
const unsigned char DSTAR_NULL_FRAME_SYNC_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16 };
|
|
||||||
const unsigned char DSTAR_NULL_FRAME_DATA_BYTES[] = { TAG_DATA, 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xF5 };
|
|
||||||
|
|
||||||
const unsigned char DSTAR_NULL_FRAME_DATA_SRAMBLED_BYTES[] = { 0xEEU, 0xC2U, 0xA1U, 0xC8U, 0x42U, 0x6EU, 0x52U, 0x51U, 0xC3U };
|
|
||||||
|
|
||||||
const unsigned int DSTAR_VOICE_FRAME_LENGTH_BYTES = 9U;
|
|
||||||
const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U;
|
|
||||||
|
|
||||||
const unsigned int DSTAR_LONG_CALLSIGN_LENGTH = 8U;
|
|
||||||
const unsigned int DSTAR_SHORT_CALLSIGN_LENGTH = 4U;
|
|
||||||
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_FAST_DATA1 = 0x80U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_FAST_DATA2 = 0x90U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U;
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU;
|
|
||||||
|
|
||||||
const unsigned char DSTAR_SCRAMBLER_BYTES[] = { 0x70U, 0x4FU, 0x93U, 0x40U, 0x64U, 0x74U, 0x6DU, 0x30U, 0x2BU };
|
|
||||||
|
|
||||||
const unsigned char DSTAR_DATA_MASK = 0x80U;
|
|
||||||
const unsigned char DSTAR_REPEATER_MASK = 0x40U;
|
|
||||||
const unsigned char DSTAR_INTERRUPTED_MASK = 0x20U;
|
|
||||||
const unsigned char DSTAR_CONTROL_SIGNAL_MASK = 0x10U;
|
|
||||||
const unsigned char DSTAR_URGENT_MASK = 0x08U;
|
|
||||||
const unsigned char DSTAR_REPEATER_CONTROL = 0x07U;
|
|
||||||
const unsigned char DSTAR_AUTO_REPLY = 0x06U;
|
|
||||||
const unsigned char DSTAR_RESEND_REQUESTED = 0x04U;
|
|
||||||
const unsigned char DSTAR_ACK_FLAG = 0x03U;
|
|
||||||
const unsigned char DSTAR_NO_RESPONSE = 0x02U;
|
|
||||||
const unsigned char DSTAR_RELAY_UNAVAILABLE = 0x01U;
|
|
||||||
|
|
||||||
const unsigned char DSTAR_SYNC_BYTES[] = {0x55U, 0x2DU, 0x16U};
|
|
||||||
|
|
||||||
const unsigned char DSTAR_DTMF_MASK[] = { 0x82U, 0x08U, 0x20U, 0x82U, 0x00U, 0x00U, 0x82U, 0x00U, 0x00U };
|
|
||||||
const unsigned char DSTAR_DTMF_SIG[] = { 0x82U, 0x08U, 0x20U, 0x82U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U };
|
|
||||||
|
|
||||||
const unsigned int DSTAR_FRAME_TIME = 20U;
|
|
||||||
|
|
||||||
enum LINK_STATUS {
|
|
||||||
LS_NONE,
|
|
||||||
LS_PENDING_IRCDDB,
|
|
||||||
LS_LINKING_LOOPBACK,
|
|
||||||
LS_LINKING_DEXTRA,
|
|
||||||
LS_LINKING_DPLUS,
|
|
||||||
LS_LINKING_DCS,
|
|
||||||
LS_LINKING_CCS,
|
|
||||||
LS_LINKED_LOOPBACK,
|
|
||||||
LS_LINKED_DEXTRA,
|
|
||||||
LS_LINKED_DPLUS,
|
|
||||||
LS_LINKED_DCS,
|
|
||||||
LS_LINKED_CCS
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
165
DStarHeader.cpp
165
DStarHeader.cpp
|
@ -1,165 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "DStarHeader.h"
|
|
||||||
#include "CRC.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
CDStarHeader::CDStarHeader(const unsigned char* header) :
|
|
||||||
m_header(NULL)
|
|
||||||
{
|
|
||||||
assert(header != NULL);
|
|
||||||
|
|
||||||
m_header = new unsigned char[DSTAR_HEADER_LENGTH_BYTES];
|
|
||||||
|
|
||||||
::memcpy(m_header, header, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarHeader::CDStarHeader() :
|
|
||||||
m_header(NULL)
|
|
||||||
{
|
|
||||||
m_header = new unsigned char[DSTAR_HEADER_LENGTH_BYTES];
|
|
||||||
|
|
||||||
::memset(m_header, ' ', DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
m_header[0U] = 0x00U;
|
|
||||||
m_header[1U] = 0x00U;
|
|
||||||
m_header[2U] = 0x00U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarHeader::~CDStarHeader()
|
|
||||||
{
|
|
||||||
delete[] m_header;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarHeader& CDStarHeader::operator=(const CDStarHeader& header)
|
|
||||||
{
|
|
||||||
if (&header != this)
|
|
||||||
::memcpy(m_header, header.m_header, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarHeader::isRepeater() const
|
|
||||||
{
|
|
||||||
return (m_header[0U] & DSTAR_REPEATER_MASK) == DSTAR_REPEATER_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setRepeater(bool on)
|
|
||||||
{
|
|
||||||
if (on)
|
|
||||||
m_header[0U] |= DSTAR_REPEATER_MASK;
|
|
||||||
else
|
|
||||||
m_header[0U] &= ~DSTAR_REPEATER_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarHeader::isDataPacket() const
|
|
||||||
{
|
|
||||||
return (m_header[0U] & DSTAR_DATA_MASK) == DSTAR_DATA_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setUnavailable(bool on)
|
|
||||||
{
|
|
||||||
if (on)
|
|
||||||
m_header[0U] |= DSTAR_RELAY_UNAVAILABLE;
|
|
||||||
else
|
|
||||||
m_header[0U] &= ~DSTAR_RELAY_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::getMyCall1(unsigned char* call1) const
|
|
||||||
{
|
|
||||||
assert(call1 != NULL);
|
|
||||||
|
|
||||||
::memcpy(call1, m_header + 27U, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::getMyCall2(unsigned char* call2) const
|
|
||||||
{
|
|
||||||
assert(call2 != NULL);
|
|
||||||
|
|
||||||
::memcpy(call2, m_header + 35U, DSTAR_SHORT_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setMyCall1(const unsigned char* call1)
|
|
||||||
{
|
|
||||||
assert(call1 != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_header + 27U, call1, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setMyCall2(const unsigned char* call2)
|
|
||||||
{
|
|
||||||
assert(call2 != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_header + 35U, call2, DSTAR_SHORT_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::getRPTCall1(unsigned char* call1) const
|
|
||||||
{
|
|
||||||
assert(call1 != NULL);
|
|
||||||
|
|
||||||
::memcpy(call1, m_header + 11U, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::getRPTCall2(unsigned char* call2) const
|
|
||||||
{
|
|
||||||
assert(call2 != NULL);
|
|
||||||
|
|
||||||
::memcpy(call2, m_header + 3U, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setRPTCall1(const unsigned char* call1)
|
|
||||||
{
|
|
||||||
assert(call1 != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_header + 11U, call1, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setRPTCall2(const unsigned char* call2)
|
|
||||||
{
|
|
||||||
assert(call2 != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_header + 3U, call2, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::getYourCall(unsigned char* call) const
|
|
||||||
{
|
|
||||||
assert(call != NULL);
|
|
||||||
|
|
||||||
::memcpy(call, m_header + 19U, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::setYourCall(const unsigned char* call)
|
|
||||||
{
|
|
||||||
assert(call != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_header + 19U, call, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarHeader::get(unsigned char* header) const
|
|
||||||
{
|
|
||||||
assert(header != NULL);
|
|
||||||
|
|
||||||
::memcpy(header, m_header, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
CCRC::addCCITT161(header, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DStarHeader_H
|
|
||||||
#define DStarHeader_H
|
|
||||||
|
|
||||||
class CDStarHeader {
|
|
||||||
public:
|
|
||||||
CDStarHeader(const unsigned char* header);
|
|
||||||
CDStarHeader();
|
|
||||||
~CDStarHeader();
|
|
||||||
|
|
||||||
bool isRepeater() const;
|
|
||||||
void setRepeater(bool on);
|
|
||||||
|
|
||||||
bool isDataPacket() const;
|
|
||||||
|
|
||||||
void setUnavailable(bool on);
|
|
||||||
|
|
||||||
void getMyCall1(unsigned char* call1) const;
|
|
||||||
void getMyCall2(unsigned char* call2) const;
|
|
||||||
|
|
||||||
void setMyCall1(const unsigned char* call1);
|
|
||||||
void setMyCall2(const unsigned char* call2);
|
|
||||||
|
|
||||||
void getRPTCall1(unsigned char* call1) const;
|
|
||||||
void getRPTCall2(unsigned char* call2) const;
|
|
||||||
|
|
||||||
void setRPTCall1(const unsigned char* call1);
|
|
||||||
void setRPTCall2(const unsigned char* call2);
|
|
||||||
|
|
||||||
void getYourCall(unsigned char* call) const;
|
|
||||||
void setYourCall(const unsigned char* call);
|
|
||||||
|
|
||||||
void get(unsigned char* header) const;
|
|
||||||
|
|
||||||
CDStarHeader& operator=(const CDStarHeader& header);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_header;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
341
DStarNetwork.cpp
341
DStarNetwork.cpp
|
@ -1,341 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,2019,2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "DStarNetwork.h"
|
|
||||||
#include "StopWatch.h"
|
|
||||||
#include "Defines.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 100U;
|
|
||||||
|
|
||||||
CDStarNetwork::CDStarNetwork(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool duplex, const char* version, bool debug) :
|
|
||||||
m_socket(localPort),
|
|
||||||
m_addr(),
|
|
||||||
m_addrLen(0U),
|
|
||||||
m_duplex(duplex),
|
|
||||||
m_version(version),
|
|
||||||
m_debug(debug),
|
|
||||||
m_enabled(false),
|
|
||||||
m_outId(0U),
|
|
||||||
m_outSeq(0U),
|
|
||||||
m_inId(0U),
|
|
||||||
m_buffer(1000U, "D-Star Network"),
|
|
||||||
m_pollTimer(1000U, 60U),
|
|
||||||
m_linkStatus(LS_NONE),
|
|
||||||
m_linkReflector(NULL),
|
|
||||||
m_random()
|
|
||||||
{
|
|
||||||
if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0)
|
|
||||||
m_addrLen = 0U;
|
|
||||||
|
|
||||||
m_linkReflector = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH];
|
|
||||||
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 mt(rd());
|
|
||||||
m_random = mt;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarNetwork::~CDStarNetwork()
|
|
||||||
{
|
|
||||||
delete[] m_linkReflector;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarNetwork::open()
|
|
||||||
{
|
|
||||||
if (m_addrLen == 0U) {
|
|
||||||
LogError("Unable to resolve the address of the ircDDB Gateway");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("Opening D-Star network connection");
|
|
||||||
|
|
||||||
m_pollTimer.start();
|
|
||||||
|
|
||||||
return m_socket.open(m_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarNetwork::writeHeader(const unsigned char* header, unsigned int length, bool busy)
|
|
||||||
{
|
|
||||||
assert(header != NULL);
|
|
||||||
|
|
||||||
unsigned char buffer[50U];
|
|
||||||
|
|
||||||
buffer[0] = 'D';
|
|
||||||
buffer[1] = 'S';
|
|
||||||
buffer[2] = 'R';
|
|
||||||
buffer[3] = 'P';
|
|
||||||
|
|
||||||
buffer[4] = busy ? 0x22U : 0x20U;
|
|
||||||
|
|
||||||
// Create a random id for this transmission
|
|
||||||
std::uniform_int_distribution<uint16_t> dist(0x0001, 0xfffe);
|
|
||||||
m_outId = dist(m_random);
|
|
||||||
|
|
||||||
buffer[5] = m_outId / 256U; // Unique session id
|
|
||||||
buffer[6] = m_outId % 256U;
|
|
||||||
|
|
||||||
buffer[7] = 0U;
|
|
||||||
|
|
||||||
::memcpy(buffer + 8U, header, length);
|
|
||||||
|
|
||||||
m_outSeq = 0U;
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "D-Star Network Header Sent", buffer, 49U);
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 2U; i++) {
|
|
||||||
bool ret = m_socket.write(buffer, 49U, m_addr, m_addrLen);
|
|
||||||
if (!ret)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarNetwork::writeData(const unsigned char* data, unsigned int length, unsigned int errors, bool end, bool busy)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char buffer[30U];
|
|
||||||
|
|
||||||
buffer[0] = 'D';
|
|
||||||
buffer[1] = 'S';
|
|
||||||
buffer[2] = 'R';
|
|
||||||
buffer[3] = 'P';
|
|
||||||
|
|
||||||
buffer[4] = busy ? 0x23U : 0x21U;
|
|
||||||
|
|
||||||
buffer[5] = m_outId / 256U; // Unique session id
|
|
||||||
buffer[6] = m_outId % 256U;
|
|
||||||
|
|
||||||
// If this is a data sync, reset the sequence to zero
|
|
||||||
if (data[9] == 0x55 && data[10] == 0x2D && data[11] == 0x16)
|
|
||||||
m_outSeq = 0U;
|
|
||||||
|
|
||||||
buffer[7] = m_outSeq;
|
|
||||||
if (end)
|
|
||||||
buffer[7] |= 0x40U; // End of data marker
|
|
||||||
|
|
||||||
buffer[8] = errors;
|
|
||||||
|
|
||||||
m_outSeq++;
|
|
||||||
if (m_outSeq > 0x14U)
|
|
||||||
m_outSeq = 0U;
|
|
||||||
|
|
||||||
::memcpy(buffer + 9U, data, length);
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "D-Star Network Data Sent", buffer, length + 9U);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, length + 9U, m_addr, m_addrLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarNetwork::writePoll(const char* text)
|
|
||||||
{
|
|
||||||
assert(text != NULL);
|
|
||||||
|
|
||||||
unsigned char buffer[40U];
|
|
||||||
|
|
||||||
buffer[0] = 'D';
|
|
||||||
buffer[1] = 'S';
|
|
||||||
buffer[2] = 'R';
|
|
||||||
buffer[3] = 'P';
|
|
||||||
|
|
||||||
buffer[4] = 0x0A; // Poll with text
|
|
||||||
|
|
||||||
unsigned int length = ::strlen(text);
|
|
||||||
|
|
||||||
// Include the nul at the end also
|
|
||||||
::memcpy(buffer + 5U, text, length + 1U);
|
|
||||||
|
|
||||||
// if (m_debug)
|
|
||||||
// CUtils::dump(1U, "D-Star Network Poll Sent", buffer, 6U + length);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, 6U + length, m_addr, m_addrLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarNetwork::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
m_pollTimer.clock(ms);
|
|
||||||
if (m_pollTimer.hasExpired()) {
|
|
||||||
char text[60U];
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
if (m_duplex)
|
|
||||||
::sprintf(text, "win_mmdvm-%s", m_version);
|
|
||||||
else
|
|
||||||
::sprintf(text, "win_mmdvm-dvmega-%s", m_version);
|
|
||||||
#else
|
|
||||||
if (m_duplex)
|
|
||||||
::sprintf(text, "linux_mmdvm-%s", m_version);
|
|
||||||
else
|
|
||||||
::sprintf(text, "linux_mmdvm-dvmega-%s", m_version);
|
|
||||||
#endif
|
|
||||||
writePoll(text);
|
|
||||||
m_pollTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char buffer[BUFFER_LENGTH];
|
|
||||||
|
|
||||||
sockaddr_storage address;
|
|
||||||
unsigned int addrLen;
|
|
||||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen);
|
|
||||||
if (length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!CUDPSocket::match(m_addr, address)) {
|
|
||||||
LogMessage("D-Star, packet received from an invalid source");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid packet type?
|
|
||||||
if (::memcmp(buffer, "DSRP", 4U) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (buffer[4]) {
|
|
||||||
case 0x00U: // NETWORK_TEXT;
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "D-Star Network Status Received", buffer, length);
|
|
||||||
|
|
||||||
m_linkStatus = LINK_STATUS(buffer[25U]);
|
|
||||||
::memcpy(m_linkReflector, buffer + 26U, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
LogMessage("D-Star link status set to \"%20.20s\"", buffer + 5U);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x01U: // NETWORK_TEMPTEXT;
|
|
||||||
case 0x04U: // NETWORK_STATUS1..5
|
|
||||||
case 0x24U: // NETWORK_DD_DATA
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x20U: // NETWORK_HEADER
|
|
||||||
if (m_inId == 0U && m_enabled) {
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "D-Star Network Header Received", buffer, length);
|
|
||||||
|
|
||||||
m_inId = buffer[5] * 256U + buffer[6];
|
|
||||||
|
|
||||||
unsigned char c = length - 7U;
|
|
||||||
m_buffer.addData(&c, 1U);
|
|
||||||
|
|
||||||
c = TAG_HEADER;
|
|
||||||
m_buffer.addData(&c, 1U);
|
|
||||||
|
|
||||||
m_buffer.addData(buffer + 8U, length - 8U);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x21U: // NETWORK_DATA
|
|
||||||
if (m_enabled) {
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "D-Star Network Data Received", buffer, length);
|
|
||||||
|
|
||||||
uint16_t id = buffer[5] * 256U + buffer[6];
|
|
||||||
|
|
||||||
// Check that the stream id matches the valid header, reject otherwise
|
|
||||||
if (id == m_inId && m_enabled) {
|
|
||||||
unsigned char ctrl[3U];
|
|
||||||
|
|
||||||
ctrl[0U] = length - 7U;
|
|
||||||
|
|
||||||
// Is this the last packet in the stream?
|
|
||||||
if ((buffer[7] & 0x40) == 0x40) {
|
|
||||||
m_inId = 0U;
|
|
||||||
ctrl[1U] = TAG_EOT;
|
|
||||||
} else {
|
|
||||||
ctrl[1U] = TAG_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl[2U] = buffer[7] & 0x3FU;
|
|
||||||
|
|
||||||
m_buffer.addData(ctrl, 3U);
|
|
||||||
|
|
||||||
m_buffer.addData(buffer + 9U, length - 9U);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
CUtils::dump("Unknown D-Star packet from the Gateway", buffer, length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CDStarNetwork::read(unsigned char* data, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
if (m_buffer.isEmpty())
|
|
||||||
return 0U;
|
|
||||||
|
|
||||||
unsigned char c = 0U;
|
|
||||||
m_buffer.getData(&c, 1U);
|
|
||||||
|
|
||||||
assert(c <= 100U);
|
|
||||||
assert(c <= length);
|
|
||||||
|
|
||||||
unsigned char buffer[100U];
|
|
||||||
m_buffer.getData(buffer, c);
|
|
||||||
|
|
||||||
switch (buffer[0U]) {
|
|
||||||
case TAG_HEADER:
|
|
||||||
case TAG_DATA:
|
|
||||||
case TAG_EOT:
|
|
||||||
::memcpy(data, buffer, c);
|
|
||||||
return c;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarNetwork::reset()
|
|
||||||
{
|
|
||||||
m_inId = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarNetwork::close()
|
|
||||||
{
|
|
||||||
m_socket.close();
|
|
||||||
|
|
||||||
LogMessage("Closing D-Star network connection");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarNetwork::enable(bool enabled)
|
|
||||||
{
|
|
||||||
if (enabled && !m_enabled)
|
|
||||||
reset();
|
|
||||||
else if (!enabled && m_enabled)
|
|
||||||
m_buffer.clear();
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarNetwork::getStatus(LINK_STATUS& status, unsigned char* reflector)
|
|
||||||
{
|
|
||||||
assert(reflector != NULL);
|
|
||||||
|
|
||||||
status = m_linkStatus;
|
|
||||||
|
|
||||||
::memcpy(reflector, m_linkReflector, DSTAR_LONG_CALLSIGN_LENGTH);
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DStarNetwork_H
|
|
||||||
#define DStarNetwork_H
|
|
||||||
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
class CDStarNetwork {
|
|
||||||
public:
|
|
||||||
CDStarNetwork(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool duplex, const char* version, bool debug);
|
|
||||||
~CDStarNetwork();
|
|
||||||
|
|
||||||
bool open();
|
|
||||||
|
|
||||||
void enable(bool enabled);
|
|
||||||
|
|
||||||
bool writeHeader(const unsigned char* header, unsigned int length, bool busy);
|
|
||||||
bool writeData(const unsigned char* data, unsigned int length, unsigned int errors, bool end, bool busy);
|
|
||||||
|
|
||||||
void getStatus(LINK_STATUS& status, unsigned char* reflector);
|
|
||||||
|
|
||||||
unsigned int read(unsigned char* data, unsigned int length);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void close();
|
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CUDPSocket m_socket;
|
|
||||||
sockaddr_storage m_addr;
|
|
||||||
unsigned int m_addrLen;
|
|
||||||
bool m_duplex;
|
|
||||||
const char* m_version;
|
|
||||||
bool m_debug;
|
|
||||||
bool m_enabled;
|
|
||||||
uint16_t m_outId;
|
|
||||||
uint8_t m_outSeq;
|
|
||||||
uint16_t m_inId;
|
|
||||||
CRingBuffer<unsigned char> m_buffer;
|
|
||||||
CTimer m_pollTimer;
|
|
||||||
LINK_STATUS m_linkStatus;
|
|
||||||
unsigned char* m_linkReflector;
|
|
||||||
std::mt19937 m_random;
|
|
||||||
|
|
||||||
bool writePoll(const char* text);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,158 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "DStarSlowData.h"
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "CRC.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
CDStarSlowData::CDStarSlowData() :
|
|
||||||
m_header(NULL),
|
|
||||||
m_ptr(0U),
|
|
||||||
m_buffer(NULL),
|
|
||||||
m_text(NULL),
|
|
||||||
m_textPtr(0U),
|
|
||||||
m_state(SDD_FIRST)
|
|
||||||
{
|
|
||||||
m_header = new unsigned char[50U]; // DSTAR_HEADER_LENGTH_BYTES
|
|
||||||
m_buffer = new unsigned char[DSTAR_DATA_FRAME_LENGTH_BYTES * 2U];
|
|
||||||
m_text = new unsigned char[24U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarSlowData::~CDStarSlowData()
|
|
||||||
{
|
|
||||||
delete[] m_header;
|
|
||||||
delete[] m_buffer;
|
|
||||||
delete[] m_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarHeader* CDStarSlowData::add(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
switch (m_state) {
|
|
||||||
case SDD_FIRST:
|
|
||||||
m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
|
||||||
m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
|
||||||
m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
|
||||||
m_state = SDD_SECOND;
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
case SDD_SECOND:
|
|
||||||
m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
|
||||||
m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
|
||||||
m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
|
||||||
m_state = SDD_FIRST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_buffer[0U] & DSTAR_SLOW_DATA_TYPE_MASK) != DSTAR_SLOW_DATA_TYPE_HEADER)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (m_ptr >= 45U)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
::memcpy(m_header + m_ptr, m_buffer + 1U, 5U);
|
|
||||||
m_ptr += 5U;
|
|
||||||
|
|
||||||
// Clean up the data
|
|
||||||
m_header[0U] &= (DSTAR_INTERRUPTED_MASK | DSTAR_URGENT_MASK | DSTAR_REPEATER_MASK);
|
|
||||||
m_header[1U] = 0x00U;
|
|
||||||
m_header[2U] = 0x00U;
|
|
||||||
|
|
||||||
for (unsigned int i = 3U; i < 39U; i++)
|
|
||||||
m_header[i] &= 0x7FU;
|
|
||||||
|
|
||||||
// Check the CRC
|
|
||||||
bool ret = CCRC::checkCCITT161(m_header, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
if (!ret) {
|
|
||||||
if (m_ptr == 45U)
|
|
||||||
LogMessage("D-Star, invalid slow data header");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CDStarHeader(m_header);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarSlowData::start()
|
|
||||||
{
|
|
||||||
::memset(m_header, 0x00U, DSTAR_HEADER_LENGTH_BYTES);
|
|
||||||
|
|
||||||
m_ptr = 0U;
|
|
||||||
m_state = SDD_FIRST;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarSlowData::reset()
|
|
||||||
{
|
|
||||||
m_ptr = 0U;
|
|
||||||
m_state = SDD_FIRST;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarSlowData::setText(const char* text)
|
|
||||||
{
|
|
||||||
assert(text != NULL);
|
|
||||||
|
|
||||||
m_text[0U] = DSTAR_SLOW_DATA_TYPE_TEXT | 0U;
|
|
||||||
m_text[1U] = text[0U];
|
|
||||||
m_text[2U] = text[1U];
|
|
||||||
m_text[3U] = text[2U];
|
|
||||||
m_text[4U] = text[3U];
|
|
||||||
m_text[5U] = text[4U];
|
|
||||||
|
|
||||||
m_text[6U] = DSTAR_SLOW_DATA_TYPE_TEXT | 1U;
|
|
||||||
m_text[7U] = text[5U];
|
|
||||||
m_text[8U] = text[6U];
|
|
||||||
m_text[9U] = text[7U];
|
|
||||||
m_text[10U] = text[8U];
|
|
||||||
m_text[11U] = text[9U];
|
|
||||||
|
|
||||||
m_text[12U] = DSTAR_SLOW_DATA_TYPE_TEXT | 2U;
|
|
||||||
m_text[13U] = text[10U];
|
|
||||||
m_text[14U] = text[11U];
|
|
||||||
m_text[15U] = text[12U];
|
|
||||||
m_text[16U] = text[13U];
|
|
||||||
m_text[17U] = text[14U];
|
|
||||||
|
|
||||||
m_text[18U] = DSTAR_SLOW_DATA_TYPE_TEXT | 3U;
|
|
||||||
m_text[19U] = text[15U];
|
|
||||||
m_text[20U] = text[16U];
|
|
||||||
m_text[21U] = text[17U];
|
|
||||||
m_text[22U] = text[18U];
|
|
||||||
m_text[23U] = text[19U];
|
|
||||||
|
|
||||||
m_textPtr = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarSlowData::get(unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
if (m_textPtr < 24U) {
|
|
||||||
data[0U] = m_text[m_textPtr++] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
|
||||||
data[1U] = m_text[m_textPtr++] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
|
||||||
data[2U] = m_text[m_textPtr++] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
|
||||||
} else {
|
|
||||||
data[0U] = 'f' ^ DSTAR_SCRAMBLER_BYTES[0U];
|
|
||||||
data[1U] = 'f' ^ DSTAR_SCRAMBLER_BYTES[1U];
|
|
||||||
data[2U] = 'f' ^ DSTAR_SCRAMBLER_BYTES[2U];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DStarSlowData_H
|
|
||||||
#define DStarSlowData_H
|
|
||||||
|
|
||||||
#include "DStarHeader.h"
|
|
||||||
|
|
||||||
class CDStarSlowData {
|
|
||||||
public:
|
|
||||||
CDStarSlowData();
|
|
||||||
~CDStarSlowData();
|
|
||||||
|
|
||||||
CDStarHeader* add(const unsigned char* data);
|
|
||||||
|
|
||||||
void start();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void setText(const char* text);
|
|
||||||
void get(unsigned char* data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_header;
|
|
||||||
unsigned int m_ptr;
|
|
||||||
unsigned char* m_buffer;
|
|
||||||
unsigned char* m_text;
|
|
||||||
unsigned int m_textPtr;
|
|
||||||
|
|
||||||
enum SDD_STATE {
|
|
||||||
SDD_FIRST,
|
|
||||||
SDD_SECOND
|
|
||||||
};
|
|
||||||
|
|
||||||
SDD_STATE m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
16
Defines.h
16
Defines.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,14 +20,7 @@
|
||||||
#define Defines_H
|
#define Defines_H
|
||||||
|
|
||||||
const unsigned char MODE_IDLE = 0U;
|
const unsigned char MODE_IDLE = 0U;
|
||||||
const unsigned char MODE_DSTAR = 1U;
|
|
||||||
const unsigned char MODE_DMR = 2U;
|
const unsigned char MODE_DMR = 2U;
|
||||||
const unsigned char MODE_YSF = 3U;
|
|
||||||
const unsigned char MODE_P25 = 4U;
|
|
||||||
const unsigned char MODE_NXDN = 5U;
|
|
||||||
const unsigned char MODE_POCSAG = 6U;
|
|
||||||
|
|
||||||
const unsigned char MODE_FM = 10U;
|
|
||||||
|
|
||||||
const unsigned char MODE_CW = 98U;
|
const unsigned char MODE_CW = 98U;
|
||||||
const unsigned char MODE_LOCKOUT = 99U;
|
const unsigned char MODE_LOCKOUT = 99U;
|
||||||
|
@ -39,6 +32,8 @@ const unsigned char TAG_DATA = 0x01U;
|
||||||
const unsigned char TAG_LOST = 0x02U;
|
const unsigned char TAG_LOST = 0x02U;
|
||||||
const unsigned char TAG_EOT = 0x03U;
|
const unsigned char TAG_EOT = 0x03U;
|
||||||
|
|
||||||
|
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
||||||
|
|
||||||
enum HW_TYPE {
|
enum HW_TYPE {
|
||||||
HWT_MMDVM,
|
HWT_MMDVM,
|
||||||
HWT_DVMEGA,
|
HWT_DVMEGA,
|
||||||
|
@ -58,6 +53,7 @@ enum RPT_RF_STATE {
|
||||||
RS_RF_LISTENING,
|
RS_RF_LISTENING,
|
||||||
RS_RF_LATE_ENTRY,
|
RS_RF_LATE_ENTRY,
|
||||||
RS_RF_AUDIO,
|
RS_RF_AUDIO,
|
||||||
|
RS_RF_DATA_AUDIO,
|
||||||
RS_RF_DATA,
|
RS_RF_DATA,
|
||||||
RS_RF_REJECTED,
|
RS_RF_REJECTED,
|
||||||
RS_RF_INVALID
|
RS_RF_INVALID
|
||||||
|
@ -66,6 +62,7 @@ enum RPT_RF_STATE {
|
||||||
enum RPT_NET_STATE {
|
enum RPT_NET_STATE {
|
||||||
RS_NET_IDLE,
|
RS_NET_IDLE,
|
||||||
RS_NET_AUDIO,
|
RS_NET_AUDIO,
|
||||||
|
RS_NET_DATA_AUDIO,
|
||||||
RS_NET_DATA
|
RS_NET_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +76,8 @@ enum DMR_OVCM_TYPES {
|
||||||
DMR_OVCM_OFF,
|
DMR_OVCM_OFF,
|
||||||
DMR_OVCM_RX_ON,
|
DMR_OVCM_RX_ON,
|
||||||
DMR_OVCM_TX_ON,
|
DMR_OVCM_TX_ON,
|
||||||
DMR_OVCM_ON
|
DMR_OVCM_ON,
|
||||||
|
DMR_OVCM_FORCE_OFF
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
285
Display.cpp
285
Display.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,17 +18,15 @@
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
#include "SerialController.h"
|
#include "UARTController.h"
|
||||||
#include "ModemSerialPort.h"
|
#include "ModemSerialPort.h"
|
||||||
#include "NullDisplay.h"
|
#include "NullDisplay.h"
|
||||||
#include "TFTSerial.h"
|
|
||||||
#include "TFTSurenoo.h"
|
#include "TFTSurenoo.h"
|
||||||
#include "LCDproc.h"
|
#include "LCDproc.h"
|
||||||
#include "Nextion.h"
|
#include "Nextion.h"
|
||||||
#include "CASTInfo.h"
|
#include "CASTInfo.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
#include "Modem.h"
|
#include "Modem.h"
|
||||||
#include "UMP.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#if defined(HD44780)
|
#if defined(HD44780)
|
||||||
|
@ -101,53 +99,6 @@ void CDisplay::setQuit()
|
||||||
setQuitInt();
|
setQuitInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::setFM()
|
|
||||||
{
|
|
||||||
m_timer1.stop();
|
|
||||||
m_timer2.stop();
|
|
||||||
|
|
||||||
m_mode1 = MODE_FM;
|
|
||||||
m_mode2 = MODE_FM;
|
|
||||||
|
|
||||||
setFMInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
|
||||||
{
|
|
||||||
assert(my1 != NULL);
|
|
||||||
assert(my2 != NULL);
|
|
||||||
assert(your != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
assert(reflector != NULL);
|
|
||||||
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
|
|
||||||
writeDStarInt(my1, my2, your, type, reflector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDStarRSSI(unsigned char rssi)
|
|
||||||
{
|
|
||||||
if (rssi != 0U)
|
|
||||||
writeDStarRSSIInt(rssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDStarBER(float ber)
|
|
||||||
{
|
|
||||||
writeDStarBERInt(ber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::clearDStar()
|
|
||||||
{
|
|
||||||
if (m_timer1.hasExpired()) {
|
|
||||||
clearDStarInt();
|
|
||||||
m_timer1.stop();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
} else {
|
|
||||||
m_mode1 = MODE_DSTAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
{
|
||||||
assert(type != NULL);
|
assert(type != NULL);
|
||||||
|
@ -223,137 +174,6 @@ void CDisplay::clearDMR(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeFusion(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(dest != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
assert(origin != NULL);
|
|
||||||
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
|
|
||||||
writeFusionInt(source, dest, dgid, type, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeFusionRSSI(unsigned char rssi)
|
|
||||||
{
|
|
||||||
if (rssi != 0U)
|
|
||||||
writeFusionRSSIInt(rssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeFusionBER(float ber)
|
|
||||||
{
|
|
||||||
writeFusionBERInt(ber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::clearFusion()
|
|
||||||
{
|
|
||||||
if (m_timer1.hasExpired()) {
|
|
||||||
clearFusionInt();
|
|
||||||
m_timer1.stop();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
} else {
|
|
||||||
m_mode1 = MODE_YSF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeP25(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
|
|
||||||
writeP25Int(source, group, dest, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeP25RSSI(unsigned char rssi)
|
|
||||||
{
|
|
||||||
if (rssi != 0U)
|
|
||||||
writeP25RSSIInt(rssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeP25BER(float ber)
|
|
||||||
{
|
|
||||||
writeP25BERInt(ber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::clearP25()
|
|
||||||
{
|
|
||||||
if (m_timer1.hasExpired()) {
|
|
||||||
clearP25Int();
|
|
||||||
m_timer1.stop();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
} else {
|
|
||||||
m_mode1 = MODE_P25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDN(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
|
|
||||||
writeNXDNInt(source, group, dest, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDN(const class CUserDBentry& source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
assert(type != NULL);
|
|
||||||
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
|
|
||||||
if (writeNXDNIntEx(source, group, dest, type))
|
|
||||||
writeNXDNInt(source.get(keyCALLSIGN).c_str(), group, dest, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDNRSSI(unsigned char rssi)
|
|
||||||
{
|
|
||||||
if (rssi != 0U)
|
|
||||||
writeNXDNRSSIInt(rssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDNBER(float ber)
|
|
||||||
{
|
|
||||||
writeNXDNBERInt(ber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::clearNXDN()
|
|
||||||
{
|
|
||||||
if (m_timer1.hasExpired()) {
|
|
||||||
clearNXDNInt();
|
|
||||||
m_timer1.stop();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
} else {
|
|
||||||
m_mode1 = MODE_NXDN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writePOCSAG(uint32_t ric, const std::string& message)
|
|
||||||
{
|
|
||||||
m_timer1.start();
|
|
||||||
m_mode1 = MODE_POCSAG;
|
|
||||||
|
|
||||||
writePOCSAGInt(ric, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::clearPOCSAG()
|
|
||||||
{
|
|
||||||
if (m_timer1.hasExpired()) {
|
|
||||||
clearPOCSAGInt();
|
|
||||||
m_timer1.stop();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
} else {
|
|
||||||
m_mode1 = MODE_POCSAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeCW()
|
void CDisplay::writeCW()
|
||||||
{
|
{
|
||||||
m_timer1.start();
|
m_timer1.start();
|
||||||
|
@ -367,36 +187,11 @@ void CDisplay::clock(unsigned int ms)
|
||||||
m_timer1.clock(ms);
|
m_timer1.clock(ms);
|
||||||
if (m_timer1.isRunning() && m_timer1.hasExpired()) {
|
if (m_timer1.isRunning() && m_timer1.hasExpired()) {
|
||||||
switch (m_mode1) {
|
switch (m_mode1) {
|
||||||
case MODE_DSTAR:
|
|
||||||
clearDStarInt();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
m_timer1.stop();
|
|
||||||
break;
|
|
||||||
case MODE_DMR:
|
case MODE_DMR:
|
||||||
clearDMRInt(1U);
|
clearDMRInt(1U);
|
||||||
m_mode1 = MODE_IDLE;
|
m_mode1 = MODE_IDLE;
|
||||||
m_timer1.stop();
|
m_timer1.stop();
|
||||||
break;
|
break;
|
||||||
case MODE_YSF:
|
|
||||||
clearFusionInt();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
m_timer1.stop();
|
|
||||||
break;
|
|
||||||
case MODE_P25:
|
|
||||||
clearP25Int();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
m_timer1.stop();
|
|
||||||
break;
|
|
||||||
case MODE_NXDN:
|
|
||||||
clearNXDNInt();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
m_timer1.stop();
|
|
||||||
break;
|
|
||||||
case MODE_POCSAG:
|
|
||||||
clearPOCSAGInt();
|
|
||||||
m_mode1 = MODE_IDLE;
|
|
||||||
m_timer1.stop();
|
|
||||||
break;
|
|
||||||
case MODE_CW:
|
case MODE_CW:
|
||||||
clearCWInt();
|
clearCWInt();
|
||||||
m_mode1 = MODE_IDLE;
|
m_mode1 = MODE_IDLE;
|
||||||
|
@ -424,14 +219,6 @@ void CDisplay::clockInt(unsigned int ms)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeDStarRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDStarBERInt(float ber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -458,49 +245,19 @@ void CDisplay::writeDMRBERInt(unsigned int slotNo, float ber)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeFusionRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeFusionBERInt(float ber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeP25RSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeP25BERInt(float ber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDNRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeNXDNBERInt(float ber)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int CDisplay::writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
/* return value definition is same as writeDMRIntEx() */
|
|
||||||
return -1; // not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Factory method extracted from MMDVMHost.cpp - BG5HHP */
|
/* Factory method extracted from MMDVMHost.cpp - BG5HHP */
|
||||||
CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
CDisplay* CDisplay::createDisplay(const CConf& conf, CModem* modem)
|
||||||
{
|
{
|
||||||
CDisplay *display = NULL;
|
CDisplay *display = NULL;
|
||||||
|
|
||||||
std::string type = conf.getDisplay();
|
std::string type = conf.getDisplay();
|
||||||
unsigned int dmrid = conf.getDMRId();
|
unsigned int dmrid = conf.getDMRId();
|
||||||
|
|
||||||
LogInfo("Display Parameters");
|
LogInfo("Display Parameters");
|
||||||
LogInfo(" Type: %s", type.c_str());
|
LogInfo(" Type: %s", type.c_str());
|
||||||
|
|
||||||
if (type == "TFT Serial" || type == "TFT Surenoo") {
|
if (type == "TFT Surenoo") {
|
||||||
std::string port = conf.getTFTSerialPort();
|
std::string port = conf.getTFTSerialPort();
|
||||||
unsigned int brightness = conf.getTFTSerialBrightness();
|
unsigned int brightness = conf.getTFTSerialBrightness();
|
||||||
|
|
||||||
|
@ -509,14 +266,11 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
||||||
|
|
||||||
ISerialPort* serial = NULL;
|
ISerialPort* serial = NULL;
|
||||||
if (port == "modem")
|
if (port == "modem")
|
||||||
serial = new CModemSerialPort(modem);
|
serial = new IModemSerialPort(modem);
|
||||||
else
|
else
|
||||||
serial = new CSerialController(port, (type == "TFT Serial") ? SERIAL_9600 : SERIAL_115200);
|
serial = new CUARTController(port, 115200U);
|
||||||
|
|
||||||
if (type == "TFT Surenoo")
|
display = new CTFTSurenoo(conf.getCallsign(), dmrid, serial, brightness, conf.getDuplex());
|
||||||
display = new CTFTSurenoo(conf.getCallsign(), dmrid, serial, brightness, conf.getDuplex());
|
|
||||||
else
|
|
||||||
display = new CTFTSerial(conf.getCallsign(), dmrid, serial, brightness);
|
|
||||||
} else if (type == "Nextion") {
|
} else if (type == "Nextion") {
|
||||||
std::string port = conf.getNextionPort();
|
std::string port = conf.getNextionPort();
|
||||||
unsigned int brightness = conf.getNextionBrightness();
|
unsigned int brightness = conf.getNextionBrightness();
|
||||||
|
@ -555,22 +309,15 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port == "modem") {
|
if (port == "modem") {
|
||||||
ISerialPort* serial = new CModemSerialPort(modem);
|
ISerialPort* serial = new IModemSerialPort(modem);
|
||||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
||||||
} else if (port == "ump") {
|
|
||||||
if (ump != NULL) {
|
|
||||||
display = new CNextion(conf.getCallsign(), dmrid, ump, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
|
||||||
} else {
|
|
||||||
LogInfo(" NullDisplay loaded");
|
|
||||||
display = new CNullDisplay;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SERIAL_SPEED baudrate = SERIAL_9600;
|
unsigned int baudrate = 9600U;
|
||||||
if (screenLayout&0x0cU)
|
if (screenLayout == 4U)
|
||||||
baudrate = SERIAL_115200;
|
baudrate = 115200U;
|
||||||
|
|
||||||
LogInfo(" Display baudrate: %u ",baudrate);
|
LogInfo(" Display baudrate: %u ", baudrate);
|
||||||
ISerialPort* serial = new CSerialController(port, baudrate);
|
ISerialPort* serial = new CUARTController(port, baudrate);
|
||||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
||||||
}
|
}
|
||||||
} else if (type == "LCDproc") {
|
} else if (type == "LCDproc") {
|
||||||
|
@ -642,7 +389,7 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
||||||
bool rotate = conf.getOLEDRotate();
|
bool rotate = conf.getOLEDRotate();
|
||||||
bool logosaver = conf.getOLEDLogoScreensaver();
|
bool logosaver = conf.getOLEDLogoScreensaver();
|
||||||
|
|
||||||
display = new COLED(type, brightness, invert, scroll, rotate, logosaver, conf.getDMRNetworkSlot1(), conf.getDMRNetworkSlot2());
|
display = new COLED(type, brightness, invert, scroll, rotate, logosaver, conf.getDuplex());
|
||||||
#endif
|
#endif
|
||||||
} else if (type == "CAST") {
|
} else if (type == "CAST") {
|
||||||
display = new CCASTInfo(modem);
|
display = new CCASTInfo(modem);
|
||||||
|
|
55
Display.h
55
Display.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "UserDBentry.h"
|
#include "UserDBentry.h"
|
||||||
|
#include "Modem.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -28,7 +29,6 @@
|
||||||
|
|
||||||
class CConf;
|
class CConf;
|
||||||
class CModem;
|
class CModem;
|
||||||
class CUMP;
|
|
||||||
|
|
||||||
class CDisplay
|
class CDisplay
|
||||||
{
|
{
|
||||||
|
@ -44,11 +44,6 @@ public:
|
||||||
void setQuit();
|
void setQuit();
|
||||||
void setFM();
|
void setFM();
|
||||||
|
|
||||||
void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
|
||||||
void writeDStarRSSI(unsigned char rssi);
|
|
||||||
void writeDStarBER(float ber);
|
|
||||||
void clearDStar();
|
|
||||||
|
|
||||||
void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
void writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type);
|
void writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type);
|
||||||
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
|
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
|
||||||
|
@ -56,44 +51,19 @@ public:
|
||||||
void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||||
void clearDMR(unsigned int slotNo);
|
void clearDMR(unsigned int slotNo);
|
||||||
|
|
||||||
void writeFusion(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
|
||||||
void writeFusionRSSI(unsigned char rssi);
|
|
||||||
void writeFusionBER(float ber);
|
|
||||||
void clearFusion();
|
|
||||||
|
|
||||||
void writeP25(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
void writeP25RSSI(unsigned char rssi);
|
|
||||||
void writeP25BER(float ber);
|
|
||||||
void clearP25();
|
|
||||||
|
|
||||||
void writeNXDN(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
void writeNXDN(const class CUserDBentry& source, bool group, unsigned int dest, const char* type);
|
|
||||||
void writeNXDNRSSI(unsigned char rssi);
|
|
||||||
void writeNXDNBER(float ber);
|
|
||||||
void clearNXDN();
|
|
||||||
|
|
||||||
void writePOCSAG(uint32_t ric, const std::string& message);
|
|
||||||
void clearPOCSAG();
|
|
||||||
|
|
||||||
void writeCW();
|
void writeCW();
|
||||||
|
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
static CDisplay* createDisplay(const CConf& conf, CUMP* ump, CModem* modem);
|
static CDisplay* createDisplay(const CConf& conf, CModem* modem);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setIdleInt() = 0;
|
virtual void setIdleInt() = 0;
|
||||||
virtual void setLockoutInt() = 0;
|
virtual void setLockoutInt() = 0;
|
||||||
virtual void setErrorInt(const char* text) = 0;
|
virtual void setErrorInt(const char* text) = 0;
|
||||||
virtual void setQuitInt() = 0;
|
virtual void setQuitInt() = 0;
|
||||||
virtual void setFMInt() = 0;
|
|
||||||
|
|
||||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) = 0;
|
|
||||||
virtual void writeDStarRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeDStarBERInt(float ber);
|
|
||||||
virtual void clearDStarInt() = 0;
|
|
||||||
|
|
||||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0;
|
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0;
|
||||||
virtual int writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type);
|
virtual int writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type);
|
||||||
|
@ -102,25 +72,6 @@ protected:
|
||||||
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
||||||
virtual void clearDMRInt(unsigned int slotNo) = 0;
|
virtual void clearDMRInt(unsigned int slotNo) = 0;
|
||||||
|
|
||||||
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin) = 0;
|
|
||||||
virtual void writeFusionRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeFusionBERInt(float ber);
|
|
||||||
virtual void clearFusionInt() = 0;
|
|
||||||
|
|
||||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type) = 0;
|
|
||||||
virtual void writeP25RSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeP25BERInt(float ber);
|
|
||||||
virtual void clearP25Int() = 0;
|
|
||||||
|
|
||||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type) = 0;
|
|
||||||
virtual int writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeNXDNBERInt(float ber);
|
|
||||||
virtual void clearNXDNInt() = 0;
|
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message) = 0;
|
|
||||||
virtual void clearPOCSAGInt() = 0;
|
|
||||||
|
|
||||||
virtual void writeCWInt() = 0;
|
virtual void writeCWInt() = 0;
|
||||||
virtual void clearCWInt() = 0;
|
virtual void clearCWInt() = 0;
|
||||||
|
|
||||||
|
|
19
Dockerfile
19
Dockerfile
|
@ -1,19 +0,0 @@
|
||||||
FROM alpine
|
|
||||||
|
|
||||||
RUN apk add --update --no-cache \
|
|
||||||
cmake \
|
|
||||||
make \
|
|
||||||
g++ \
|
|
||||||
git \
|
|
||||||
&& rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
ADD ./ /MMDVMHost
|
|
||||||
WORKDIR /MMDVMHost
|
|
||||||
RUN make \
|
|
||||||
&& cp MMDVMHost /usr/local/bin
|
|
||||||
|
|
||||||
VOLUME /MMDVMHost
|
|
||||||
WORKDIR /MMDVMHost
|
|
||||||
|
|
||||||
CMD ["MMDVMHost", "/MMDVMHost/MMDVM.ini"]
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2010,2016,2021 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved.
|
* Copyright (C) 2002 by Robert H. Morelos-Zaragoza. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Golay24128.h"
|
#include "Golay24128.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -1089,20 +1090,25 @@ unsigned int CGolay24128::decode23127(unsigned int code)
|
||||||
return code >> 11;
|
return code >> 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CGolay24128::decode24128(unsigned int code)
|
bool CGolay24128::decode24128(unsigned int in, unsigned int& out)
|
||||||
{
|
{
|
||||||
return decode23127(code >> 1);
|
unsigned int syndrome = ::get_syndrome_23127(in >> 1);
|
||||||
|
unsigned int error_pattern = DECODING_TABLE_23127[syndrome] << 1;
|
||||||
|
|
||||||
|
out = in ^ error_pattern;
|
||||||
|
|
||||||
|
bool valid = (CUtils::countBits(syndrome) < 3U) || !(CUtils::countBits(out) & 1);
|
||||||
|
|
||||||
|
out >>= 12;
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CGolay24128::decode24128(unsigned char* bytes)
|
bool CGolay24128::decode24128(unsigned char* in, unsigned int& out)
|
||||||
{
|
{
|
||||||
assert(bytes != NULL);
|
assert(in != NULL);
|
||||||
|
|
||||||
unsigned int code = bytes[0U];
|
unsigned int code = (in[0U] << 16) | (in[1U] << 8) | (in[2U] << 0);
|
||||||
code <<= 8;
|
|
||||||
code |= bytes[1U];
|
|
||||||
code <<= 8;
|
|
||||||
code |= bytes[2U];
|
|
||||||
|
|
||||||
return decode23127(code >> 1);
|
return decode24128(code, out);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2010,2016,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,8 +25,9 @@ public:
|
||||||
static unsigned int encode24128(unsigned int data);
|
static unsigned int encode24128(unsigned int data);
|
||||||
|
|
||||||
static unsigned int decode23127(unsigned int code);
|
static unsigned int decode23127(unsigned int code);
|
||||||
static unsigned int decode24128(unsigned int code);
|
|
||||||
static unsigned int decode24128(unsigned char* bytes);
|
static bool decode24128(unsigned int in, unsigned int& out);
|
||||||
|
static bool decode24128(unsigned char* in, unsigned int& out);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
278
HD44780.cpp
278
HD44780.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX & Tony Corbett G0WFV
|
* Copyright (C) 2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX & Tony Corbett G0WFV
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -41,6 +41,7 @@ const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
|
||||||
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
|
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
|
||||||
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||||
const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
||||||
|
const unsigned int M17_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
||||||
|
|
||||||
CHD44780::CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, unsigned int i2cAddress, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex) :
|
CHD44780::CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, unsigned int i2cAddress, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex) :
|
||||||
CDisplay(),
|
CDisplay(),
|
||||||
|
@ -211,12 +212,12 @@ void CHD44780::adafruitLCDSetup()
|
||||||
::pinMode(AF_RW, OUTPUT);
|
::pinMode(AF_RW, OUTPUT);
|
||||||
::digitalWrite(AF_RW, LOW);
|
::digitalWrite(AF_RW, LOW);
|
||||||
|
|
||||||
m_rb = AF_RS;
|
m_rb = AF_RS;
|
||||||
m_strb = AF_E;
|
m_strb = AF_E;
|
||||||
m_d0 = AF_D0;
|
m_d0 = AF_D0;
|
||||||
m_d1 = AF_D1;
|
m_d1 = AF_D1;
|
||||||
m_d2 = AF_D2;
|
m_d2 = AF_D2;
|
||||||
m_d3 = AF_D3;
|
m_d3 = AF_D3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour)
|
void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour)
|
||||||
|
@ -275,12 +276,12 @@ void CHD44780::pcf8574LCDSetup()
|
||||||
::pcf8574Setup(AF_BASE, m_i2cAddress);
|
::pcf8574Setup(AF_BASE, m_i2cAddress);
|
||||||
|
|
||||||
// Turn on backlight
|
// Turn on backlight
|
||||||
::pinMode (AF_BL, OUTPUT);
|
::pinMode(AF_BL, OUTPUT);
|
||||||
::digitalWrite (AF_BL, 1);
|
::digitalWrite(AF_BL, 1);
|
||||||
|
|
||||||
// Set LCD to write mode.
|
// Set LCD to write mode.
|
||||||
::pinMode (AF_RW, OUTPUT);
|
::pinMode(AF_RW, OUTPUT);
|
||||||
::digitalWrite (AF_RW, 0);
|
::digitalWrite(AF_RW, 0);
|
||||||
|
|
||||||
m_rb = AF_RS;
|
m_rb = AF_RS;
|
||||||
m_strb = AF_E;
|
m_strb = AF_E;
|
||||||
|
@ -297,7 +298,7 @@ void CHD44780::setIdleInt()
|
||||||
::lcdClear(m_fd);
|
::lcdClear(m_fd);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_WHITE);
|
adafruitLCDColour(AC_WHITE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pwm) {
|
if (m_pwm) {
|
||||||
|
@ -327,7 +328,7 @@ void CHD44780::setErrorInt(const char* text)
|
||||||
assert(text != NULL);
|
assert(text != NULL);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_RED);
|
adafruitLCDColour(AC_RED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
@ -405,7 +406,7 @@ void CHD44780::setFMInt()
|
||||||
::lcdClear(m_fd);
|
::lcdClear(m_fd);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_WHITE);
|
adafruitLCDColour(AC_WHITE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pwm) {
|
if (m_pwm) {
|
||||||
|
@ -439,7 +440,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
||||||
assert(reflector != NULL);
|
assert(reflector != NULL);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_RED);
|
adafruitLCDColour(AC_RED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
@ -463,11 +464,10 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
||||||
::lcdPrintf(m_fd, " %.8s/%.4s", my1, my2);
|
::lcdPrintf(m_fd, " %.8s/%.4s", my1, my2);
|
||||||
::lcdPosition(m_fd, m_cols - 1, (m_rows / 2) - 1);
|
::lcdPosition(m_fd, m_cols - 1, (m_rows / 2) - 1);
|
||||||
|
|
||||||
if (strcmp(type, "R") == 0) {
|
if (strcmp(type, "R") == 0)
|
||||||
::lcdPutchar(m_fd, 2);
|
::lcdPutchar(m_fd, 2);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 3);
|
::lcdPutchar(m_fd, 3);
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(m_buffer1, "%.8s", your);
|
::sprintf(m_buffer1, "%.8s", your);
|
||||||
|
|
||||||
|
@ -493,19 +493,19 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
||||||
::lcdPrintf(m_fd, " %.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, " %.*s", m_cols, m_buffer1);
|
||||||
|
|
||||||
m_dmr = false;
|
m_dmr = false;
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeDStarRSSIInt(unsigned char rssi)
|
void CHD44780::writeDStarRSSIInt(unsigned char rssi)
|
||||||
{
|
{
|
||||||
if (m_rssiCount1 == 0U && m_rows > 2) {
|
if (m_rssiCount1 == 0U && m_rows > 2) {
|
||||||
::lcdPosition(m_fd, 0, 3);
|
::lcdPosition(m_fd, 0, 3);
|
||||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rssiCount1++;
|
m_rssiCount1++;
|
||||||
if (m_rssiCount1 >= DSTAR_RSSI_COUNT)
|
if (m_rssiCount1 >= DSTAR_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::clearDStarInt()
|
void CHD44780::clearDStarInt()
|
||||||
|
@ -599,21 +599,20 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1);
|
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1);
|
||||||
::lcdPuts(m_fd, " ");
|
::lcdPuts(m_fd, " ");
|
||||||
|
|
||||||
if (group) {
|
if (group)
|
||||||
::lcdPutchar(m_fd, 5);
|
::lcdPutchar(m_fd, 5);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 4);
|
::lcdPutchar(m_fd, 4);
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, "R") == 0) {
|
if (strcmp(type, "R") == 0)
|
||||||
::lcdPutchar(m_fd, 2);
|
::lcdPutchar(m_fd, 2);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 3);
|
::lcdPutchar(m_fd, 3);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||||
::lcdPuts(m_fd, "2 ");
|
::lcdPuts(m_fd, "2 ");
|
||||||
if (m_cols > 16 )
|
|
||||||
|
if (m_cols > 16)
|
||||||
::sprintf(m_buffer2, "%s > %s%s%s", src.c_str(), group ? "TG" : "", dst.c_str(), DEADSPACE);
|
::sprintf(m_buffer2, "%s > %s%s%s", src.c_str(), group ? "TG" : "", dst.c_str(), DEADSPACE);
|
||||||
else
|
else
|
||||||
::sprintf(m_buffer2, "%s>%s%s", src.c_str(), dst.c_str(), DEADSPACE);
|
::sprintf(m_buffer2, "%s>%s%s", src.c_str(), dst.c_str(), DEADSPACE);
|
||||||
|
@ -622,17 +621,15 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2));
|
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2));
|
||||||
::lcdPuts(m_fd, " ");
|
::lcdPuts(m_fd, " ");
|
||||||
|
|
||||||
if (group) {
|
if (group)
|
||||||
::lcdPutchar(m_fd, 5);
|
::lcdPutchar(m_fd, 5);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 4);
|
::lcdPutchar(m_fd, 4);
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(type, "R") == 0) {
|
if (strcmp(type, "R") == 0)
|
||||||
::lcdPutchar(m_fd, 2);
|
::lcdPutchar(m_fd, 2);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 3);
|
::lcdPutchar(m_fd, 3);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_rows > 2U) {
|
if (m_rows > 2U) {
|
||||||
|
@ -647,11 +644,10 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
||||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2) - 1);
|
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2) - 1);
|
||||||
|
|
||||||
if (strcmp(type, "R") == 0) {
|
if (strcmp(type, "R") == 0)
|
||||||
::lcdPutchar(m_fd, 2);
|
::lcdPutchar(m_fd, 2);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 3);
|
::lcdPutchar(m_fd, 3);
|
||||||
}
|
|
||||||
|
|
||||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||||
::lcdPutchar(m_fd, 1);
|
::lcdPutchar(m_fd, 1);
|
||||||
|
@ -659,15 +655,15 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
||||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2));
|
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2));
|
||||||
|
|
||||||
if (group) {
|
if (group)
|
||||||
::lcdPutchar(m_fd, 5);
|
::lcdPutchar(m_fd, 5);
|
||||||
} else {
|
else
|
||||||
::lcdPutchar(m_fd, 4);
|
::lcdPutchar(m_fd, 4);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dmr = true;
|
m_dmr = true;
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
m_rssiCount2 = 0U;
|
m_rssiCount2 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
void CHD44780::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
||||||
|
@ -688,9 +684,9 @@ void CHD44780::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
||||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rssiCount2++;
|
m_rssiCount2++;
|
||||||
if (m_rssiCount2 >= DMR_RSSI_COUNT)
|
if (m_rssiCount2 >= DMR_RSSI_COUNT)
|
||||||
m_rssiCount2 = 0U;
|
m_rssiCount2 = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,7 +718,6 @@ void CHD44780::clearDMRInt(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (m_rows > 2U) {
|
if (m_rows > 2U) {
|
||||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 2);
|
::lcdPosition(m_fd, 0, (m_rows / 2) - 2);
|
||||||
::sprintf(m_buffer1, "%s", DEADSPACE);
|
::sprintf(m_buffer1, "%s", DEADSPACE);
|
||||||
|
@ -745,7 +740,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, unsigned cha
|
||||||
assert(origin != NULL);
|
assert(origin != NULL);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_RED);
|
adafruitLCDColour(AC_RED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
@ -762,12 +757,10 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, unsigned cha
|
||||||
::lcdPuts(m_fd, "System Fusion");
|
::lcdPuts(m_fd, "System Fusion");
|
||||||
|
|
||||||
if (m_rows == 2U && m_cols == 16U) {
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 16U) {
|
} else if (m_rows == 4U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -776,7 +769,6 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, unsigned cha
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 20U) {
|
} else if (m_rows == 4U && m_cols == 20U) {
|
||||||
char m_buffer1[20U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -785,7 +777,6 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, unsigned cha
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 2 && m_cols == 40U) {
|
} else if (m_rows == 2 && m_cols == 40U) {
|
||||||
char m_buffer1[40U];
|
|
||||||
::sprintf(m_buffer1, "%.10s > DG-ID %u", source, dgid);
|
::sprintf(m_buffer1, "%.10s > DG-ID %u", source, dgid);
|
||||||
|
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
@ -848,7 +839,7 @@ void CHD44780::writeP25Int(const char* source, bool group, unsigned int dest, co
|
||||||
assert(type != NULL);
|
assert(type != NULL);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_RED);
|
adafruitLCDColour(AC_RED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
@ -865,12 +856,10 @@ void CHD44780::writeP25Int(const char* source, bool group, unsigned int dest, co
|
||||||
::lcdPuts(m_fd, "P25");
|
::lcdPuts(m_fd, "P25");
|
||||||
|
|
||||||
if (m_rows == 2U && m_cols == 16U) {
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 16U) {
|
} else if (m_rows == 4U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -879,7 +868,6 @@ void CHD44780::writeP25Int(const char* source, bool group, unsigned int dest, co
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 20U) {
|
} else if (m_rows == 4U && m_cols == 20U) {
|
||||||
char m_buffer1[20U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -888,7 +876,6 @@ void CHD44780::writeP25Int(const char* source, bool group, unsigned int dest, co
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 2 && m_cols == 40U) {
|
} else if (m_rows == 2 && m_cols == 40U) {
|
||||||
char m_buffer1[40U];
|
|
||||||
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
||||||
|
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
@ -896,19 +883,19 @@ void CHD44780::writeP25Int(const char* source, bool group, unsigned int dest, co
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dmr = false;
|
m_dmr = false;
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeP25RSSIInt(unsigned char rssi)
|
void CHD44780::writeP25RSSIInt(unsigned char rssi)
|
||||||
{
|
{
|
||||||
if (m_rssiCount1 == 0U && m_rows > 2) {
|
if (m_rssiCount1 == 0U && m_rows > 2) {
|
||||||
::lcdPosition(m_fd, 0, 3);
|
::lcdPosition(m_fd, 0, 3);
|
||||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rssiCount1++;
|
m_rssiCount1++;
|
||||||
if (m_rssiCount1 >= P25_RSSI_COUNT)
|
if (m_rssiCount1 >= P25_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::clearP25Int()
|
void CHD44780::clearP25Int()
|
||||||
|
@ -952,7 +939,7 @@ void CHD44780::writeNXDNInt(const char* source, bool group, unsigned int dest, c
|
||||||
assert(type != NULL);
|
assert(type != NULL);
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_RED);
|
adafruitLCDColour(AC_RED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
@ -969,12 +956,10 @@ void CHD44780::writeNXDNInt(const char* source, bool group, unsigned int dest, c
|
||||||
::lcdPuts(m_fd, "NXDN");
|
::lcdPuts(m_fd, "NXDN");
|
||||||
|
|
||||||
if (m_rows == 2U && m_cols == 16U) {
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 16U) {
|
} else if (m_rows == 4U && m_cols == 16U) {
|
||||||
char m_buffer1[16U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -983,7 +968,6 @@ void CHD44780::writeNXDNInt(const char* source, bool group, unsigned int dest, c
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 4U && m_cols == 20U) {
|
} else if (m_rows == 4U && m_cols == 20U) {
|
||||||
char m_buffer1[20U];
|
|
||||||
::sprintf(m_buffer1, "%.10s >", source);
|
::sprintf(m_buffer1, "%.10s >", source);
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
@ -992,27 +976,25 @@ void CHD44780::writeNXDNInt(const char* source, bool group, unsigned int dest, c
|
||||||
::lcdPosition(m_fd, 0, 2);
|
::lcdPosition(m_fd, 0, 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
} else if (m_rows == 2 && m_cols == 40U) {
|
} else if (m_rows == 2 && m_cols == 40U) {
|
||||||
char m_buffer1[40U];
|
|
||||||
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
||||||
|
|
||||||
::lcdPosition(m_fd, 0, 1);
|
::lcdPosition(m_fd, 0, 1);
|
||||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dmr = false;
|
m_dmr = false;
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeNXDNRSSIInt(unsigned char rssi)
|
void CHD44780::writeNXDNRSSIInt(unsigned char rssi)
|
||||||
{
|
{
|
||||||
if (m_rssiCount1 == 0U && m_rows > 2) {
|
if (m_rssiCount1 == 0U && m_rows > 2) {
|
||||||
::lcdPosition(m_fd, 0, 3);
|
::lcdPosition(m_fd, 0, 3);
|
||||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rssiCount1++;
|
m_rssiCount1++;
|
||||||
if (m_rssiCount1 >= NXDN_RSSI_COUNT)
|
if (m_rssiCount1 >= NXDN_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::clearNXDNInt()
|
void CHD44780::clearNXDNInt()
|
||||||
|
@ -1050,16 +1032,115 @@ void CHD44780::clearNXDNInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHD44780::writeM17Int(const char* source, const char* dest, const char* type)
|
||||||
|
{
|
||||||
|
assert(source != NULL);
|
||||||
|
assert(dest != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
|
||||||
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
|
adafruitLCDColour(AC_RED);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
::lcdClear(m_fd);
|
||||||
|
|
||||||
|
if (m_pwm) {
|
||||||
|
if (m_pwmPin != 1U)
|
||||||
|
::softPwmWrite(m_pwmPin, m_pwmBright);
|
||||||
|
else
|
||||||
|
::pwmWrite(m_pwmPin, (m_pwmBright / 100) * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
::lcdPosition(m_fd, 0, 0);
|
||||||
|
::lcdPuts(m_fd, "M17");
|
||||||
|
|
||||||
|
::sprintf(m_buffer1, "%.9s", source);
|
||||||
|
::sprintf(m_buffer2, "%.9s", dest);
|
||||||
|
|
||||||
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
|
::lcdPosition(m_fd, 5, 0);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols - 5, m_buffer1);
|
||||||
|
::lcdPosition(m_fd, 5, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols - 5, m_buffer2);
|
||||||
|
} else if (m_rows == 4U && m_cols == 16U) {
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
::lcdPosition(m_fd, 0, 2);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer2);
|
||||||
|
} else if (m_rows == 4U && m_cols == 20U) {
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
::lcdPosition(m_fd, 0, 2);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
} else if (m_rows == 2 && m_cols == 40U) {
|
||||||
|
::sprintf(m_buffer1, "%.9s > %.9s", source, dest);
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dmr = false;
|
||||||
|
m_rssiCount1 = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHD44780::writeM17RSSIInt(unsigned char rssi)
|
||||||
|
{
|
||||||
|
if (m_rssiCount1 == 0U && m_rows > 2) {
|
||||||
|
::lcdPosition(m_fd, 0, 3);
|
||||||
|
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rssiCount1++;
|
||||||
|
if (m_rssiCount1 >= M17_RSSI_COUNT)
|
||||||
|
m_rssiCount1 = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHD44780::clearM17Int()
|
||||||
|
{
|
||||||
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
|
adafruitLCDColour(AC_PURPLE);
|
||||||
|
#endif
|
||||||
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
|
::lcdPosition(m_fd, 5, 0);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols - 5, LISTENING);
|
||||||
|
::lcdPosition(m_fd, 5, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols - 5, " ");
|
||||||
|
} else if (m_rows == 4U && m_cols == 16U) {
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||||
|
|
||||||
|
::lcdPosition(m_fd, 0, 2);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, " ");
|
||||||
|
|
||||||
|
::lcdPosition(m_fd, 0, 3);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, " ");
|
||||||
|
} else if (m_rows == 4U && m_cols == 20U) {
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||||
|
|
||||||
|
::lcdPosition(m_fd, 0, 2);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, " ");
|
||||||
|
|
||||||
|
::lcdPosition(m_fd, 0, 3);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, " ");
|
||||||
|
} else if (m_rows == 2 && m_cols == 40U) {
|
||||||
|
::lcdPosition(m_fd, 0, 1);
|
||||||
|
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CHD44780::writePOCSAGInt(uint32_t ric, const std::string& message)
|
void CHD44780::writePOCSAGInt(uint32_t ric, const std::string& message)
|
||||||
{
|
{
|
||||||
::lcdPosition(m_fd, m_cols - 5, m_rows - 1);
|
::lcdPosition(m_fd, m_cols - 5, m_rows - 1);
|
||||||
::lcdPuts(m_fd, "POCSAG TX");
|
::lcdPuts(m_fd, "POCSG"); // Shortened "POCSAG TX" to 5 characters because it wraps around onto the next line (or on 16x2 displays the 1st line).
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::clearPOCSAGInt()
|
void CHD44780::clearPOCSAGInt()
|
||||||
{
|
{
|
||||||
::lcdPosition(m_fd, m_cols - 5, m_rows - 1);
|
::lcdPosition(m_fd, m_cols - 5, m_rows - 1);
|
||||||
::lcdPuts(m_fd, " Idle");
|
::lcdPuts(m_fd, " Idle"); // Reverted back to 5 character implementation.
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeCWInt()
|
void CHD44780::writeCWInt()
|
||||||
|
@ -1080,31 +1161,30 @@ void CHD44780::clockInt(unsigned int ms)
|
||||||
|
|
||||||
// Idle clock display
|
// Idle clock display
|
||||||
if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) {
|
if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) {
|
||||||
time_t currentTime;
|
time_t currentTime;
|
||||||
struct tm *Time;
|
struct tm *Time;
|
||||||
time(¤tTime);
|
::time(¤tTime);
|
||||||
|
|
||||||
if (m_utc) {
|
if (m_utc)
|
||||||
Time = gmtime(¤tTime);
|
Time = ::gmtime(¤tTime);
|
||||||
} else {
|
else
|
||||||
Time = localtime(¤tTime);
|
Time = ::localtime(¤tTime);
|
||||||
}
|
|
||||||
|
|
||||||
setlocale(LC_TIME,"");
|
setlocale(LC_TIME,"");
|
||||||
strftime(m_buffer1, 128, "%X", Time); // Time
|
::strftime(m_buffer1, 128, "%X", Time); // Time
|
||||||
strftime(m_buffer2, 128, "%x", Time); // Date
|
::strftime(m_buffer2, 128, "%x", Time); // Date
|
||||||
|
|
||||||
if (m_cols == 16U && m_rows == 2U) {
|
if (m_cols == 16U && m_rows == 2U) {
|
||||||
::lcdPosition(m_fd, m_cols - 10, 1);
|
::lcdPosition(m_fd, m_cols - 10, 1);
|
||||||
::lcdPrintf(m_fd, "%s%.*s", strlen(m_buffer1) > 8 ? "" : " ", 10, m_buffer1);
|
::lcdPrintf(m_fd, "%s%.*s", strlen(m_buffer1) > 8 ? "" : " ", 10, m_buffer1);
|
||||||
} else {
|
} else {
|
||||||
::lcdPosition(m_fd, (m_cols - (strlen(m_buffer1) == 8 ? 8 : 10)) / 2, m_rows == 2 ? 1 : 2);
|
::lcdPosition(m_fd, (m_cols - (strlen(m_buffer1) == 8 ? 8 : 10)) / 2, m_rows == 2 ? 1 : 2);
|
||||||
::lcdPrintf(m_fd, "%.*s", strlen(m_buffer1) == 8 ? 8 : 10, m_buffer1);
|
::lcdPrintf(m_fd, "%.*s", strlen(m_buffer1) == 8 ? 8 : 10, m_buffer1);
|
||||||
::lcdPosition(m_fd, (m_cols - strlen(m_buffer2)) / 2, m_rows == 2 ? 0 : 1);
|
::lcdPosition(m_fd, (m_cols - strlen(m_buffer2)) / 2, m_rows == 2 ? 0 : 1);
|
||||||
::lcdPrintf(m_fd, "%s", m_buffer2);
|
::lcdPrintf(m_fd, "%s", m_buffer2);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clockDisplayTimer.start();
|
m_clockDisplayTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
70
HD44780.h
70
HD44780.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018,2020 by Jonathan Naylor G4KLX & Tony Corbett G0WFV
|
* Copyright (C) 2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX & Tony Corbett G0WFV
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -89,47 +89,51 @@ enum ADAFRUIT_COLOUR {
|
||||||
class CHD44780 : public CDisplay
|
class CHD44780 : public CDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, unsigned int i2cAddress, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex);
|
CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, unsigned int i2cAddress, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex);
|
||||||
virtual ~CHD44780();
|
virtual ~CHD44780();
|
||||||
|
|
||||||
virtual bool open();
|
virtual bool open();
|
||||||
|
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setIdleInt();
|
virtual void setIdleInt();
|
||||||
virtual void setErrorInt(const char* text);
|
virtual void setErrorInt(const char* text);
|
||||||
virtual void setLockoutInt();
|
virtual void setLockoutInt();
|
||||||
virtual void setQuitInt();
|
virtual void setQuitInt();
|
||||||
virtual void setFMInt();
|
virtual void setFMInt();
|
||||||
|
|
||||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
||||||
virtual void writeDStarRSSIInt(unsigned char rssi);
|
virtual void writeDStarRSSIInt(unsigned char rssi);
|
||||||
virtual void clearDStarInt();
|
virtual void clearDStarInt();
|
||||||
|
|
||||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||||
virtual void clearDMRInt(unsigned int slotNo);
|
virtual void clearDMRInt(unsigned int slotNo);
|
||||||
|
|
||||||
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
||||||
virtual void writeFusionRSSIInt(unsigned char rssi);
|
virtual void writeFusionRSSIInt(unsigned char rssi);
|
||||||
virtual void clearFusionInt();
|
virtual void clearFusionInt();
|
||||||
|
|
||||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
||||||
virtual void writeP25RSSIInt(unsigned char rssi);
|
virtual void writeP25RSSIInt(unsigned char rssi);
|
||||||
virtual void clearP25Int();
|
virtual void clearP25Int();
|
||||||
|
|
||||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
||||||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
||||||
virtual void clearNXDNInt();
|
virtual void clearNXDNInt();
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
virtual void writeM17Int(const char* source, const char* dest, const char* type);
|
||||||
virtual void clearPOCSAGInt();
|
virtual void writeM17RSSIInt(unsigned char rssi);
|
||||||
|
virtual void clearM17Int();
|
||||||
|
|
||||||
virtual void writeCWInt();
|
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||||
virtual void clearCWInt();
|
virtual void clearPOCSAGInt();
|
||||||
|
|
||||||
virtual void clockInt(unsigned int ms);
|
virtual void writeCWInt();
|
||||||
|
virtual void clearCWInt();
|
||||||
|
|
||||||
|
virtual void clockInt(unsigned int ms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_rows;
|
unsigned int m_rows;
|
||||||
|
@ -162,12 +166,12 @@ private:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
void adafruitLCDSetup();
|
void adafruitLCDSetup();
|
||||||
void adafruitLCDColour(ADAFRUIT_COLOUR colour);
|
void adafruitLCDColour(ADAFRUIT_COLOUR colour);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PCF8574_DISPLAY
|
#ifdef PCF8574_DISPLAY
|
||||||
void pcf8574LCDSetup();
|
void pcf8574LCDSetup();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004,2007-2011,2013,2014-2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2002-2004,2007-2011,2013,2014-2017,2020 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
|
||||||
#include "I2CController.h"
|
#include "I2CController.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
|
@ -24,52 +26,18 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
|
|
||||||
#include <setupapi.h>
|
|
||||||
#include <winioctl.h>
|
|
||||||
|
|
||||||
CI2CController::CI2CController(const std::string& device, SERIAL_SPEED speed, unsigned int address, bool assertRTS) :
|
|
||||||
CSerialController(device, speed, assertRTS),
|
|
||||||
m_address(address)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CI2CController::~CI2CController()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CI2CController::open()
|
|
||||||
{
|
|
||||||
return CSerialController::open();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CI2CController::read(unsigned char* buffer, unsigned int length)
|
|
||||||
{
|
|
||||||
return CSerialController::read(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CI2CController::write(const unsigned char* buffer, unsigned int length)
|
|
||||||
{
|
|
||||||
return CSerialController::write(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#if defined(__linux__)
|
|
||||||
#include <linux/i2c-dev.h>
|
#include <linux/i2c-dev.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
CI2CController::CI2CController(const std::string& device, SERIAL_SPEED speed, unsigned int address, bool assertRTS) :
|
CI2CController::CI2CController(const std::string& device, unsigned int address) :
|
||||||
CSerialController(device, speed, assertRTS),
|
m_device(device),
|
||||||
m_address(address)
|
m_address(address),
|
||||||
|
m_fd(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +49,6 @@ bool CI2CController::open()
|
||||||
{
|
{
|
||||||
assert(m_fd == -1);
|
assert(m_fd == -1);
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
m_fd = ::open(m_device.c_str(), O_RDWR);
|
m_fd = ::open(m_device.c_str(), O_RDWR);
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
LogError("Cannot open device - %s", m_device.c_str());
|
LogError("Cannot open device - %s", m_device.c_str());
|
||||||
|
@ -89,19 +56,16 @@ bool CI2CController::open()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::ioctl(m_fd, I2C_TENBIT, 0) < 0) {
|
if (::ioctl(m_fd, I2C_TENBIT, 0) < 0) {
|
||||||
LogError("CI2C: failed to set 7bitaddress");
|
LogError("I2C: failed to set 7bitaddress");
|
||||||
::close(m_fd);
|
::close(m_fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::ioctl(m_fd, I2C_SLAVE, m_address) < 0) {
|
if (::ioctl(m_fd, I2C_SLAVE, m_address) < 0) {
|
||||||
LogError("CI2C: Failed to acquire bus access/talk to slave 0x%02X", m_address);
|
LogError("I2C: Failed to acquire bus access/talk to slave 0x%02X", m_address);
|
||||||
::close(m_fd);
|
::close(m_fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#warning "I2C controller supports Linux only"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +81,6 @@ int CI2CController::read(unsigned char* buffer, unsigned int length)
|
||||||
unsigned int offset = 0U;
|
unsigned int offset = 0U;
|
||||||
|
|
||||||
while (offset < length) {
|
while (offset < length) {
|
||||||
#if defined(__linux__)
|
|
||||||
ssize_t n = ::read(m_fd, buffer + offset, 1U);
|
ssize_t n = ::read(m_fd, buffer + offset, 1U);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
|
@ -128,7 +91,6 @@ int CI2CController::read(unsigned char* buffer, unsigned int length)
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
offset += n;
|
offset += n;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
@ -144,10 +106,7 @@ int CI2CController::write(const unsigned char* buffer, unsigned int length)
|
||||||
|
|
||||||
unsigned int ptr = 0U;
|
unsigned int ptr = 0U;
|
||||||
while (ptr < length) {
|
while (ptr < length) {
|
||||||
ssize_t n = 0U;
|
ssize_t n = ::write(m_fd, buffer + ptr, 1U);
|
||||||
#if defined(__linux__)
|
|
||||||
n = ::write(m_fd, buffer + ptr, 1U);
|
|
||||||
#endif
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
LogError("Error returned from write(), errno=%d", errno);
|
LogError("Error returned from write(), errno=%d", errno);
|
||||||
|
@ -162,4 +121,12 @@ int CI2CController::write(const unsigned char* buffer, unsigned int length)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CI2CController::close()
|
||||||
|
{
|
||||||
|
assert(m_fd != -1);
|
||||||
|
|
||||||
|
::close(m_fd);
|
||||||
|
m_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004,2007-2009,2011-2013,2015-2017 by Jonathan Naylor G4KLX
|
* Copyright (C) 2002-2004,2007-2009,2011-2013,2015-2017,2020,2021 by Jonathan Naylor G4KLX
|
||||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -20,11 +20,16 @@
|
||||||
#ifndef I2CController_H
|
#ifndef I2CController_H
|
||||||
#define I2CController_H
|
#define I2CController_H
|
||||||
|
|
||||||
#include "SerialController.h"
|
#if defined(__linux__)
|
||||||
|
|
||||||
class CI2CController : public CSerialController {
|
#include "ModemPort.h"
|
||||||
|
#include "SerialPort.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CI2CController : public ISerialPort, public IModemPort {
|
||||||
public:
|
public:
|
||||||
CI2CController(const std::string& device, SERIAL_SPEED speed, unsigned int address = 0x22U, bool assertRTS = false);
|
CI2CController(const std::string& device, unsigned int address = 0x22U);
|
||||||
virtual ~CI2CController();
|
virtual ~CI2CController();
|
||||||
|
|
||||||
virtual bool open();
|
virtual bool open();
|
||||||
|
@ -33,8 +38,14 @@ public:
|
||||||
|
|
||||||
virtual int write(const unsigned char* buffer, unsigned int length);
|
virtual int write(const unsigned char* buffer, unsigned int length);
|
||||||
|
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string m_device;
|
||||||
unsigned int m_address;
|
unsigned int m_address;
|
||||||
|
int m_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
60
IIRDirectForm1Filter.cpp
Normal file
60
IIRDirectForm1Filter.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2020 by Geoffrey Merck - F4FXL KC3FRA
|
||||||
|
*
|
||||||
|
* 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; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IIRDirectForm1Filter.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
CIIRDirectForm1Filter::CIIRDirectForm1Filter(float b0, float b1, float b2, float , float a1, float a2, float addtionalGaindB) :
|
||||||
|
m_x2(0.0F),
|
||||||
|
m_y2(0.0F),
|
||||||
|
m_x1(0.0F),
|
||||||
|
m_y1(0.0F),
|
||||||
|
m_b0(b0),
|
||||||
|
m_b1(b1),
|
||||||
|
m_b2(b2),
|
||||||
|
m_a1(a1),
|
||||||
|
m_a2(a2),
|
||||||
|
m_additionalGainLin(0.0F)
|
||||||
|
{
|
||||||
|
m_additionalGainLin = ::powf(10.0F, addtionalGaindB / 20.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CIIRDirectForm1Filter::filter(float sample)
|
||||||
|
{
|
||||||
|
float output = m_b0 * sample
|
||||||
|
+ m_b1 * m_x1
|
||||||
|
+ m_b2 * m_x2
|
||||||
|
- m_a1 * m_y1
|
||||||
|
- m_a2 * m_y2;
|
||||||
|
|
||||||
|
m_x2 = m_x1;
|
||||||
|
m_y2 = m_y1;
|
||||||
|
m_x1 = sample;
|
||||||
|
m_y1 = output;
|
||||||
|
|
||||||
|
return output * m_additionalGainLin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIIRDirectForm1Filter::reset()
|
||||||
|
{
|
||||||
|
m_x1 = 0.0f;
|
||||||
|
m_x2 = 0.0f;
|
||||||
|
m_y1 = 0.0f;
|
||||||
|
m_y2 = 0.0f;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||||
|
* Copyright (C) 2020 by Geoffrey Merck - F4FXL KC3FRA
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,30 +17,34 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(NXDNConvolution_H)
|
#if !defined(IIRDIRECTFORM1FILTER_H)
|
||||||
#define NXDNConvolution_H
|
#define IIRDIRECTFORM1FILTER_H
|
||||||
|
|
||||||
#include <cstdint>
|
class CIIRDirectForm1Filter
|
||||||
|
{
|
||||||
class CNXDNConvolution {
|
|
||||||
public:
|
public:
|
||||||
CNXDNConvolution();
|
CIIRDirectForm1Filter(float b0, float b1, float b2, float, float a1, float a2, float additionalGaindB);
|
||||||
~CNXDNConvolution();
|
float filter(float sample);
|
||||||
|
void reset();
|
||||||
void start();
|
|
||||||
void decode(uint8_t s0, uint8_t s1);
|
|
||||||
void chainback(unsigned char* out, unsigned int nBits);
|
|
||||||
|
|
||||||
void encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t* m_metrics1;
|
// delay line
|
||||||
uint16_t* m_metrics2;
|
float m_x2; // x[n-2]
|
||||||
uint16_t* m_oldMetrics;
|
float m_y2; // y[n-2]
|
||||||
uint16_t* m_newMetrics;
|
float m_x1; // x[n-1]
|
||||||
uint64_t* m_decisions;
|
float m_y1; // y[n-1]
|
||||||
uint64_t* m_dp;
|
|
||||||
|
// coefficients
|
||||||
|
// FIR
|
||||||
|
float m_b0;
|
||||||
|
float m_b1;
|
||||||
|
float m_b2;
|
||||||
|
// IIR
|
||||||
|
float m_a1;
|
||||||
|
float m_a2;
|
||||||
|
|
||||||
|
float m_additionalGainLin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,9 +0,0 @@
|
||||||
D-Star: On some radios, the header is not decoded correctly. It looks like frequency drift at the beginning of the transmission.
|
|
||||||
|
|
||||||
DMR: DMO mode doesn't wake up older radios like other radios do.
|
|
||||||
|
|
||||||
YSF: No known issues.
|
|
||||||
|
|
||||||
P25: Upgrade the filters, processing power in the Due permiting.
|
|
||||||
|
|
||||||
NXDN: No known issues.
|
|
BIN
Images/M17.bmp
Normal file
BIN
Images/M17.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
69
LCDproc.cpp
69
LCDproc.cpp
|
@ -95,8 +95,9 @@ const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
|
||||||
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
|
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
|
||||||
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||||
const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
||||||
|
const unsigned int M17_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
||||||
|
|
||||||
CLCDproc::CLCDproc(std::string address, unsigned int port, unsigned int localPort, const std::string& callsign, unsigned int dmrid, bool displayClock, bool utc, bool duplex, bool dimOnIdle) :
|
CLCDproc::CLCDproc(std::string address, unsigned int port, unsigned short localPort, const std::string& callsign, unsigned int dmrid, bool displayClock, bool utc, bool duplex, bool dimOnIdle) :
|
||||||
CDisplay(),
|
CDisplay(),
|
||||||
m_address(address),
|
m_address(address),
|
||||||
m_port(port),
|
m_port(port),
|
||||||
|
@ -188,6 +189,7 @@ void CLCDproc::setIdleInt()
|
||||||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Idle", m_cols - 3, m_rows);
|
socketPrintf(m_socketfd, "widget_set Status Status %u %u Idle", m_cols - 3, m_rows);
|
||||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||||
}
|
}
|
||||||
|
@ -207,6 +209,7 @@ void CLCDproc::setErrorInt(const char* text)
|
||||||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Error", m_cols - 4, m_rows);
|
socketPrintf(m_socketfd, "widget_set Status Status %u %u Error", m_cols - 4, m_rows);
|
||||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||||
}
|
}
|
||||||
|
@ -224,6 +227,7 @@ void CLCDproc::setLockoutInt()
|
||||||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Lockout", m_cols - 6, m_rows);
|
socketPrintf(m_socketfd, "widget_set Status Status %u %u Lockout", m_cols - 6, m_rows);
|
||||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||||
}
|
}
|
||||||
|
@ -243,6 +247,7 @@ void CLCDproc::setQuitInt()
|
||||||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Stopped", m_cols - 6, m_rows);
|
socketPrintf(m_socketfd, "widget_set Status Status %u %u Stopped", m_cols - 6, m_rows);
|
||||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||||
}
|
}
|
||||||
|
@ -260,6 +265,7 @@ void CLCDproc::setFMInt()
|
||||||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
socketPrintf(m_socketfd, "screen_set NXDN -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority hidden");
|
||||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u FM", m_cols - 6, m_rows);
|
socketPrintf(m_socketfd, "widget_set Status Status %u %u FM", m_cols - 6, m_rows);
|
||||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||||
}
|
}
|
||||||
|
@ -556,6 +562,51 @@ void CLCDproc::clearNXDNInt()
|
||||||
socketPrintf(m_socketfd, "output 16"); // Set LED5 color green
|
socketPrintf(m_socketfd, "output 16"); // Set LED5 color green
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CLCDproc::writeM17Int(const char* source, const char* dest, const char* type)
|
||||||
|
{
|
||||||
|
assert(source != NULL);
|
||||||
|
assert(dest != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
|
||||||
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -priority foreground");
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Mode 1 1 M17");
|
||||||
|
|
||||||
|
if (m_rows == 2U) {
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line2 1 2 15 2 h 3 \"%.9s > %.9s\"", source, dest);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line2 1 2 15 2 h 3 \"%.9s >\"", source);
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line3 1 3 15 3 h 3 \"%.9ss\"", dest);
|
||||||
|
socketPrintf(m_socketfd, "output 255"); // Set LED5 color red
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dmr = false;
|
||||||
|
m_rssiCount1 = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLCDproc::writeM17RSSIInt(unsigned char rssi)
|
||||||
|
{
|
||||||
|
if (m_rssiCount1 == 0U) {
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line4 1 4 %u 4 h 3 \"-%3udBm\"", m_cols - 1, rssi);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rssiCount1++;
|
||||||
|
if (m_rssiCount1 >= M17_RSSI_COUNT)
|
||||||
|
m_rssiCount1 = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLCDproc::clearM17Int()
|
||||||
|
{
|
||||||
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line3 1 3 15 3 h 3 \"\"");
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line4 1 4 15 4 h 3 \"\"");
|
||||||
|
socketPrintf(m_socketfd, "output 16"); // Set LED5 color green
|
||||||
|
}
|
||||||
|
|
||||||
void CLCDproc::writePOCSAGInt(uint32_t ric, const std::string& message)
|
void CLCDproc::writePOCSAGInt(uint32_t ric, const std::string& message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -850,5 +901,21 @@ void CLCDproc::defineScreens()
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line4 4 2 15 2 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set NXDN Line4 4 2 15 2 h 3 \" \"");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// The M17 Screen
|
||||||
|
|
||||||
|
socketPrintf(m_socketfd, "screen_add M17");
|
||||||
|
socketPrintf(m_socketfd, "screen_set M17 -name M17 -heartbeat on -priority hidden -backlight on");
|
||||||
|
|
||||||
|
socketPrintf(m_socketfd, "widget_add M17 Mode string");
|
||||||
|
socketPrintf(m_socketfd, "widget_add M17 Line2 scroller");
|
||||||
|
socketPrintf(m_socketfd, "widget_add M17 Line3 scroller");
|
||||||
|
socketPrintf(m_socketfd, "widget_add M17 Line4 scroller");
|
||||||
|
|
||||||
|
/* Do we need to pre-populate the values??
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line3 2 1 15 1 h 3 \"Listening\"");
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line3 3 1 15 1 h 3 \" \"");
|
||||||
|
socketPrintf(m_socketfd, "widget_set M17 Line4 4 2 15 2 h 3 \" \"");
|
||||||
|
*/
|
||||||
|
|
||||||
m_screensDefined = true;
|
m_screensDefined = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
class CLCDproc : public CDisplay
|
class CLCDproc : public CDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CLCDproc(std::string address, unsigned int port, unsigned int localPort, const std::string& callsign, unsigned int dmrid, bool displayClock, bool utc, bool duplex, bool dimOnIdle);
|
CLCDproc(std::string address, unsigned int port, unsigned short localPort, const std::string& callsign, unsigned int dmrid, bool displayClock, bool utc, bool duplex, bool dimOnIdle);
|
||||||
virtual ~CLCDproc();
|
virtual ~CLCDproc();
|
||||||
|
|
||||||
virtual bool open();
|
virtual bool open();
|
||||||
|
@ -62,6 +62,10 @@ protected:
|
||||||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
||||||
virtual void clearNXDNInt();
|
virtual void clearNXDNInt();
|
||||||
|
|
||||||
|
virtual void writeM17Int(const char* source, const char* dest, const char* type);
|
||||||
|
virtual void writeM17RSSIInt(unsigned char rssi);
|
||||||
|
virtual void clearM17Int();
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||||
virtual void clearPOCSAGInt();
|
virtual void clearPOCSAGInt();
|
||||||
|
|
||||||
|
@ -73,7 +77,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
std::string m_address;
|
std::string m_address;
|
||||||
unsigned int m_port;
|
unsigned int m_port;
|
||||||
unsigned int m_localPort;
|
unsigned short m_localPort;
|
||||||
std::string m_callsign;
|
std::string m_callsign;
|
||||||
unsigned int m_dmrid;
|
unsigned int m_dmrid;
|
||||||
bool m_displayClock;
|
bool m_displayClock;
|
||||||
|
|
2
Log.cpp
2
Log.cpp
|
@ -161,7 +161,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
||||||
|
|
||||||
struct tm* tm = ::gmtime(&now.tv_sec);
|
struct tm* tm = ::gmtime(&now.tv_sec);
|
||||||
|
|
||||||
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03ld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000L);
|
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03lld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000LL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_list vl;
|
va_list vl;
|
||||||
|
|
176
MMDVM.ini
176
MMDVM.ini
|
@ -1,6 +1,6 @@
|
||||||
[General]
|
[General]
|
||||||
Callsign=G9BF
|
Callsign=MUTRPT
|
||||||
Id=123456
|
Id=1337
|
||||||
Timeout=180
|
Timeout=180
|
||||||
Duplex=1
|
Duplex=1
|
||||||
# ModeHang=10
|
# ModeHang=10
|
||||||
|
@ -31,16 +31,23 @@ Time=10
|
||||||
File=DMRIds.dat
|
File=DMRIds.dat
|
||||||
Time=24
|
Time=24
|
||||||
|
|
||||||
[NXDN Id Lookup]
|
|
||||||
File=NXDN.csv
|
|
||||||
Time=24
|
|
||||||
|
|
||||||
[Modem]
|
[Modem]
|
||||||
# Port=/dev/ttyACM0
|
# Valid values are "null", "uart", "udp", and (on Linux) "i2c"
|
||||||
# Port=/dev/ttyAMA0
|
|
||||||
Port=\\.\COM4
|
|
||||||
Protocol=uart
|
Protocol=uart
|
||||||
# Address=0x22
|
# The port and speed used for a UART connection
|
||||||
|
# UARTPort=\\.\COM4
|
||||||
|
# UARTPort=/dev/ttyACM0
|
||||||
|
UARTPort=/dev/ttyAMA0
|
||||||
|
UARTSpeed=460800
|
||||||
|
# The port and address for an I2C connection
|
||||||
|
I2CPort=/dev/i2c
|
||||||
|
I2CAddress=0x22
|
||||||
|
# IP parameters for UDP connection
|
||||||
|
ModemAddress=192.168.2.100
|
||||||
|
ModemPort=3334
|
||||||
|
LocalAddress=192.168.2.1
|
||||||
|
LocalPort=3335
|
||||||
|
|
||||||
TXInvert=1
|
TXInvert=1
|
||||||
RXInvert=0
|
RXInvert=0
|
||||||
PTTInvert=0
|
PTTInvert=0
|
||||||
|
@ -53,14 +60,7 @@ TXLevel=50
|
||||||
RXDCOffset=0
|
RXDCOffset=0
|
||||||
TXDCOffset=0
|
TXDCOffset=0
|
||||||
RFLevel=100
|
RFLevel=100
|
||||||
# CWIdTXLevel=50
|
DMRTXLevel=50
|
||||||
# D-StarTXLevel=50
|
|
||||||
# DMRTXLevel=50
|
|
||||||
# YSFTXLevel=50
|
|
||||||
# P25TXLevel=50
|
|
||||||
# NXDNTXLevel=50
|
|
||||||
# POCSAGTXLevel=50
|
|
||||||
# FMTXLevel=50
|
|
||||||
RSSIMappingFile=RSSI.dat
|
RSSIMappingFile=RSSI.dat
|
||||||
UseCOSAsLockout=0
|
UseCOSAsLockout=0
|
||||||
Trace=0
|
Trace=0
|
||||||
|
@ -73,29 +73,12 @@ RemotePort=40094
|
||||||
LocalPort=40095
|
LocalPort=40095
|
||||||
# SendFrameType=0
|
# SendFrameType=0
|
||||||
|
|
||||||
[UMP]
|
|
||||||
Enable=0
|
|
||||||
# Port=\\.\COM4
|
|
||||||
Port=/dev/ttyACM1
|
|
||||||
|
|
||||||
[D-Star]
|
|
||||||
Enable=1
|
|
||||||
Module=C
|
|
||||||
SelfOnly=0
|
|
||||||
AckReply=1
|
|
||||||
AckTime=750
|
|
||||||
AckMessage=0
|
|
||||||
ErrorReply=1
|
|
||||||
RemoteGateway=0
|
|
||||||
# ModeHang=10
|
|
||||||
WhiteList=
|
|
||||||
|
|
||||||
[DMR]
|
[DMR]
|
||||||
Enable=1
|
Enable=1
|
||||||
Beacons=0
|
Beacons=0
|
||||||
BeaconInterval=60
|
BeaconInterval=60
|
||||||
BeaconDuration=3
|
BeaconDuration=3
|
||||||
ColorCode=1
|
ColorCode=7
|
||||||
SelfOnly=0
|
SelfOnly=0
|
||||||
EmbeddedLCOnly=0
|
EmbeddedLCOnly=0
|
||||||
DumpTAData=1
|
DumpTAData=1
|
||||||
|
@ -105,124 +88,23 @@ DumpTAData=1
|
||||||
CallHang=3
|
CallHang=3
|
||||||
TXHang=4
|
TXHang=4
|
||||||
# ModeHang=10
|
# ModeHang=10
|
||||||
# OVCM Values, 0=off, 1=rx_on, 2=tx_on, 3=both_on
|
# OVCM Values, 0=off, 1=rx_on, 2=tx_on, 3=both_on, 4=force off
|
||||||
# OVCM=0
|
# OVCM=0
|
||||||
|
|
||||||
[System Fusion]
|
|
||||||
Enable=1
|
|
||||||
LowDeviation=0
|
|
||||||
SelfOnly=0
|
|
||||||
TXHang=4
|
|
||||||
RemoteGateway=0
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[P25]
|
|
||||||
Enable=1
|
|
||||||
NAC=293
|
|
||||||
SelfOnly=0
|
|
||||||
OverrideUIDCheck=0
|
|
||||||
RemoteGateway=0
|
|
||||||
TXHang=5
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[NXDN]
|
|
||||||
Enable=1
|
|
||||||
RAN=1
|
|
||||||
SelfOnly=0
|
|
||||||
RemoteGateway=0
|
|
||||||
TXHang=5
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[POCSAG]
|
|
||||||
Enable=1
|
|
||||||
Frequency=439987500
|
|
||||||
|
|
||||||
[FM]
|
|
||||||
Enable=1
|
|
||||||
# Callsign=G4KLX
|
|
||||||
CallsignSpeed=20
|
|
||||||
CallsignFrequency=1000
|
|
||||||
CallsignTime=10
|
|
||||||
CallsignHoldoff=0
|
|
||||||
CallsignHighLevel=50
|
|
||||||
CallsignLowLevel=20
|
|
||||||
CallsignAtStart=1
|
|
||||||
CallsignAtEnd=1
|
|
||||||
CallsignAtLatch=0
|
|
||||||
RFAck=K
|
|
||||||
ExtAck=N
|
|
||||||
AckSpeed=20
|
|
||||||
AckFrequency=1750
|
|
||||||
AckMinTime=4
|
|
||||||
AckDelay=1000
|
|
||||||
AckLevel=50
|
|
||||||
# Timeout=180
|
|
||||||
TimeoutLevel=80
|
|
||||||
CTCSSFrequency=88.4
|
|
||||||
CTCSSThreshold=30
|
|
||||||
# CTCSSHighThreshold=30
|
|
||||||
# CTCSSLowThreshold=20
|
|
||||||
CTCSSLevel=20
|
|
||||||
KerchunkTime=0
|
|
||||||
HangTime=7
|
|
||||||
AccessMode=1
|
|
||||||
COSInvert=0
|
|
||||||
RFAudioBoost=1
|
|
||||||
MaxDevLevel=90
|
|
||||||
ExtAudioBoost=1
|
|
||||||
|
|
||||||
[D-Star Network]
|
|
||||||
Enable=1
|
|
||||||
GatewayAddress=127.0.0.1
|
|
||||||
GatewayPort=20010
|
|
||||||
LocalPort=20011
|
|
||||||
# ModeHang=3
|
|
||||||
Debug=0
|
|
||||||
|
|
||||||
[DMR Network]
|
[DMR Network]
|
||||||
Enable=1
|
Enable=1
|
||||||
Address=127.0.0.1
|
# Type may be either 'Direct' or 'Gateway'. When Direct you must provide the Master's
|
||||||
Port=62031
|
# address as well as the Password, and for DMR+, Options also.
|
||||||
Local=62032
|
Type=Direct
|
||||||
|
LocalAddress=127.0.0.1
|
||||||
|
LocalPort=62032
|
||||||
|
RemoteAddress=127.0.0.1
|
||||||
|
RemotePort=62031
|
||||||
|
# Password=P@ssw0rd1234
|
||||||
Jitter=360
|
Jitter=360
|
||||||
Slot1=1
|
Slot1=1
|
||||||
Slot2=1
|
Slot2=1
|
||||||
# ModeHang=3
|
# Options=
|
||||||
Debug=0
|
|
||||||
|
|
||||||
[System Fusion Network]
|
|
||||||
Enable=1
|
|
||||||
LocalAddress=127.0.0.1
|
|
||||||
LocalPort=3200
|
|
||||||
GatewayAddress=127.0.0.1
|
|
||||||
GatewayPort=4200
|
|
||||||
# ModeHang=3
|
|
||||||
Debug=0
|
|
||||||
|
|
||||||
[P25 Network]
|
|
||||||
Enable=1
|
|
||||||
GatewayAddress=127.0.0.1
|
|
||||||
GatewayPort=42020
|
|
||||||
LocalPort=32010
|
|
||||||
# ModeHang=3
|
|
||||||
Debug=0
|
|
||||||
|
|
||||||
[NXDN Network]
|
|
||||||
Enable=1
|
|
||||||
Protocol=Icom
|
|
||||||
LocalAddress=127.0.0.1
|
|
||||||
LocalPort=14021
|
|
||||||
GatewayAddress=127.0.0.1
|
|
||||||
GatewayPort=14020
|
|
||||||
# ModeHang=3
|
|
||||||
Debug=0
|
|
||||||
|
|
||||||
[POCSAG Network]
|
|
||||||
Enable=1
|
|
||||||
LocalAddress=127.0.0.1
|
|
||||||
LocalPort=3800
|
|
||||||
GatewayAddress=127.0.0.1
|
|
||||||
GatewayPort=4800
|
|
||||||
# ModeHang=3
|
# ModeHang=3
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
|
|
1300
MMDVMHost.cpp
1300
MMDVMHost.cpp
File diff suppressed because it is too large
Load diff
61
MMDVMHost.h
61
MMDVMHost.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,25 +20,30 @@
|
||||||
#define MMDVMHOST_H
|
#define MMDVMHOST_H
|
||||||
|
|
||||||
#include "RemoteControl.h"
|
#include "RemoteControl.h"
|
||||||
#include "POCSAGNetwork.h"
|
//#include "POCSAGNetwork.h"
|
||||||
#include "POCSAGControl.h"
|
//#include "POCSAGControl.h"
|
||||||
#include "DStarNetwork.h"
|
//#include "DStarNetwork.h"
|
||||||
#include "NXDNNetwork.h"
|
//#include "AX25Network.h"
|
||||||
#include "DStarControl.h"
|
//#include "NXDNNetwork.h"
|
||||||
|
//#include "DStarControl.h"
|
||||||
|
//#include "AX25Control.h"
|
||||||
#include "DMRControl.h"
|
#include "DMRControl.h"
|
||||||
#include "YSFControl.h"
|
//#include "YSFControl.h"
|
||||||
#include "P25Control.h"
|
//#include "P25Control.h"
|
||||||
#include "NXDNControl.h"
|
//#include "NXDNControl.h"
|
||||||
#include "NXDNLookup.h"
|
//#include "M17Control.h"
|
||||||
#include "YSFNetwork.h"
|
//#include "NXDNLookup.h"
|
||||||
#include "P25Network.h"
|
//#include "YSFNetwork.h"
|
||||||
|
//#include "P25Network.h"
|
||||||
#include "DMRNetwork.h"
|
#include "DMRNetwork.h"
|
||||||
|
//#include "M17Network.h"
|
||||||
|
//#include "FMNetwork.h"
|
||||||
#include "DMRLookup.h"
|
#include "DMRLookup.h"
|
||||||
#include "Display.h"
|
//#include "FMControl.h"
|
||||||
|
//#include "Display.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Modem.h"
|
#include "Modem.h"
|
||||||
#include "Conf.h"
|
#include "Conf.h"
|
||||||
#include "UMP.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -51,35 +56,33 @@ public:
|
||||||
|
|
||||||
int run();
|
int run();
|
||||||
|
|
||||||
|
void buildNetworkStatusString(std::string &str);
|
||||||
|
void buildNetworkHostsString(std::string &str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CConf m_conf;
|
CConf m_conf;
|
||||||
CModem* m_modem;
|
CModem* m_modem;
|
||||||
CDStarControl* m_dstar;
|
|
||||||
CDMRControl* m_dmr;
|
CDMRControl* m_dmr;
|
||||||
CYSFControl* m_ysf;
|
|
||||||
CP25Control* m_p25;
|
IDMRNetwork* m_dmrNetwork;
|
||||||
CNXDNControl* m_nxdn;
|
|
||||||
CPOCSAGControl* m_pocsag;
|
|
||||||
CDStarNetwork* m_dstarNetwork;
|
|
||||||
CDMRNetwork* m_dmrNetwork;
|
|
||||||
CYSFNetwork* m_ysfNetwork;
|
|
||||||
CP25Network* m_p25Network;
|
|
||||||
INXDNNetwork* m_nxdnNetwork;
|
|
||||||
CPOCSAGNetwork* m_pocsagNetwork;
|
|
||||||
CDisplay* m_display;
|
CDisplay* m_display;
|
||||||
CUMP* m_ump;
|
|
||||||
unsigned char m_mode;
|
unsigned char m_mode;
|
||||||
unsigned int m_dstarRFModeHang;
|
unsigned int m_dstarRFModeHang;
|
||||||
unsigned int m_dmrRFModeHang;
|
unsigned int m_dmrRFModeHang;
|
||||||
unsigned int m_ysfRFModeHang;
|
unsigned int m_ysfRFModeHang;
|
||||||
unsigned int m_p25RFModeHang;
|
unsigned int m_p25RFModeHang;
|
||||||
unsigned int m_nxdnRFModeHang;
|
unsigned int m_nxdnRFModeHang;
|
||||||
|
unsigned int m_m17RFModeHang;
|
||||||
|
unsigned int m_fmRFModeHang;
|
||||||
unsigned int m_dstarNetModeHang;
|
unsigned int m_dstarNetModeHang;
|
||||||
unsigned int m_dmrNetModeHang;
|
unsigned int m_dmrNetModeHang;
|
||||||
unsigned int m_ysfNetModeHang;
|
unsigned int m_ysfNetModeHang;
|
||||||
unsigned int m_p25NetModeHang;
|
unsigned int m_p25NetModeHang;
|
||||||
unsigned int m_nxdnNetModeHang;
|
unsigned int m_nxdnNetModeHang;
|
||||||
|
unsigned int m_m17NetModeHang;
|
||||||
unsigned int m_pocsagNetModeHang;
|
unsigned int m_pocsagNetModeHang;
|
||||||
|
unsigned int m_fmNetModeHang;
|
||||||
CTimer m_modeTimer;
|
CTimer m_modeTimer;
|
||||||
CTimer m_dmrTXTimer;
|
CTimer m_dmrTXTimer;
|
||||||
CTimer m_cwIdTimer;
|
CTimer m_cwIdTimer;
|
||||||
|
@ -90,11 +93,12 @@ private:
|
||||||
bool m_ysfEnabled;
|
bool m_ysfEnabled;
|
||||||
bool m_p25Enabled;
|
bool m_p25Enabled;
|
||||||
bool m_nxdnEnabled;
|
bool m_nxdnEnabled;
|
||||||
|
bool m_m17Enabled;
|
||||||
bool m_pocsagEnabled;
|
bool m_pocsagEnabled;
|
||||||
bool m_fmEnabled;
|
bool m_fmEnabled;
|
||||||
|
bool m_ax25Enabled;
|
||||||
unsigned int m_cwIdTime;
|
unsigned int m_cwIdTime;
|
||||||
CDMRLookup* m_dmrLookup;
|
CDMRLookup* m_dmrLookup;
|
||||||
CNXDNLookup* m_nxdnLookup;
|
|
||||||
std::string m_callsign;
|
std::string m_callsign;
|
||||||
unsigned int m_id;
|
unsigned int m_id;
|
||||||
std::string m_cwCallsign;
|
std::string m_cwCallsign;
|
||||||
|
@ -110,7 +114,10 @@ private:
|
||||||
bool createYSFNetwork();
|
bool createYSFNetwork();
|
||||||
bool createP25Network();
|
bool createP25Network();
|
||||||
bool createNXDNNetwork();
|
bool createNXDNNetwork();
|
||||||
|
bool createM17Network();
|
||||||
bool createPOCSAGNetwork();
|
bool createPOCSAGNetwork();
|
||||||
|
bool createFMNetwork();
|
||||||
|
bool createAX25Network();
|
||||||
|
|
||||||
void remoteControl();
|
void remoteControl();
|
||||||
void processModeCommand(unsigned char mode, unsigned int timeout);
|
void processModeCommand(unsigned char mode, unsigned int timeout);
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
VisualStudioVersion = 15.0.28307.271
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MMDVMHost", "MMDVMHost.vcxproj", "{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RemoteCommand", "RemoteCommand.vcxproj", "{5A61AB93-58BB-413A-BBD9-A26284CB37AE}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x64.Build.0 = Release|x64
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}.Release|x86.Build.0 = Release|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x64.Build.0 = Release|x64
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{5A61AB93-58BB-413A-BBD9-A26284CB37AE}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {4FE84D69-7345-440E-8E0A-0CC1C84477F8}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,344 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{1D34E8C1-CFA5-4D60-B509-9DB58DC4AE92}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>MMDVMHost</RootNamespace>
|
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>HAVE_LOG_H;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Command>"$(ProjectDir)prebuild.cmd" $(ProjectDir)</Command>
|
|
||||||
</PreBuildEvent>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Message>prebuild.cmd generates GitVersion.h from git refs heads master</Message>
|
|
||||||
</PreBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>HAVE_LOG_H;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="AMBEFEC.h" />
|
|
||||||
<ClInclude Include="BCH.h" />
|
|
||||||
<ClInclude Include="BPTC19696.h" />
|
|
||||||
<ClInclude Include="CASTInfo.h" />
|
|
||||||
<ClInclude Include="Conf.h" />
|
|
||||||
<ClInclude Include="CRC.h" />
|
|
||||||
<ClInclude Include="Defines.h" />
|
|
||||||
<ClInclude Include="Display.h" />
|
|
||||||
<ClInclude Include="DMRAccessControl.h" />
|
|
||||||
<ClInclude Include="DMRControl.h" />
|
|
||||||
<ClInclude Include="DMRCSBK.h" />
|
|
||||||
<ClInclude Include="DMRData.h" />
|
|
||||||
<ClInclude Include="DMRDataHeader.h" />
|
|
||||||
<ClInclude Include="DMRDefines.h" />
|
|
||||||
<ClInclude Include="DMREMB.h" />
|
|
||||||
<ClInclude Include="DMREmbeddedData.h" />
|
|
||||||
<ClInclude Include="DMRFullLC.h" />
|
|
||||||
<ClInclude Include="DMRLC.h" />
|
|
||||||
<ClInclude Include="DMRNetwork.h" />
|
|
||||||
<ClInclude Include="DMRShortLC.h" />
|
|
||||||
<ClInclude Include="DMRSlot.h" />
|
|
||||||
<ClInclude Include="DMRSlotType.h" />
|
|
||||||
<ClInclude Include="DMRTA.h" />
|
|
||||||
<ClInclude Include="DMRTrellis.h" />
|
|
||||||
<ClInclude Include="DStarControl.h" />
|
|
||||||
<ClInclude Include="DStarDefines.h" />
|
|
||||||
<ClInclude Include="DStarHeader.h" />
|
|
||||||
<ClInclude Include="DStarNetwork.h" />
|
|
||||||
<ClInclude Include="DStarSlowData.h" />
|
|
||||||
<ClInclude Include="Golay2087.h" />
|
|
||||||
<ClInclude Include="Golay24128.h" />
|
|
||||||
<ClInclude Include="Hamming.h" />
|
|
||||||
<ClInclude Include="DMRLookup.h" />
|
|
||||||
<ClInclude Include="I2CController.h" />
|
|
||||||
<ClInclude Include="LCDproc.h" />
|
|
||||||
<ClInclude Include="Log.h" />
|
|
||||||
<ClInclude Include="MMDVMHost.h" />
|
|
||||||
<ClInclude Include="Modem.h" />
|
|
||||||
<ClInclude Include="ModemSerialPort.h" />
|
|
||||||
<ClInclude Include="Mutex.h" />
|
|
||||||
<ClInclude Include="NetworkInfo.h" />
|
|
||||||
<ClInclude Include="Nextion.h" />
|
|
||||||
<ClInclude Include="NullDisplay.h" />
|
|
||||||
<ClInclude Include="NullModem.h" />
|
|
||||||
<ClInclude Include="NXDNAudio.h" />
|
|
||||||
<ClInclude Include="NXDNControl.h" />
|
|
||||||
<ClInclude Include="NXDNConvolution.h" />
|
|
||||||
<ClInclude Include="NXDNCRC.h" />
|
|
||||||
<ClInclude Include="NXDNDefines.h" />
|
|
||||||
<ClInclude Include="NXDNFACCH1.h" />
|
|
||||||
<ClInclude Include="NXDNIcomNetwork.h" />
|
|
||||||
<ClInclude Include="NXDNKenwoodNetwork.h" />
|
|
||||||
<ClInclude Include="NXDNLayer3.h" />
|
|
||||||
<ClInclude Include="NXDNLICH.h" />
|
|
||||||
<ClInclude Include="NXDNLookup.h" />
|
|
||||||
<ClInclude Include="NXDNNetwork.h" />
|
|
||||||
<ClInclude Include="NXDNUDCH.h" />
|
|
||||||
<ClInclude Include="P25Audio.h" />
|
|
||||||
<ClInclude Include="P25Control.h" />
|
|
||||||
<ClInclude Include="P25Defines.h" />
|
|
||||||
<ClInclude Include="P25Data.h" />
|
|
||||||
<ClInclude Include="P25LowSpeedData.h" />
|
|
||||||
<ClInclude Include="P25Network.h" />
|
|
||||||
<ClInclude Include="P25NID.h" />
|
|
||||||
<ClInclude Include="P25Trellis.h" />
|
|
||||||
<ClInclude Include="P25Utils.h" />
|
|
||||||
<ClInclude Include="POCSAGControl.h" />
|
|
||||||
<ClInclude Include="POCSAGDefines.h" />
|
|
||||||
<ClInclude Include="POCSAGNetwork.h" />
|
|
||||||
<ClInclude Include="QR1676.h" />
|
|
||||||
<ClInclude Include="RemoteControl.h" />
|
|
||||||
<ClInclude Include="RingBuffer.h" />
|
|
||||||
<ClInclude Include="RS129.h" />
|
|
||||||
<ClInclude Include="RS241213.h" />
|
|
||||||
<ClInclude Include="RSSIInterpolator.h" />
|
|
||||||
<ClInclude Include="NXDNSACCH.h" />
|
|
||||||
<ClInclude Include="SerialController.h" />
|
|
||||||
<ClInclude Include="SerialPort.h" />
|
|
||||||
<ClInclude Include="StopWatch.h" />
|
|
||||||
<ClInclude Include="Sync.h" />
|
|
||||||
<ClInclude Include="TFTSerial.h" />
|
|
||||||
<ClInclude Include="TFTSurenoo.h" />
|
|
||||||
<ClInclude Include="Thread.h" />
|
|
||||||
<ClInclude Include="Timer.h" />
|
|
||||||
<ClInclude Include="UDPSocket.h" />
|
|
||||||
<ClInclude Include="UMP.h" />
|
|
||||||
<ClInclude Include="UserDB.h" />
|
|
||||||
<ClInclude Include="UserDBentry.h" />
|
|
||||||
<ClInclude Include="Utils.h" />
|
|
||||||
<ClInclude Include="Version.h" />
|
|
||||||
<ClInclude Include="YSFControl.h" />
|
|
||||||
<ClInclude Include="YSFConvolution.h" />
|
|
||||||
<ClInclude Include="YSFDefines.h" />
|
|
||||||
<ClInclude Include="YSFFICH.h" />
|
|
||||||
<ClInclude Include="YSFNetwork.h" />
|
|
||||||
<ClInclude Include="YSFPayload.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="AMBEFEC.cpp" />
|
|
||||||
<ClCompile Include="BCH.cpp" />
|
|
||||||
<ClCompile Include="BPTC19696.cpp" />
|
|
||||||
<ClCompile Include="CASTInfo.cpp" />
|
|
||||||
<ClCompile Include="Conf.cpp" />
|
|
||||||
<ClCompile Include="CRC.cpp" />
|
|
||||||
<ClCompile Include="Display.cpp" />
|
|
||||||
<ClCompile Include="DMRAccessControl.cpp" />
|
|
||||||
<ClCompile Include="DMRControl.cpp" />
|
|
||||||
<ClCompile Include="DMRCSBK.cpp" />
|
|
||||||
<ClCompile Include="DMRData.cpp" />
|
|
||||||
<ClCompile Include="DMRDataHeader.cpp" />
|
|
||||||
<ClCompile Include="DMREMB.cpp" />
|
|
||||||
<ClCompile Include="DMREmbeddedData.cpp" />
|
|
||||||
<ClCompile Include="DMRFullLC.cpp" />
|
|
||||||
<ClCompile Include="DMRLC.cpp" />
|
|
||||||
<ClCompile Include="DMRLookup.cpp" />
|
|
||||||
<ClCompile Include="DMRNetwork.cpp" />
|
|
||||||
<ClCompile Include="DMRShortLC.cpp" />
|
|
||||||
<ClCompile Include="DMRSlot.cpp" />
|
|
||||||
<ClCompile Include="DMRSlotType.cpp" />
|
|
||||||
<ClCompile Include="DMRTA.cpp" />
|
|
||||||
<ClCompile Include="DMRTrellis.cpp" />
|
|
||||||
<ClCompile Include="DStarControl.cpp" />
|
|
||||||
<ClCompile Include="DStarHeader.cpp" />
|
|
||||||
<ClCompile Include="DStarNetwork.cpp" />
|
|
||||||
<ClCompile Include="DStarSlowData.cpp" />
|
|
||||||
<ClCompile Include="Golay2087.cpp" />
|
|
||||||
<ClCompile Include="Golay24128.cpp" />
|
|
||||||
<ClCompile Include="Hamming.cpp" />
|
|
||||||
<ClCompile Include="I2CController.cpp" />
|
|
||||||
<ClCompile Include="LCDproc.cpp" />
|
|
||||||
<ClCompile Include="Log.cpp" />
|
|
||||||
<ClCompile Include="MMDVMHost.cpp" />
|
|
||||||
<ClCompile Include="Modem.cpp" />
|
|
||||||
<ClCompile Include="ModemSerialPort.cpp" />
|
|
||||||
<ClCompile Include="Mutex.cpp" />
|
|
||||||
<ClCompile Include="NetworkInfo.cpp" />
|
|
||||||
<ClCompile Include="Nextion.cpp" />
|
|
||||||
<ClCompile Include="NullDisplay.cpp" />
|
|
||||||
<ClCompile Include="NullModem.cpp" />
|
|
||||||
<ClCompile Include="NXDNAudio.cpp" />
|
|
||||||
<ClCompile Include="NXDNControl.cpp" />
|
|
||||||
<ClCompile Include="NXDNConvolution.cpp" />
|
|
||||||
<ClCompile Include="NXDNCRC.cpp" />
|
|
||||||
<ClCompile Include="NXDNFACCH1.cpp" />
|
|
||||||
<ClCompile Include="NXDNIcomNetwork.cpp" />
|
|
||||||
<ClCompile Include="NXDNKenwoodNetwork.cpp" />
|
|
||||||
<ClCompile Include="NXDNLayer3.cpp" />
|
|
||||||
<ClCompile Include="NXDNLICH.cpp" />
|
|
||||||
<ClCompile Include="NXDNLookup.cpp" />
|
|
||||||
<ClCompile Include="NXDNNetwork.cpp" />
|
|
||||||
<ClCompile Include="NXDNSACCH.cpp" />
|
|
||||||
<ClCompile Include="NXDNUDCH.cpp" />
|
|
||||||
<ClCompile Include="P25Audio.cpp" />
|
|
||||||
<ClCompile Include="P25Control.cpp" />
|
|
||||||
<ClCompile Include="P25Data.cpp" />
|
|
||||||
<ClCompile Include="P25LowSpeedData.cpp" />
|
|
||||||
<ClCompile Include="P25Network.cpp" />
|
|
||||||
<ClCompile Include="P25NID.cpp" />
|
|
||||||
<ClCompile Include="P25Trellis.cpp" />
|
|
||||||
<ClCompile Include="P25Utils.cpp" />
|
|
||||||
<ClCompile Include="POCSAGControl.cpp" />
|
|
||||||
<ClCompile Include="POCSAGNetwork.cpp" />
|
|
||||||
<ClCompile Include="QR1676.cpp" />
|
|
||||||
<ClCompile Include="RemoteControl.cpp" />
|
|
||||||
<ClCompile Include="RS129.cpp" />
|
|
||||||
<ClCompile Include="RS241213.cpp" />
|
|
||||||
<ClCompile Include="RSSIInterpolator.cpp" />
|
|
||||||
<ClCompile Include="SerialController.cpp" />
|
|
||||||
<ClCompile Include="SerialPort.cpp" />
|
|
||||||
<ClCompile Include="StopWatch.cpp" />
|
|
||||||
<ClCompile Include="Sync.cpp" />
|
|
||||||
<ClCompile Include="TFTSerial.cpp" />
|
|
||||||
<ClCompile Include="TFTSurenoo.cpp" />
|
|
||||||
<ClCompile Include="Thread.cpp" />
|
|
||||||
<ClCompile Include="Timer.cpp" />
|
|
||||||
<ClCompile Include="UDPSocket.cpp" />
|
|
||||||
<ClCompile Include="UMP.cpp" />
|
|
||||||
<ClCompile Include="UserDB.cpp" />
|
|
||||||
<ClCompile Include="UserDBentry.cpp" />
|
|
||||||
<ClCompile Include="Utils.cpp" />
|
|
||||||
<ClCompile Include="YSFNetwork.cpp" />
|
|
||||||
<ClCompile Include="YSFPayload.cpp" />
|
|
||||||
<ClCompile Include="YSFControl.cpp" />
|
|
||||||
<ClCompile Include="YSFConvolution.cpp" />
|
|
||||||
<ClCompile Include="YSFFICH.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
|
@ -1,566 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="BPTC19696.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Conf.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="CRC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Defines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Display.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRData.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRDefines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRSlot.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DStarDefines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Golay2087.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Golay24128.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Hamming.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Log.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="MMDVMHost.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Modem.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NullDisplay.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="QR1676.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="RemoteControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="RingBuffer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="RS129.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="SerialController.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="StopWatch.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="TFTSerial.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Timer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="UDPSocket.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Utils.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFDefines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Version.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="AMBEFEC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DStarNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRDataHeader.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DStarHeader.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DStarSlowData.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DStarControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFConvolution.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFFICH.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRCSBK.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Sync.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMREMB.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMREmbeddedData.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRFullLC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRLC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRShortLC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRSlotType.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFPayload.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Nextion.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRLookup.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="YSFNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Thread.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRTrellis.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRAccessControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Defines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Control.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25NID.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Audio.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Data.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Utils.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25LowSpeedData.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Network.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="BCH.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="RS241213.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="SerialPort.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ModemSerialPort.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Mutex.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="LCDproc.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="UMP.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="RSSIInterpolator.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NetworkInfo.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="P25Trellis.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNDefines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNLICH.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNConvolution.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNCRC.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNLookup.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNSACCH.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNFACCH1.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNUDCH.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNLayer3.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNAudio.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="POCSAGNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="POCSAGControl.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="POCSAGDefines.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="I2CController.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NullModem.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRTA.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="CASTInfo.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="TFTSurenoo.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="UserDB.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="UserDBentry.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNIcomNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NXDNKenwoodNetwork.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="BPTC19696.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Conf.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CRC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Display.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRData.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRSlot.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Golay2087.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Golay24128.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Hamming.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Log.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="MMDVMHost.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Modem.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NullDisplay.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="QR1676.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="RemoteControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="RS129.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SerialController.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="StopWatch.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="TFTSerial.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Timer.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="UDPSocket.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Utils.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="AMBEFEC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DStarNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRDataHeader.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DStarHeader.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DStarSlowData.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DStarControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="YSFConvolution.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="YSFFICH.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRCSBK.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Sync.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMREMB.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMREmbeddedData.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRFullLC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRLC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRShortLC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRSlotType.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="YSFControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="YSFPayload.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Nextion.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRLookup.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="YSFNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Thread.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRTrellis.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRAccessControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Control.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25NID.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Audio.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Data.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Utils.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25LowSpeedData.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Network.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="BCH.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="RS241213.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SerialPort.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ModemSerialPort.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Mutex.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="LCDproc.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="UMP.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="RSSIInterpolator.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NetworkInfo.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="P25Trellis.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNLICH.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNConvolution.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNCRC.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNLookup.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNSACCH.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNFACCH1.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNUDCH.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNLayer3.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNAudio.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="POCSAGNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="POCSAGControl.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="I2CController.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NullModem.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRTA.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CASTInfo.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="TFTSurenoo.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="UserDB.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="UserDBentry.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNIcomNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NXDNKenwoodNetwork.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
46
Makefile
46
Makefile
|
@ -2,19 +2,18 @@
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
CXX = c++
|
CXX = c++
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H
|
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -I/usr/local/include
|
||||||
LIBS = -lpthread
|
LIBS = -lpthread -lutil
|
||||||
LDFLAGS = -g
|
LDFLAGS = -g -L/usr/local/lib
|
||||||
|
|
||||||
OBJECTS = \
|
OBJECTS = \
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
DMRAccessControl.o DMRTA.o DMRTrellis.o Golay2087.o Golay24128.o\
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o \
|
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.o \
|
||||||
NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
|
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||||
P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o \
|
RemoteControl.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSurenoo.o Thread.o \
|
||||||
SerialController.o SerialPort.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o \
|
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||||
YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
all: MMDVMHost RemoteCommand
|
||||||
|
|
||||||
|
@ -27,10 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
install:
|
.PHONY install:
|
||||||
|
install: all
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
install -m 755 MMDVMHost /usr/local/bin/
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
install -m 755 RemoteCommand /usr/local/bin/
|
||||||
|
|
||||||
|
.PHONY install-service:
|
||||||
|
install-service: install /etc/MMDVM.ini
|
||||||
|
@useradd --user-group -M --system mmdvm --shell /bin/false || true
|
||||||
|
@usermod --groups dialout --append mmdvm || true
|
||||||
|
@mkdir /var/log/mmdvm || true
|
||||||
|
@chown mmdvm:mmdvm /var/log/mmdvm
|
||||||
|
@cp ./linux/systemd/mmdvmhost.service /lib/systemd/system/
|
||||||
|
@systemctl enable mmdvmhost.service
|
||||||
|
|
||||||
|
/etc/MMDVM.ini:
|
||||||
|
@cp -n MMDVM.ini /etc/MMDVM.ini
|
||||||
|
@sed -i 's/FilePath=./FilePath=\/var\/log\/mmdvm\//' /etc/MMDVM.ini
|
||||||
|
@sed -i 's/Daemon=0/Daemon=1/' /etc/MMDVM.ini
|
||||||
|
@chown mmdvm:mmdvm /etc/MMDVM.ini
|
||||||
|
|
||||||
|
.PHONY uninstall-service:
|
||||||
|
uninstall-service:
|
||||||
|
@systemctl stop mmdvmhost.service || true
|
||||||
|
@systemctl disable mmdvmhost.service || true
|
||||||
|
@rm -f /usr/local/bin/MMDVMHost || true
|
||||||
|
@rm -f /lib/systemd/system/mmdvmhost.service || true
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
||||||
|
|
||||||
|
|
42
Makefile.Pi
42
Makefile.Pi
|
@ -3,18 +3,17 @@
|
||||||
CC = cc
|
CC = cc
|
||||||
CXX = c++
|
CXX = c++
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DRASPBERRY_PI -I/usr/local/include
|
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DRASPBERRY_PI -I/usr/local/include
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
LIBS = -lwiringPi -lwiringPiDev -lpthread -lutil
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
LDFLAGS = -g -L/usr/local/lib
|
||||||
|
|
||||||
OBJECTS = \
|
OBJECTS = \
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
DMRAccessControl.o DMRTA.o DMRTrellis.o Golay2087.o Golay24128.o\
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o \
|
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.o \
|
||||||
NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
|
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||||
P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
RemoteControl.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSurenoo.o Thread.o \
|
||||||
StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
|
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
all: MMDVMHost RemoteCommand
|
||||||
|
|
||||||
|
@ -27,10 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
install:
|
.PHONY install:
|
||||||
|
install: all
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
install -m 755 MMDVMHost /usr/local/bin/
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
install -m 755 RemoteCommand /usr/local/bin/
|
||||||
|
|
||||||
|
.PHONY install-service:
|
||||||
|
install-service: install /etc/MMDVM.ini
|
||||||
|
@useradd --user-group -M --system mmdvm --shell /bin/false || true
|
||||||
|
@usermod --groups dialout --append mmdvm || true
|
||||||
|
@mkdir /var/log/mmdvm || true
|
||||||
|
@chown mmdvm:mmdvm /var/log/mmdvm
|
||||||
|
@cp ./linux/systemd/mmdvmhost.service /lib/systemd/system/
|
||||||
|
@systemctl enable mmdvmhost.service
|
||||||
|
|
||||||
|
/etc/MMDVM.ini:
|
||||||
|
@cp -n MMDVM.ini /etc/MMDVM.ini
|
||||||
|
@sed -i 's/FilePath=./FilePath=\/var\/log\/mmdvm\//' /etc/MMDVM.ini
|
||||||
|
@sed -i 's/Daemon=0/Daemon=1/' /etc/MMDVM.ini
|
||||||
|
@chown mmdvm:mmdvm /etc/MMDVM.ini
|
||||||
|
|
||||||
|
.PHONY uninstall-service:
|
||||||
|
uninstall-service:
|
||||||
|
@systemctl stop mmdvmhost.service || true
|
||||||
|
@systemctl disable mmdvmhost.service || true
|
||||||
|
@rm -f /usr/local/bin/MMDVMHost || true
|
||||||
|
@rm -f /lib/systemd/system/mmdvmhost.service || true
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an HD44780 compatible display. The wiringpi library is needed.
|
|
||||||
# Support for the Adafruit i2c 16 x 2 RGB LCD Pi Plate
|
|
||||||
|
|
||||||
CC = cc
|
|
||||||
CXX = c++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o \
|
|
||||||
NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
|
|
||||||
P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
|
||||||
StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
|
|
||||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
|
||||||
|
|
||||||
MMDVMHost: GitVersion.h $(OBJECTS)
|
|
||||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
|
||||||
|
|
||||||
RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|
||||||
$(CXX) Log.o RemoteCommand.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommand
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
install:
|
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
|
||||||
|
|
||||||
# Export the current git version if the index file exists, else 000...
|
|
||||||
GitVersion.h:
|
|
||||||
ifneq ("$(wildcard .git/index)","")
|
|
||||||
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
|
|
||||||
else
|
|
||||||
echo "const char *gitversion = \"0000000000000000000000000000000000000000\";" > $@
|
|
||||||
endif
|
|
|
@ -1,43 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an HD44780 compatible display. The wiringpi library is needed.
|
|
||||||
|
|
||||||
CC = cc
|
|
||||||
CXX = c++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DHD44780 -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o \
|
|
||||||
NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
|
|
||||||
P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
|
||||||
StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
|
|
||||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
|
||||||
|
|
||||||
MMDVMHost: GitVersion.h $(OBJECTS)
|
|
||||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
|
||||||
|
|
||||||
RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|
||||||
$(CXX) Log.o RemoteCommand.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommand
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
install:
|
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
|
||||||
|
|
||||||
# Export the current git version if the index file exists, else 000...
|
|
||||||
GitVersion.h:
|
|
||||||
ifneq ("$(wildcard .git/index)","")
|
|
||||||
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
|
|
||||||
else
|
|
||||||
echo "const char *gitversion = \"0000000000000000000000000000000000000000\";" > $@
|
|
||||||
endif
|
|
|
@ -1,48 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an OLED display. The wiringpi library is not needed.
|
|
||||||
|
|
||||||
CC = cc
|
|
||||||
CXX = c++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DOLED -I/usr/local/include
|
|
||||||
LIBS = -lArduiPi_OLED -lpthread
|
|
||||||
|
|
||||||
# If you use NetBSD, add following CFLAGS
|
|
||||||
#CFLAGS += -L/usr/local/lib -Wl,-rpath=/usr/local/lib
|
|
||||||
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o \
|
|
||||||
NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
|
|
||||||
P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
|
||||||
StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
|
|
||||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
|
||||||
|
|
||||||
MMDVMHost: GitVersion.h $(OBJECTS)
|
|
||||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
|
||||||
|
|
||||||
RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|
||||||
$(CXX) Log.o RemoteCommand.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommand
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
install:
|
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
|
||||||
|
|
||||||
# Export the current git version if the index file exists, else 000...
|
|
||||||
GitVersion.h:
|
|
||||||
ifneq ("$(wildcard .git/index)","")
|
|
||||||
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
|
|
||||||
else
|
|
||||||
echo "const char *gitversion = \"0000000000000000000000000000000000000000\";" > $@
|
|
||||||
endif
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an HD44780 compatible display. The wiringpi library is needed.
|
|
||||||
# Support for the HD44780 connected via a PCF8574 8-bit GPIO expander IC
|
|
||||||
|
|
||||||
CC = cc
|
|
||||||
CXX = c++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DHD44780 -DPCF8574_DISPLAY -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
|
||||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
|
||||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o \
|
|
||||||
NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o \
|
|
||||||
NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \
|
|
||||||
P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o \
|
|
||||||
StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
|
|
||||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
|
||||||
|
|
||||||
MMDVMHost: GitVersion.h $(OBJECTS)
|
|
||||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o MMDVMHost
|
|
||||||
|
|
||||||
RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|
||||||
$(CXX) Log.o RemoteCommand.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommand
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
install:
|
|
||||||
install -m 755 MMDVMHost /usr/local/bin/
|
|
||||||
install -m 755 RemoteCommand /usr/local/bin/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) MMDVMHost RemoteCommand *.o *.d *.bak *~ GitVersion.h
|
|
||||||
|
|
||||||
# Export the current git version if the index file exists, else 000...
|
|
||||||
GitVersion.h:
|
|
||||||
ifneq ("$(wildcard .git/index)","")
|
|
||||||
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
|
|
||||||
else
|
|
||||||
echo "const char *gitversion = \"0000000000000000000000000000000000000000\";" > $@
|
|
||||||
endif
|
|
220
Modem.h
220
Modem.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2018,2020 by Jonathan Naylor G4KLX
|
* Copyright (C) 2011-2018,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,10 +16,10 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MODEM_H
|
#ifndef Modem_H
|
||||||
#define MODEM_H
|
#define Modem_H
|
||||||
|
|
||||||
#include "SerialController.h"
|
#include "ModemPort.h"
|
||||||
#include "RingBuffer.h"
|
#include "RingBuffer.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
@ -32,96 +32,107 @@ enum RESP_TYPE_MMDVM {
|
||||||
RTM_ERROR
|
RTM_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SERIAL_STATE {
|
||||||
|
SS_START,
|
||||||
|
SS_LENGTH1,
|
||||||
|
SS_LENGTH2,
|
||||||
|
SS_TYPE,
|
||||||
|
SS_DATA
|
||||||
|
};
|
||||||
|
|
||||||
class CModem {
|
class CModem {
|
||||||
public:
|
public:
|
||||||
CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool useCOSAsLockout, bool trace, bool debug);
|
CModem(bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool useCOSAsLockout, bool trace, bool debug);
|
||||||
virtual ~CModem();
|
~CModem();
|
||||||
|
|
||||||
virtual void setSerialParams(const std::string& protocol, unsigned int address);
|
void setPort(IModemPort* port);
|
||||||
virtual void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel, unsigned int pocsagFrequency);
|
void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel);
|
||||||
virtual void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool pocsagEnabled, bool fmEnabled);
|
void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool m17Enabled, bool pocsagEnabled, bool fmEnabled, bool ax25Enabled);
|
||||||
virtual void setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagLevel, float fmTXLevel);
|
void setLevels(float rxLevel, float cwIdTXLevel, float dmrTXLevel);
|
||||||
virtual void setDMRParams(unsigned int colorCode);
|
void setDMRParams(unsigned int colorCode);
|
||||||
virtual void setYSFParams(bool loDev, unsigned int txHang);
|
void setYSFParams(bool loDev, unsigned int txHang);
|
||||||
virtual void setP25Params(unsigned int txHang);
|
void setP25Params(unsigned int txHang);
|
||||||
virtual void setNXDNParams(unsigned int txHang);
|
void setNXDNParams(unsigned int txHang);
|
||||||
virtual void setTransparentDataParams(unsigned int sendFrameType);
|
void setM17Params(unsigned int txHang);
|
||||||
|
void setAX25Params(int rxTwist, unsigned int txDelay, unsigned int slotTime, unsigned int pPersist);
|
||||||
|
void setTransparentDataParams(unsigned int sendFrameType);
|
||||||
|
|
||||||
virtual void setFMCallsignParams(const std::string& callsign, unsigned int callsignSpeed, unsigned int callsignFrequency, unsigned int callsignTime, unsigned int callsignHoldoff, float callsignHighLevel, float callsignLowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch);
|
void setFMCallsignParams(const std::string& callsign, unsigned int callsignSpeed, unsigned int callsignFrequency, unsigned int callsignTime, unsigned int callsignHoldoff, float callsignHighLevel, float callsignLowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch);
|
||||||
virtual void setFMAckParams(const std::string& rfAck, unsigned int ackSpeed, unsigned int ackFrequency, unsigned int ackMinTime, unsigned int ackDelay, float ackLevel);
|
void setFMAckParams(const std::string& rfAck, unsigned int ackSpeed, unsigned int ackFrequency, unsigned int ackMinTime, unsigned int ackDelay, float ackLevel);
|
||||||
virtual void setFMMiscParams(unsigned int timeout, float timeoutLevel, float ctcssFrequency, unsigned int ctcssHighThreshold, unsigned int ctcssLowThreshold, float ctcssLevel, unsigned int kerchunkTime, unsigned int hangTime, unsigned int accessMode, bool cosInvert, unsigned int rfAudioBoost, float maxDevLevel);
|
void setFMMiscParams(unsigned int timeout, float timeoutLevel, float ctcssFrequency, unsigned int ctcssHighThreshold, unsigned int ctcssLowThreshold, float ctcssLevel, unsigned int kerchunkTime, unsigned int hangTime, unsigned int accessMode, bool linkMode, bool cosInvert, bool noiseSquelch, unsigned int squelchHighThreshold, unsigned int squelchLowThreshold, unsigned int rfAudioBoost, float maxDevLevel);
|
||||||
|
void setFMExtParams(const std::string& ack, unsigned int audioBoost);
|
||||||
|
|
||||||
virtual bool open();
|
bool open();
|
||||||
|
|
||||||
virtual unsigned int readDStarData(unsigned char* data);
|
bool hasDStar() const;
|
||||||
virtual unsigned int readDMRData1(unsigned char* data);
|
bool hasDMR() const;
|
||||||
virtual unsigned int readDMRData2(unsigned char* data);
|
bool hasYSF() const;
|
||||||
virtual unsigned int readYSFData(unsigned char* data);
|
bool hasP25() const;
|
||||||
virtual unsigned int readP25Data(unsigned char* data);
|
bool hasNXDN() const;
|
||||||
virtual unsigned int readNXDNData(unsigned char* data);
|
bool hasM17() const;
|
||||||
virtual unsigned int readTransparentData(unsigned char* data);
|
bool hasPOCSAG() const;
|
||||||
|
bool hasFM() const;
|
||||||
|
bool hasAX25() const;
|
||||||
|
|
||||||
virtual unsigned int readSerial(unsigned char* data, unsigned int length);
|
unsigned int getVersion() const;
|
||||||
|
|
||||||
virtual bool hasDStarSpace() const;
|
unsigned int readDStarData(unsigned char* data);
|
||||||
virtual bool hasDMRSpace1() const;
|
unsigned int readDMRData1(unsigned char* data);
|
||||||
virtual bool hasDMRSpace2() const;
|
unsigned int readDMRData2(unsigned char* data);
|
||||||
virtual bool hasYSFSpace() const;
|
unsigned int readYSFData(unsigned char* data);
|
||||||
virtual bool hasP25Space() const;
|
unsigned int readP25Data(unsigned char* data);
|
||||||
virtual bool hasNXDNSpace() const;
|
unsigned int readNXDNData(unsigned char* data);
|
||||||
virtual bool hasPOCSAGSpace() const;
|
unsigned int readM17Data(unsigned char* data);
|
||||||
|
unsigned int readFMData(unsigned char* data);
|
||||||
|
unsigned int readAX25Data(unsigned char* data);
|
||||||
|
|
||||||
virtual bool hasTX() const;
|
bool hasDStarSpace() const;
|
||||||
virtual bool hasCD() const;
|
bool hasDMRSpace1() const;
|
||||||
|
bool hasDMRSpace2() const;
|
||||||
|
bool hasYSFSpace() const;
|
||||||
|
bool hasP25Space() const;
|
||||||
|
bool hasNXDNSpace() const;
|
||||||
|
bool hasM17Space() const;
|
||||||
|
bool hasPOCSAGSpace() const;
|
||||||
|
unsigned int getFMSpace() const;
|
||||||
|
bool hasAX25Space() const;
|
||||||
|
|
||||||
virtual bool hasLockout() const;
|
bool hasTX() const;
|
||||||
virtual bool hasError() const;
|
bool hasCD() const;
|
||||||
|
|
||||||
virtual bool writeConfig();
|
bool hasLockout() const;
|
||||||
virtual bool writeDStarData(const unsigned char* data, unsigned int length);
|
bool hasError() const;
|
||||||
virtual bool writeDMRData1(const unsigned char* data, unsigned int length);
|
|
||||||
virtual bool writeDMRData2(const unsigned char* data, unsigned int length);
|
|
||||||
virtual bool writeYSFData(const unsigned char* data, unsigned int length);
|
|
||||||
virtual bool writeP25Data(const unsigned char* data, unsigned int length);
|
|
||||||
virtual bool writeNXDNData(const unsigned char* data, unsigned int length);
|
|
||||||
virtual bool writePOCSAGData(const unsigned char* data, unsigned int length);
|
|
||||||
|
|
||||||
virtual bool writeTransparentData(const unsigned char* data, unsigned int length);
|
bool writeConfig();
|
||||||
|
bool writeDMRData1(const unsigned char* data, unsigned int length);
|
||||||
|
bool writeDMRData2(const unsigned char* data, unsigned int length);
|
||||||
|
bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
|
bool writeIPInfo(const std::string& address);
|
||||||
|
|
||||||
virtual bool writeDStarInfo(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
bool writeDMRStart(bool tx);
|
||||||
virtual bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
bool writeDMRShortLC(const unsigned char* lc);
|
||||||
virtual bool writeYSFInfo(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
bool writeDMRAbort(unsigned int slotNo);
|
||||||
virtual bool writeP25Info(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual bool writeNXDNInfo(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual bool writePOCSAGInfo(unsigned int ric, const std::string& message);
|
|
||||||
virtual bool writeIPInfo(const std::string& address);
|
|
||||||
|
|
||||||
virtual bool writeDMRStart(bool tx);
|
bool writeTransparentData(const unsigned char* data, unsigned int length);
|
||||||
virtual bool writeDMRShortLC(const unsigned char* lc);
|
unsigned int readTransparentData(unsigned char* data);
|
||||||
virtual bool writeDMRAbort(unsigned int slotNo);
|
|
||||||
|
|
||||||
virtual bool writeSerial(const unsigned char* data, unsigned int length);
|
bool writeSerial(const unsigned char* data, unsigned int length);
|
||||||
|
unsigned int readSerial(unsigned char* data, unsigned int length);
|
||||||
|
|
||||||
virtual unsigned char getMode() const;
|
unsigned char getMode() const;
|
||||||
virtual bool setMode(unsigned char mode);
|
bool setMode(unsigned char mode);
|
||||||
|
|
||||||
virtual bool sendCWId(const std::string& callsign);
|
bool sendCWId(const std::string& callsign);
|
||||||
|
|
||||||
virtual HW_TYPE getHWType() const;
|
HW_TYPE getHWType() const;
|
||||||
|
|
||||||
virtual void clock(unsigned int ms);
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
virtual void close();
|
void close();
|
||||||
|
|
||||||
static CModem* createModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool useCOSAsLockout, bool trace, bool debug);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_port;
|
unsigned int m_protocolVersion;
|
||||||
unsigned int m_dmrColorCode;
|
unsigned int m_dmrColorCode;
|
||||||
bool m_ysfLoDev;
|
|
||||||
unsigned int m_ysfTXHang;
|
|
||||||
unsigned int m_p25TXHang;
|
|
||||||
unsigned int m_nxdnTXHang;
|
|
||||||
bool m_duplex;
|
bool m_duplex;
|
||||||
bool m_rxInvert;
|
bool m_rxInvert;
|
||||||
bool m_txInvert;
|
bool m_txInvert;
|
||||||
|
@ -130,102 +141,55 @@ private:
|
||||||
unsigned int m_dmrDelay;
|
unsigned int m_dmrDelay;
|
||||||
float m_rxLevel;
|
float m_rxLevel;
|
||||||
float m_cwIdTXLevel;
|
float m_cwIdTXLevel;
|
||||||
float m_dstarTXLevel;
|
|
||||||
float m_dmrTXLevel;
|
float m_dmrTXLevel;
|
||||||
float m_ysfTXLevel;
|
|
||||||
float m_p25TXLevel;
|
|
||||||
float m_nxdnTXLevel;
|
|
||||||
float m_pocsagTXLevel;
|
|
||||||
float m_fmTXLevel;
|
|
||||||
float m_rfLevel;
|
float m_rfLevel;
|
||||||
bool m_useCOSAsLockout;
|
bool m_useCOSAsLockout;
|
||||||
bool m_trace;
|
bool m_trace;
|
||||||
bool m_debug;
|
bool m_debug;
|
||||||
unsigned int m_rxFrequency;
|
unsigned int m_rxFrequency;
|
||||||
unsigned int m_txFrequency;
|
unsigned int m_txFrequency;
|
||||||
unsigned int m_pocsagFrequency;
|
|
||||||
bool m_dstarEnabled;
|
bool m_dstarEnabled;
|
||||||
bool m_dmrEnabled;
|
bool m_dmrEnabled;
|
||||||
bool m_ysfEnabled;
|
|
||||||
bool m_p25Enabled;
|
|
||||||
bool m_nxdnEnabled;
|
|
||||||
bool m_pocsagEnabled;
|
|
||||||
bool m_fmEnabled;
|
|
||||||
int m_rxDCOffset;
|
int m_rxDCOffset;
|
||||||
int m_txDCOffset;
|
int m_txDCOffset;
|
||||||
CSerialController* m_serial;
|
IModemPort* m_port;
|
||||||
unsigned char* m_buffer;
|
unsigned char* m_buffer;
|
||||||
unsigned int m_length;
|
unsigned int m_length;
|
||||||
unsigned int m_offset;
|
unsigned int m_offset;
|
||||||
CRingBuffer<unsigned char> m_rxDStarData;
|
SERIAL_STATE m_state;
|
||||||
CRingBuffer<unsigned char> m_txDStarData;
|
unsigned char m_type;
|
||||||
CRingBuffer<unsigned char> m_rxDMRData1;
|
CRingBuffer<unsigned char> m_rxDMRData1;
|
||||||
CRingBuffer<unsigned char> m_rxDMRData2;
|
CRingBuffer<unsigned char> m_rxDMRData2;
|
||||||
CRingBuffer<unsigned char> m_txDMRData1;
|
CRingBuffer<unsigned char> m_txDMRData1;
|
||||||
CRingBuffer<unsigned char> m_txDMRData2;
|
CRingBuffer<unsigned char> m_txDMRData2;
|
||||||
CRingBuffer<unsigned char> m_rxYSFData;
|
CRingBuffer<unsigned char> m_rxSerialData;
|
||||||
CRingBuffer<unsigned char> m_txYSFData;
|
CRingBuffer<unsigned char> m_txSerialData;
|
||||||
CRingBuffer<unsigned char> m_rxP25Data;
|
|
||||||
CRingBuffer<unsigned char> m_txP25Data;
|
|
||||||
CRingBuffer<unsigned char> m_rxNXDNData;
|
|
||||||
CRingBuffer<unsigned char> m_txNXDNData;
|
|
||||||
CRingBuffer<unsigned char> m_txPOCSAGData;
|
|
||||||
CRingBuffer<unsigned char> m_rxTransparentData;
|
CRingBuffer<unsigned char> m_rxTransparentData;
|
||||||
CRingBuffer<unsigned char> m_txTransparentData;
|
CRingBuffer<unsigned char> m_txTransparentData;
|
||||||
unsigned int m_sendTransparentDataFrameType;
|
unsigned int m_sendTransparentDataFrameType;
|
||||||
CTimer m_statusTimer;
|
CTimer m_statusTimer;
|
||||||
CTimer m_inactivityTimer;
|
CTimer m_inactivityTimer;
|
||||||
CTimer m_playoutTimer;
|
CTimer m_playoutTimer;
|
||||||
unsigned int m_dstarSpace;
|
|
||||||
unsigned int m_dmrSpace1;
|
unsigned int m_dmrSpace1;
|
||||||
unsigned int m_dmrSpace2;
|
unsigned int m_dmrSpace2;
|
||||||
unsigned int m_ysfSpace;
|
|
||||||
unsigned int m_p25Space;
|
|
||||||
unsigned int m_nxdnSpace;
|
|
||||||
unsigned int m_pocsagSpace;
|
|
||||||
bool m_tx;
|
bool m_tx;
|
||||||
bool m_cd;
|
bool m_cd;
|
||||||
bool m_lockout;
|
bool m_lockout;
|
||||||
bool m_error;
|
bool m_error;
|
||||||
unsigned char m_mode;
|
unsigned char m_mode;
|
||||||
HW_TYPE m_hwType;
|
HW_TYPE m_hwType;
|
||||||
|
unsigned char m_capabilities1;
|
||||||
std::string m_fmCallsign;
|
unsigned char m_capabilities2;
|
||||||
unsigned int m_fmCallsignSpeed;
|
|
||||||
unsigned int m_fmCallsignFrequency;
|
|
||||||
unsigned int m_fmCallsignTime;
|
|
||||||
unsigned int m_fmCallsignHoldoff;
|
|
||||||
float m_fmCallsignHighLevel;
|
|
||||||
float m_fmCallsignLowLevel;
|
|
||||||
bool m_fmCallsignAtStart;
|
|
||||||
bool m_fmCallsignAtEnd;
|
|
||||||
bool m_fmCallsignAtLatch;
|
|
||||||
std::string m_fmRfAck;
|
|
||||||
unsigned int m_fmAckSpeed;
|
|
||||||
unsigned int m_fmAckFrequency;
|
|
||||||
unsigned int m_fmAckMinTime;
|
|
||||||
unsigned int m_fmAckDelay;
|
|
||||||
float m_fmAckLevel;
|
|
||||||
unsigned int m_fmTimeout;
|
|
||||||
float m_fmTimeoutLevel;
|
|
||||||
float m_fmCtcssFrequency;
|
|
||||||
unsigned int m_fmCtcssHighThreshold;
|
|
||||||
unsigned int m_fmCtcssLowThreshold;
|
|
||||||
float m_fmCtcssLevel;
|
|
||||||
unsigned int m_fmKerchunkTime;
|
|
||||||
unsigned int m_fmHangTime;
|
|
||||||
unsigned int m_fmAccessMode;
|
|
||||||
bool m_fmCOSInvert;
|
|
||||||
unsigned int m_fmRFAudioBoost;
|
|
||||||
float m_fmMaxDevLevel;
|
|
||||||
|
|
||||||
bool readVersion();
|
bool readVersion();
|
||||||
bool readStatus();
|
bool readStatus();
|
||||||
bool setConfig();
|
bool setConfig1();
|
||||||
|
bool setConfig2();
|
||||||
bool setFrequency();
|
bool setFrequency();
|
||||||
bool setFMCallsignParams();
|
bool setFMCallsignParams();
|
||||||
bool setFMAckParams();
|
bool setFMAckParams();
|
||||||
bool setFMMiscParams();
|
bool setFMMiscParams();
|
||||||
|
bool setFMExtParams();
|
||||||
|
|
||||||
void printDebug();
|
void printDebug();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,22 +16,8 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(NXDNAudio_H)
|
#include "ModemPort.h"
|
||||||
#define NXDNAudio_H
|
|
||||||
|
|
||||||
class CNXDNAudio {
|
IModemPort::~IModemPort()
|
||||||
public:
|
{
|
||||||
CNXDNAudio();
|
}
|
||||||
~CNXDNAudio();
|
|
||||||
|
|
||||||
void encode(const unsigned char* in, unsigned char* out) const;
|
|
||||||
|
|
||||||
void decode(const unsigned char* in, unsigned char* out) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void encode(const unsigned char* in, unsigned char* out, unsigned int offset) const;
|
|
||||||
|
|
||||||
void decode(const unsigned char* in, unsigned char* out, unsigned int offset) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -16,24 +16,25 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(P25Audio_H)
|
#ifndef ModemPort_H
|
||||||
#define P25Audio_H
|
#define ModemPort_H
|
||||||
|
|
||||||
#include "AMBEFEC.h"
|
class IModemPort {
|
||||||
|
|
||||||
class CP25Audio {
|
|
||||||
public:
|
public:
|
||||||
CP25Audio();
|
virtual ~IModemPort() = 0;
|
||||||
~CP25Audio();
|
|
||||||
|
|
||||||
unsigned int process(unsigned char* data);
|
virtual bool open() = 0;
|
||||||
|
|
||||||
void encode(unsigned char* data, const unsigned char* imbe, unsigned int n);
|
virtual int read(unsigned char* buffer, unsigned int length) = 0;
|
||||||
|
|
||||||
void decode(const unsigned char* data, unsigned char* imbe, unsigned int n);
|
virtual int write(const unsigned char* buffer, unsigned int length) = 0;
|
||||||
|
|
||||||
|
virtual void close() = 0;
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
virtual int setNonblock(bool nonblock) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CAMBEFEC m_fec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,22 +21,22 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
CModemSerialPort::CModemSerialPort(CModem* modem) :
|
IModemSerialPort::IModemSerialPort(CModem* modem) :
|
||||||
m_modem(modem)
|
m_modem(modem)
|
||||||
{
|
{
|
||||||
assert(modem != NULL);
|
assert(modem != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CModemSerialPort::~CModemSerialPort()
|
IModemSerialPort::~IModemSerialPort()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModemSerialPort::open()
|
bool IModemSerialPort::open()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CModemSerialPort::write(const unsigned char* data, unsigned int length)
|
int IModemSerialPort::write(const unsigned char* data, unsigned int length)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
assert(length > 0U);
|
assert(length > 0U);
|
||||||
|
@ -46,7 +46,7 @@ int CModemSerialPort::write(const unsigned char* data, unsigned int length)
|
||||||
return ret ? int(length) : -1;
|
return ret ? int(length) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CModemSerialPort::read(unsigned char* data, unsigned int length)
|
int IModemSerialPort::read(unsigned char* data, unsigned int length)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
assert(length > 0U);
|
assert(length > 0U);
|
||||||
|
@ -54,6 +54,6 @@ int CModemSerialPort::read(unsigned char* data, unsigned int length)
|
||||||
return m_modem->readSerial(data, length);
|
return m_modem->readSerial(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModemSerialPort::close()
|
void IModemSerialPort::close()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2020,2021 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,10 +22,10 @@
|
||||||
#include "SerialPort.h"
|
#include "SerialPort.h"
|
||||||
#include "Modem.h"
|
#include "Modem.h"
|
||||||
|
|
||||||
class CModemSerialPort : public ISerialPort {
|
class IModemSerialPort : public ISerialPort {
|
||||||
public:
|
public:
|
||||||
CModemSerialPort(CModem* modem);
|
IModemSerialPort(CModem* modem);
|
||||||
virtual ~CModemSerialPort();
|
virtual ~IModemSerialPort();
|
||||||
|
|
||||||
virtual bool open();
|
virtual bool open();
|
||||||
|
|
||||||
|
|
577
NXDNAudio.cpp
577
NXDNAudio.cpp
|
@ -1,577 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNAudio.h"
|
|
||||||
#include "Golay24128.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
const unsigned int PRNG_TABLE[] = {
|
|
||||||
0x42CC47U, 0x19D6FEU, 0x304729U, 0x6B2CD0U, 0x60BF47U, 0x39650EU, 0x7354F1U, 0xEACF60U, 0x819C9FU, 0xDE25CEU,
|
|
||||||
0xD7B745U, 0x8CC8B8U, 0x8D592BU, 0xF71257U, 0xBCA084U, 0xA5B329U, 0xEE6AFAU, 0xF7D9A7U, 0xBCC21CU, 0x4712D9U,
|
|
||||||
0x4F2922U, 0x14FA37U, 0x5D43ECU, 0x564115U, 0x299A92U, 0x20A9EBU, 0x7B707DU, 0x3BE3A4U, 0x20D95BU, 0x6B085AU,
|
|
||||||
0x5233A5U, 0x99A474U, 0xC0EDCBU, 0xCB5F12U, 0x918455U, 0xF897ECU, 0xE32E3BU, 0xAA7CC2U, 0xB1E7C9U, 0xFC561DU,
|
|
||||||
0xA70DE6U, 0x8DBE73U, 0xD4F608U, 0x57658DU, 0x0E5E56U, 0x458DABU, 0x7E15B8U, 0x376645U, 0x2DFD86U, 0x64EC3BU,
|
|
||||||
0x3F1F60U, 0x3481B4U, 0x4DA00FU, 0x067BCEU, 0x1B68B1U, 0xD19328U, 0xCA03FFU, 0xA31856U, 0xF8EB81U, 0xF9F2F8U,
|
|
||||||
0xA26067U, 0xA91BB6U, 0xF19A59U, 0x9A6148U, 0x8372B6U, 0xC8E86FU, 0x9399DCU, 0x1A0291U, 0x619142U, 0x6DE9FFU,
|
|
||||||
0x367A2CU, 0x7D2511U, 0x6484DAU, 0x2F1F0FU, 0x1E6DB4U, 0x55F6E1U, 0x0EA70AU, 0x061C96U, 0xDD0E45U, 0xB4D738U,
|
|
||||||
0xAF64ABU, 0xE47F42U, 0xFDBE9DU, 0xB684ACU, 0xFE5773U, 0xC1E4A2U, 0x8AFD0DU, 0x932ED4U, 0xD814E3U, 0x81853AU,
|
|
||||||
0x225EECU, 0x7A6945U, 0x31A112U, 0x2AB2EBU, 0x630974U, 0x785AB5U, 0x11E3CEU, 0x4A715BU, 0x402AA0U, 0x199B7DU,
|
|
||||||
0x16C05EU, 0x6F5283U, 0xA4FB10U, 0xBFA8ECU, 0xF633B7U, 0xEC4012U, 0xADD8C9U, 0xD6EB1CU, 0xDD3027U, 0x84A1FAU,
|
|
||||||
0xCF9E19U, 0xD64C80U, 0xBC4557U, 0xA7B62EU, 0x6E2DA1U, 0x311F50U, 0x38C68EU, 0x63D5BFU, 0x486E60U, 0x10BFE1U,
|
|
||||||
0x5BAD1EU, 0x4A4647U, 0x0157F0U, 0x7ACC29U, 0x73BEEAU, 0x2825D7U, 0xA0940CU, 0xFBCFF9U, 0xB05C62U, 0x892426U,
|
|
||||||
0xC6B3DDU, 0xDF3840U, 0x9449B3U, 0xCED3BEU, 0xE7804DU, 0xBC3B90U, 0xF5AA0BU, 0xE6D17EU, 0x2D43B5U, 0x345A04U,
|
|
||||||
0x5EA9DBU, 0x07A202U, 0x0C7134U, 0x45C9FDU, 0x5EDA0AU, 0x310193U, 0x6830C4U, 0x62AA3DU, 0x3B59B2U, 0xB04043U,
|
|
||||||
0xEB975CU, 0x82BCADU, 0x912E62U, 0xD8F7FBU, 0x82C489U, 0x895F54U, 0xF00FE7U, 0xFBBC2AU, 0xA2E771U, 0xE956C4U,
|
|
||||||
0xF6CD1FU, 0x3F8FEAU, 0x0534E1U, 0x4C653CU, 0x17FE8FU, 0x1C4C52U, 0x4515A1U, 0x2E86A9U, 0x3FBD56U, 0x756C87U,
|
|
||||||
0x6ED218U, 0x279179U, 0x7C0AA6U, 0xD53B17U, 0x8EE0C8U, 0x85F291U, 0xD94B36U, 0x9298EFU, 0xAB8318U, 0xE07301U,
|
|
||||||
0xBB68DFU, 0xB2CB7CU, 0xE910A5U, 0xE101D2U, 0x92BB4BU, 0x59E8B4U, 0x407175U, 0x0B026AU, 0x12989BU, 0x792944U,
|
|
||||||
0x2376EDU, 0x2EF5BAU, 0x758663U, 0x7C1ED5U, 0x078D0CU, 0x4EF6ABU, 0x5567F2U, 0x9F7C29U, 0xC68E9CU, 0xC51747U,
|
|
||||||
0xBC6422U, 0xB7EFB9U, 0xECFD44U, 0xA50497U, 0xAF178AU, 0xD68C69U, 0xD97DB5U, 0x82670EU, 0xCBB45BU, 0x508D90U,
|
|
||||||
0x190A25U, 0x63F0FEU, 0x68E3C7U, 0x317A10U, 0x3A09D9U, 0x6B926EU, 0x004237U, 0x1B79C8U, 0x53EA59U, 0x48B3B7U,
|
|
||||||
0x811166U, 0xDE4A79U, 0xF5F988U, 0xAC6057U, 0xE733FEU, 0xFF89ADU, 0xB49830U, 0x8F4BC3U, 0xC6F00EU, 0x9DA135U,
|
|
||||||
0x942FE0U, 0xC71C3BU, 0x4DC78FU, 0x3476C4U, 0x7F6C39U, 0x66BFAAU, 0x298657U, 0x725504U, 0x5B4E89U, 0x01FE72U,
|
|
||||||
0x0835A3U, 0x53269CU, 0x189D4DU, 0x01CDC2U, 0xEA763BU, 0xF3A56DU, 0xB0BCD4U, 0xE80F13U, 0xE355CAU, 0x98C47DU,
|
|
||||||
0x91AB24U, 0xCE38DBU, 0x87A35AU, 0x9CD3A5U, 0xD648F4U, 0xAF7B6FU, 0x24A292U, 0x7D3011U, 0x764B6DU, 0x2DDABEU,
|
|
||||||
0x44D123U, 0x5E22D8U, 0x1FB09DU, 0x04A926U, 0x4F5AF3U, 0x064128U, 0x3DB105U, 0x70AAD6U, 0xAA392FU, 0xA1C4B8U,
|
|
||||||
0xF8C7C0U, 0xD35D0FU, 0x8A2E9EU, 0xC1B761U, 0xDA44F0U, 0x925E8FU, 0x89CF4EU, 0xE8B4D1U, 0xB32728U, 0xB8FE7FU,
|
|
||||||
0x61DCC6U, 0x2A4701U, 0x1614D8U, 0x5DADE2U, 0x46BE37U, 0x0F44DCU, 0x54D549U, 0x5D8E32U, 0x263DAFU, 0x2C237CU,
|
|
||||||
0x75E291U, 0xBE5982U, 0xA74A7FU, 0xC493A4U, 0xDFA131U, 0x967A5AU, 0xCCCB8EU, 0xC1D835U, 0x9A02ECU, 0xF331BBU,
|
|
||||||
0xE8B812U, 0xA3EBC5U, 0xBA507CU, 0x7080ABU, 0x099BC2U, 0x02285DU, 0x59718CU, 0x50C273U, 0x0B1862U, 0x4A1F8CU,
|
|
||||||
0x70A655U, 0x3BF5C2U, 0x666FBBU, 0x6DDE68U, 0x3485C5U, 0x9F161EU, 0xC46F4BU, 0x8CFDF0U, 0x97C625U, 0xDE058EU,
|
|
||||||
0xC59CD3U, 0xAEAE20U, 0xF775BCU, 0xFC647FU, 0xBD9F02U, 0xE70C91U, 0xCC1468U, 0x11E7B7U, 0x1AFC36U, 0x435B49U,
|
|
||||||
0x080398U, 0x139027U, 0x7B63FEU, 0x607AF9U, 0x29E900U, 0x7293D6U, 0x79026FU, 0x00D930U, 0x0BEAF1U, 0xD3614EU,
|
|
||||||
0x90119FU, 0x8B8AE4U, 0xC61969U, 0xBD609AU, 0xB4F247U, 0xEFA954U, 0xE518A9U, 0xBC0362U, 0xD7D0D6U, 0xCE7E8DU,
|
|
||||||
0x856F18U, 0x1C94E3U, 0x578726U, 0x0D5F1DU, 0x24ECC0U, 0x7FF713U, 0x3E26AAU, 0x251D6DU, 0x6A8F14U, 0x53648BU,
|
|
||||||
0x19757AU, 0x40AEB4U, 0xCB9CA5U, 0x90055AU, 0x9956C3U, 0xE2ED34U, 0xAB3C7DU, 0xB126EAU, 0xFA9513U, 0xA3D2C8U,
|
|
||||||
0x886BFDU, 0xD9F836U, 0xD2A2E3U, 0x8D1359U, 0x454804U, 0x5EDBF7U, 0x37637AU, 0x2C3089U, 0x67ABD4U, 0x3E8847U,
|
|
||||||
0x3551BAU, 0x4D6331U, 0x46B8C4U, 0x1D299FU, 0x54120EU, 0x5FC0E1U, 0x86D93BU, 0xE56A0EU, 0xFBB1D5U, 0xB2B600U,
|
|
||||||
0xA94EABU, 0xE05DF6U, 0x9BE605U, 0x90B798U, 0xC92C6BU, 0xC3DE66U, 0x9AC7BDU, 0xD15448U, 0x6A3FD3U, 0x23ADA3U,
|
|
||||||
0x78346CU, 0x7147F5U, 0x2BDC02U, 0x0EAD5BU, 0x553FFCU, 0x1EA425U, 0x07D5F2U, 0x4C4ECBU, 0x554C14U, 0x3EB3F5U,
|
|
||||||
0xE4A26AU, 0xED799BU, 0xB6CA85U, 0xFFD25CU, 0xC421BFU, 0x8F3A22U, 0x96AB51U, 0xDC518CU, 0x895217U, 0x8289F2U,
|
|
||||||
0xF9B8A9U, 0xF0231CU, 0x2BF1C7U, 0x62C80AU, 0x781B39U, 0x1320E5U, 0x4AB156U, 0x41EB8FU, 0x1848E0U, 0x13D771U,
|
|
||||||
0x4886AEU, 0x203C5FU, 0x3B6F40U, 0x76F6A1U, 0xE5457EU, 0xAE1EE7U, 0xD7AC10U, 0xDCB549U, 0x8476EFU, 0x8FC536U,
|
|
||||||
0xD49DE9U, 0x9D0ED8U, 0xA63513U, 0xEFE4A6U, 0xB4DF7DU, 0x3E0D00U, 0x779693U, 0x4CA75EU, 0x0568ADU, 0x527BB0U,
|
|
||||||
0x59C34BU, 0x00109FU, 0x0A0B14U, 0x73FA61U, 0x38E0BAU, 0x23530FU, 0x6A88D4U, 0xB199DDU, 0x98322AU, 0xC260F3U,
|
|
||||||
0xCBF944U, 0x908A0DU, 0xDB11F2U, 0xC28163U, 0xADFABDU, 0xBC694CU, 0xF65243U, 0xAD83BAU, 0xA40D6DU, 0x5F7EF4U,
|
|
||||||
0x16E787U, 0x0DF44AU, 0x460EF1U, 0x5E1F24U, 0x15CC3FU, 0x6C77CAU, 0x676401U, 0x3C9CBDU, 0x359FEEU, 0x6A0413U,
|
|
||||||
0x02F590U, 0x91EE4DU, 0xDA3C3EU, 0xC305A3U, 0x889658U, 0xF14D99U, 0xFA7F86U, 0xA1E677U, 0xE981E8U, 0xF21A10U,
|
|
||||||
0xBB4BD7U, 0x80F1CEU, 0xCB6239U, 0x123BE0U, 0x1D885FU, 0x45921EU, 0x6641E1U, 0x3DE870U, 0x74BBAFU, 0x6F00C6U,
|
|
||||||
0x261055U, 0x7DCBA8U, 0x57787AU, 0x0E2167U, 0x05B28CU, 0xCC8819U, 0x975BE2U, 0xBC52B7U, 0xE5E52CU, 0xEB37C9U,
|
|
||||||
0xB20E12U, 0xF9DD2FU, 0xE8C6FCU, 0x837701U, 0xD8AD82U, 0xD1BE5AU, 0x0B0525U, 0x0244B4U, 0x79FE5BU, 0x322DCAU,
|
|
||||||
0x2B3495U, 0x60876CU, 0x79DCFBU, 0x334C12U, 0x4C7745U, 0x45A4DCU, 0x1E3F23U, 0x175FF2U, 0xC4C0D8U, 0xAFF30DU,
|
|
||||||
0xB72AF6U, 0xFCB96BU, 0xA5C338U, 0xAE5295U, 0xF54946U, 0xDCBABBU, 0x87A1A8U, 0xCF2165U, 0xD4DA9EU, 0x9FC90BU,
|
|
||||||
0x223070U, 0x6922A4U, 0x30B92FU, 0x3348D6U, 0x695B01U, 0x20C038U, 0x1BB2EFU, 0x523B06U, 0x49EC99U, 0x02D7C8U,
|
|
||||||
0x5B4777U, 0x713CA6U, 0xA8AF49U, 0xA3B650U, 0xF84586U, 0xB5DF7FU, 0xAE8CF8U, 0xC72581U, 0x9D3652U, 0x9EEDCFU,
|
|
||||||
0xC75D34U, 0xCC0671U, 0xB5B5CAU, 0xFEAC1FU, 0x677EA4U, 0x2DC5F9U, 0x26D63AU, 0x7F1F86U, 0x142855U, 0x0DF2A8U,
|
|
||||||
0x42E3B3U, 0x195872U, 0x108B8DU, 0x6AB31CU, 0x632063U, 0x307BAAU, 0xFBC83DU, 0xE201C4U, 0xA91393U, 0x90A82AU,
|
|
||||||
0xDAF9E4U, 0x816A55U, 0x88D00AU, 0xD383DBU, 0xFA3A64U, 0xA569A5U, 0xEEE2DEU, 0x76D243U, 0x3D0D90U, 0x649E6DU,
|
|
||||||
0x47E76EU, 0x1C7491U, 0x156E49U, 0x4E9DDEU, 0x0604B7U, 0x3D3720U, 0x76FDD9U, 0x6FEC06U, 0x2417B7U, 0xFD04F8U,
|
|
||||||
0xF29D29U, 0x886F92U, 0xC1744FU, 0xDAC73CU, 0x939EB1U, 0x880C63U, 0xEBE79EU, 0xB2F285U, 0xB86970U, 0xE11ABBU,
|
|
||||||
0xEA822EU, 0x311155U, 0x586AC0U, 0x43F92BU, 0x0A81F6U, 0x5412C5U, 0x5D111CU, 0x26E8CBU, 0x2D7B63U, 0x74213CU,
|
|
||||||
0x3F90CDU, 0x2E8B52U, 0x645883U, 0xDFE36CU, 0x96F375U, 0xDD0882U, 0xC40B1BU, 0x8FD6CCU, 0xB464A5U, 0xFC7F3EU,
|
|
||||||
0xA7AECBU, 0xAA9511U, 0xF10634U, 0xBA5CEFU, 0x83ED32U, 0x483681U, 0x5015DCU, 0x138D3FU, 0x48DEA2U, 0x616571U,
|
|
||||||
0x3AF40CU, 0x33AF97U, 0x681D72U, 0x2246E9U, 0x3BD7B9U, 0x506C46U, 0x0D2FDFU, 0x869338U, 0xDDC061U, 0xD45BD6U,
|
|
||||||
0xAF6A0FU, 0xE7B8C0U, 0xFC2371U, 0xBF102EU, 0xA6C9DFU, 0xEDDA40U, 0x943089U, 0x9FA1BFU, 0x459A66U, 0x0C4995U,
|
|
||||||
0x175108U, 0x7AE243U, 0x6139B6U, 0x2A2A2DU, 0x73D3D8U, 0x79C183U, 0x204A26U, 0x0B3FFDU, 0x5AA420U, 0x111613U,
|
|
||||||
0x8A4FDFU, 0xC3DC2CU, 0xF9A7B5U, 0xB034EAU, 0xEBAC5BU, 0xE0CF94U, 0xBD5465U, 0xF605FAU, 0xCFBEA3U, 0x85AC54U,
|
|
||||||
0x9E55DDU, 0xD7C62AU, 0x0CDD73U, 0x252FCDU, 0x76361CU, 0x7DF5D3U, 0x3546E2U, 0x6E5B39U, 0x67A98CU, 0x1CB247U,
|
|
||||||
0x57231AU, 0x4AD8A9U, 0x01CA74U, 0x191187U, 0xF2208AU, 0xA9AB50U, 0xA0F8A5U, 0xFB403EU, 0xF2D34BU, 0xA9A880U,
|
|
||||||
0xCB393DU, 0xD262EEU, 0x99D0B7U, 0xC04B00U, 0xCB1AC9U, 0xB0B176U, 0x39E3A7U, 0x677EF8U, 0x2ECD58U, 0x359687U,
|
|
||||||
0x7E277EU, 0x473D69U, 0x0CEEB0U, 0x55D557U, 0x5F04CEU, 0x0C8EBDU, 0x25BD60U, 0x7E64DBU, 0xB7771EU, 0xACCC05U,
|
|
||||||
0xE51CF0U, 0xBF2F2AU, 0x90F497U, 0xC9E7D4U, 0xC25F09U, 0x9B9CBAU, 0xD08767U, 0xEB320CU, 0xA36999U, 0x38FB42U,
|
|
||||||
0x7180B3U, 0x22112CU, 0x29AA45U, 0x50F9D2U, 0x1B610AU, 0x0202FDU, 0x4899E4U, 0x57080BU, 0x3E72DAU, 0x65E165U,
|
|
||||||
0x6CFA34U, 0xB70BEBU, 0xBC104AU, 0xE4E295U, 0x8F7BECU, 0x96787FU, 0xD583B2U, 0x9E9740U, 0x870C5DU, 0xECFFA6U,
|
|
||||||
0xF4E433U, 0xBF35F8U, 0xE00F8DU, 0x699C16U, 0x3265EBU, 0x1B6638U, 0x40F515U, 0x0A8DC6U, 0x131E1BU, 0x5845A0U,
|
|
||||||
0x21F670U, 0x2A6E1FU, 0x791D8EU, 0x708651U, 0x2AD7E8U, 0xE37CAFU, 0xD8EE56U, 0x97B3C1U, 0x8E0018U, 0xC51B6FU,
|
|
||||||
0x9CC9E6U, 0xB67019U, 0xEF23C8U, 0xE498F2U, 0xBF9927U, 0xF643ECU, 0xCD7051U, 0x04E902U, 0x563AFFU, 0x5D006CU,
|
|
||||||
0x04D3A1U, 0x0FCA9AU, 0x72794FU, 0x39A2B4U, 0x228231U, 0x6A19EAU, 0x714E96U, 0x18F705U, 0x4324FCU, 0xC83E3BU,
|
|
||||||
0x918D02U, 0xDADCD5U, 0xC2470CU, 0xA135B3U, 0xBABCF2U, 0xF30F4DU, 0xA8549EU, 0xA1C543U, 0xDEFF78U, 0xD42CBCU,
|
|
||||||
0x0DB747U, 0x46C6D2U, 0x5F5C89U, 0x144F60U, 0x6FA6F7U, 0x66350EU, 0x2C0A59U, 0x35DAE0U, 0x7EC12FU, 0x0D32FEU,
|
|
||||||
0x0429C1U, 0x5FB911U, 0xD642AEU, 0x895167U, 0xC3D8B0U, 0xFAAB89U, 0xB1315AU, 0xA8C0A7U, 0xE3DB24U, 0xB84879U,
|
|
||||||
0x913382U, 0xCBA317U, 0x82F8FCU, 0x994BA9U, 0x50C213U, 0x4390CEU, 0x282F5DU, 0x713E30U, 0x7FCDE3U, 0x26565EU,
|
|
||||||
0x2D0485U, 0x56BDD4U, 0x1FAE7BU, 0x0475AAU, 0x4DD555U, 0x17CE4CU, 0x9C1D9BU, 0xE52473U, 0xEEF7E4U, 0xB7CD1DU,
|
|
||||||
0xF45E42U, 0xEF87E3U, 0x87B43CU, 0x986FADU, 0xD16FD2U, 0x8AD403U, 0x8103A8U, 0xD83A75U, 0x33A826U, 0x2BF39BU,
|
|
||||||
0x604049U, 0x7B99A4U, 0x328ABFU, 0x49306AU, 0x407191U, 0x1BEA04U, 0x19D96FU, 0x4001F2U, 0x0FB201U, 0x36E9DCU,
|
|
||||||
0xFD7ADFU, 0xE64326U, 0xAF91F9U, 0xF51249U, 0xDC2B16U, 0x87F8D7U, 0xCCE668U, 0xC517B1U, 0x9E8C46U, 0x97BF5FU,
|
|
||||||
0xED6498U, 0xA67461U, 0x378FF6U, 0x788C8FU, 0x611514U, 0x0AE6F1U, 0x53FC2BU, 0x596F3EU, 0x0216C5U, 0x4B8508U,
|
|
||||||
0x507FBBU, 0x396EE6U, 0x22F535U, 0xE99688U, 0xB10F43U, 0xBA1D36U, 0xC3E2ADU, 0xC07178U, 0x9B28C3U, 0xD69A8BU,
|
|
||||||
0xCD817CU, 0x8570E5U, 0xFEEB12U, 0xF5E8CBU, 0xAC10C4U, 0x270335U, 0x7ED8EAU, 0x156B5BU, 0x0E7A14U, 0x46A0C5U,
|
|
||||||
0x5D937AU, 0x144AA3U, 0x4F79D5U, 0x6CF35CU, 0x31228FU, 0x7A1932U, 0x628E69U, 0xA9D59CU, 0x926517U, 0xDBBEE2U,
|
|
||||||
0x80ADB9U, 0x891424U, 0xD246D7U, 0xD8ED1AU, 0xA17C28U, 0xEA27F5U, 0xF3942EU, 0xB8CE8FU, 0xAB5FD0U, 0x466461U,
|
|
||||||
0x1CB7BEU, 0x152F6FU, 0x4E1CC0U, 0x05D799U, 0x1CE66EU, 0x773DF7U, 0x7EAB00U, 0x249048U, 0x6D41D7U, 0x765A26U,
|
|
||||||
0x1DA9F9U, 0x8431C8U, 0xCF0203U, 0x96C1DEU, 0x90D86DU, 0xCB6A30U, 0xA23193U, 0xB9A24EU, 0xF05B95U, 0xEB48A0U,
|
|
||||||
0xA0D27AU, 0xD8A39FU, 0xD33804U, 0x0A9B79U, 0x01C3AAU, 0x5A5437U, 0x132FD4U, 0x28BC0DU, 0x60253AU, 0x3F57E3U,
|
|
||||||
0x3CCC7CU, 0x65DD9DU, 0x4E26C2U, 0x172572U, 0xDCDDADU, 0xC64E64U, 0x8F5553U, 0x94A68AU, 0xFDBE7DU, 0xA66DE4U,
|
|
||||||
0xADD68BU, 0xF4C75AU, 0xFE0CC1U, 0x873E34U, 0xC8A72FU, 0xDBD0C2U, 0x124B10U, 0x49998DU, 0x40A8FEU, 0x3A3323U,
|
|
||||||
0x316088U, 0x68D95DU, 0x235B06U, 0x3A00B3U, 0x51B178U, 0x4AEA89U, 0x025816U, 0x59C36FU, 0xD092B8U, 0x8B2930U,
|
|
||||||
0xE43AC7U, 0xF5E2DEU, 0xBEC121U, 0xA71AF0U, 0xED8B7FU, 0x94B40EU, 0x9F66D1U, 0xD45D68U, 0xCD8CBFU, 0x8617F6U,
|
|
||||||
0x5F2545U, 0x75FC98U, 0x2EFF62U, 0x674467U, 0x7C959CU, 0x318F09U, 0x0A7CD2U, 0x4967AFU, 0x11D62CU, 0x1A8CD1U,
|
|
||||||
0x431F02U, 0x48A69DU, 0xB3E5ECU, 0xFA7623U, 0xE10E9AU, 0xA99948U, 0xB20215U, 0xD971A6U, 0x80E86BU, 0x8BDA90U,
|
|
||||||
0xD60185U, 0x9D907EU, 0x8FFBFBU, 0xE66920U, 0x7D705DU, 0x3483CEU, 0x6F9833U, 0x646BF1U, 0x1DF3E8U, 0x17E017U,
|
|
||||||
0x4E1BC6U, 0x050A79U, 0x1E8038U, 0x5773E7U, 0x2C685EU, 0xA1BD89U, 0xFB86B0U, 0xF01477U, 0xA16D8EU, 0xCAFE19U,
|
|
||||||
0xD365C1U, 0x9815AEU, 0x839E3FU, 0xCBCDC4U, 0x907611U, 0xB9E70AU, 0xE2BDE7U, 0x2B0E34U, 0x301789U, 0x7BE4DAU,
|
|
||||||
0x477707U, 0x0C2FACU, 0x558C79U, 0x5E9743U, 0x0D4496U, 0x04786DU, 0x7FABE0U, 0x3730B3U, 0x3C014AU, 0xE7DADDU,
|
|
||||||
0xEEE834U, 0x956163U, 0xDCB2FAU, 0xC78905U, 0x8D5BD4U, 0xD0427BU, 0xDBF12BU, 0xA22AB4U, 0xA93B4DU, 0xFA819AU,
|
|
||||||
0xB3D2B3U, 0x287B64U, 0x40289DU, 0x5BB206U, 0x100153U, 0x495CB8U, 0x42CF2DU, 0x3BF4D6U, 0x70248BU, 0x6ABF19U,
|
|
||||||
0x23CCF4U, 0x3C4527U, 0x75761AU, 0x8EACC1U, 0x853F44U, 0xD44EBFU, 0xDED5EEU, 0x87C751U, 0xEC3E80U, 0xF72D6FU,
|
|
||||||
0xBEB676U, 0xE557A1U, 0xEC4D59U, 0xB6BECEU, 0x9DA527U, 0x443078U, 0x0BCAE9U, 0x12D916U, 0x594087U, 0x6033E8U,
|
|
||||||
0x22A831U, 0x7948A2U, 0x70535FU, 0x2BC01CU, 0x62BBA1U, 0x592A7BU, 0x92308EU, 0x8AC395U, 0xC15A50U, 0x9809ABU,
|
|
||||||
0xB3B336U, 0xECB245U, 0xE54998U, 0xBEDA1BU, 0xF681E6U, 0xED35F5U, 0x8E2E0CU, 0x87FDD3U, 0x5CC453U, 0x1556ACU,
|
|
||||||
0x0E85FDU, 0x64AC42U, 0x3D7F8BU, 0x36447CU, 0x6FD665U, 0x640FB2U, 0x3B3C4BU, 0x52A7C4U, 0x48F7B5U, 0x014C2EU,
|
|
||||||
0x9A9FFBU, 0xD19601U, 0xA0250CU, 0xAB7FFFU, 0xF2C822U, 0xB8D1B1U, 0xA302CCU, 0xEAB907U, 0xD1E9B2U, 0x987269U,
|
|
||||||
0xC3411CU, 0xCC8897U, 0x141A42U, 0x3F61B8U, 0x66F2A1U, 0x2DCB56U, 0x3618DFU, 0x778208U, 0x2CB3F1U, 0x0468EEU,
|
|
||||||
0x5F7B1FU, 0x5693D0U, 0x0D8041U, 0x461B3EU, 0xFFECE7U, 0xB4FD50U, 0xA94798U, 0xE314CFU, 0xB88D76U, 0xB17EADU,
|
|
||||||
0xCA7508U, 0xC3E553U, 0x989EA6U, 0xDB0D3DU, 0xC396E8U, 0xA8E683U, 0x717D1EU, 0x7A0EEDU, 0x219730U, 0x288422U,
|
|
||||||
0x736ECFU, 0x1BFF14U, 0x04A4A1U, 0x4F177AU, 0x56092BU, 0x1DD884U, 0x64635DU, 0xEF70EAU, 0xA589B3U, 0xF49B54U,
|
|
||||||
0xFF50CDU, 0xA66312U, 0x8DFA62U, 0xD628FDU, 0x9F131CU, 0x8582C3U, 0xCCF9DAU, 0xF36A29U, 0xB8B2F4U, 0x618157U,
|
|
||||||
0x6A020AU, 0x335999U, 0x79E864U, 0x4272BFU, 0x03259AU, 0x189C40U, 0x51CFB5U, 0x0A752EU, 0x216463U, 0x79BF90U,
|
|
||||||
0x721C0DU, 0xAB47FEU, 0xE4D727U, 0xFDEC28U, 0x963FD9U, 0x8DA646U, 0xC594B7U, 0x9E4FE8U, 0x977E60U, 0xECA597U,
|
|
||||||
0xAF264EU, 0xB61C79U, 0xFDCDA0U, 0x65D64FU, 0x2E61DCU, 0x553881U, 0x5CAA72U, 0x0351FBU, 0x0A400CU, 0x51FB55U,
|
|
||||||
0x3BB9CAU, 0x22223AU, 0x6993B5U, 0x30C8C4U, 0x3B5B1BU, 0xE02B82U, 0xC1B075U, 0x9B23BCU, 0xD25A8BU, 0xC9C852U,
|
|
||||||
0x82A3A9U, 0xBB303CU, 0xF42977U, 0xADDA82U, 0xA64418U, 0xFC55E5U, 0xB5AEE6U, 0x0EBD3BU, 0x4765C8U, 0x4CD655U,
|
|
||||||
0x17DD2EU, 0x562EEBU, 0x6C3770U, 0x25A585U, 0x3E5EDEU, 0x754F6FU, 0x2C94A1U, 0x23A758U, 0x5A3F4FU, 0xD07C96U,
|
|
||||||
0x8BC761U, 0xC254E8U, 0xD92C97U, 0xB0BF06U, 0xEBE0D9U, 0xE25138U, 0xB8CAA7U, 0xBB98DEU, 0xE22109U, 0x896291U,
|
|
||||||
0x10F172U, 0x5BCB2FU, 0x401A94U, 0x0CA141U, 0x77B2BAU, 0x7E6BBFU, 0x255964U, 0x6E82D9U, 0x77130AU, 0x3C3877U,
|
|
||||||
0x04EAF4U, 0x4FD129U, 0x9C40DBU, 0x959BC6U, 0xCEAC2DU, 0xE774FCU, 0xBC6763U, 0xF6DC12U, 0xEB8DCDU, 0xA00664U,
|
|
||||||
0xF9F4B3U, 0xD2EF4AU, 0x895E5DU, 0x800584U, 0x5A972BU, 0x132EFBU, 0x287D84U, 0x63E615U, 0x7297CEU, 0x391D23U,
|
|
||||||
0x608E30U, 0x6AF5CDU, 0x11641EU, 0x5C5E93U, 0x4789E0U, 0x0E903DU, 0x956386U, 0xFEF053U, 0xB6E879U, 0xAD0BACU,
|
|
||||||
0xE41077U, 0xFF83CAU, 0xB47A99U, 0xCD6870U, 0xCE93E7U, 0x96823EU, 0x9D1941U, 0xC4EBD0U, 0x2BF23FU, 0x3031EEU,
|
|
||||||
0x790A71U, 0x229909U, 0x2AC1CEU, 0x717677U, 0x5AEDA0U, 0x039C99U, 0x480646U, 0x515587U, 0x1AEC3CU, 0x296F69U,
|
|
||||||
0xE13492U, 0xBA8607U, 0xB39FCCU, 0xEC4CB1U, 0xA77723U, 0x9EA7DEU, 0xD51C0DU, 0xCD0F00U, 0x86D4FBU, 0xDDF56EU,
|
|
||||||
0xF46F95U, 0x2FBCD4U, 0x268D6BU, 0x7D52B2U, 0x374165U, 0x26F9DCU, 0x4D2A9BU, 0x141163U, 0x1FD2FCU, 0x40CA2DU,
|
|
||||||
0x497952U, 0x3322D3U, 0x7AB32CU, 0xE108F5U, 0xAA5AE2U, 0xB3E31BU, 0xF8B098U, 0x812B65U, 0x8B8936U, 0xD0D08AU,
|
|
||||||
0xD94341U, 0x8A7894U, 0xE3A9AFU, 0xF8377AU, 0xB74481U, 0x6FDD0CU, 0x64EE5FU, 0x3D35A2U, 0x163731U, 0x5F8ECCU,
|
|
||||||
0x045DC7U, 0x0F4616U, 0x57B6E8U, 0x7CAD79U, 0x253E86U, 0x6EC7CFU, 0x7DD478U, 0xB426A1U, 0xCF2D76U, 0xC3BC5FU,
|
|
||||||
0x984780U, 0x935571U, 0xCACCEEU, 0x81BBBFU, 0xB82054U, 0xF371C0U, 0xE9CB3BU, 0xA05826U, 0xFB33F5U, 0x52A218U,
|
|
||||||
0x09B88BU, 0x424BF6U, 0x53D22DU, 0x198198U, 0x043A53U, 0x6F2A06U, 0x34F1BDU, 0x3DC260U, 0x664982U, 0x6FB81BU,
|
|
||||||
0x15A24CU, 0xDE71F5U, 0xC7482AU, 0x8CDFCBU, 0x9505D4U, 0xDE3405U, 0xA5EFFAU, 0xA4FC63U, 0xFE5704U, 0xB387DDU,
|
|
||||||
0xA8BC6AU, 0xC32FB2U, 0x5A7EE5U, 0x11C44CU, 0x489797U, 0x420E62U, 0x19BD79U, 0x30E6BCU, 0x6B6407U, 0x225DDAU,
|
|
||||||
0x398EA9U, 0x703534U, 0x0A64F7U, 0x09FA0AU, 0xD4C910U, 0xDF10E5U, 0x86833EU, 0xCDB99BU, 0xE67A40U, 0xBE631BU,
|
|
||||||
0xB590AEU, 0xEC8B75U, 0xA73BD0U, 0x9CE08BU, 0xD5F35EU, 0x8E0AE5U, 0x061828U, 0x5D835AU, 0x5660C7U, 0x277914U,
|
|
||||||
0x68CAE9U, 0x7190E2U, 0x3A0113U, 0x20FECCU, 0x49ED7DU, 0x127522U, 0x1B06ABU, 0x40855CU, 0x8B9E85U, 0x926FB2U,
|
|
||||||
0xF8F56AU, 0xE186A5U, 0xAA1F14U, 0xF10CCBU, 0xF0F7BAU, 0x8F6735U, 0x867CECU, 0xDC9F1FU, 0x978402U, 0x8E54F1U,
|
|
||||||
0x45EF3CU, 0x7CFC8FU, 0x3705D2U, 0x6C1248U, 0x64C8BDU, 0x3FF976U, 0x566243U, 0x4DA198U, 0x069B45U, 0x1F0AF6U,
|
|
||||||
0x5851BBU, 0x00E248U, 0xAB3BD1U, 0xF2090EU, 0xF9926FU, 0xA2C3F1U, 0xEB7800U, 0xD07B9FU, 0x98A1E6U, 0xC31021U,
|
|
||||||
0xC84BB8U, 0x91D84FU, 0x9AEC96U, 0x6337A9U, 0x288468U, 0x369FB3U, 0x774E06U, 0x6C645DU, 0x05B7A9U, 0x4E2E22U,
|
|
||||||
0x551DFFU, 0x1CC78CU, 0x47D611U, 0x4F2DF2U, 0x343E6FU, 0xBF8514U, 0xE655C1U, 0xAD5E5AU, 0xB4EDBFU, 0xDFB4E4U,
|
|
||||||
0xC1265DU, 0x80DD8BU, 0xDBC852U, 0xD25375U, 0x8920ACU, 0xA2BA53U, 0xFB0BC2U, 0x31401DU, 0x28D33CU, 0x63AAE3U,
|
|
||||||
0x18381AU, 0x11238DU, 0x4AD2E4U, 0x434933U, 0x195BABU, 0x56A058U, 0x6FB105U, 0x2C5AAEU, 0x35C97BU, 0xFED9A0U,
|
|
||||||
0xA52295U, 0x8D314EU, 0xD6ECA3U, 0x9F5E30U, 0x84456DU, 0xCFB6DEU, 0xD6AF03U, 0xBD2CE9U, 0xE556FCU, 0xEEC707U,
|
|
||||||
0xB71CD6U, 0x382F59U, 0x43B720U, 0x02E4F7U, 0x195F4EU, 0x51CC99U, 0x0AA550U, 0x013767U, 0x786CBEU, 0x73DD01U,
|
|
||||||
0x2AC6D1U, 0x61159EU, 0x7BA92FU, 0x92BAF4U, 0x896109U, 0xC0521AU, 0x9F9AF7U, 0x942924U, 0xC532B9U, 0xEFE3C2U,
|
|
||||||
0xA6D807U, 0xFD0ABCU, 0xF69369U, 0xAFA033U, 0x44738EU, 0x5D694DU, 0x17C8F0U, 0x0C93A3U, 0x45207AU, 0x1EF9C5U,
|
|
||||||
0x37EB04U, 0x6850FBU, 0x6305EAU, 0x3B9E15U, 0x782DC4U, 0x41774BU, 0x8AF633U, 0xD18DE4U, 0xD81E5DU, 0x83A69AU,
|
|
||||||
0x8AF583U, 0xF06E7CU, 0xBB5FADU, 0xA28416U, 0xE99653U, 0xF06D88U, 0x9FEC35U, 0xC4F7E6U, 0x4C059AU, 0x1F1C19U,
|
|
||||||
0x56EFC4U, 0x4D743FU, 0x24612AU, 0x3F9BD1U, 0x748814U, 0x2C13AFU, 0x27F276U, 0x5EE861U, 0x553B88U, 0x0E0A5FU,
|
|
||||||
0xC791E6U, 0xD8E2B0U, 0x907A69U, 0xABE9C6U, 0xE09217U, 0xB10168U, 0xBA48F9U, 0xE3FA26U, 0x8861CFU, 0x9230D8U,
|
|
||||||
0xDB8B21U, 0xC099B2U, 0x09644FU, 0x52F704U, 0x79AC90U, 0x201F6BU, 0x2E17BEU, 0x77C495U, 0x3CFF48U, 0x172E9BU,
|
|
||||||
0x4E9426U, 0x0D8775U, 0x145E98U, 0x5E6D03U, 0xC5F6D6U, 0xAC242DU, 0xF70D3CU, 0xFEDED2U, 0xA5C543U, 0xAE74BCU,
|
|
||||||
0xD62EE5U, 0x9D9D72U, 0x80029BU, 0xCB534CU, 0x90E175U, 0x19BAAAU, 0x6A3B6BU, 0x6280D4U, 0x39D385U, 0x724B7AU,
|
|
||||||
0x6B78E2U, 0x00A321U, 0x19101CU, 0x5248CFU, 0x0ADB30U, 0x01F0A9U, 0x5A21CEU, 0xB73A17U, 0xACC880U, 0xE55179U,
|
|
||||||
0xFE42A6U, 0xB4B987U, 0xC5AF58U, 0xCE1688U, 0x97C533U, 0x9CCE76U, 0xC73F8DU, 0x8E2510U, 0xB4B6C3U, 0x7D4FFEU,
|
|
||||||
0x665C3DU, 0x2DC7C0U, 0x70B55BU, 0x5B2C2EU, 0x025FF5U, 0x49D470U, 0x53448AU, 0x1A3FD7U, 0x09AC64U, 0x60BDBDU,
|
|
||||||
0x3B467AU, 0xB0D043U, 0xE98B9CU, 0xE33A2DU, 0x9A21E2U, 0xD1C3B3U, 0xCA5A0CU, 0x8709DDU, 0xDCB222U, 0xF5A3AAU,
|
|
||||||
0xBF79DDU, 0xA44A04U, 0xEDD193U, 0x3E006AU, 0x373B21U, 0x4CF994U, 0x47C04FU, 0x1F53DAU, 0x5488A1U, 0x4DB86CU,
|
|
||||||
0x2623DFU, 0x7D7402U, 0x70CF50U, 0x2B9EFDU, 0x232426U, 0xF8A7D3U, 0x91FEC8U, 0x8A4D39U, 0xC117F6U, 0xD0866FU,
|
|
||||||
0x9B3D18U, 0xE36EC1U, 0xE8F576U, 0xB3C5BFU, 0xBA1629U, 0xE1BD50U, 0xA8EC8FU, 0x17763EU, 0x5D45F1U, 0x049CA0U,
|
|
||||||
0x0F8F1FU, 0x5630C6U, 0x7DE225U, 0x26FB38U, 0x6F08CBU, 0x7D0316U, 0x34B28DU, 0x2F68E9U, 0xC47B72U, 0x9DC287U,
|
|
||||||
0x96915CU, 0xCF0B41U, 0x85F8A2U, 0xBAE17FU, 0xF372CCU, 0xE81991U, 0xA1894AU, 0xFAF2EBU, 0xF16134U, 0x89F845U,
|
|
||||||
0x0A8ADBU, 0x53153AU, 0x1806E5U, 0x03FF7CU, 0x6A7C0BU, 0x312692U, 0x399775U, 0x628CACU, 0x6D7FB3U, 0x34EE42U,
|
|
||||||
0x5FF49DU, 0x56073CU, 0x8D1C67U, 0x87CDBBU, 0xDEE708U, 0xB574D5U, 0xA4ADB6U, 0xEF9E2BU, 0xF605D0U, 0xBD7545U,
|
|
||||||
0xE6EE0EU, 0xCE39FBU, 0x950260U, 0xD8929DU, 0x43D9CEU, 0x086A47U, 0x31B3B1U, 0x7AA068U, 0x221ADFU, 0x294B86U,
|
|
||||||
0x72F049U, 0x73E3F8U, 0x083927U, 0x418856U, 0x5AC3C9U, 0x105020U, 0xC969B7U, 0xE2BBEEU, 0xBF2019U, 0xB41181U,
|
|
||||||
0xEFCA6AU, 0xA6FD3FU, 0xBC27A4U, 0xD53651U, 0xCE9D9AU, 0x854EA7U, 0xDC5E74U, 0xDFE5A9U, 0x26B61AU, 0x6C0D57U,
|
|
||||||
0x77DCECU, 0x3EC639U, 0x2575C3U, 0x682CD6U, 0x13AF1DU, 0x1855ECU, 0x404473U, 0x4BDF8AU, 0x12ACDDU, 0xF93754U,
|
|
||||||
0xE207A3U, 0xABD87AU, 0xF04B45U, 0xF03284U, 0xABB05BU, 0x80ABEBU, 0xD95AB4U, 0x92C10DU, 0x8FD2CEU, 0xC42833U,
|
|
||||||
0xEC3920U, 0x37C2FDU, 0x7C5106U, 0x654883U, 0x2EAAF8U, 0x37B12DU, 0x5C20B6U, 0x065B42U, 0x07C909U, 0x5C12B4U,
|
|
||||||
0x152367U, 0x2EB4FAU, 0x65CF19U, 0xFC5F40U, 0xB294FFU, 0xEBA72EU, 0xE03ED1U, 0x9B6CD0U, 0x92D70FU, 0xC944F6U,
|
|
||||||
0x801D60U, 0x9AAE19U, 0xF1F4DEU, 0xA85547U, 0xAB4EB8U, 0x729DE9U, 0x792456U, 0x223697U, 0x4BED0CU, 0x55DE71U,
|
|
||||||
0x1C03A2U, 0x07910FU, 0x4CAADCU, 0x356BA0U, 0x3E5033U, 0x67C3EEU, 0x2D9B05U, 0xB62810U, 0xFFF3EBU, 0xC4E03EU,
|
|
||||||
0x8558A5U, 0xDE0B48U, 0xD5905BU, 0x8D71A2U, 0xA26A75U, 0xFBD8ECU, 0xB08982U, 0xAB1253U, 0xE2A1ECU, 0x79FB3FU,
|
|
||||||
0x116E52U, 0x4A15C9U, 0x43861CU, 0x188FE7U, 0x537DF2U, 0x62E619U, 0x29D7C0U, 0x310C57U, 0x7A1F2EU, 0x25E5B8U,
|
|
||||||
0xAC7451U, 0xC76F86U, 0xDE9C9FU, 0x959460U, 0xCF27B1U, 0xC6FC1EU, 0xBDEDCFU, 0xF416B0U, 0xEF0429U, 0xA49FEEU,
|
|
||||||
0xBDEA17U, 0xFF7104U, 0x06A3F8U, 0x0D8A63U, 0x5219A6U, 0x5B62DDU, 0x00F348U, 0x6969B3U, 0x731A6EU, 0x38816DU,
|
|
||||||
0x61D090U, 0x6A6343U, 0x33F9FEU, 0x18B8A5U, 0xC30340U, 0x8B10DAU, 0x98E80BU, 0xD1FB74U, 0xEA20F5U, 0xA5930AU,
|
|
||||||
0xFC8E93U, 0xF75CC4U, 0xAF673DU, 0xA4E6BAU, 0xDF3D43U, 0x960F9CU, 0x0DD68DU, 0x44E572U, 0x1F7EB2U, 0x35AD09U,
|
|
||||||
0x6C9554U, 0x6746A7U, 0x365D3AU, 0x7DFCF9U, 0x64A6C4U, 0x0B351FU, 0x118CEAU, 0x58DF61U, 0x836434U, 0x8A36CFU,
|
|
||||||
0xF1AB5BU, 0xBA18A0U, 0xA343EDU, 0xE8C27EU, 0xF0F887U, 0xBB2B50U, 0xC03A69U, 0xC9C1A6U, 0x9A5317U, 0x9368C8U,
|
|
||||||
0x5CB919U, 0x26A226U, 0x2F01EFU, 0x74D919U, 0x3DCA80U, 0x2631D7U, 0x6D223EU, 0x54BAA1U, 0x1E4950U, 0x47520BU,
|
|
||||||
0x4CA79EU, 0x97BC75U, 0xBE3EA8U, 0xED479BU, 0xA4D446U, 0xBA4FF5U, 0xF13C39U, 0xE8A46AU, 0x83D7D7U, 0xDA4C0CU,
|
|
||||||
0xD1DDF9U, 0x8AA7F2U, 0xC22427U, 0x793DDCU, 0x30CE45U, 0x2B5522U, 0x6007FBU, 0x39BE6CU, 0x32AD95U, 0x42560BU,
|
|
||||||
0x4D426AU, 0x16D1B5U, 0x5F3A04U, 0x442BDBU, 0x2DF082U, 0xF6C225U, 0xFE59FCU, 0xA5880FU, 0xAEB312U, 0xF761C9U,
|
|
||||||
0x9C582CU, 0x85CBB7U, 0xCE00C3U, 0xD43118U, 0x9DAB9DU, 0xEAF866U, 0xE3437BU, 0x381288U, 0x738955U, 0x6A3BF6U,
|
|
||||||
0x2066ABU, 0x19D570U, 0x52DEC1U, 0x090E1EU, 0x00B5FFU, 0x5BE6E1U, 0x727D38U, 0x284CCFU, 0x639656U, 0xFA8531U,
|
|
||||||
0xBD3CA8U, 0xD4EF77U, 0xCFC586U, 0x841489U, 0x9C0F78U, 0xD7BCA7U, 0x8E671EU, 0xA5774DU, 0xFE8481U, 0xF79F32U,
|
|
||||||
0xAC0AEFU, 0x65F09CU, 0x5FF301U, 0x144ACAU, 0x0D193FU, 0x468224U, 0x13F0D1U, 0x18694AU, 0x63FA87U, 0x2B81F4U,
|
|
||||||
0x30106DU, 0x790A9BU, 0xE2E952U, 0x8970CDU, 0xD003BCU, 0xDB9963U, 0x838AD2U, 0x88731DU, 0xD1E064U, 0xBAFFF3U,
|
|
||||||
0xA10F2AU, 0xEC049DU, 0xBFD7D4U, 0xB7EE2BU, 0x4C7CBBU, 0x478760U, 0x1E9415U, 0x554D9EU, 0x4C7E6BU, 0x07E4B0U,
|
|
||||||
0x3D35ADU, 0x741E4EU, 0x2F8D93U, 0x26FC20U, 0x7D667DU, 0x16B586U, 0x8B8E02U, 0xC91FD9U, 0xD0456CU, 0x9BF237U,
|
|
||||||
0xC0EBCEU, 0xE92849U, 0xB29390U, 0xBBC3E7U, 0xE1787EU, 0xAA6B81U, 0x93B040U, 0xD8005FU, 0x411BAEU, 0x0AC870U,
|
|
||||||
0x51F1D1U, 0x5D328EU, 0x362837U, 0x6799E0U, 0x6C4239U, 0x37711AU, 0x3EABC7U, 0x45BA3CU, 0x0D01A9U, 0x16D6F2U,
|
|
||||||
0xDDCF17U, 0xC46D8CU, 0x8F3670U, 0xF6A723U, 0xFD5CBCU, 0xA74F5DU, 0xEAF582U, 0xF1A43BU, 0x903768U, 0x8B0CC5U,
|
|
||||||
0xC0DC16U, 0x9957CBU, 0x1324F0U, 0x4ABD25U, 0x61AECEU, 0x38545AU, 0x73C701U, 0x68FEF4U, 0x212D6FU, 0x5B3382U,
|
|
||||||
0x52C2D1U, 0x09494CU, 0x065ABFU, 0xDFA126U, 0x9CB149U, 0xA56A98U, 0xEE5927U, 0xF4C0F6U, 0xBD33B8U, 0xE62901U,
|
|
||||||
0xCFB8D6U, 0x94D32FU, 0x9F40B8U, 0xC69AF1U, 0x8CAB0EU, 0x15309FU, 0x7E6360U, 0x21DA31U, 0x2848BAU, 0x733747U,
|
|
||||||
0x72A6D4U, 0x08EDA8U, 0x435F7BU, 0x5A4CD6U, 0x119505U, 0x082658U, 0x433DE3U, 0xB8ED26U, 0xB0D6DDU, 0xEB05C8U,
|
|
||||||
0xA2BC13U, 0xA9BEEAU, 0xD6656DU, 0xDF5614U, 0x848F82U, 0xC41C5BU, 0xDF26A4U, 0x94F7A5U, 0xADCC5AU, 0x665B8BU,
|
|
||||||
0x3F1234U, 0x34A0EDU, 0x6E7BAAU, 0x076813U, 0x1CD1C4U, 0x55833DU, 0x4E1836U, 0x03A9E2U, 0x58F219U, 0x72418CU,
|
|
||||||
0x2B09F7U, 0xA89A72U, 0xF1A1A9U, 0xBA7254U, 0x81EA47U, 0xC899BAU, 0xD20279U, 0x9B13C4U, 0xC0E09FU, 0xCB7E4BU,
|
|
||||||
0xB25FF0U, 0xF98431U, 0xE4974EU, 0x2E6CD7U, 0x35FC00U, 0x5CE7A9U, 0x07147EU, 0x060D07U, 0x5D9F98U, 0x56E449U,
|
|
||||||
0x0E65A6U, 0x659EB7U, 0x7C8D49U, 0x371790U, 0x6C6623U, 0xE5FD6EU, 0x9E6EBDU, 0x921600U, 0xC985D3U, 0x82DAEEU,
|
|
||||||
0x9B7B25U, 0xD0E0F0U, 0xE1924BU, 0xAA091EU, 0xF158F5U, 0xF9E369U, 0x22F1BAU, 0x4B28C7U, 0x509B54U, 0x1B80BDU,
|
|
||||||
0x024162U, 0x497B53U, 0x01A88CU, 0x3E1B5DU, 0x7502F2U, 0x6CD12BU, 0x27EB1CU, 0x7E7AC5U, 0xDDA113U, 0x8596BAU,
|
|
||||||
0xCE5EEDU, 0xD54D14U, 0x9CF68BU, 0x87A54AU, 0xEE1C31U, 0xB58EA4U, 0xBFD55FU, 0xE66482U, 0xE93FA1U, 0x90AD7CU,
|
|
||||||
0x5B04EFU, 0x405713U, 0x09CC48U, 0x13BFEDU, 0x522736U, 0x2914E3U, 0x22CFD8U, 0x7B5E05U, 0x3061E6U, 0x29B37FU,
|
|
||||||
0x43BAA8U, 0x5849D1U, 0x91D25EU, 0xCEE0AFU, 0xC73971U, 0x9C2A40U, 0xB7919FU, 0xEF401EU, 0xA452E1U, 0xB5B9B8U,
|
|
||||||
0xFEA80FU, 0x8533D6U, 0x8C4115U, 0xD7DA28U, 0x5F6BF3U, 0x043006U, 0x4FA39DU, 0x76DBD9U, 0x394C22U, 0x20C7BFU,
|
|
||||||
0x6BB64CU, 0x312C41U, 0x187FB2U, 0x43C46FU, 0x0A55F4U, 0x192E81U, 0xD2BC4AU, 0xCBA5FBU, 0xA15624U, 0xF85DFDU,
|
|
||||||
0xF38ECBU, 0xBA3602U, 0xA125F5U, 0xCEFE6CU, 0x97CF3BU, 0x9D55C2U, 0xC4A64DU, 0x4FBFBCU, 0x1468A3U, 0x7D4352U,
|
|
||||||
0x6ED19DU, 0x270804U, 0x7D3B76U, 0x76A0ABU, 0x0FF018U, 0x0443D5U, 0x5D188EU, 0x16A93BU, 0x0932E0U, 0xC07015U,
|
|
||||||
0xFACB1EU, 0xB39AC3U, 0xE80170U, 0xE3B3ADU, 0xBAEA5EU, 0xD17956U, 0xC042A9U, 0x8A9378U, 0x912DE7U, 0xD86E86U,
|
|
||||||
0x83F559U, 0x2AC4E8U, 0x711F37U, 0x7A0D6EU, 0x26B4C9U, 0x6D6710U, 0x547CE7U, 0x1F8CFEU, 0x449720U, 0x4D3483U,
|
|
||||||
0x16EF5AU, 0x1EFE2DU, 0x6D44B4U, 0xA6174BU, 0xBF8E8AU, 0xF4FD95U, 0xED6764U, 0x86D6BBU, 0xDC8912U, 0xD10A45U,
|
|
||||||
0x8A799CU, 0x83E12AU, 0xF872F3U, 0xB10954U, 0xAA980DU, 0x6083D6U, 0x397163U, 0x3AE8B8U, 0x439BDDU, 0x481046U,
|
|
||||||
0x1302BBU, 0x5AFB68U, 0x50E875U, 0x297396U, 0x26824AU, 0x7D98F1U, 0x344BA4U, 0xAF726FU, 0xE6F5DAU, 0x9C0F01U,
|
|
||||||
0x971C38U, 0xCE85EFU, 0xC5F626U, 0x946D91U, 0xFFBDC8U, 0xE48637U, 0xAC15A6U, 0xB74C48U, 0x7EEE99U, 0x21B586U,
|
|
||||||
0x0A0677U, 0x539FA8U, 0x18CC01U, 0x007652U, 0x4B67CFU, 0x70B43CU, 0x390FF1U, 0x625ECAU, 0x6BD01FU, 0x38E3C4U,
|
|
||||||
0xB23870U, 0xCB893BU, 0x8093C6U, 0x994055U, 0xD679A8U, 0x8DAAFBU, 0xA4B176U, 0xFE018DU, 0xF7CA5CU, 0xACD963U,
|
|
||||||
0xE762B2U, 0xFE323DU, 0x1589C4U, 0x0C5A92U, 0x4F432BU, 0x17F0ECU, 0x1CAA35U, 0x673B82U, 0x6E54DBU, 0x31C724U,
|
|
||||||
0x785CA5U, 0x632C5AU, 0x29B70BU, 0x508490U, 0xDB5D6DU, 0x82CFEEU, 0x89B492U, 0xD22541U, 0xBB2EDCU, 0xA1DD27U,
|
|
||||||
0xE04F62U, 0xFB56D9U, 0xB0A50CU, 0xF9BED7U, 0xC24EFAU, 0x8F5529U, 0x55C6D0U, 0x5E3B47U, 0x07383FU, 0x2CA2F0U,
|
|
||||||
0x75D161U, 0x3E489EU, 0x25BB0FU, 0x6DA170U, 0x7630B1U, 0x174B2EU, 0x4CD8D7U, 0x470180U, 0x9E2339U, 0xD5B8FEU,
|
|
||||||
0xE9EB27U, 0xA2521DU, 0xB941C8U, 0xF0BB23U, 0xAB2AB6U, 0xA271CDU, 0xD9C250U, 0xD3DC83U, 0x8A1D6EU, 0x41A67DU,
|
|
||||||
0x58B580U, 0x3B6C5BU, 0x205ECEU, 0x6985A5U, 0x333471U, 0x3E27CAU, 0x65FD13U, 0x0CCE44U, 0x1747EDU, 0x5C143AU,
|
|
||||||
0x45AF83U, 0x8F7F54U, 0xF6643DU, 0xFDD7A2U, 0xA68E73U, 0xAF3D8CU, 0xF4E79DU, 0xB5E073U, 0x8F59AAU, 0xC40A3DU,
|
|
||||||
0x999044U, 0x922197U, 0xCB7A3AU, 0x60E9E1U, 0x3B90B4U, 0x73020FU, 0x6839DAU, 0x21FA71U, 0x3A632CU, 0x5151DFU,
|
|
||||||
0x088A43U, 0x039B80U, 0x4260FDU, 0x18F36EU, 0x33EB97U, 0xEE1848U, 0xE503C9U, 0xBCA4B6U, 0xF7FC67U, 0xEC6FD8U,
|
|
||||||
0x849C01U, 0x9F8506U, 0xD616FFU, 0x8D6C29U, 0x86FD90U, 0xFF26CFU, 0xF4150EU, 0x2C9EB1U, 0x6FEE60U, 0x74751BU,
|
|
||||||
0x39E696U, 0x429F65U, 0x4B0DB8U, 0x1056ABU, 0x1AE756U, 0x43FC9DU, 0x282F29U, 0x318172U, 0x7A90E7U, 0xE36B1CU,
|
|
||||||
0xA878D9U, 0xF2A0E2U, 0xDB133FU, 0x8008ECU, 0xC1D955U, 0xDAE292U, 0x9570EBU, 0xAC9B74U, 0xE68A85U, 0xBF514BU,
|
|
||||||
0x34635AU, 0x6FFAA5U, 0x66A93CU, 0x1D12CBU, 0x54C382U, 0x4ED915U, 0x056AECU, 0x5C2D37U, 0x779402U, 0x2607C9U,
|
|
||||||
0x2D5D1CU, 0x72ECA6U, 0xBAB7FBU, 0xA12408U, 0xC89C85U, 0xD3CF76U, 0x98542BU, 0xC177B8U, 0xCAAE45U, 0xB29CCEU,
|
|
||||||
0xB9473BU, 0xE2D660U, 0xABEDF1U, 0xA03F1EU, 0x7926C4U, 0x1A95F1U, 0x044E2AU, 0x4D49FFU, 0x56B154U, 0x1FA209U,
|
|
||||||
0x6419FAU, 0x6F4867U, 0x36D394U, 0x3C2199U, 0x653842U, 0x2EABB7U, 0x95C02CU, 0xDC525CU, 0x87CB93U, 0x8EB80AU,
|
|
||||||
0xD423FDU, 0xF152A4U, 0xAAC003U, 0xE15BDAU, 0xF82A0DU, 0xB3B134U, 0xAAB3EBU, 0xC14C0AU, 0x1B5D95U, 0x128664U,
|
|
||||||
0x49357AU, 0x002DA3U, 0x3BDE40U, 0x70C5DDU, 0x6954AEU, 0x23AE73U, 0x76ADE8U, 0x7D760DU, 0x064756U, 0x0FDCE3U,
|
|
||||||
0xD40E38U, 0x9D37F5U, 0x87E4C6U, 0xECDF1AU, 0xB54EA9U, 0xBE1470U, 0xE7B71FU, 0xEC288EU, 0xB77951U, 0xDFC3A0U,
|
|
||||||
0xC490BFU, 0x89095EU, 0x1ABA81U, 0x51E118U, 0x2853EFU, 0x234AB6U, 0x7B8910U, 0x703AC9U, 0x2B6216U, 0x62F127U,
|
|
||||||
0x59CAECU, 0x101B59U, 0x4B2082U, 0xC1F2FFU, 0x88696CU, 0xB358A1U, 0xFA9752U, 0xAD844FU, 0xA63CB4U, 0xFFEF60U,
|
|
||||||
0xF5F4EBU, 0x8C059EU, 0xC71F45U, 0xDCACF0U, 0x95772BU, 0x4E6622U, 0x67CDD5U, 0x3D9F0CU, 0x3406BBU, 0x6F75F2U,
|
|
||||||
0x24EE0DU, 0x3D7E9CU, 0x520542U, 0x4396B3U, 0x09ADBCU, 0x527C45U, 0x5BF292U, 0xA0810BU, 0xE91878U, 0xF20BB5U,
|
|
||||||
0xB9F10EU, 0xA1E0DBU, 0xEA33C0U, 0x938835U, 0x989BFEU, 0xC36342U, 0xCA6011U, 0x95FBECU, 0xFD0A6FU, 0x6E11B2U,
|
|
||||||
0x25C3C1U, 0x3CFA5CU, 0x7769A7U, 0x0EB266U, 0x058079U, 0x5E1988U, 0x167E17U, 0x0DE5EFU, 0x44B428U, 0x7F0E31U,
|
|
||||||
0x349DC6U, 0xEDC41FU, 0xE277A0U, 0xBA6DE1U, 0x99BE1EU, 0xC2178FU, 0x8B4450U, 0x90FF39U, 0xD9EFAAU, 0x823457U,
|
|
||||||
0xA88785U, 0xF1DE98U, 0xFA4D73U, 0x3377E6U, 0x68A41DU, 0x43AD48U, 0x1A1AD3U, 0x14C836U, 0x4DF1EDU, 0x0622D0U,
|
|
||||||
0x173903U, 0x7C88FEU, 0x27527DU, 0x2E41A5U, 0xF4FADAU, 0xFDBB4BU, 0x8601A4U, 0xCDD235U, 0xD4CB6AU, 0x9F7893U,
|
|
||||||
0x862304U, 0xCCB3EDU, 0xB388BAU, 0xBA5B23U, 0xE1C0DCU, 0xE8A00DU, 0x3B3F27U, 0x500CF2U, 0x48D509U, 0x034694U,
|
|
||||||
0x5A3CC7U, 0x51AD6AU, 0x0AB6B9U, 0x234544U, 0x785E57U, 0x30DE9AU, 0x2B2561U, 0x6036F4U, 0xDDCF8FU, 0x96DD5BU,
|
|
||||||
0xCF46D0U, 0xCCB729U, 0x96A4FEU, 0xDF3FC7U, 0xE44D10U, 0xADC4F9U, 0xB61366U, 0xFD2837U, 0xA4B888U, 0x8EC359U,
|
|
||||||
0x5750B6U, 0x5C49AFU, 0x07BA79U, 0x4A2080U, 0x517307U, 0x38DA7EU, 0x62C9ADU, 0x611230U, 0x38A2CBU, 0x33F98EU,
|
|
||||||
0x4A4A35U, 0x0153E0U, 0x98815BU, 0xD23A06U, 0xD929C5U, 0x80E079U, 0xEBD7AAU, 0xF20D57U, 0xBD1C4CU, 0xE6A78DU,
|
|
||||||
0xEF7472U, 0x954CE3U, 0x9CDF9CU, 0xCF8455U, 0x0437C2U, 0x1DFE3BU, 0x56EC6CU, 0x6F57D5U, 0x25061BU, 0x7E95AAU,
|
|
||||||
0x772FF5U, 0x2C7C24U, 0x05C59BU, 0x5A965AU, 0x111D21U, 0x892DBCU, 0xC2F26FU, 0x9B6192U, 0xB81891U, 0xE38B6EU,
|
|
||||||
0xEA91B6U, 0xB16221U, 0xF9FB48U, 0xC2C8DFU, 0x890226U, 0x9013F9U, 0xDBE848U, 0x02FB07U, 0x0D62D6U, 0x77906DU,
|
|
||||||
0x3E8BB0U, 0x2538C3U, 0x6C614EU, 0x77F39CU, 0x141861U, 0x4D0D7AU, 0x47968FU, 0x1EE544U, 0x157DD1U, 0xCEEEAAU,
|
|
||||||
0xA7953FU, 0xBC06D4U, 0xF57E09U, 0xABED3AU, 0xA2EEE3U, 0xD91734U, 0xD2849CU, 0x8BDEC3U, 0xC06F32U, 0xD174ADU,
|
|
||||||
0x9BA77CU, 0x201C93U, 0x690C8AU, 0x22F77DU, 0x3BF4E4U, 0x702933U, 0x4B9B5AU, 0x0380C1U, 0x585134U, 0x556AEEU,
|
|
||||||
0x0EF9CBU, 0x45A310U, 0x7C12CDU, 0xB7C97EU, 0xAFEA23U, 0xEC72C0U, 0xB7215DU, 0x9E9A8EU, 0xC50BF3U, 0xCC5068U,
|
|
||||||
0x97E28DU, 0xDDB916U, 0xC42846U, 0xAF93B9U, 0xF2D020U, 0x796CC7U, 0x223F9EU, 0x2BA429U, 0x5095F0U, 0x18473FU,
|
|
||||||
0x03DC8EU, 0x40EFD1U, 0x593620U, 0x1225BFU, 0x6BCF76U, 0x605E40U, 0xBA6599U, 0xF3B66AU, 0xE8AEF7U, 0x851DBCU,
|
|
||||||
0x9EC649U, 0xD5D5D2U, 0x8C2C27U, 0x863E7CU, 0xDFB5D9U, 0xF4C002U, 0xA55BDFU, 0xEEE9ECU, 0x75B020U, 0x3C23D3U,
|
|
||||||
0x06584AU, 0x4FCB15U, 0x1453A4U, 0x1F306BU, 0x42AB9AU, 0x09FA05U, 0x30415CU, 0x7A53ABU, 0x61AA22U, 0x2839D5U,
|
|
||||||
0xF3228CU, 0xDAD032U, 0x89C9E3U, 0x820A2CU, 0xCAB91DU, 0x91A4C6U, 0x985673U, 0xE34DB8U, 0xA8DCE5U, 0xB52756U,
|
|
||||||
0xFE358BU, 0xE6EE78U, 0x0DDF75U, 0x5654AFU, 0x5F075AU, 0x04BFC1U, 0x0D2CB4U, 0x56577FU, 0x34C6C2U, 0x2D9D11U,
|
|
||||||
0x662F48U, 0x3FB4FFU, 0x34E536U, 0x4F4E89U, 0xC61C58U, 0x988107U, 0xD132A7U, 0xCA6978U, 0x81D881U, 0xB8C296U,
|
|
||||||
0xF3114FU, 0xAA2AA8U, 0xA0FB31U, 0xF37142U, 0xDA429FU, 0x819B24U, 0x4888E1U, 0x5333FAU, 0x1AE30FU, 0x40D0D5U,
|
|
||||||
0x6F0B68U, 0x36182BU, 0x3DA0F6U, 0x646345U, 0x2F7898U, 0x14CDF3U, 0x5C9666U, 0xC704BDU, 0x8E7F4CU, 0xDDEED3U,
|
|
||||||
0xD655BAU, 0xAF062DU, 0xE49EF5U, 0xFDFD02U, 0xB7661BU, 0xA8F7F4U, 0xC18D25U, 0x9A1E9AU, 0x9305CBU, 0x48F414U,
|
|
||||||
0x43EFB5U, 0x1B1D6AU, 0x708413U, 0x698780U, 0x2A7C4DU, 0x6168BFU, 0x78F3A2U, 0x130059U, 0x0B1BCCU, 0x40CA07U,
|
|
||||||
0x1FF072U, 0x9663E9U, 0xCD9A14U, 0xE499C7U, 0xBF0AEAU, 0xF57239U, 0xECE1E4U, 0xA7BA5FU, 0xDE098FU, 0xD591E0U,
|
|
||||||
0x86E271U, 0x8F79AEU, 0xD52817U, 0x1C8350U, 0x2711A9U, 0x684C3EU, 0x71FFE7U, 0x3AE490U, 0x633619U, 0x498FE6U,
|
|
||||||
0x10DC37U, 0x1B670DU, 0x4066D8U, 0x09BC13U, 0x328FAEU, 0xFB16FDU, 0xA9C500U, 0xA2FF93U, 0xFB2C5EU, 0xF03565U,
|
|
||||||
0x8D86B0U, 0xC65D4BU, 0xDD7DCEU, 0x95E615U, 0x8EB169U, 0xE708FAU, 0xBCDB03U, 0x37C1C4U, 0x6E72FDU, 0x25232AU,
|
|
||||||
0x3DB8F3U, 0x5ECA4CU, 0x45430DU, 0x0CF0B2U, 0x57AB61U, 0x5E3ABCU, 0x210087U, 0x2BD343U, 0xF248B8U, 0xB9392DU,
|
|
||||||
0xA0A376U, 0xEBB09FU, 0x905908U, 0x99CAF1U, 0xD3F5A6U, 0xCA251FU, 0x813ED0U, 0xF2CD01U, 0xFBD63EU, 0xA046EEU,
|
|
||||||
0x29BD51U, 0x76AE98U, 0x3C274FU, 0x055476U, 0x4ECEA5U, 0x573F58U, 0x1C24DBU, 0x47B786U, 0x6ECC7DU, 0x345CE8U,
|
|
||||||
0x7D0703U, 0x66B456U, 0xAF3DECU, 0xBC6F31U, 0xD7D0A2U, 0x8EC1CFU, 0x80321CU, 0xD9A9A1U, 0xD2FB7AU, 0xA9422BU,
|
|
||||||
0xE05184U, 0xFB8A55U, 0xB22AAAU, 0xE831B3U, 0x63E264U, 0x1ADB8CU, 0x11081BU, 0x4832E2U, 0x0BA1BDU, 0x10781CU,
|
|
||||||
0x784BC3U, 0x679052U, 0x2E902DU, 0x752BFCU, 0x7EFC57U, 0x27C58AU, 0xCC57D9U, 0xD40C64U, 0x9FBFB6U, 0x84665BU,
|
|
||||||
0xCD7540U, 0xB6CF95U, 0xBF8E6EU, 0xE415FBU, 0xE62690U, 0xBFFE0DU, 0xF04DFEU, 0xC91623U, 0x028520U, 0x19BCD9U,
|
|
||||||
0x506E06U, 0x0AEDB6U, 0x23D4E9U, 0x780728U, 0x331997U, 0x3AE84EU, 0x6173B9U, 0x6840A0U, 0x129B67U, 0x598B9EU,
|
|
||||||
0xC87009U, 0x877370U, 0x9EEAEBU, 0xF5190EU, 0xAC03D4U, 0xA690C1U, 0xFDE93AU, 0xB47AF7U, 0xAF8044U, 0xC69119U,
|
|
||||||
0xDD0ACAU, 0x166977U, 0x4EF0BCU, 0x45E2C9U, 0x3C1D52U, 0x3F8E87U, 0x64D73CU, 0x296574U, 0x327E83U, 0x7A8F1AU,
|
|
||||||
0x0114EDU, 0x0A1734U, 0x53EF3BU, 0xD8FCCAU, 0x812715U, 0xEA94A4U, 0xF185EBU, 0xB95F3AU, 0xA26C85U, 0xEBB55CU,
|
|
||||||
0xB0862AU, 0x930CA3U, 0xCEDD70U, 0x85E6CDU, 0x9D7196U, 0x562A63U, 0x6D9AE8U, 0x24411DU, 0x7F5246U, 0x76EBDBU,
|
|
||||||
0x2DB928U, 0x2712E5U, 0x5E83D7U, 0x15D80AU, 0x0C6BD1U, 0x473170U, 0x54A02FU, 0xB99B9EU, 0xE34841U, 0xEAD090U,
|
|
||||||
0xB1E33FU, 0xFA2866U, 0xE31991U, 0x88C208U, 0x8154FFU, 0xDB6FB7U, 0x92BE28U, 0x89A5D9U, 0xE25606U, 0x7BCE37U,
|
|
||||||
0x30FDFCU, 0x693E21U, 0x6F2792U, 0x3495CFU, 0x5DCE6CU, 0x465DB1U, 0x0FA46AU, 0x14B75FU, 0x5F2D85U, 0x275C60U,
|
|
||||||
0x2CC7FBU, 0xF56486U, 0xFE3C55U, 0xA5ABC8U, 0xECD02BU, 0xD743F2U, 0x9FDAC5U, 0xC0A81CU, 0xC33383U, 0x9A2262U,
|
|
||||||
0xB1D93DU, 0xE8DA8DU, 0x232252U, 0x39B19BU, 0x70AAACU, 0x6B5975U, 0x024182U, 0x59921BU, 0x522974U, 0x0B38A5U,
|
|
||||||
0x01F33EU, 0x78C1CBU, 0x3758D0U, 0x242F3DU, 0xEDB4EFU, 0xB66672U, 0xBF5701U, 0xC5CCDCU, 0xCE9F77U, 0x9726A2U,
|
|
||||||
0xDCA4F9U, 0xC5FF4CU, 0xAE4E87U, 0xB51576U, 0xFDA7E9U, 0xA63C90U, 0x2F6D47U, 0x74D6CFU, 0x1BC538U, 0x0A1D21U,
|
|
||||||
0x413EDEU, 0x58E50FU, 0x127480U, 0x6B4BF1U, 0x60992EU, 0x2BA297U, 0x327340U, 0x79E809U, 0xA0DABAU, 0x8A0367U,
|
|
||||||
0xD1009DU, 0x98BB98U, 0x836A63U, 0xCE70F6U, 0xF5832DU, 0xB69850U, 0xEE29D3U, 0xE5732EU, 0xBCE0FDU, 0xB75962U,
|
|
||||||
0x4C1A13U, 0x0589DCU, 0x1EF165U, 0x5666B7U, 0x4DFDEAU, 0x268E59U, 0x7F1794U, 0x74256FU, 0x29FE7AU, 0x626F81U,
|
|
||||||
0x700404U, 0x1996DFU, 0x828FA2U, 0xCB7C31U, 0x9067CCU, 0x9B940EU, 0xE20C17U, 0xE81FE8U, 0xB1E439U, 0xFAF586U,
|
|
||||||
0xE17FC7U, 0xA88C18U, 0xD397A1U, 0x5E4276U, 0x04794FU, 0x0FEB88U, 0x5E9271U, 0x3501E6U, 0x2C9A3EU, 0x67EA51U,
|
|
||||||
0x7C61C0U, 0x34323BU, 0x6F89EEU, 0x4618F5U, 0x1D4218U, 0xD4F1CBU, 0xCFE876U, 0x841B25U, 0xB888F8U, 0xF3D053U,
|
|
||||||
0xAA7386U, 0xA168BCU, 0xF2BB69U, 0xFB8792U, 0x80541FU, 0xC8CF4CU, 0xC3FEB5U, 0x182522U, 0x1117CBU, 0x6A9E9CU,
|
|
||||||
0x234D05U, 0x3876FAU, 0x72A42BU, 0x2FBD84U, 0x240ED4U, 0x5DD54BU, 0x56C4B2U, 0x057E65U, 0x4C2D4CU, 0xD7849BU,
|
|
||||||
0xBFD762U, 0xA44DF9U, 0xEFFEACU, 0xB6A347U, 0xBD30D2U, 0xC40B29U, 0x8FDB74U, 0x9540E6U, 0xDC330BU, 0xC3BAD8U,
|
|
||||||
0x8A89E5U, 0x71533EU, 0x7AC0BBU, 0x2BB140U, 0x212A11U, 0x7838AEU, 0x13C17FU, 0x08D290U, 0x414989U, 0x1AA85EU,
|
|
||||||
0x13B2A6U, 0x494131U, 0x625AD8U, 0xBBCF87U, 0xF43516U, 0xED26E9U, 0xA6BF78U, 0x9FCC17U, 0xDD57CEU, 0x86B75DU,
|
|
||||||
0x8FACA0U, 0xD43FE3U, 0x9D445EU, 0xA6D584U, 0x6DCF71U, 0x753C6AU, 0x3EA5AFU, 0x67F654U, 0x4C4CC9U, 0x134DBAU,
|
|
||||||
0x1AB667U, 0x4125E4U, 0x097E19U, 0x12CA0AU, 0x71D1F3U, 0x78022CU, 0xA33BACU, 0xEAA953U, 0xF17A02U, 0x9B53BDU,
|
|
||||||
0xC28074U, 0xC9BB83U, 0x90299AU, 0x9BF04DU, 0xC4C3B4U, 0xAD583BU, 0xB7084AU, 0xFEB3D1U, 0x656004U, 0x2E69FEU,
|
|
||||||
0x5FDAF3U, 0x548000U, 0x0D37DDU, 0x472E4EU, 0x5CFD33U, 0x1546F8U, 0x2E164DU, 0x678D96U, 0x3CBEE3U, 0x337768U,
|
|
||||||
0xEBE5BDU, 0xC09E47U, 0x990D5EU, 0xD234A9U, 0xC9E720U, 0x887DF7U, 0xD34C0EU, 0xFB9711U, 0xA084E0U, 0xA96C2FU,
|
|
||||||
0xF27FBEU, 0xB9E4C1U, 0x001318U, 0x4B02AFU, 0x56B867U, 0x1CEB30U, 0x477289U, 0x4E8152U, 0x358AF7U, 0x3C1AACU,
|
|
||||||
0x676159U, 0x24F2C2U, 0x3C6917U, 0x57197CU, 0x8E82E1U, 0x85F112U, 0xDE68CFU, 0xD77BDDU, 0x8C9130U, 0xE400EBU,
|
|
||||||
0xFB5B5EU, 0xB0E885U, 0xA9F6D4U, 0xE2277BU, 0x9B9CA2U, 0x108F15U, 0x5A764CU, 0x0B64ABU, 0x00AF32U, 0x599CEDU,
|
|
||||||
0x72059DU, 0x29D702U, 0x60ECE3U, 0x7A7D3CU, 0x330625U, 0x0C95D6U, 0x474D0BU, 0x9E7EA8U, 0x95FDF5U, 0xCCA666U,
|
|
||||||
0x86179BU, 0xBD8D40U, 0xFCDA65U, 0xE763BFU, 0xAE304AU, 0xF58AD1U, 0xDE9B9CU, 0x86406FU, 0x8DE3F2U, 0x54B801U,
|
|
||||||
0x1B28D8U, 0x0213D7U, 0x69C026U, 0x7259B9U, 0x3A6B48U, 0x61B017U, 0x68819FU, 0x135A68U, 0x50D9B1U, 0x49E386U,
|
|
||||||
0x02325FU, 0x9A29B0U, 0xD19E23U, 0xAAC77EU, 0xA3558DU, 0xFCAE04U, 0xF5BFF3U, 0xAE04AAU, 0xC44635U, 0xDDDDC5U,
|
|
||||||
0x966C4AU, 0xCF373BU, 0xC4A4E4U, 0x1FD47DU, 0x3E4F8AU, 0x64DC43U, 0x2DA574U, 0x3637ADU, 0x7D5C56U, 0x44CFC3U,
|
|
||||||
0x0BD688U, 0x52257DU, 0x59BBE7U, 0x03AA1AU, 0x4A5119U, 0xF142C4U, 0xB89A37U, 0xB329AAU, 0xE822D1U, 0xA9D114U,
|
|
||||||
0x93C88FU, 0xDA5A7AU, 0xC1A121U, 0x8AB090U, 0xD36B5EU, 0xDC58A7U, 0xA5C0B0U, 0x2F8369U, 0x74389EU, 0x3DAB17U,
|
|
||||||
0x26D368U, 0x4F40F9U, 0x141F26U, 0x1DAEC7U, 0x473558U, 0x446721U, 0x1DDEF6U, 0x769D6EU, 0xEF0E8DU, 0xA434D0U,
|
|
||||||
0xBFE56BU, 0xF35EBEU, 0x884D45U, 0x819440U, 0xDAA69BU, 0x917D26U, 0x88ECF5U, 0xC3C788U, 0xFB150BU, 0xB02ED6U,
|
|
||||||
0x63BF24U, 0x6A6439U, 0x3153D2U, 0x188B03U, 0x43989CU, 0x0923EDU, 0x147232U, 0x5FF99BU, 0x060B4CU, 0x2D10B5U,
|
|
||||||
0x76A1A2U, 0x7FFA7BU, 0xA568D4U, 0xECD104U, 0xD7827BU, 0x9C19EAU, 0x8D6831U, 0xC6E2DCU, 0x9F71CFU, 0x950A32U,
|
|
||||||
0xEE9BE1U, 0xA3A16CU, 0xB8761FU, 0xF16FC2U, 0x6A9C79U, 0x010FACU, 0x491786U, 0x52F453U, 0x1BEF88U, 0x007C35U,
|
|
||||||
0x4B8566U, 0x32978FU, 0x316C18U, 0x697DC1U, 0x62E6BEU, 0x3B142FU, 0xD40DC0U, 0xCFCE11U, 0x86F58EU, 0xDD66F6U,
|
|
||||||
0xD53E31U, 0x8E8988U, 0xA5125FU, 0xFC6366U, 0xB7F9B9U, 0xAEAA78U, 0xE513C3U, 0xD69096U, 0x1ECB6DU, 0x4579F8U,
|
|
||||||
0x4C6033U, 0x13B34EU, 0x5888DCU, 0x615821U, 0x2AE3F2U, 0x32F0FFU, 0x792B04U, 0x220A91U, 0x0B906AU, 0xD0432BU,
|
|
||||||
0xD97294U, 0x82AD4DU, 0xC8BE9AU, 0xD90623U, 0xB2D564U, 0xEBEE9CU, 0xE02D03U, 0xBF35D2U, 0xB686ADU, 0xCCDD2CU,
|
|
||||||
0x854CD3U, 0x1EF70AU, 0x55A51DU, 0x4C1CE4U, 0x074F67U, 0x7ED49AU, 0x7476C9U, 0x2F2F75U, 0x26BCBEU, 0x75876BU,
|
|
||||||
0x1C5650U, 0x07C885U, 0x48BB7EU, 0x9022F3U, 0x9B11A0U, 0xC2CA5DU, 0xE9C8CEU, 0xA07133U, 0xFBA238U, 0xF0B9E9U,
|
|
||||||
0xA84917U, 0x835286U, 0xDAC179U, 0x913830U, 0x822B87U, 0x4BD95EU, 0x30D289U, 0x3C43A0U, 0x67B87FU, 0x6CAA8EU,
|
|
||||||
0x353311U, 0x7E4440U, 0x47DFABU, 0x0C8E3FU, 0x1634C4U, 0x5FA7D9U, 0x04CC0AU, 0xAD5DE7U, 0xF64774U, 0xBDB409U,
|
|
||||||
0xAC2DD2U, 0xE67E67U, 0xFBC5ACU, 0x90D5F9U, 0xCB0E42U, 0xC23D9FU, 0x99B67DU, 0x9047E4U, 0xEA5DB3U, 0x218E0AU,
|
|
||||||
0x38B7D5U, 0x732034U, 0x6AFA2BU, 0x21CBFAU, 0x5A1005U, 0x5B039CU, 0x01A8FBU, 0x4C7822U, 0x574395U, 0x3CD04DU,
|
|
||||||
0xA5811AU, 0xEE3BB3U, 0xB76868U, 0xBDF19DU, 0xE64286U, 0xCF1943U, 0x949BF8U, 0xDDA225U, 0xC67156U, 0x8FCACBU,
|
|
||||||
0xF59B08U, 0xF605F5U, 0x2B36EFU, 0x20EF1AU, 0x797CC1U, 0x324664U, 0x1985BFU, 0x419CE4U, 0x4A6F51U, 0x13748AU,
|
|
||||||
0x58C42FU, 0x631F74U, 0x2A0CA1U, 0x71F51AU, 0xF9E7D7U, 0xA27CA5U, 0xA99F38U, 0xD886EBU, 0x973516U, 0x8E6F1DU,
|
|
||||||
0xC5FEECU, 0xDF0133U, 0xB61282U, 0xED8ADDU, 0xE4F954U, 0xBF7AA3U, 0x74617AU, 0x6D904DU, 0x070A95U, 0x1E795AU,
|
|
||||||
0x55E0EBU, 0x0EF334U, 0x0F0845U, 0x7098CAU, 0x798313U, 0x2360E0U, 0x687BFDU, 0x71AB0EU, 0xBA10C3U, 0x830370U,
|
|
||||||
0xC8FA2DU, 0x93EDB7U, 0x9B3742U, 0xC00689U, 0xA99DBCU, 0xB25E67U, 0xF964BAU, 0xE0F509U, 0xA7AE44U, 0xFF1DB7U,
|
|
||||||
0x54C42EU, 0x0DF6F1U, 0x066D90U, 0x5D3C0EU, 0x1487FFU, 0x2F8460U, 0x675E19U, 0x3CEFDEU, 0x37B447U, 0x6E27B0U,
|
|
||||||
0x651369U, 0x9CC856U, 0xD77B97U, 0xC9604CU, 0x88B1F9U, 0x939BA2U, 0xFA4856U, 0xB1D1DDU, 0xAAE200U, 0xE33873U,
|
|
||||||
0xB829EEU, 0xB0D20DU, 0xCBC190U, 0x407AEBU, 0x19AA3EU, 0x52A1A5U, 0x4B1240U, 0x204B1BU, 0x3ED9A2U, 0x7F2274U,
|
|
||||||
0x2437ADU, 0x2DAC8AU, 0x76DF53U, 0x5D45ACU, 0x04F43DU, 0xCEBFE2U, 0xD72CC3U, 0x9C551CU, 0xE7C7E5U, 0xEEDC72U,
|
|
||||||
0xB52D1BU, 0xBCB6CCU, 0xE6A454U, 0xA95FA7U, 0x904EFAU, 0xD3A551U, 0xCA3684U, 0x01265FU, 0x5ADD6AU, 0x72CEB1U,
|
|
||||||
0x29135CU, 0x60A1CFU, 0x7BBA92U, 0x304921U, 0x2950FCU, 0x42D316U, 0x1AA903U, 0x1138F8U, 0x48E329U, 0xC7D0A6U,
|
|
||||||
0xBC48DFU, 0xFD1B08U, 0xE6A0B1U, 0xAE3366U, 0xF55AAFU, 0xFEC898U, 0x879341U, 0x8C22FEU, 0xD5392EU, 0x9EEA61U,
|
|
||||||
0x8456D0U, 0x6D450BU, 0x769EF6U, 0x3FADE5U, 0x606508U, 0x6BD6DBU, 0x3ACD46U, 0x101C3DU, 0x5927F8U, 0x02F543U,
|
|
||||||
0x096C96U, 0x505FCCU, 0xBB8C71U, 0xA296B2U, 0xE8370FU, 0xF36C5CU, 0xBADF85U, 0xE1063AU, 0xC814FBU, 0x97AF04U,
|
|
||||||
0x9CFA15U, 0xC461EAU, 0x87D23BU, 0xBE88B4U, 0x7509CCU, 0x2E721BU, 0x27E1A2U, 0x7C5965U, 0x750A7CU, 0x0F9183U,
|
|
||||||
0x44A052U, 0x5D7BE9U, 0x1669ACU, 0x0F9277U, 0x6013CAU, 0x3B0819U, 0xB3FA65U, 0xE0E3E6U, 0xA9103BU, 0xB28BC0U,
|
|
||||||
0xDB9ED5U, 0xC0642EU, 0x8B77EBU, 0xD3EC50U, 0xD80D89U, 0xA1179EU, 0xAAC477U, 0xF1F5A0U, 0x386E19U, 0x271D4FU,
|
|
||||||
0x6F8596U, 0x541639U, 0x1F6DE8U, 0x4EFE97U, 0x45B706U, 0x1C05D9U, 0x779E30U, 0x6DCF27U, 0x2474DEU, 0x3F664DU,
|
|
||||||
0xF69BB0U, 0xAD08FBU, 0x86536FU, 0xDFE094U, 0xD1E841U, 0x883B6AU, 0xC300B7U, 0xE8D164U, 0xB16BD9U, 0xF2788AU,
|
|
||||||
0xEBA167U, 0xA192FCU, 0x3A0929U, 0x53DBD2U, 0x08F2C3U, 0x01212DU, 0x5A3ABCU, 0x518B43U, 0x29D11AU, 0x62628DU,
|
|
||||||
0x7FFD64U, 0x34ACB3U, 0x6F1E8AU, 0xE64555U, 0x95C494U, 0x9D7F2BU, 0xC62C7AU, 0x8DB485U, 0x94871DU, 0xFF5CDEU,
|
|
||||||
0xE6EFE3U, 0xADB730U, 0xF524CFU, 0xFE0F56U, 0xA5DE31U, 0x48C5E8U, 0x53377FU, 0x1AAE86U, 0x01BD59U, 0x4B4678U,
|
|
||||||
0x3A50A7U, 0x31E977U, 0x683ACCU, 0x633189U, 0x38C072U, 0x71DAEFU, 0x4B493CU, 0x82B001U, 0x99A3C2U, 0xD2383FU,
|
|
||||||
0x8F4AA4U, 0xA4D3D1U, 0xFDA00AU, 0xB62B8FU, 0xACBB75U, 0xE5C028U, 0xF6539BU, 0x9F4242U, 0xC4B985U, 0x4F2FBCU,
|
|
||||||
0x167463U, 0x1CC5D2U, 0x65DE1DU, 0x2E3C4CU, 0x35A5F3U, 0x78F622U, 0x234DDDU, 0x0A5C55U, 0x408622U, 0x5BB5FBU,
|
|
||||||
0x122E6CU, 0xC1FF95U, 0xC8C4DEU, 0xB3066BU, 0xB83FB0U, 0xE0AC25U, 0xAB775EU, 0xB24793U, 0xD9DC20U, 0x828BFDU,
|
|
||||||
0x8F30AFU, 0xD46102U, 0xDCDBD9U, 0x07582CU, 0x6E0137U, 0x75B2C6U, 0x3EE809U, 0x2F7990U, 0x64C2E7U, 0x1C913EU,
|
|
||||||
0x170A89U, 0x4C3A40U, 0x45E9D6U, 0x1E42AFU, 0x571370U, 0xE889C1U, 0xA2BA0EU, 0xFB635FU, 0xF070E0U, 0xA9CF39U,
|
|
||||||
0x821DDAU, 0xD904C7U, 0x90F734U, 0x82FCE9U, 0xCB4D72U, 0xD09716U, 0x3B848DU, 0x623D78U, 0x696EA3U, 0x30F4BEU,
|
|
||||||
0x7A075DU, 0x451E80U, 0x0C8D33U, 0x17E66EU, 0x5E76B5U, 0x050D14U, 0x0E9ECBU, 0x7607BAU, 0xF57524U, 0xACEAC5U,
|
|
||||||
0xE7F91AU, 0xFC0083U, 0x9583F4U, 0xCED96DU, 0xC6688AU, 0x9D7353U, 0x92804CU, 0xCB11BDU, 0xA00B62U, 0xA9F8C3U,
|
|
||||||
0x72E398U, 0x783244U, 0x2118F7U, 0x4A8B2AU, 0x5B5249U, 0x1061D4U, 0x09FA2FU, 0x428ABAU, 0x1911F1U, 0x31C604U,
|
|
||||||
0x6AFD9FU, 0x276D62U, 0xBC2631U, 0xF795B8U, 0xCE4C4EU, 0x855F97U, 0xDDE520U, 0xD6B479U, 0x8D0FB6U, 0x8C1C07U,
|
|
||||||
0xF7C6D8U, 0xBE77A9U, 0xA53C36U, 0xEFAFDFU, 0x369648U, 0x1D4411U, 0x40DFE6U, 0x4BEE7EU, 0x103595U, 0x5902C0U,
|
|
||||||
0x43D85BU, 0x2AC9AEU, 0x316265U, 0x7AB158U, 0x23A18BU, 0x201A56U, 0xD949E5U, 0x93F2A8U, 0x882313U, 0xC139C6U,
|
|
||||||
0xDA8A3CU, 0x97D329U, 0xEC50E2U, 0xE7AA13U, 0xBFBB8CU, 0xB42075U, 0xED5322U, 0x06C8ABU, 0x1DF85CU, 0x542785U,
|
|
||||||
0x0FB4BAU, 0x0FCD7BU, 0x544FA4U, 0x7F5414U, 0x26A54BU, 0x6D3EF2U, 0x702D31U, 0x3BD7CCU, 0x13C6DFU, 0xC83D02U,
|
|
||||||
0x83AEF9U, 0x9AB77CU, 0xD15507U, 0xC84ED2U, 0xA3DF49U, 0xF9A4BDU, 0xF836F6U, 0xA3ED4BU, 0xEADC98U, 0xD14B05U,
|
|
||||||
0x9A30E6U, 0x03A0BFU, 0x4D6B00U, 0x1458D1U, 0x1FC12EU, 0x64932FU, 0x6D28F0U, 0x36BB09U, 0x7FE29FU, 0x6551E6U,
|
|
||||||
0x0E0B21U, 0x57AAB8U, 0x54B147U, 0x8D6216U, 0x86DBA9U, 0xDDC968U, 0xB412F3U, 0xAA218EU, 0xE3FC5DU, 0xF86EF0U,
|
|
||||||
0xB35523U, 0xCA945FU, 0xC1AFCCU, 0x983C11U, 0xD264FAU, 0x49D7EFU, 0x000C14U, 0x3B1FC1U, 0x7AA75AU, 0x21F4B7U,
|
|
||||||
0x2A6FA4U, 0x728E5DU, 0x5D958AU, 0x042713U, 0x4F767DU, 0x54EDACU, 0x1D5E13U, 0x8604C0U, 0xEE91ADU, 0xB5EA36U,
|
|
||||||
0xBC79E3U, 0xE77018U, 0xAC820DU, 0x9D19E6U, 0xD6283FU, 0xCEF3A8U, 0x85E0D1U, 0xDA1A47U, 0x538BAEU, 0x389079U,
|
|
||||||
0x216360U, 0x6A6B9FU, 0x30D84EU, 0x3903E1U, 0x421230U, 0x0BE94FU, 0x10FBD6U, 0x5B6011U, 0x4215E8U, 0x008EFBU,
|
|
||||||
0xF95C07U, 0xF2759CU, 0xADE659U, 0xA49D22U, 0xFF0CB7U, 0x96964CU, 0x8CE591U, 0xC77E92U, 0x9E2F6FU, 0x959CBCU,
|
|
||||||
0xCC0601U, 0xE7475AU, 0x3CFCBFU, 0x74EF25U, 0x6717F4U, 0x2E048BU, 0x15DF0AU, 0x5A6CF5U, 0x03716CU, 0x08A33BU,
|
|
||||||
0x5098C2U, 0x5B1945U, 0x20C2BCU, 0x69F063U, 0xF22972U, 0xBB1A8DU, 0xE0814DU, 0xCA52F6U, 0x936AABU, 0x98B958U,
|
|
||||||
0xC9A2C5U, 0x820306U, 0x9B593BU, 0xF4CAE0U, 0xEE7315U, 0xA7209EU, 0x7C9BCBU, 0x75C930U, 0x0E54A4U, 0x45E75FU,
|
|
||||||
0x5CBC12U, 0x173D81U, 0x0F0778U, 0x44D4AFU, 0x3FC596U, 0x363E59U, 0x65ACE8U, 0x6C9737U, 0xA346E6U, 0xD95DD9U,
|
|
||||||
0xD0FE10U, 0x8B26E6U, 0xC2357FU, 0xD9CE28U, 0x92DDC1U, 0xAB455EU, 0xE1B6AFU, 0xB8ADF4U, 0xB35861U, 0x68438AU,
|
|
||||||
0x41C157U, 0x12B864U, 0x5B2BB9U, 0x45B00AU, 0x0EC3C6U, 0x175B95U, 0x7C2828U, 0x25B3F3U, 0x2E2206U, 0x75580DU,
|
|
||||||
0x3DDBD8U, 0x86C223U, 0xCF31BAU, 0xD4AADDU, 0x9FF804U, 0xC64193U, 0xCD526AU, 0xBDA9F4U, 0xB2BD95U, 0xE92E4AU,
|
|
||||||
0xA0C5FBU, 0xBBD424U, 0xD20F7DU, 0x093DDAU, 0x01A603U, 0x5A77F0U, 0x514CEDU, 0x089E36U, 0x63A7D3U, 0x7A3448U,
|
|
||||||
0x31FF3CU, 0x2BCEE7U, 0x625462U, 0x150799U, 0x1CBC84U, 0xC7ED77U, 0x8C76AAU, 0x95C409U, 0xDF9954U, 0xE62A8FU,
|
|
||||||
0xAD213EU, 0xF6F1E1U, 0xFF4A00U, 0xA4191EU, 0x8D82C7U, 0xD7B330U, 0x9C69A9U, 0x057ACEU, 0x42C357U, 0x2B1088U,
|
|
||||||
0x303A79U, 0x7BEB76U, 0x63F087U, 0x284358U, 0x7198E1U, 0x5A88B2U, 0x017B7EU, 0x0860CDU, 0x53F510U, 0x9A0F63U,
|
|
||||||
0xA00CFEU, 0xEBB535U, 0xF2E6C0U, 0xB97DDBU, 0xEC0F2EU, 0xE796B5U, 0x9C0578U, 0xD47E0BU, 0xCFEF92U, 0x86F564U,
|
|
||||||
0x1D16ADU, 0x768F32U, 0x2FFC43U, 0x24669CU, 0x7C752DU, 0x778CE2U, 0x2E1F9BU, 0x45000CU, 0x5EF0D5U, 0x13FB62U,
|
|
||||||
0x40282BU, 0x4811D4U, 0xB38344U, 0xB8789FU, 0xE16BEAU, 0xAAB261U, 0xB38194U, 0xF81B4FU, 0xC2CA52U, 0x8BE1B1U,
|
|
||||||
0xD0726CU, 0xD903DFU, 0x829982U, 0xE94A79U, 0x7471FDU, 0x36E026U, 0x2FBA93U, 0x640DC8U, 0x3F1431U, 0x16D7B6U,
|
|
||||||
0x4D6C6FU, 0x443C18U, 0x1E8781U, 0x55947EU, 0x6C4FBFU, 0x27FFA0U, 0xBEE451U, 0xF5378FU, 0xAE0E2EU, 0xA2CD71U,
|
|
||||||
0xC9D7C8U, 0x98661FU, 0x93BDC6U, 0xC88EE5U, 0xC15438U, 0xBA45C3U, 0xF2FE56U, 0xE9290DU, 0x2230E8U, 0x3B9273U,
|
|
||||||
0x70C98FU, 0x0958DCU, 0x02A343U, 0x58B0A2U, 0x150A7DU, 0x0E5BC4U, 0x6FC897U, 0x74F33AU, 0x3F23E9U, 0x66A834U,
|
|
||||||
0xECDB0FU, 0xB542DAU, 0x9E5131U, 0xC7ABA5U, 0x8C38FEU, 0x97010BU, 0xDED290U, 0xA4CC7DU, 0xAD3D2EU, 0xF6B6B3U,
|
|
||||||
0xF9A540U, 0x205ED9U, 0x634EB6U, 0x5A9567U, 0x11A6D8U, 0x0B3F09U };
|
|
||||||
|
|
||||||
const unsigned int A_TABLE[] = { 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, 32U, 36U, 40U, 44U,
|
|
||||||
48U, 52U, 56U, 60U, 64U, 68U, 1U, 5U, 9U, 13U, 17U, 21U };
|
|
||||||
const unsigned int B_TABLE[] = { 25U, 29U, 33U, 37U, 41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U,
|
|
||||||
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U };
|
|
||||||
const unsigned int C_TABLE[] = { 46U, 50U, 54U, 58U, 62U, 66U, 70U, 3U, 7U, 11U, 15U, 19U,
|
|
||||||
23U, 27U, 31U, 35U, 39U, 43U, 47U, 51U, 55U, 59U, 63U, 67U, 71U };
|
|
||||||
|
|
||||||
CNXDNAudio::CNXDNAudio()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNAudio::~CNXDNAudio()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNAudio::decode(const unsigned char* in, unsigned char* out) const
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
decode(in + 0U, out, 0U);
|
|
||||||
decode(in + 9U, out, 49U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNAudio::encode(const unsigned char* in, unsigned char* out) const
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
encode(in, out + 0U, 0U);
|
|
||||||
encode(in, out + 9U, 49U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNAudio::decode(const unsigned char* in, unsigned char* out, unsigned int offset) const
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
unsigned int a = 0U;
|
|
||||||
unsigned int MASK = 0x800000U;
|
|
||||||
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
|
|
||||||
unsigned int aPos = A_TABLE[i];
|
|
||||||
if (READ_BIT(in, aPos))
|
|
||||||
a |= MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int b = 0U;
|
|
||||||
MASK = 0x400000U;
|
|
||||||
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
|
|
||||||
unsigned int bPos = B_TABLE[i];
|
|
||||||
if (READ_BIT(in, bPos))
|
|
||||||
b |= MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int c = 0U;
|
|
||||||
MASK = 0x1000000U;
|
|
||||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
|
||||||
unsigned int cPos = C_TABLE[i];
|
|
||||||
if (READ_BIT(in, cPos))
|
|
||||||
c |= MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
a >>= 12;
|
|
||||||
|
|
||||||
// The PRNG
|
|
||||||
b ^= (PRNG_TABLE[a] >> 1);
|
|
||||||
b >>= 11;
|
|
||||||
|
|
||||||
MASK = 0x000800U;
|
|
||||||
for (unsigned int i = 0U; i < 12U; i++, MASK >>= 1) {
|
|
||||||
unsigned int aPos = i + offset + 0U;
|
|
||||||
unsigned int bPos = i + offset + 12U;
|
|
||||||
WRITE_BIT(out, aPos, a & MASK);
|
|
||||||
WRITE_BIT(out, bPos, b & MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
MASK = 0x1000000U;
|
|
||||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
|
||||||
unsigned int cPos = i + offset + 24U;
|
|
||||||
WRITE_BIT(out, cPos, c & MASK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNAudio::encode(const unsigned char* in, unsigned char* out, unsigned int offset) const
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
unsigned int aOrig = 0U;
|
|
||||||
unsigned int bOrig = 0U;
|
|
||||||
unsigned int cOrig = 0U;
|
|
||||||
|
|
||||||
unsigned int MASK = 0x000800U;
|
|
||||||
for (unsigned int i = 0U; i < 12U; i++, MASK >>= 1) {
|
|
||||||
unsigned int n1 = i + offset + 0U;
|
|
||||||
unsigned int n2 = i + offset + 12U;
|
|
||||||
if (READ_BIT(in, n1))
|
|
||||||
aOrig |= MASK;
|
|
||||||
if (READ_BIT(in, n2))
|
|
||||||
bOrig |= MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
MASK = 0x1000000U;
|
|
||||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
|
||||||
unsigned int n = i + offset + 24U;
|
|
||||||
if (READ_BIT(in, n))
|
|
||||||
cOrig |= MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int a = CGolay24128::encode24128(aOrig);
|
|
||||||
|
|
||||||
// The PRNG
|
|
||||||
unsigned int p = PRNG_TABLE[aOrig] >> 1;
|
|
||||||
|
|
||||||
unsigned int b = CGolay24128::encode23127(bOrig) >> 1;
|
|
||||||
b ^= p;
|
|
||||||
|
|
||||||
MASK = 0x800000U;
|
|
||||||
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
|
|
||||||
unsigned int aPos = A_TABLE[i];
|
|
||||||
WRITE_BIT(out, aPos, a & MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
MASK = 0x400000U;
|
|
||||||
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
|
|
||||||
unsigned int bPos = B_TABLE[i];
|
|
||||||
WRITE_BIT(out, bPos, b & MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
MASK = 0x1000000U;
|
|
||||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
|
||||||
unsigned int cPos = C_TABLE[i];
|
|
||||||
WRITE_BIT(out, cPos, cOrig & MASK);
|
|
||||||
}
|
|
||||||
}
|
|
185
NXDNCRC.cpp
185
NXDNCRC.cpp
|
@ -1,185 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNCRC.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
const uint8_t BIT_MASK_TABLE1[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE1[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE1[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE1[(i)&7])
|
|
||||||
|
|
||||||
bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint8_t crc = createCRC6(in, length);
|
|
||||||
|
|
||||||
uint8_t temp[1U];
|
|
||||||
temp[0U] = 0x00U;
|
|
||||||
unsigned int j = length;
|
|
||||||
for (unsigned int i = 2U; i < 8U; i++, j++) {
|
|
||||||
bool b = READ_BIT1(in, j);
|
|
||||||
WRITE_BIT1(temp, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc == temp[0U];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint8_t crc[1U];
|
|
||||||
crc[0U] = createCRC6(in, length);
|
|
||||||
|
|
||||||
unsigned int n = length;
|
|
||||||
for (unsigned int i = 2U; i < 8U; i++, n++) {
|
|
||||||
bool b = READ_BIT1(crc, i);
|
|
||||||
WRITE_BIT1(in, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint16_t crc = createCRC12(in, length);
|
|
||||||
uint8_t temp1[2U];
|
|
||||||
temp1[0U] = (crc >> 8) & 0xFFU;
|
|
||||||
temp1[1U] = (crc >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
uint8_t temp2[2U];
|
|
||||||
temp2[0U] = 0x00U;
|
|
||||||
temp2[1U] = 0x00U;
|
|
||||||
unsigned int j = length;
|
|
||||||
for (unsigned int i = 4U; i < 16U; i++, j++) {
|
|
||||||
bool b = READ_BIT1(in, j);
|
|
||||||
WRITE_BIT1(temp2, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint16_t crc = createCRC12(in, length);
|
|
||||||
|
|
||||||
uint8_t temp[2U];
|
|
||||||
temp[0U] = (crc >> 8) & 0xFFU;
|
|
||||||
temp[1U] = (crc >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
unsigned int n = length;
|
|
||||||
for (unsigned int i = 4U; i < 16U; i++, n++) {
|
|
||||||
bool b = READ_BIT1(temp, i);
|
|
||||||
WRITE_BIT1(in, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint16_t crc = createCRC15(in, length);
|
|
||||||
uint8_t temp1[2U];
|
|
||||||
temp1[0U] = (crc >> 8) & 0xFFU;
|
|
||||||
temp1[1U] = (crc >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
uint8_t temp2[2U];
|
|
||||||
temp2[0U] = 0x00U;
|
|
||||||
temp2[1U] = 0x00U;
|
|
||||||
unsigned int j = length;
|
|
||||||
for (unsigned int i = 1U; i < 16U; i++, j++) {
|
|
||||||
bool b = READ_BIT1(in, j);
|
|
||||||
WRITE_BIT1(temp2, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
|
|
||||||
uint16_t crc = createCRC15(in, length);
|
|
||||||
|
|
||||||
uint8_t temp[2U];
|
|
||||||
temp[0U] = (crc >> 8) & 0xFFU;
|
|
||||||
temp[1U] = (crc >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
unsigned int n = length;
|
|
||||||
for (unsigned int i = 1U; i < 16U; i++, n++) {
|
|
||||||
bool b = READ_BIT1(temp, i);
|
|
||||||
WRITE_BIT1(in, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
uint8_t crc = 0x3FU;
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < length; i++) {
|
|
||||||
bool bit1 = READ_BIT1(in, i) != 0x00U;
|
|
||||||
bool bit2 = (crc & 0x20U) == 0x20U;
|
|
||||||
|
|
||||||
crc <<= 1;
|
|
||||||
|
|
||||||
if (bit1 ^ bit2)
|
|
||||||
crc ^= 0x27U;
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc & 0x3FU;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
uint16_t crc = 0x0FFFU;
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < length; i++) {
|
|
||||||
bool bit1 = READ_BIT1(in, i) != 0x00U;
|
|
||||||
bool bit2 = (crc & 0x0800U) == 0x0800U;
|
|
||||||
|
|
||||||
crc <<= 1;
|
|
||||||
|
|
||||||
if (bit1 ^ bit2)
|
|
||||||
crc ^= 0x080FU;
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc & 0x0FFFU;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int length)
|
|
||||||
{
|
|
||||||
uint16_t crc = 0x7FFFU;
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < length; i++) {
|
|
||||||
bool bit1 = READ_BIT1(in, i) != 0x00U;
|
|
||||||
bool bit2 = (crc & 0x4000U) == 0x4000U;
|
|
||||||
|
|
||||||
crc <<= 1;
|
|
||||||
|
|
||||||
if (bit1 ^ bit2)
|
|
||||||
crc ^= 0x4CC5U;
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc & 0x7FFFU;
|
|
||||||
}
|
|
42
NXDNCRC.h
42
NXDNCRC.h
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNCRC_H)
|
|
||||||
#define NXDNCRC_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
class CNXDNCRC
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static bool checkCRC6(const unsigned char* in, unsigned int length);
|
|
||||||
static void encodeCRC6(unsigned char* in, unsigned int length);
|
|
||||||
|
|
||||||
static bool checkCRC12(const unsigned char* in, unsigned int length);
|
|
||||||
static void encodeCRC12(unsigned char* in, unsigned int length);
|
|
||||||
|
|
||||||
static bool checkCRC15(const unsigned char* in, unsigned int length);
|
|
||||||
static void encodeCRC15(unsigned char* in, unsigned int length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static uint8_t createCRC6(const unsigned char* in, unsigned int length);
|
|
||||||
static uint16_t createCRC12(const unsigned char* in, unsigned int length);
|
|
||||||
static uint16_t createCRC15(const unsigned char* in, unsigned int length);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
1139
NXDNControl.cpp
1139
NXDNControl.cpp
File diff suppressed because it is too large
Load diff
105
NXDNControl.h
105
NXDNControl.h
|
@ -1,105 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015-2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNControl_H)
|
|
||||||
#define NXDNControl_H
|
|
||||||
|
|
||||||
#include "RSSIInterpolator.h"
|
|
||||||
#include "NXDNNetwork.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNLayer3.h"
|
|
||||||
#include "NXDNLookup.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "StopWatch.h"
|
|
||||||
#include "NXDNLICH.h"
|
|
||||||
#include "Display.h"
|
|
||||||
#include "Defines.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "Modem.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class CNXDNControl {
|
|
||||||
public:
|
|
||||||
CNXDNControl(unsigned int ran, unsigned int id, bool selfOnly, INXDNNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CNXDNLookup* lookup, CRSSIInterpolator* rssiMapper);
|
|
||||||
~CNXDNControl();
|
|
||||||
|
|
||||||
bool writeModem(unsigned char* data, unsigned int len);
|
|
||||||
|
|
||||||
unsigned int readModem(unsigned char* data);
|
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
|
||||||
|
|
||||||
bool isBusy() const;
|
|
||||||
|
|
||||||
void enable(bool enabled);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_ran;
|
|
||||||
unsigned int m_id;
|
|
||||||
bool m_selfOnly;
|
|
||||||
INXDNNetwork* m_network;
|
|
||||||
CDisplay* m_display;
|
|
||||||
bool m_duplex;
|
|
||||||
bool m_remoteGateway;
|
|
||||||
CNXDNLookup* m_lookup;
|
|
||||||
CRingBuffer<unsigned char> m_queue;
|
|
||||||
RPT_RF_STATE m_rfState;
|
|
||||||
RPT_NET_STATE m_netState;
|
|
||||||
CTimer m_rfTimeoutTimer;
|
|
||||||
CTimer m_netTimeoutTimer;
|
|
||||||
CTimer m_packetTimer;
|
|
||||||
CTimer m_networkWatchdog;
|
|
||||||
CStopWatch m_elapsed;
|
|
||||||
unsigned int m_rfFrames;
|
|
||||||
unsigned int m_netFrames;
|
|
||||||
unsigned int m_rfErrs;
|
|
||||||
unsigned int m_rfBits;
|
|
||||||
CNXDNLICH m_rfLastLICH;
|
|
||||||
CNXDNLayer3 m_rfLayer3;
|
|
||||||
CNXDNLayer3 m_netLayer3;
|
|
||||||
unsigned char m_rfMask;
|
|
||||||
unsigned char m_netMask;
|
|
||||||
CRSSIInterpolator* m_rssiMapper;
|
|
||||||
unsigned char m_rssi;
|
|
||||||
unsigned char m_maxRSSI;
|
|
||||||
unsigned char m_minRSSI;
|
|
||||||
unsigned int m_aveRSSI;
|
|
||||||
unsigned int m_rssiCount;
|
|
||||||
bool m_enabled;
|
|
||||||
FILE* m_fp;
|
|
||||||
|
|
||||||
bool processVoice(unsigned char usc, unsigned char option, unsigned char *data);
|
|
||||||
bool processData(unsigned char option, unsigned char *data);
|
|
||||||
|
|
||||||
void writeQueueRF(const unsigned char* data);
|
|
||||||
void writeQueueNet(const unsigned char* data);
|
|
||||||
void writeNetwork(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type);
|
|
||||||
void writeNetwork();
|
|
||||||
|
|
||||||
void scrambler(unsigned char* data) const;
|
|
||||||
|
|
||||||
void writeEndRF();
|
|
||||||
void writeEndNet();
|
|
||||||
|
|
||||||
bool openFile();
|
|
||||||
bool writeFile(const unsigned char* data);
|
|
||||||
void closeFile();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2016,2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNConvolution.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
const uint8_t BRANCH_TABLE1[] = {0U, 0U, 0U, 0U, 2U, 2U, 2U, 2U};
|
|
||||||
const uint8_t BRANCH_TABLE2[] = {0U, 2U, 2U, 0U, 0U, 2U, 2U, 0U};
|
|
||||||
|
|
||||||
const unsigned int NUM_OF_STATES_D2 = 8U;
|
|
||||||
const unsigned int NUM_OF_STATES = 16U;
|
|
||||||
const uint32_t M = 4U;
|
|
||||||
const unsigned int K = 5U;
|
|
||||||
|
|
||||||
CNXDNConvolution::CNXDNConvolution() :
|
|
||||||
m_metrics1(NULL),
|
|
||||||
m_metrics2(NULL),
|
|
||||||
m_oldMetrics(NULL),
|
|
||||||
m_newMetrics(NULL),
|
|
||||||
m_decisions(NULL),
|
|
||||||
m_dp(NULL)
|
|
||||||
{
|
|
||||||
m_metrics1 = new uint16_t[16U];
|
|
||||||
m_metrics2 = new uint16_t[16U];
|
|
||||||
m_decisions = new uint64_t[300U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNConvolution::~CNXDNConvolution()
|
|
||||||
{
|
|
||||||
delete[] m_metrics1;
|
|
||||||
delete[] m_metrics2;
|
|
||||||
delete[] m_decisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNConvolution::start()
|
|
||||||
{
|
|
||||||
::memset(m_metrics1, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
|
||||||
::memset(m_metrics2, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
|
||||||
|
|
||||||
m_oldMetrics = m_metrics1;
|
|
||||||
m_newMetrics = m_metrics2;
|
|
||||||
m_dp = m_decisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNConvolution::decode(uint8_t s0, uint8_t s1)
|
|
||||||
{
|
|
||||||
*m_dp = 0U;
|
|
||||||
|
|
||||||
for (uint8_t i = 0U; i < NUM_OF_STATES_D2; i++) {
|
|
||||||
uint8_t j = i * 2U;
|
|
||||||
|
|
||||||
uint16_t metric = std::abs(BRANCH_TABLE1[i] - s0) + std::abs(BRANCH_TABLE2[i] - s1);
|
|
||||||
|
|
||||||
uint16_t m0 = m_oldMetrics[i] + metric;
|
|
||||||
uint16_t m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric);
|
|
||||||
uint8_t decision0 = (m0 >= m1) ? 1U : 0U;
|
|
||||||
m_newMetrics[j + 0U] = decision0 != 0U ? m1 : m0;
|
|
||||||
|
|
||||||
m0 = m_oldMetrics[i] + (M - metric);
|
|
||||||
m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + metric;
|
|
||||||
uint8_t decision1 = (m0 >= m1) ? 1U : 0U;
|
|
||||||
m_newMetrics[j + 1U] = decision1 != 0U ? m1 : m0;
|
|
||||||
|
|
||||||
*m_dp |= (uint64_t(decision1) << (j + 1U)) | (uint64_t(decision0) << (j + 0U));
|
|
||||||
}
|
|
||||||
|
|
||||||
++m_dp;
|
|
||||||
|
|
||||||
assert((m_dp - m_decisions) <= 300);
|
|
||||||
|
|
||||||
uint16_t* tmp = m_oldMetrics;
|
|
||||||
m_oldMetrics = m_newMetrics;
|
|
||||||
m_newMetrics = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNConvolution::chainback(unsigned char* out, unsigned int nBits)
|
|
||||||
{
|
|
||||||
assert(out != NULL);
|
|
||||||
|
|
||||||
uint32_t state = 0U;
|
|
||||||
|
|
||||||
while (nBits-- > 0) {
|
|
||||||
--m_dp;
|
|
||||||
|
|
||||||
uint32_t i = state >> (9 - K);
|
|
||||||
uint8_t bit = uint8_t(*m_dp >> i) & 1;
|
|
||||||
state = (bit << 7) | (state >> 1);
|
|
||||||
|
|
||||||
WRITE_BIT1(out, nBits, bit != 0U);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
|
||||||
{
|
|
||||||
assert(in != NULL);
|
|
||||||
assert(out != NULL);
|
|
||||||
assert(nBits > 0U);
|
|
||||||
|
|
||||||
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
|
||||||
uint32_t k = 0U;
|
|
||||||
for (unsigned int i = 0U; i < nBits; i++) {
|
|
||||||
uint8_t d = READ_BIT1(in, i) ? 1U : 0U;
|
|
||||||
|
|
||||||
uint8_t g1 = (d + d3 + d4) & 1;
|
|
||||||
uint8_t g2 = (d + d1 + d2 + d4) & 1;
|
|
||||||
|
|
||||||
d4 = d3;
|
|
||||||
d3 = d2;
|
|
||||||
d2 = d1;
|
|
||||||
d1 = d;
|
|
||||||
|
|
||||||
WRITE_BIT1(out, k, g1 != 0U);
|
|
||||||
k++;
|
|
||||||
|
|
||||||
WRITE_BIT1(out, k, g2 != 0U);
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
102
NXDNDefines.h
102
NXDNDefines.h
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016,2017,2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNDEFINES_H)
|
|
||||||
#define NXDNDEFINES_H
|
|
||||||
|
|
||||||
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
|
||||||
|
|
||||||
const unsigned int NXDN_FRAME_LENGTH_BITS = 384U;
|
|
||||||
const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U;
|
|
||||||
const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U;
|
|
||||||
|
|
||||||
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
|
|
||||||
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
|
|
||||||
const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
|
|
||||||
|
|
||||||
const unsigned char NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U};
|
|
||||||
const unsigned char NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U};
|
|
||||||
const unsigned int NXDN_FSW_BYTES_LENGTH = 3U;
|
|
||||||
|
|
||||||
const unsigned int NXDN_LICH_LENGTH_BITS = 16U;
|
|
||||||
|
|
||||||
const unsigned int NXDN_SACCH_LENGTH_BITS = 60U;
|
|
||||||
const unsigned int NXDN_FACCH1_LENGTH_BITS = 144U;
|
|
||||||
const unsigned int NXDN_FACCH2_LENGTH_BITS = 348U;
|
|
||||||
|
|
||||||
const unsigned int NXDN_FSW_LICH_SACCH_LENGTH_BITS = NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS;
|
|
||||||
const unsigned int NXDN_FSW_LICH_SACCH_LENGTH_BYTES = NXDN_FSW_LICH_SACCH_LENGTH_BITS / 8U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_LICH_RFCT_RCCH = 0U;
|
|
||||||
const unsigned char NXDN_LICH_RFCT_RTCH = 1U;
|
|
||||||
const unsigned char NXDN_LICH_RFCT_RDCH = 2U;
|
|
||||||
const unsigned char NXDN_LICH_RFCT_RTCH_C = 3U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_NS = 0U;
|
|
||||||
const unsigned char NXDN_LICH_USC_UDCH = 1U;
|
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_SS = 2U;
|
|
||||||
const unsigned char NXDN_LICH_USC_SACCH_SS_IDLE = 3U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_LICH_STEAL_NONE = 3U;
|
|
||||||
const unsigned char NXDN_LICH_STEAL_FACCH1_2 = 2U;
|
|
||||||
const unsigned char NXDN_LICH_STEAL_FACCH1_1 = 1U;
|
|
||||||
const unsigned char NXDN_LICH_STEAL_FACCH = 0U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_LICH_DIRECTION_INBOUND = 0U;
|
|
||||||
const unsigned char NXDN_LICH_DIRECTION_OUTBOUND = 1U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_SR_SINGLE = 0U;
|
|
||||||
const unsigned char NXDN_SR_4_4 = 0U;
|
|
||||||
const unsigned char NXDN_SR_3_4 = 1U;
|
|
||||||
const unsigned char NXDN_SR_2_4 = 2U;
|
|
||||||
const unsigned char NXDN_SR_1_4 = 3U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_VCALL = 0x01U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_VCALL_IV = 0x03U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_HDR = 0x09U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_DATA = 0x0BU;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_ACK = 0x0CU;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_TX_REL = 0x08U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_HEAD_DLY = 0x0FU;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_HDR = 0x38U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_DATA = 0x39U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_RESP = 0x3BU;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_IV = 0x3AU;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_REQ = 0x30U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_RESP = 0x31U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_REQ = 0x32U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_RESP = 0x33U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_REM_CON_REQ = 0x34U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_REM_CON_RESP = 0x35U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_IDLE = 0x10U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_REQ = 0x28U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_RESP = 0x29U;
|
|
||||||
const unsigned char NXDN_MESSAGE_TYPE_PROP_FORM = 0x3FU;
|
|
||||||
|
|
||||||
const unsigned char NXDN_VOICE_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
|
||||||
const unsigned char NXDN_VOICE_CALL_OPTION_DUPLEX = 0x10U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_DATA_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
|
||||||
const unsigned char NXDN_DATA_CALL_OPTION_DUPLEX = 0x10U;
|
|
||||||
|
|
||||||
const unsigned char NXDN_DATA_CALL_OPTION_4800 = 0x00U;
|
|
||||||
const unsigned char NXDN_DATA_CALL_OPTION_9600 = 0x02U;
|
|
||||||
|
|
||||||
const unsigned char SACCH_IDLE[] = { NXDN_MESSAGE_TYPE_IDLE, 0x00U, 0x00U };
|
|
||||||
|
|
||||||
#endif
|
|
188
NXDNFACCH1.cpp
188
NXDNFACCH1.cpp
|
@ -1,188 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNFACCH1.h"
|
|
||||||
|
|
||||||
#include "NXDNConvolution.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNCRC.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int INTERLEAVE_TABLE[] = {
|
|
||||||
0U, 9U, 18U, 27U, 36U, 45U, 54U, 63U, 72U, 81U, 90U, 99U, 108U, 117U, 126U, 135U,
|
|
||||||
1U, 10U, 19U, 28U, 37U, 46U, 55U, 64U, 73U, 82U, 91U, 100U, 109U, 118U, 127U, 136U,
|
|
||||||
2U, 11U, 20U, 29U, 38U, 47U, 56U, 65U, 74U, 83U, 92U, 101U, 110U, 119U, 128U, 137U,
|
|
||||||
3U, 12U, 21U, 30U, 39U, 48U, 57U, 66U, 75U, 84U, 93U, 102U, 111U, 120U, 129U, 138U,
|
|
||||||
4U, 13U, 22U, 31U, 40U, 49U, 58U, 67U, 76U, 85U, 94U, 103U, 112U, 121U, 130U, 139U,
|
|
||||||
5U, 14U, 23U, 32U, 41U, 50U, 59U, 68U, 77U, 86U, 95U, 104U, 113U, 122U, 131U, 140U,
|
|
||||||
6U, 15U, 24U, 33U, 42U, 51U, 60U, 69U, 78U, 87U, 96U, 105U, 114U, 123U, 132U, 141U,
|
|
||||||
7U, 16U, 25U, 34U, 43U, 52U, 61U, 70U, 79U, 88U, 97U, 106U, 115U, 124U, 133U, 142U,
|
|
||||||
8U, 17U, 26U, 35U, 44U, 53U, 62U, 71U, 80U, 89U, 98U, 107U, 116U, 125U, 134U, 143U };
|
|
||||||
|
|
||||||
const unsigned int PUNCTURE_LIST[] = { 1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U,
|
|
||||||
41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U, 73U, 77U,
|
|
||||||
81U, 85U, 89U, 93U, 97U, 101U, 105U, 109U, 113U, 117U,
|
|
||||||
121U, 125U, 129U, 133U, 137U, 141U, 145U, 149U, 153U, 157U,
|
|
||||||
161U, 165U, 169U, 173U, 177U, 181U, 185U, 189U };
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
CNXDNFACCH1::CNXDNFACCH1(const CNXDNFACCH1& facch1) :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[10U + 2U];
|
|
||||||
::memcpy(m_data, facch1.m_data, 10U + 2U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNFACCH1::CNXDNFACCH1() :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[10U + 2U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNFACCH1::~CNXDNFACCH1()
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNFACCH1::decode(const unsigned char* data, unsigned int offset)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[18U];
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + offset;
|
|
||||||
bool b = READ_BIT1(data, n);
|
|
||||||
WRITE_BIT1(temp1, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t temp2[210U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
|
||||||
if (n == PUNCTURE_LIST[index]) {
|
|
||||||
temp2[n++] = 1U;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool b = READ_BIT1(temp1, i);
|
|
||||||
temp2[n++] = b ? 2U : 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 8U; i++) {
|
|
||||||
temp2[n++] = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.start();
|
|
||||||
|
|
||||||
n = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 100U; i++) {
|
|
||||||
uint8_t s0 = temp2[n++];
|
|
||||||
uint8_t s1 = temp2[n++];
|
|
||||||
|
|
||||||
conv.decode(s0, s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
conv.chainback(m_data, 96U);
|
|
||||||
|
|
||||||
return CNXDNCRC::checkCRC12(m_data, 80U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNFACCH1::encode(unsigned char* data, unsigned int offset) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[12U];
|
|
||||||
::memset(temp1, 0x00U, 12U);
|
|
||||||
::memcpy(temp1, m_data, 10U);
|
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC12(temp1, 80U);
|
|
||||||
|
|
||||||
unsigned char temp2[24U];
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.encode(temp1, temp2, 96U);
|
|
||||||
|
|
||||||
unsigned char temp3[18U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 192U; i++) {
|
|
||||||
if (i != PUNCTURE_LIST[index]) {
|
|
||||||
bool b = READ_BIT1(temp2, i);
|
|
||||||
WRITE_BIT1(temp3, n, b);
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH1_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + offset;
|
|
||||||
bool b = READ_BIT1(temp3, i);
|
|
||||||
WRITE_BIT1(data, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNFACCH1::getData(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(data, m_data, 10U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNFACCH1::getRaw(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memset(data, 0x00U, 12U);
|
|
||||||
::memcpy(data, m_data, 10U);
|
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC12(data, 80U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNFACCH1::setData(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_data, data, 10U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNFACCH1::setRaw(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_data, data, 12U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNFACCH1& CNXDNFACCH1::operator=(const CNXDNFACCH1& facch1)
|
|
||||||
{
|
|
||||||
if (&facch1 != this)
|
|
||||||
::memcpy(m_data, facch1.m_data, 10U + 2U);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
44
NXDNFACCH1.h
44
NXDNFACCH1.h
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNFACCH1_H)
|
|
||||||
#define NXDNFACCH1_H
|
|
||||||
|
|
||||||
class CNXDNFACCH1 {
|
|
||||||
public:
|
|
||||||
CNXDNFACCH1(const CNXDNFACCH1& facch);
|
|
||||||
CNXDNFACCH1();
|
|
||||||
~CNXDNFACCH1();
|
|
||||||
|
|
||||||
bool decode(const unsigned char* data, unsigned int offset);
|
|
||||||
|
|
||||||
void encode(unsigned char* data, unsigned int offset) const;
|
|
||||||
|
|
||||||
void getData(unsigned char* data) const;
|
|
||||||
void getRaw(unsigned char* data) const;
|
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
|
||||||
void setRaw(const unsigned char* data);
|
|
||||||
|
|
||||||
CNXDNFACCH1& operator=(const CNXDNFACCH1& facch);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,171 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,2018-2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNIcomNetwork.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "Defines.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 200U;
|
|
||||||
|
|
||||||
CNXDNIcomNetwork::CNXDNIcomNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug) :
|
|
||||||
m_socket(localAddress, localPort),
|
|
||||||
m_addr(),
|
|
||||||
m_addrLen(0U),
|
|
||||||
m_debug(debug),
|
|
||||||
m_enabled(false),
|
|
||||||
m_buffer(1000U, "NXDN Network")
|
|
||||||
{
|
|
||||||
assert(gatewayPort > 0U);
|
|
||||||
assert(!gatewayAddress.empty());
|
|
||||||
|
|
||||||
if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0)
|
|
||||||
m_addrLen = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNIcomNetwork::~CNXDNIcomNetwork()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNIcomNetwork::open()
|
|
||||||
{
|
|
||||||
if (m_addrLen == 0U) {
|
|
||||||
LogError("Unable to resolve the address of the NXDN Gateway");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("Opening NXDN network connection");
|
|
||||||
|
|
||||||
return m_socket.open(m_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNIcomNetwork::write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char buffer[110U];
|
|
||||||
::memset(buffer, 0x00U, 110U);
|
|
||||||
|
|
||||||
buffer[0U] = 'I';
|
|
||||||
buffer[1U] = 'C';
|
|
||||||
buffer[2U] = 'O';
|
|
||||||
buffer[3U] = 'M';
|
|
||||||
buffer[4U] = 0x01U;
|
|
||||||
buffer[5U] = 0x01U;
|
|
||||||
buffer[6U] = 0x08U;
|
|
||||||
buffer[7U] = 0xE0U;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case NNMT_VOICE_HEADER:
|
|
||||||
case NNMT_VOICE_TRAILER:
|
|
||||||
buffer[37U] = 0x23U;
|
|
||||||
buffer[38U] = 0x1CU;
|
|
||||||
buffer[39U] = 0x21U;
|
|
||||||
break;
|
|
||||||
case NNMT_VOICE_BODY:
|
|
||||||
buffer[37U] = 0x23U;
|
|
||||||
buffer[38U] = 0x10U;
|
|
||||||
buffer[39U] = 0x21U;
|
|
||||||
break;
|
|
||||||
case NNMT_DATA_HEADER:
|
|
||||||
case NNMT_DATA_BODY:
|
|
||||||
case NNMT_DATA_TRAILER:
|
|
||||||
buffer[37U] = 0x23U;
|
|
||||||
buffer[38U] = 0x02U;
|
|
||||||
buffer[39U] = 0x18U;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
::memcpy(buffer + 40U, data, 33U);
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "NXDN Network Data Sent", buffer, 102U);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, 102U, m_addr, m_addrLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNIcomNetwork::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
unsigned char buffer[BUFFER_LENGTH];
|
|
||||||
|
|
||||||
sockaddr_storage address;
|
|
||||||
unsigned int addrLen;
|
|
||||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen);
|
|
||||||
if (length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!CUDPSocket::match(m_addr, address)) {
|
|
||||||
LogMessage("NXDN, packet received from an invalid source");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "NXDN Network Data Received", buffer, length);
|
|
||||||
|
|
||||||
// Invalid packet type?
|
|
||||||
if (::memcmp(buffer, "ICOM", 4U) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (length != 102)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_buffer.addData(buffer + 40U, 33U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNIcomNetwork::read(unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
if (m_buffer.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_buffer.getData(data, 33U);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNIcomNetwork::reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNIcomNetwork::close()
|
|
||||||
{
|
|
||||||
m_socket.close();
|
|
||||||
|
|
||||||
LogMessage("Closing NXDN network connection");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNIcomNetwork::enable(bool enabled)
|
|
||||||
{
|
|
||||||
if (enabled && !m_enabled)
|
|
||||||
reset();
|
|
||||||
else if (!enabled && m_enabled)
|
|
||||||
m_buffer.clear();
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,2018,2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NXDNIcomNetwork_H
|
|
||||||
#define NXDNIcomNetwork_H
|
|
||||||
|
|
||||||
#include "NXDNNetwork.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class CNXDNIcomNetwork : public INXDNNetwork {
|
|
||||||
public:
|
|
||||||
CNXDNIcomNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug);
|
|
||||||
virtual ~CNXDNIcomNetwork();
|
|
||||||
|
|
||||||
virtual bool open();
|
|
||||||
|
|
||||||
virtual void enable(bool enabled);
|
|
||||||
|
|
||||||
virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type);
|
|
||||||
|
|
||||||
virtual bool read(unsigned char* data);
|
|
||||||
|
|
||||||
virtual void reset();
|
|
||||||
|
|
||||||
virtual void close();
|
|
||||||
|
|
||||||
virtual void clock(unsigned int ms);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CUDPSocket m_socket;
|
|
||||||
sockaddr_storage m_addr;
|
|
||||||
unsigned int m_addrLen;
|
|
||||||
bool m_debug;
|
|
||||||
bool m_enabled;
|
|
||||||
CRingBuffer<unsigned char> m_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,2018,2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NXDNKenwoodNetwork_H
|
|
||||||
#define NXDNKenwoodNetwork_H
|
|
||||||
|
|
||||||
#include "NXDNNetwork.h"
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
class CNXDNKenwoodNetwork : public INXDNNetwork {
|
|
||||||
public:
|
|
||||||
CNXDNKenwoodNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gwyAddress, unsigned int gwyPort, bool debug);
|
|
||||||
virtual ~CNXDNKenwoodNetwork();
|
|
||||||
|
|
||||||
virtual bool open();
|
|
||||||
|
|
||||||
virtual void enable(bool enabled);
|
|
||||||
|
|
||||||
virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type);
|
|
||||||
|
|
||||||
virtual bool read(unsigned char* data);
|
|
||||||
|
|
||||||
virtual void reset();
|
|
||||||
|
|
||||||
virtual void close();
|
|
||||||
|
|
||||||
virtual void clock(unsigned int ms);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CUDPSocket m_rtpSocket;
|
|
||||||
CUDPSocket m_rtcpSocket;
|
|
||||||
sockaddr_storage m_rtcpAddr;
|
|
||||||
sockaddr_storage m_rtpAddr;
|
|
||||||
unsigned int m_rtcpAddrLen;
|
|
||||||
unsigned int m_rtpAddrLen;
|
|
||||||
bool m_enabled;
|
|
||||||
bool m_headerSeen;
|
|
||||||
bool m_seen1;
|
|
||||||
bool m_seen2;
|
|
||||||
bool m_seen3;
|
|
||||||
bool m_seen4;
|
|
||||||
unsigned char* m_sacch;
|
|
||||||
uint8_t m_sessionId;
|
|
||||||
uint16_t m_seqNo;
|
|
||||||
unsigned int m_ssrc;
|
|
||||||
bool m_debug;
|
|
||||||
uint32_t m_startSecs;
|
|
||||||
uint32_t m_startUSecs;
|
|
||||||
CTimer m_rtcpTimer;
|
|
||||||
CTimer m_hangTimer;
|
|
||||||
unsigned char m_hangType;
|
|
||||||
unsigned short m_hangSrc;
|
|
||||||
unsigned short m_hangDst;
|
|
||||||
std::mt19937 m_random;
|
|
||||||
|
|
||||||
bool processIcomVoiceHeader(const unsigned char* data);
|
|
||||||
bool processIcomVoiceData(const unsigned char* data);
|
|
||||||
bool processIcomDataHeader(const unsigned char* data);
|
|
||||||
bool processIcomDataData(const unsigned char* data);
|
|
||||||
bool processIcomDataTrailer(const unsigned char* data);
|
|
||||||
bool processKenwoodVoiceHeader(unsigned char* data);
|
|
||||||
bool processKenwoodVoiceData(unsigned char* data);
|
|
||||||
bool processKenwoodVoiceLateEntry(unsigned char* data);
|
|
||||||
bool processKenwoodData(unsigned char* data);
|
|
||||||
bool writeRTPVoiceHeader(const unsigned char* data);
|
|
||||||
bool writeRTPVoiceData(const unsigned char* data);
|
|
||||||
bool writeRTPVoiceTrailer(const unsigned char* data);
|
|
||||||
bool writeRTPDataHeader(const unsigned char* data);
|
|
||||||
bool writeRTPDataData(const unsigned char* data);
|
|
||||||
bool writeRTPDataTrailer(const unsigned char* data);
|
|
||||||
bool writeRTCPStart();
|
|
||||||
bool writeRTCPPing();
|
|
||||||
bool writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst);
|
|
||||||
bool writeRTCPHang();
|
|
||||||
unsigned int readRTP(unsigned char* data);
|
|
||||||
unsigned int readRTCP(unsigned char* data);
|
|
||||||
unsigned long getTimeStamp() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
162
NXDNLICH.cpp
162
NXDNLICH.cpp
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNLICH.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
CNXDNLICH::CNXDNLICH(const CNXDNLICH& lich) :
|
|
||||||
m_lich(NULL)
|
|
||||||
{
|
|
||||||
m_lich = new unsigned char[1U];
|
|
||||||
m_lich[0U] = lich.m_lich[0U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLICH::CNXDNLICH() :
|
|
||||||
m_lich(NULL)
|
|
||||||
{
|
|
||||||
m_lich = new unsigned char[1U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLICH::~CNXDNLICH()
|
|
||||||
{
|
|
||||||
delete[] m_lich;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLICH::decode(const unsigned char* bytes)
|
|
||||||
{
|
|
||||||
assert(bytes != NULL);
|
|
||||||
|
|
||||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
|
||||||
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset += 2U) {
|
|
||||||
bool b = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(m_lich, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool newParity = getParity();
|
|
||||||
bool origParity = (m_lich[0U] & 0x01U) == 0x01U;
|
|
||||||
|
|
||||||
return origParity == newParity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::encode(unsigned char* bytes)
|
|
||||||
{
|
|
||||||
assert(bytes != NULL);
|
|
||||||
|
|
||||||
bool parity = getParity();
|
|
||||||
if (parity)
|
|
||||||
m_lich[0U] |= 0x01U;
|
|
||||||
else
|
|
||||||
m_lich[0U] &= 0xFEU;
|
|
||||||
|
|
||||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
|
||||||
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++) {
|
|
||||||
bool b = READ_BIT1(m_lich, i);
|
|
||||||
WRITE_BIT1(bytes, offset, b);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getRFCT() const
|
|
||||||
{
|
|
||||||
return (m_lich[0U] >> 6) & 0x03U;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getFCT() const
|
|
||||||
{
|
|
||||||
return (m_lich[0U] >> 4) & 0x03U;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getOption() const
|
|
||||||
{
|
|
||||||
return (m_lich[0U] >> 2) & 0x03U;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getDirection() const
|
|
||||||
{
|
|
||||||
return (m_lich[0U] >> 1) & 0x01U;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getRaw() const
|
|
||||||
{
|
|
||||||
bool parity = getParity();
|
|
||||||
if (parity)
|
|
||||||
m_lich[0U] |= 0x01U;
|
|
||||||
else
|
|
||||||
m_lich[0U] &= 0xFEU;
|
|
||||||
|
|
||||||
return m_lich[0U];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::setRFCT(unsigned char rfct)
|
|
||||||
{
|
|
||||||
m_lich[0U] &= 0x3FU;
|
|
||||||
m_lich[0U] |= (rfct << 6) & 0xC0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::setFCT(unsigned char usc)
|
|
||||||
{
|
|
||||||
m_lich[0U] &= 0xCFU;
|
|
||||||
m_lich[0U] |= (usc << 4) & 0x30U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::setOption(unsigned char option)
|
|
||||||
{
|
|
||||||
m_lich[0U] &= 0xF3U;
|
|
||||||
m_lich[0U] |= (option << 2) & 0x0CU;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::setDirection(unsigned char direction)
|
|
||||||
{
|
|
||||||
m_lich[0U] &= 0xFDU;
|
|
||||||
m_lich[0U] |= (direction << 1) & 0x02U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLICH::setRaw(unsigned char lich)
|
|
||||||
{
|
|
||||||
m_lich[0U] = lich;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLICH& CNXDNLICH::operator=(const CNXDNLICH& lich)
|
|
||||||
{
|
|
||||||
if (&lich != this)
|
|
||||||
m_lich[0U] = lich.m_lich[0U];
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLICH::getParity() const
|
|
||||||
{
|
|
||||||
switch (m_lich[0U] & 0xF0U) {
|
|
||||||
case 0x80U:
|
|
||||||
case 0xB0U:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
52
NXDNLICH.h
52
NXDNLICH.h
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNLICH_H)
|
|
||||||
#define NXDNLICH_H
|
|
||||||
|
|
||||||
class CNXDNLICH {
|
|
||||||
public:
|
|
||||||
CNXDNLICH(const CNXDNLICH& lich);
|
|
||||||
CNXDNLICH();
|
|
||||||
~CNXDNLICH();
|
|
||||||
|
|
||||||
bool decode(const unsigned char* bytes);
|
|
||||||
|
|
||||||
void encode(unsigned char* bytes);
|
|
||||||
|
|
||||||
unsigned char getRFCT() const;
|
|
||||||
unsigned char getFCT() const;
|
|
||||||
unsigned char getOption() const;
|
|
||||||
unsigned char getDirection() const;
|
|
||||||
unsigned char getRaw() const;
|
|
||||||
|
|
||||||
void setRFCT(unsigned char rfct);
|
|
||||||
void setFCT(unsigned char usc);
|
|
||||||
void setOption(unsigned char option);
|
|
||||||
void setDirection(unsigned char direction);
|
|
||||||
void setRaw(unsigned char lich);
|
|
||||||
|
|
||||||
CNXDNLICH& operator=(const CNXDNLICH& lich);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_lich;
|
|
||||||
|
|
||||||
bool getParity() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
117
NXDNLayer3.cpp
117
NXDNLayer3.cpp
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNLayer3.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
CNXDNLayer3::CNXDNLayer3(const CNXDNLayer3& layer3) :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[22U];
|
|
||||||
::memcpy(m_data, layer3.m_data, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLayer3::CNXDNLayer3() :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[22U];
|
|
||||||
::memset(m_data, 0x00U, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLayer3::~CNXDNLayer3()
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLayer3::decode(const unsigned char* bytes, unsigned int length, unsigned int offset)
|
|
||||||
{
|
|
||||||
assert(bytes != NULL);
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < length; i++, offset++) {
|
|
||||||
bool b = READ_BIT1(bytes, i);
|
|
||||||
WRITE_BIT1(m_data, offset, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLayer3::encode(unsigned char* bytes, unsigned int length, unsigned int offset)
|
|
||||||
{
|
|
||||||
assert(bytes != NULL);
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < length; i++, offset++) {
|
|
||||||
bool b = READ_BIT1(m_data, offset);
|
|
||||||
WRITE_BIT1(bytes, i, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLayer3::getMessageType() const
|
|
||||||
{
|
|
||||||
return m_data[0U] & 0x3FU;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short CNXDNLayer3::getSourceUnitId() const
|
|
||||||
{
|
|
||||||
return (m_data[3U] << 8) | m_data[4U];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short CNXDNLayer3::getDestinationGroupId() const
|
|
||||||
{
|
|
||||||
return (m_data[5U] << 8) | m_data[6U];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLayer3::getIsGroup() const
|
|
||||||
{
|
|
||||||
return (m_data[2U] & 0x80U) != 0x80U;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNLayer3::getDataBlocks() const
|
|
||||||
{
|
|
||||||
return (m_data[8U] & 0x0FU) + 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLayer3::getData(unsigned char* data) const
|
|
||||||
{
|
|
||||||
::memcpy(data, m_data, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLayer3::setData(const unsigned char* data, unsigned int length)
|
|
||||||
{
|
|
||||||
::memset(m_data, 0x00U, 22U);
|
|
||||||
::memcpy(m_data, data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLayer3::reset()
|
|
||||||
{
|
|
||||||
::memset(m_data, 0x00U, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3)
|
|
||||||
{
|
|
||||||
if (&layer3 != this)
|
|
||||||
::memcpy(m_data, layer3.m_data, 22U);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
49
NXDNLayer3.h
49
NXDNLayer3.h
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNLayer3_H)
|
|
||||||
#define NXDNLayer3_H
|
|
||||||
|
|
||||||
class CNXDNLayer3 {
|
|
||||||
public:
|
|
||||||
CNXDNLayer3(const CNXDNLayer3& layer3);
|
|
||||||
CNXDNLayer3();
|
|
||||||
~CNXDNLayer3();
|
|
||||||
|
|
||||||
void decode(const unsigned char* bytes, unsigned int length, unsigned int offset = 0U);
|
|
||||||
|
|
||||||
void encode(unsigned char* bytes, unsigned int length, unsigned int offset = 0U);
|
|
||||||
|
|
||||||
unsigned char getMessageType() const;
|
|
||||||
unsigned short getSourceUnitId() const;
|
|
||||||
unsigned short getDestinationGroupId() const;
|
|
||||||
bool getIsGroup() const;
|
|
||||||
unsigned char getDataBlocks() const;
|
|
||||||
|
|
||||||
void setData(const unsigned char* data, unsigned int length);
|
|
||||||
void getData(unsigned char* data) const;
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
CNXDNLayer3& operator=(const CNXDNLayer3& layer3);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
126
NXDNLookup.cpp
126
NXDNLookup.cpp
|
@ -1,126 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016,2017,2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNLookup.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
CNXDNLookup::CNXDNLookup(const std::string& filename, unsigned int reloadTime) :
|
|
||||||
CThread(),
|
|
||||||
m_filename(filename),
|
|
||||||
m_reloadTime(reloadTime),
|
|
||||||
m_table(),
|
|
||||||
m_stop(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLookup::~CNXDNLookup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLookup::read()
|
|
||||||
{
|
|
||||||
bool ret = m_table.load(m_filename);
|
|
||||||
|
|
||||||
if (m_reloadTime > 0U)
|
|
||||||
run();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLookup::entry()
|
|
||||||
{
|
|
||||||
LogInfo("Started the NXDN Id lookup reload thread");
|
|
||||||
|
|
||||||
CTimer timer(1U, 3600U * m_reloadTime);
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
while (!m_stop) {
|
|
||||||
sleep(1000U);
|
|
||||||
|
|
||||||
timer.clock();
|
|
||||||
if (timer.hasExpired()) {
|
|
||||||
m_table.load(m_filename);
|
|
||||||
timer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("Stopped the NXDN Id lookup reload thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLookup::stop()
|
|
||||||
{
|
|
||||||
if (m_reloadTime == 0U) {
|
|
||||||
delete this;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stop = true;
|
|
||||||
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLookup::findWithName(unsigned int id, class CUserDBentry *entry)
|
|
||||||
{
|
|
||||||
if (id == 0xFFFFU) {
|
|
||||||
entry->clear();
|
|
||||||
entry->set(keyCALLSIGN, "ALL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_table.lookup(id, entry)) {
|
|
||||||
LogDebug("FindWithName =%s %s", entry->get(keyCALLSIGN).c_str(), entry->get(keyFIRST_NAME).c_str());
|
|
||||||
} else {
|
|
||||||
entry->clear();
|
|
||||||
|
|
||||||
char text[10U];
|
|
||||||
::snprintf(text, sizeof(text), "%u", id);
|
|
||||||
entry->set(keyCALLSIGN, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CNXDNLookup::find(unsigned int id)
|
|
||||||
{
|
|
||||||
std::string callsign;
|
|
||||||
|
|
||||||
if (id == 0xFFFFU)
|
|
||||||
return std::string("ALL");
|
|
||||||
|
|
||||||
class CUserDBentry entry;
|
|
||||||
if (m_table.lookup(id, &entry)) {
|
|
||||||
callsign = entry.get(keyCALLSIGN);
|
|
||||||
} else {
|
|
||||||
char text[10U];
|
|
||||||
::snprintf(text, sizeof(text), "%u", id);
|
|
||||||
callsign = std::string(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return callsign;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLookup::exists(unsigned int id)
|
|
||||||
{
|
|
||||||
return m_table.lookup(id, NULL);
|
|
||||||
}
|
|
50
NXDNLookup.h
50
NXDNLookup.h
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016,2017,2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NXDNLookup_H
|
|
||||||
#define NXDNLookup_H
|
|
||||||
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "UserDB.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class CNXDNLookup : public CThread {
|
|
||||||
public:
|
|
||||||
CNXDNLookup(const std::string& filename, unsigned int reloadTime);
|
|
||||||
virtual ~CNXDNLookup();
|
|
||||||
|
|
||||||
bool read();
|
|
||||||
|
|
||||||
virtual void entry();
|
|
||||||
|
|
||||||
std::string find(unsigned int id);
|
|
||||||
void findWithName(unsigned int id, class CUserDBentry *entry);
|
|
||||||
|
|
||||||
bool exists(unsigned int id);
|
|
||||||
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_filename;
|
|
||||||
unsigned int m_reloadTime;
|
|
||||||
class CUserDB m_table;
|
|
||||||
bool m_stop;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NXDNNetwork_H
|
|
||||||
#define NXDNNetwork_H
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
enum NXDN_NETWORK_MESSAGE_TYPE {
|
|
||||||
NNMT_VOICE_HEADER,
|
|
||||||
NNMT_VOICE_BODY,
|
|
||||||
NNMT_VOICE_TRAILER,
|
|
||||||
NNMT_DATA_HEADER,
|
|
||||||
NNMT_DATA_BODY,
|
|
||||||
NNMT_DATA_TRAILER
|
|
||||||
};
|
|
||||||
|
|
||||||
class INXDNNetwork {
|
|
||||||
public:
|
|
||||||
virtual ~INXDNNetwork() = 0;
|
|
||||||
|
|
||||||
virtual bool open() = 0;
|
|
||||||
|
|
||||||
virtual void enable(bool enabled) = 0;
|
|
||||||
|
|
||||||
virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type) = 0;
|
|
||||||
|
|
||||||
virtual bool read(unsigned char* data) = 0;
|
|
||||||
|
|
||||||
virtual void reset() = 0;
|
|
||||||
|
|
||||||
virtual void close() = 0;
|
|
||||||
|
|
||||||
virtual void clock(unsigned int ms) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
214
NXDNSACCH.cpp
214
NXDNSACCH.cpp
|
@ -1,214 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNSACCH.h"
|
|
||||||
|
|
||||||
#include "NXDNConvolution.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNCRC.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int INTERLEAVE_TABLE[] = {
|
|
||||||
0U, 5U, 10U, 15U, 20U, 25U, 30U, 35U, 40U, 45U, 50U, 55U,
|
|
||||||
1U, 6U, 11U, 16U, 21U, 26U, 31U, 36U, 41U, 46U, 51U, 56U,
|
|
||||||
2U, 7U, 12U, 17U, 22U, 27U, 32U, 37U, 42U, 47U, 52U, 57U,
|
|
||||||
3U, 8U, 13U, 18U, 23U, 28U, 33U, 38U, 43U, 48U, 53U, 58U,
|
|
||||||
4U, 9U, 14U, 19U, 24U, 29U, 34U, 39U, 44U, 49U, 54U, 59U
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned int PUNCTURE_LIST[] = { 5U, 11U, 17U, 23U, 29U, 35U, 41U, 47U, 53U, 59U, 65U, 71U };
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
CNXDNSACCH::CNXDNSACCH(const CNXDNSACCH& sacch) :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[5U];
|
|
||||||
::memcpy(m_data, sacch.m_data, 5U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNSACCH::CNXDNSACCH() :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[5U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNSACCH::~CNXDNSACCH()
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNSACCH::decode(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[8U];
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
|
||||||
bool b = READ_BIT1(data, n);
|
|
||||||
WRITE_BIT1(temp1, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t temp2[90U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
|
||||||
if (n == PUNCTURE_LIST[index]) {
|
|
||||||
temp2[n++] = 1U;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool b = READ_BIT1(temp1, i);
|
|
||||||
temp2[n++] = b ? 2U : 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 8U; i++) {
|
|
||||||
temp2[n++] = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.start();
|
|
||||||
|
|
||||||
n = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 40U; i++) {
|
|
||||||
uint8_t s0 = temp2[n++];
|
|
||||||
uint8_t s1 = temp2[n++];
|
|
||||||
|
|
||||||
conv.decode(s0, s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
conv.chainback(m_data, 36U);
|
|
||||||
|
|
||||||
return CNXDNCRC::checkCRC6(m_data, 26U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::encode(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[5U];
|
|
||||||
::memset(temp1, 0x00U, 5U);
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 26U; i++) {
|
|
||||||
bool b = READ_BIT1(m_data, i);
|
|
||||||
WRITE_BIT1(temp1, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC6(temp1, 26U);
|
|
||||||
|
|
||||||
unsigned char temp2[9U];
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.encode(temp1, temp2, 36U);
|
|
||||||
|
|
||||||
unsigned char temp3[8U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 72U; i++) {
|
|
||||||
if (i != PUNCTURE_LIST[index]) {
|
|
||||||
bool b = READ_BIT1(temp2, i);
|
|
||||||
WRITE_BIT1(temp3, n, b);
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
|
||||||
bool b = READ_BIT1(temp3, i);
|
|
||||||
WRITE_BIT1(data, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNSACCH::getRAN() const
|
|
||||||
{
|
|
||||||
return m_data[0U] & 0x3FU;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNSACCH::getStructure() const
|
|
||||||
{
|
|
||||||
return (m_data[0U] >> 6) & 0x03U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::getData(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned int offset = 8U;
|
|
||||||
for (unsigned int i = 0U; i < 18U; i++, offset++) {
|
|
||||||
bool b = READ_BIT1(m_data, offset);
|
|
||||||
WRITE_BIT1(data, i, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::getRaw(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(data, m_data, 4U);
|
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC6(data, 26U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::setRAN(unsigned char ran)
|
|
||||||
{
|
|
||||||
m_data[0U] &= 0xC0U;
|
|
||||||
m_data[0U] |= ran;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::setStructure(unsigned char structure)
|
|
||||||
{
|
|
||||||
m_data[0U] &= 0x3FU;
|
|
||||||
m_data[0U] |= (structure << 6) & 0xC0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::setData(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned int offset = 8U;
|
|
||||||
for (unsigned int i = 0U; i < 18U; i++, offset++) {
|
|
||||||
bool b = READ_BIT1(data, i);
|
|
||||||
WRITE_BIT1(m_data, offset, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNSACCH::setRaw(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_data, data, 4U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNSACCH& CNXDNSACCH::operator=(const CNXDNSACCH& sacch)
|
|
||||||
{
|
|
||||||
if (&sacch != this)
|
|
||||||
::memcpy(m_data, sacch.m_data, 5U);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
50
NXDNSACCH.h
50
NXDNSACCH.h
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNSACCH_H)
|
|
||||||
#define NXDNSACCH_H
|
|
||||||
|
|
||||||
class CNXDNSACCH {
|
|
||||||
public:
|
|
||||||
CNXDNSACCH(const CNXDNSACCH& sacch);
|
|
||||||
CNXDNSACCH();
|
|
||||||
~CNXDNSACCH();
|
|
||||||
|
|
||||||
bool decode(const unsigned char* data);
|
|
||||||
|
|
||||||
void encode(unsigned char* data) const;
|
|
||||||
|
|
||||||
unsigned char getRAN() const;
|
|
||||||
unsigned char getStructure() const;
|
|
||||||
|
|
||||||
void getData(unsigned char* data) const;
|
|
||||||
void getRaw(unsigned char* data) const;
|
|
||||||
|
|
||||||
void setRAN(unsigned char ran);
|
|
||||||
void setStructure(unsigned char structure);
|
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
|
||||||
void setRaw(const unsigned char* data);
|
|
||||||
|
|
||||||
CNXDNSACCH& operator=(const CNXDNSACCH& sacch);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
217
NXDNUDCH.cpp
217
NXDNUDCH.cpp
|
@ -1,217 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNUDCH.h"
|
|
||||||
|
|
||||||
#include "NXDNConvolution.h"
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNCRC.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int INTERLEAVE_TABLE[] = {
|
|
||||||
0U, 29U, 58U, 87U, 116U, 145U, 174U, 203U, 232U, 261U, 290U, 319U,
|
|
||||||
1U, 30U, 59U, 88U, 117U, 146U, 175U, 204U, 233U, 262U, 291U, 320U,
|
|
||||||
2U, 31U, 60U, 89U, 118U, 147U, 176U, 205U, 234U, 263U, 292U, 321U,
|
|
||||||
3U, 32U, 61U, 90U, 119U, 148U, 177U, 206U, 235U, 264U, 293U, 322U,
|
|
||||||
4U, 33U, 62U, 91U, 120U, 149U, 178U, 207U, 236U, 265U, 294U, 323U,
|
|
||||||
5U, 34U, 63U, 92U, 121U, 150U, 179U, 208U, 237U, 266U, 295U, 324U,
|
|
||||||
6U, 35U, 64U, 93U, 122U, 151U, 180U, 209U, 238U, 267U, 296U, 325U,
|
|
||||||
7U, 36U, 65U, 94U, 123U, 152U, 181U, 210U, 239U, 268U, 297U, 326U,
|
|
||||||
8U, 37U, 66U, 95U, 124U, 153U, 182U, 211U, 240U, 269U, 298U, 327U,
|
|
||||||
9U, 38U, 67U, 96U, 125U, 154U, 183U, 212U, 241U, 270U, 299U, 328U,
|
|
||||||
10U, 39U, 68U, 97U, 126U, 155U, 184U, 213U, 242U, 271U, 300U, 329U,
|
|
||||||
11U, 40U, 69U, 98U, 127U, 156U, 185U, 214U, 243U, 272U, 301U, 330U,
|
|
||||||
12U, 41U, 70U, 99U, 128U, 157U, 186U, 215U, 244U, 273U, 302U, 331U,
|
|
||||||
13U, 42U, 71U, 100U, 129U, 158U, 187U, 216U, 245U, 274U, 303U, 332U,
|
|
||||||
14U, 43U, 72U, 101U, 130U, 159U, 188U, 217U, 246U, 275U, 304U, 333U,
|
|
||||||
15U, 44U, 73U, 102U, 131U, 160U, 189U, 218U, 247U, 276U, 305U, 334U,
|
|
||||||
16U, 45U, 74U, 103U, 132U, 161U, 190U, 219U, 248U, 277U, 306U, 335U,
|
|
||||||
17U, 46U, 75U, 104U, 133U, 162U, 191U, 220U, 249U, 278U, 307U, 336U,
|
|
||||||
18U, 47U, 76U, 105U, 134U, 163U, 192U, 221U, 250U, 279U, 308U, 337U,
|
|
||||||
19U, 48U, 77U, 106U, 135U, 164U, 193U, 222U, 251U, 280U, 309U, 338U,
|
|
||||||
20U, 49U, 78U, 107U, 136U, 165U, 194U, 223U, 252U, 281U, 310U, 339U,
|
|
||||||
21U, 50U, 79U, 108U, 137U, 166U, 195U, 224U, 253U, 282U, 311U, 340U,
|
|
||||||
22U, 51U, 80U, 109U, 138U, 167U, 196U, 225U, 254U, 283U, 312U, 341U,
|
|
||||||
23U, 52U, 81U, 110U, 139U, 168U, 197U, 226U, 255U, 284U, 313U, 342U,
|
|
||||||
24U, 53U, 82U, 111U, 140U, 169U, 198U, 227U, 256U, 285U, 314U, 343U,
|
|
||||||
25U, 54U, 83U, 112U, 141U, 170U, 199U, 228U, 257U, 286U, 315U, 344U,
|
|
||||||
26U, 55U, 84U, 113U, 142U, 171U, 200U, 229U, 258U, 287U, 316U, 345U,
|
|
||||||
27U, 56U, 85U, 114U, 143U, 172U, 201U, 230U, 259U, 288U, 317U, 346U,
|
|
||||||
28U, 57U, 86U, 115U, 144U, 173U, 202U, 231U, 260U, 289U, 318U, 347U };
|
|
||||||
|
|
||||||
const unsigned int PUNCTURE_LIST[] = { 3U, 11U, 17U, 25U, 31U, 39U, 45U, 53U, 59U, 67U,
|
|
||||||
73U, 81U, 87U, 95U, 101U, 109U, 115U, 123U, 129U, 137U,
|
|
||||||
143U, 151U, 157U, 165U, 171U, 179U, 185U, 193U, 199U, 207U,
|
|
||||||
213U, 221U, 227U, 235U, 241U, 249U, 255U, 263U, 269U, 277U,
|
|
||||||
283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U,
|
|
||||||
353U, 361U, 367U, 375U, 381U, 389U, 395U, 403U };
|
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
|
||||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
|
||||||
|
|
||||||
CNXDNUDCH::CNXDNUDCH(const CNXDNUDCH& udch) :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[23U + 3U];
|
|
||||||
::memcpy(m_data, udch.m_data, 23U + 3U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNUDCH::CNXDNUDCH() :
|
|
||||||
m_data(NULL)
|
|
||||||
{
|
|
||||||
m_data = new unsigned char[23U + 3U];
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNUDCH::~CNXDNUDCH()
|
|
||||||
{
|
|
||||||
delete[] m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNUDCH::decode(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[44U];
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
|
||||||
bool b = READ_BIT1(data, n);
|
|
||||||
WRITE_BIT1(temp1, i, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t temp2[420U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
|
||||||
if (n == PUNCTURE_LIST[index]) {
|
|
||||||
temp2[n++] = 1U;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool b = READ_BIT1(temp1, i);
|
|
||||||
temp2[n++] = b ? 2U : 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 8U; i++) {
|
|
||||||
temp2[n++] = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.start();
|
|
||||||
|
|
||||||
n = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 207U; i++) {
|
|
||||||
uint8_t s0 = temp2[n++];
|
|
||||||
uint8_t s1 = temp2[n++];
|
|
||||||
|
|
||||||
conv.decode(s0, s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
conv.chainback(m_data, 203U);
|
|
||||||
|
|
||||||
return CNXDNCRC::checkCRC15(m_data, 184U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::encode(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
unsigned char temp1[25U];
|
|
||||||
::memset(temp1, 0x00U, 25U);
|
|
||||||
::memcpy(temp1, m_data, 23U);
|
|
||||||
|
|
||||||
CNXDNCRC::encodeCRC15(temp1, 184U);
|
|
||||||
|
|
||||||
unsigned char temp2[51U];
|
|
||||||
|
|
||||||
CNXDNConvolution conv;
|
|
||||||
conv.encode(temp1, temp2, 203U);
|
|
||||||
|
|
||||||
unsigned char temp3[44U];
|
|
||||||
|
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned int index = 0U;
|
|
||||||
for (unsigned int i = 0U; i < 406U; i++) {
|
|
||||||
if (i != PUNCTURE_LIST[index]) {
|
|
||||||
bool b = READ_BIT1(temp2, i);
|
|
||||||
WRITE_BIT1(temp3, n, b);
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) {
|
|
||||||
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
|
|
||||||
bool b = READ_BIT1(temp3, i);
|
|
||||||
WRITE_BIT1(data, n, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char CNXDNUDCH::getRAN() const
|
|
||||||
{
|
|
||||||
return m_data[0U] & 0x3FU;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::getData(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(data, m_data + 1U, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::getRaw(unsigned char* data) const
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memset(data, 0x00U, 25U);
|
|
||||||
::memcpy(data, m_data, 23U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::setRAN(unsigned char ran)
|
|
||||||
{
|
|
||||||
m_data[0U] = ran;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::setData(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_data + 1U, data, 22U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNUDCH::setRaw(const unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
::memcpy(m_data, data, 25U);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNUDCH& CNXDNUDCH::operator=(const CNXDNUDCH& udch)
|
|
||||||
{
|
|
||||||
if (&udch != this)
|
|
||||||
::memcpy(m_data, udch.m_data, 23U + 2U);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
48
NXDNUDCH.h
48
NXDNUDCH.h
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 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; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(NXDNUDCH_H)
|
|
||||||
#define NXDNUDCH_H
|
|
||||||
|
|
||||||
class CNXDNUDCH {
|
|
||||||
public:
|
|
||||||
CNXDNUDCH(const CNXDNUDCH& udch);
|
|
||||||
CNXDNUDCH();
|
|
||||||
~CNXDNUDCH();
|
|
||||||
|
|
||||||
bool decode(const unsigned char* data);
|
|
||||||
|
|
||||||
void encode(unsigned char* data) const;
|
|
||||||
|
|
||||||
unsigned char getRAN() const;
|
|
||||||
|
|
||||||
void getData(unsigned char* data) const;
|
|
||||||
void getRaw(unsigned char* data) const;
|
|
||||||
|
|
||||||
void setRAN(unsigned char ran);
|
|
||||||
|
|
||||||
void setData(const unsigned char* data);
|
|
||||||
void setRaw(const unsigned char* data);
|
|
||||||
|
|
||||||
CNXDNUDCH& operator=(const CNXDNUDCH& udch);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned char* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
368
Nextion.cpp
368
Nextion.cpp
|
@ -26,16 +26,8 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
|
||||||
const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms
|
|
||||||
const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms
|
|
||||||
const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
|
const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
|
||||||
const unsigned int DMR_BER_COUNT = 24U; // 24 * 60ms = 1440ms
|
const unsigned int DMR_BER_COUNT = 24U; // 24 * 60ms = 1440ms
|
||||||
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
|
|
||||||
const unsigned int YSF_BER_COUNT = 13U; // 13 * 100ms = 1300ms
|
|
||||||
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
|
||||||
const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms
|
|
||||||
const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms
|
|
||||||
const unsigned int NXDN_BER_COUNT = 28U; // 28 * 40ms = 1120ms
|
|
||||||
|
|
||||||
#define LAYOUT_COMPAT_MASK (7 << 0) // compatibility for old setting
|
#define LAYOUT_COMPAT_MASK (7 << 0) // compatibility for old setting
|
||||||
#define LAYOUT_TA_ENABLE (1 << 4) // enable Talker Alias (TA) display
|
#define LAYOUT_TA_ENABLE (1 << 4) // enable Talker Alias (TA) display
|
||||||
|
@ -260,107 +252,6 @@ void CNextion::setQuitInt()
|
||||||
m_mode = MODE_QUIT;
|
m_mode = MODE_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNextion::setFMInt()
|
|
||||||
{
|
|
||||||
sendCommand("page MMDVM");
|
|
||||||
sendCommandAction(1U);
|
|
||||||
|
|
||||||
char command[20];
|
|
||||||
if (m_brightness > 0) {
|
|
||||||
::sprintf(command, "dim=%u", m_brightness);
|
|
||||||
sendCommand(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendCommand("t0.txt=\"FM\"");
|
|
||||||
sendCommandAction(15U);
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_FM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
|
||||||
{
|
|
||||||
assert(my1 != NULL);
|
|
||||||
assert(my2 != NULL);
|
|
||||||
assert(your != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
assert(reflector != NULL);
|
|
||||||
|
|
||||||
if (m_mode != MODE_DSTAR) {
|
|
||||||
sendCommand("page DStar");
|
|
||||||
sendCommandAction(2U);
|
|
||||||
}
|
|
||||||
|
|
||||||
char text[50U];
|
|
||||||
if (m_brightness>0) {
|
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
|
||||||
sendCommand(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(text, "t0.txt=\"%s %.8s/%4.4s\"", type, my1, my2);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(42U);
|
|
||||||
|
|
||||||
::sprintf(text, "t1.txt=\"%.8s\"", your);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(45U);
|
|
||||||
|
|
||||||
if (::strcmp(reflector, " ") != 0) {
|
|
||||||
::sprintf(text, "t2.txt=\"via %.8s\"", reflector);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(46U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_DSTAR;
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeDStarRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
m_rssiAccum1 += rssi;
|
|
||||||
m_rssiCount1++;
|
|
||||||
|
|
||||||
if (m_rssiCount1 == DSTAR_RSSI_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / DSTAR_RSSI_COUNT);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(47U);
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeDStarBERInt(float ber)
|
|
||||||
{
|
|
||||||
m_berAccum1 += ber;
|
|
||||||
m_berCount1++;
|
|
||||||
|
|
||||||
if (m_berCount1 == DSTAR_BER_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(DSTAR_BER_COUNT));
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(48U);
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::clearDStarInt()
|
|
||||||
{
|
|
||||||
sendCommand("t0.txt=\"Listening\"");
|
|
||||||
sendCommandAction(41U);
|
|
||||||
sendCommand("t1.txt=\"\"");
|
|
||||||
sendCommand("t2.txt=\"\"");
|
|
||||||
sendCommand("t3.txt=\"\"");
|
|
||||||
sendCommand("t4.txt=\"\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
{
|
||||||
assert(type != NULL);
|
assert(type != NULL);
|
||||||
|
@ -596,265 +487,6 @@ void CNextion::clearDMRInt(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNextion::writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(dest != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
assert(origin != NULL);
|
|
||||||
|
|
||||||
if (m_mode != MODE_YSF) {
|
|
||||||
sendCommand("page YSF");
|
|
||||||
sendCommandAction(4U);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char text[30U];
|
|
||||||
if (m_brightness>0) {
|
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
|
||||||
sendCommand(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(text, "t0.txt=\"%s %.10s\"", type, source);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(82U);
|
|
||||||
|
|
||||||
::sprintf(text, "t1.txt=\"DG-ID %u\"", dgid);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(83U);
|
|
||||||
|
|
||||||
if (::strcmp(origin, " ") != 0) {
|
|
||||||
::sprintf(text, "t2.txt=\"at %.10s\"", origin);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(84U);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_YSF;
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeFusionRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
m_rssiAccum1 += rssi;
|
|
||||||
m_rssiCount1++;
|
|
||||||
|
|
||||||
if (m_rssiCount1 == YSF_RSSI_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / YSF_RSSI_COUNT);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(85U);
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeFusionBERInt(float ber)
|
|
||||||
{
|
|
||||||
m_berAccum1 += ber;
|
|
||||||
m_berCount1++;
|
|
||||||
|
|
||||||
if (m_berCount1 == YSF_BER_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(YSF_BER_COUNT));
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(86U);
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::clearFusionInt()
|
|
||||||
{
|
|
||||||
sendCommand("t0.txt=\"Listening\"");
|
|
||||||
sendCommandAction(81U);
|
|
||||||
sendCommand("t1.txt=\"\"");
|
|
||||||
sendCommand("t2.txt=\"\"");
|
|
||||||
sendCommand("t3.txt=\"\"");
|
|
||||||
sendCommand("t4.txt=\"\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
|
|
||||||
if (m_mode != MODE_P25) {
|
|
||||||
sendCommand("page P25");
|
|
||||||
sendCommandAction(5U);
|
|
||||||
}
|
|
||||||
|
|
||||||
char text[30U];
|
|
||||||
if (m_brightness>0) {
|
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
|
||||||
sendCommand(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(text, "t0.txt=\"%s %.10s\"", type, source);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(102U);
|
|
||||||
|
|
||||||
::sprintf(text, "t1.txt=\"%s%u\"", group ? "TG" : "", dest);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(103U);
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_P25;
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeP25RSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
m_rssiAccum1 += rssi;
|
|
||||||
m_rssiCount1++;
|
|
||||||
|
|
||||||
if (m_rssiCount1 == P25_RSSI_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t2.txt=\"-%udBm\"", m_rssiAccum1 / P25_RSSI_COUNT);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(104U);
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeP25BERInt(float ber)
|
|
||||||
{
|
|
||||||
m_berAccum1 += ber;
|
|
||||||
m_berCount1++;
|
|
||||||
|
|
||||||
if (m_berCount1 == P25_BER_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t3.txt=\"%.1f%%\"", m_berAccum1 / float(P25_BER_COUNT));
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(105U);
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::clearP25Int()
|
|
||||||
{
|
|
||||||
sendCommand("t0.txt=\"Listening\"");
|
|
||||||
sendCommandAction(101U);
|
|
||||||
sendCommand("t1.txt=\"\"");
|
|
||||||
sendCommand("t2.txt=\"\"");
|
|
||||||
sendCommand("t3.txt=\"\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type)
|
|
||||||
{
|
|
||||||
assert(source != NULL);
|
|
||||||
assert(type != NULL);
|
|
||||||
|
|
||||||
if (m_mode != MODE_NXDN) {
|
|
||||||
sendCommand("page NXDN");
|
|
||||||
sendCommandAction(6U);
|
|
||||||
}
|
|
||||||
|
|
||||||
char text[30U];
|
|
||||||
if (m_brightness>0) {
|
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
|
||||||
sendCommand(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(text, "t0.txt=\"%s %.10s\"", type, source);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(122U);
|
|
||||||
|
|
||||||
::sprintf(text, "t1.txt=\"%s%u\"", group ? "TG" : "", dest);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(123U);
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_NXDN;
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeNXDNRSSIInt(unsigned char rssi)
|
|
||||||
{
|
|
||||||
m_rssiAccum1 += rssi;
|
|
||||||
m_rssiCount1++;
|
|
||||||
|
|
||||||
if (m_rssiCount1 == NXDN_RSSI_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t2.txt=\"-%udBm\"", m_rssiAccum1 / NXDN_RSSI_COUNT);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(124U);
|
|
||||||
m_rssiAccum1 = 0U;
|
|
||||||
m_rssiCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeNXDNBERInt(float ber)
|
|
||||||
{
|
|
||||||
m_berAccum1 += ber;
|
|
||||||
m_berCount1++;
|
|
||||||
|
|
||||||
if (m_berCount1 == NXDN_BER_COUNT) {
|
|
||||||
char text[25U];
|
|
||||||
::sprintf(text, "t3.txt=\"%.1f%%\"", m_berAccum1 / float(NXDN_BER_COUNT));
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(125U);
|
|
||||||
m_berAccum1 = 0.0F;
|
|
||||||
m_berCount1 = 0U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::clearNXDNInt()
|
|
||||||
{
|
|
||||||
sendCommand("t0.txt=\"Listening\"");
|
|
||||||
sendCommandAction(121U);
|
|
||||||
sendCommand("t1.txt=\"\"");
|
|
||||||
sendCommand("t2.txt=\"\"");
|
|
||||||
sendCommand("t3.txt=\"\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writePOCSAGInt(uint32_t ric, const std::string& message)
|
|
||||||
{
|
|
||||||
if (m_mode != MODE_POCSAG) {
|
|
||||||
sendCommand("page POCSAG");
|
|
||||||
sendCommandAction(7U);
|
|
||||||
}
|
|
||||||
|
|
||||||
char text[200U];
|
|
||||||
if (m_brightness>0) {
|
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
|
||||||
sendCommand(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
::sprintf(text, "t0.txt=\"RIC: %u\"", ric);
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(132U);
|
|
||||||
|
|
||||||
::sprintf(text, "t1.txt=\"%s\"", message.c_str());
|
|
||||||
sendCommand(text);
|
|
||||||
sendCommandAction(133U);
|
|
||||||
|
|
||||||
m_clockDisplayTimer.stop();
|
|
||||||
|
|
||||||
m_mode = MODE_POCSAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::clearPOCSAGInt()
|
|
||||||
{
|
|
||||||
sendCommand("t0.txt=\"Waiting\"");
|
|
||||||
sendCommandAction(134U);
|
|
||||||
sendCommand("t1.txt=\"\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNextion::writeCWInt()
|
void CNextion::writeCWInt()
|
||||||
{
|
{
|
||||||
sendCommand("t1.txt=\"Sending CW Ident\"");
|
sendCommand("t1.txt=\"Sending CW Ident\"");
|
||||||
|
|
24
Nextion.h
24
Nextion.h
|
@ -41,12 +41,6 @@ protected:
|
||||||
virtual void setErrorInt(const char* text);
|
virtual void setErrorInt(const char* text);
|
||||||
virtual void setLockoutInt();
|
virtual void setLockoutInt();
|
||||||
virtual void setQuitInt();
|
virtual void setQuitInt();
|
||||||
virtual void setFMInt();
|
|
||||||
|
|
||||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
|
||||||
virtual void writeDStarRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeDStarBERInt(float ber);
|
|
||||||
virtual void clearDStarInt();
|
|
||||||
|
|
||||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||||
|
@ -55,24 +49,6 @@ protected:
|
||||||
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
||||||
virtual void clearDMRInt(unsigned int slotNo);
|
virtual void clearDMRInt(unsigned int slotNo);
|
||||||
|
|
||||||
virtual void writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
|
||||||
virtual void writeFusionRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeFusionBERInt(float ber);
|
|
||||||
virtual void clearFusionInt();
|
|
||||||
|
|
||||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual void writeP25RSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeP25BERInt(float ber);
|
|
||||||
virtual void clearP25Int();
|
|
||||||
|
|
||||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
|
||||||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
|
||||||
virtual void writeNXDNBERInt(float ber);
|
|
||||||
virtual void clearNXDNInt();
|
|
||||||
|
|
||||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
|
||||||
virtual void clearPOCSAGInt();
|
|
||||||
|
|
||||||
virtual void writeCWInt();
|
virtual void writeCWInt();
|
||||||
virtual void clearCWInt();
|
virtual void clearCWInt();
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue