Compare commits
797 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 | ||
|
c800a4d369 | ||
|
ffe0fd0cbb | ||
|
067c1039d1 | ||
|
8c65b1c1d9 | ||
|
a4ba00f567 | ||
|
eece693f05 | ||
|
dbd779a6d3 | ||
|
f89145b772 | ||
|
f1dda251c3 | ||
|
3d489096cd | ||
|
304143d4a6 | ||
|
827a0cb72f | ||
|
d1942fcb43 | ||
|
a42e8f74c1 | ||
|
a57397e274 | ||
|
d8677b4028 | ||
|
54413e0891 | ||
|
18c8b95829 | ||
|
72654cf02a | ||
|
06ba457da2 | ||
|
9559cdb060 | ||
|
a0d60b894d | ||
|
ff8c9edb49 | ||
|
08ad50d578 | ||
|
34b3bc6166 | ||
|
424407cb82 | ||
|
258c8a1202 | ||
|
cd5624c2fb | ||
|
098cc74c9e | ||
|
bbe44df3e9 | ||
|
99cdcf1f50 | ||
|
e983aa7109 | ||
|
fc34f27f63 | ||
|
62c0165d3d | ||
|
61afb194c5 | ||
|
9932394840 | ||
|
7a5bbda248 | ||
|
53ae146667 | ||
|
31002c2757 | ||
|
d0e8574187 | ||
|
9c13baef82 | ||
|
2ff0e52558 | ||
|
9688929c3d | ||
|
bab4b50d30 | ||
|
1bb1e9da59 | ||
|
d58a0c53b5 | ||
|
9567ac0b20 | ||
|
28e013acb7 | ||
|
d2bf8eb744 | ||
|
551556b65d | ||
|
b46d2f586c | ||
|
ef07f3c035 | ||
|
5b57557a79 | ||
|
c549cf3594 | ||
|
a00ecbe7d9 | ||
|
521da9b54d | ||
|
48f95be982 | ||
|
9a72e95ec0 | ||
|
8946038e0e | ||
|
54a945ee6d | ||
|
b921f99d0a | ||
|
6e9174cf4c | ||
|
e0f4928db5 | ||
|
80a77bd12a | ||
|
8536294b76 | ||
|
e2a4ccfc05 | ||
|
ff19408e2d | ||
|
c1171bc052 | ||
|
1f72bf16d8 | ||
|
630551f6fd | ||
|
35e9a2a830 | ||
|
eb2510898d | ||
|
cfc313e5b9 | ||
|
2fc62e0e7a | ||
|
91ad967f6d | ||
|
2d557ffe30 | ||
|
f2c399308b | ||
|
879b426308 | ||
|
7c81128d77 | ||
|
64a20d9d08 | ||
|
5dc3308ef4 | ||
|
20e8d4079d | ||
|
e872ca37cd | ||
|
9ccc94923e | ||
|
9bf68e2eb7 | ||
|
3f125f055c | ||
|
768599af84 | ||
|
4ffc5cdb71 | ||
|
040ea4a15c | ||
|
d92d41b4fd | ||
|
e818d0f500 | ||
|
c5ce304edb | ||
|
ba476b6fec | ||
|
83b92f98e7 | ||
|
d77d44fd4b | ||
|
6d313fce51 | ||
|
5eabb93078 | ||
|
b2ba671071 | ||
|
c2a1aeb581 | ||
|
6d6fcc7f93 | ||
|
75652b04ae | ||
|
5a3c61644c | ||
|
90e7b58b92 | ||
|
43f4cdf092 | ||
|
98b1e6478b | ||
|
7d3e899104 | ||
|
e45f0edec4 | ||
|
e935fc1085 | ||
|
f2543de3da | ||
|
9856025923 | ||
|
def0edbaca | ||
|
457be810a3 | ||
|
2502ee94d7 | ||
|
3de54f6dd8 | ||
|
132fb62d56 | ||
|
2349520964 | ||
|
01da0ded7f | ||
|
98879b5c14 | ||
|
a9c9ff6011 | ||
|
66a17f4849 | ||
|
d5bbd77304 | ||
|
f71c8ce7bc | ||
|
70d596fea4 | ||
|
739550885b | ||
|
cdf62f1601 | ||
|
f48cfcc70c | ||
|
1cc79413b7 | ||
|
97a10c7e30 | ||
|
c7fbeecc50 | ||
|
82ea772269 | ||
|
f070410f7e | ||
|
8a6f14e6e6 | ||
|
b0d828123b | ||
|
ffd90f6941 | ||
|
c21e325ddb | ||
|
3776ed2b1b | ||
|
c57a313677 | ||
|
11c8403829 | ||
|
34c759df5f | ||
|
9ab838f653 | ||
|
52ca12e88a | ||
|
e01b153a86 | ||
|
01d8fe1a58 | ||
|
f35ab6230b | ||
|
efcecd69d3 | ||
|
0579b4387a | ||
|
b4cf7a4ad4 | ||
|
c2c1266233 | ||
|
7aec7eefcb | ||
|
869edd33fd | ||
|
f64371b4c8 | ||
|
d4e6f2cb5e | ||
|
354e808ccb | ||
|
8f59691738 | ||
|
5703758116 | ||
|
15c21de416 | ||
|
da077c73f8 | ||
|
801ba04e0d | ||
|
fa7be67d9c | ||
|
49a4e2ad0d | ||
|
bb1a542fe1 | ||
|
ba9c97289f | ||
|
76033dd301 | ||
|
87b7a7c48a | ||
|
c80894ddaa | ||
|
9c4d2f46bb | ||
|
34db212360 | ||
|
3e6d5d5a7f | ||
|
1e833d78cf | ||
|
e9a128ebdc | ||
|
009f50a913 | ||
|
4d6f64a51e | ||
|
b8f0525dcb | ||
|
40a974d7cb | ||
|
41dc96affe | ||
|
954231ccbc | ||
|
3cc77c5c57 | ||
|
f42f6f07c4 | ||
|
183430593f | ||
|
192e8e2435 | ||
|
c40291dcc2 | ||
|
16fac0b41c | ||
|
1ded19c5b2 | ||
|
9137399ea9 | ||
|
8a0db8cb8b | ||
|
6de0bdb536 | ||
|
74adbd4895 | ||
|
ba1b6a8751 | ||
|
8c52246be8 | ||
|
5dcdfd8159 | ||
|
15a8e87c3e | ||
|
c8e31ce657 | ||
|
4217ccebc4 | ||
|
ee2e997cfd | ||
|
dfaedb450b | ||
|
2bc6dd6ca9 | ||
|
fb6fb70ffb | ||
|
4dd39696b4 | ||
|
4d3869172d | ||
|
e106df3cdf | ||
|
8edfc62049 | ||
|
0892aaaaae | ||
|
79b3eaa57a | ||
|
d2be920254 | ||
|
d0fa27bfd1 | ||
|
5f0ee739e1 | ||
|
4ae141f594 | ||
|
22427cd348 | ||
|
aa8b78a311 | ||
|
14413963d9 | ||
|
974251485d | ||
|
e339de8fee | ||
|
236d467c1a | ||
|
df47466aa2 | ||
|
8383c7d320 | ||
|
5dbf916db0 | ||
|
be8c29da3e | ||
|
4ee32a506f | ||
|
8291470698 | ||
|
35a283d7b4 | ||
|
edce667018 | ||
|
fab4dc227e | ||
|
30098a5d38 | ||
|
d4c7f20696 | ||
|
93a0b9793b | ||
|
648426f44c | ||
|
97f1ebb25f | ||
|
d1a809808b | ||
|
bdb1c49bae | ||
|
f151ca6c1a | ||
|
e164538b09 | ||
|
cb51a14575 | ||
|
371661bd11 | ||
|
6321563496 | ||
|
ab3705e8e0 | ||
|
aec1ae74f7 | ||
|
2953ce85a0 | ||
|
1c6a48a8e1 | ||
|
1dc91b9a64 | ||
|
28d64e7c3d | ||
|
c174c10caf | ||
|
96a8ec0e35 | ||
|
d8716adc43 | ||
|
325b30d30b | ||
|
e8c21493c1 | ||
|
92ceba052a | ||
|
c026471aec | ||
|
27c9ad43ec | ||
|
38f59236ae | ||
|
692d6519db | ||
|
fe77cbd68c | ||
|
f936a6c5b6 | ||
|
d0878bbf7e | ||
|
e0f800ba98 | ||
|
d9e2940f08 | ||
|
b3398710bc | ||
|
50888777e6 | ||
|
3313fe8ec3 | ||
|
7c95e231e2 | ||
|
36a852b38b | ||
|
1ab09e21fe | ||
|
19c8c6515c | ||
|
816f8ea0a1 | ||
|
d409700a31 | ||
|
dbe04c3c2f | ||
|
933b9ef014 | ||
|
85751e0c51 | ||
|
f01fc3e9fc | ||
|
82c6f717cf | ||
|
f18e253eac | ||
|
17b49fde88 | ||
|
aa5eeb3554 | ||
|
97a35e69a4 | ||
|
af6b7d79da | ||
|
bd1aa20803 | ||
|
015edf9b81 | ||
|
98cd2404f5 | ||
|
eef364b1a9 | ||
|
8d4241d154 | ||
|
409e0de721 | ||
|
c2187fd624 | ||
|
75d5083f8e | ||
|
0b8a9a1a4c | ||
|
a28aa77927 | ||
|
4c7a2526e5 | ||
|
7bfe2f2b2f | ||
|
0b7efee2a7 | ||
|
924baeacd1 | ||
|
45eafe3672 | ||
|
e7ffcb5090 | ||
|
26243c0247 | ||
|
02d1e2f0ef | ||
|
1caffc1dad | ||
|
12e58d5440 | ||
|
8b31cb34ff | ||
|
c0a9bb81a3 | ||
|
3b7d4d486e | ||
|
ed3299a513 | ||
|
ad843e7283 | ||
|
af34d9abc3 | ||
|
0b185a0900 | ||
|
303a0163d3 | ||
|
0dbfe896bb | ||
|
1290f9c49e | ||
|
4eb534aab6 | ||
|
eb4dcc22a7 | ||
|
953530c23b | ||
|
9d08f1605c | ||
|
578ef5a3d4 | ||
|
23e92af6fa | ||
|
734af9453c | ||
|
a66f4c6188 | ||
|
283b54c46a | ||
|
dc41acbd21 | ||
|
b5316907ad | ||
|
56619166b6 | ||
|
d96e2204bf | ||
|
2165b38379 | ||
|
c413c3a855 | ||
|
bcf0ddc2b3 | ||
|
b5658a6478 | ||
|
9e52db3ef3 | ||
|
dc5438e3aa | ||
|
083cc1155b | ||
|
8ac6a1b208 | ||
|
ce121c59da | ||
|
143652b7f2 | ||
|
cbcbe4c56a | ||
|
f9ccb7c876 | ||
|
bc6f832b7d | ||
|
039ef44a63 | ||
|
bc3f98f19c | ||
|
7bca857852 | ||
|
29b36a66f8 | ||
|
6b4fe7dd33 | ||
|
7be89b91ea | ||
|
008bfee6b9 | ||
|
0178ba0aba | ||
|
3299913003 | ||
|
33fedb781d | ||
|
ab437c0866 | ||
|
2ae966b7fb | ||
|
467140dbf8 | ||
|
2a8e1ce9f4 | ||
|
800b7a30af | ||
|
c3efabf56c | ||
|
47862e0682 | ||
|
e28dfe79dd | ||
|
bc22709abb | ||
|
dc9e6ade23 | ||
|
9a2dd6a5e6 | ||
|
c48f45d2da | ||
|
93652c764e | ||
|
8cdc1ffe7f | ||
|
5e887a95c5 | ||
|
7ae77a01a9 | ||
|
51a1e2bb9c | ||
|
c2ca65f889 | ||
|
b3d287965f | ||
|
bc791577e7 | ||
|
d6b367b8b5 | ||
|
5410ca3ce8 | ||
|
da0f1a6a76 | ||
|
7718676928 | ||
|
ff492a518f | ||
|
d3f4b1f90c | ||
|
8b2b3d344a | ||
|
dd2f5fbe26 | ||
|
1a142e36cb | ||
|
6d6cee119d | ||
|
97327be963 | ||
|
7e145d288a | ||
|
5fe70ee654 | ||
|
9796b400c8 | ||
|
3687eb71a8 | ||
|
4a923fb27e | ||
|
70ca7c06dd | ||
|
463bda2688 | ||
|
56746e1320 | ||
|
3d1602e50e | ||
|
ac344cec69 | ||
|
a73c0dbd72 | ||
|
fbdee0edf1 | ||
|
0d956b16fa | ||
|
6df6094ebf | ||
|
93effcad3d | ||
|
cb732c9a62 | ||
|
a450c2b2ad | ||
|
9acd523bc3 | ||
|
c359d874b5 | ||
|
11cd5679a7 | ||
|
f8bce3823a | ||
|
960a60f382 | ||
|
1f17aec1f1 | ||
|
58aff1ab77 | ||
|
211e96a86d | ||
|
927f31cdfa | ||
|
dcdfca39d7 | ||
|
5df1fe551f | ||
|
c381f2ceac | ||
|
8cd75ce787 | ||
|
535ddba1a0 | ||
|
88bbb0cd0f | ||
|
15b5011ebf | ||
|
dad47317e6 | ||
|
c92039d83b | ||
|
4c4ea170b6 | ||
|
63ee2eb98c | ||
|
e780e8bd30 | ||
|
5dccd5c5ce | ||
|
022d1a768b | ||
|
90c5b24e9f | ||
|
ac50244de3 | ||
|
6d27b8d957 | ||
|
d7d83ff4d0 | ||
|
e036ac8be3 | ||
|
cc62fb62b7 | ||
|
36414acc6a | ||
|
d2751897fb | ||
|
f6b5036651 | ||
|
136a148480 | ||
|
6febd661f6 | ||
|
92a3441116 | ||
|
5bd54e97cb | ||
|
4ff77c50d6 | ||
|
abf17e19fc | ||
|
b7f5fdd8a2 | ||
|
9b15454f96 | ||
|
a2911fa5c3 | ||
|
92d9973ace | ||
|
8ff3913729 | ||
|
ab13f355d5 | ||
|
8d87037ee5 | ||
|
0bc6bcdb26 | ||
|
ead41ba9a5 | ||
|
b0fe8dc607 | ||
|
a117d70c56 | ||
|
2a9d90b7c7 | ||
|
45013ac179 | ||
|
b86bc820e8 | ||
|
4450caeddc | ||
|
fa08abfded | ||
|
8b172f1221 | ||
|
88304997d4 | ||
|
d70a124f47 | ||
|
60e82737b9 | ||
|
95c1bbb8e6 | ||
|
5686942519 | ||
|
3fa72d853d | ||
|
a0ec58539a | ||
|
3b7452feda | ||
|
0e78fafa91 | ||
|
be6f59ba5f | ||
|
ce5a212bd3 | ||
|
ab226cec27 | ||
|
31408d4a33 | ||
|
6713e0f52b | ||
|
1ba4879224 | ||
|
f3844ceae8 | ||
|
b29e1d0050 | ||
|
9234dfcf6a | ||
|
ed7f593e07 | ||
|
de88f09b68 | ||
|
2ecd9b3440 | ||
|
c2584066d8 | ||
|
88d91e420a | ||
|
d5b08ea7ea | ||
|
2f9595949a | ||
|
aa7ae2371c | ||
|
b38ba239a8 | ||
|
7cdbbdecb0 | ||
|
6caffb2bc0 | ||
|
8d88d8e5ed | ||
|
484b0f3e25 | ||
|
231efdf567 | ||
|
e74df4875b | ||
|
fa8d735b1b | ||
|
c18c0a3105 | ||
|
bc5a1d24c4 | ||
|
f4f745d58c | ||
|
4be7ccd924 | ||
|
ef1631ac33 | ||
|
98e0869257 | ||
|
079c95aac1 | ||
|
e885c84f6e | ||
|
529fdf88eb | ||
|
1ed79d01c0 | ||
|
cd40f6602d | ||
|
1993262c52 | ||
|
56298d14c4 | ||
|
0711a2b391 | ||
|
6bababeb96 | ||
|
16a8bfd757 | ||
|
4f3ca97e69 | ||
|
bb0bd4bb46 | ||
|
ed79a7176a | ||
|
87e60a81f8 | ||
|
0b7f2e1e4b | ||
|
0eae2c8224 | ||
|
881b32f0a9 | ||
|
54ae56942f | ||
|
005590b6aa | ||
|
78753cbbad | ||
|
bd5117b9e4 | ||
|
d0dbb1127b | ||
|
06af86b70d | ||
|
839a8c83ea | ||
|
0b9c1b1362 | ||
|
99c8b23f41 | ||
|
750ef77321 | ||
|
73bf04ad4b | ||
|
814059ff35 | ||
|
ffd5cd1a0b | ||
|
2aa130e22f | ||
|
847652f8ce | ||
|
6d83bfb8bc |
219 changed files with 45407 additions and 27461 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;
|
||||||
|
|
99
CASTInfo.cpp
Normal file
99
CASTInfo.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016,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 "CASTInfo.h"
|
||||||
|
|
||||||
|
static bool networkInfoInitialized = false;
|
||||||
|
static unsigned char passCounter = 0;
|
||||||
|
|
||||||
|
CCASTInfo::CCASTInfo(CModem* modem) :
|
||||||
|
CDisplay(),
|
||||||
|
m_modem(modem),
|
||||||
|
m_ipaddress()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CCASTInfo::~CCASTInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCASTInfo::open()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::setIdleInt()
|
||||||
|
{
|
||||||
|
unsigned char info[100U];
|
||||||
|
CNetworkInfo* m_network;
|
||||||
|
|
||||||
|
passCounter ++;
|
||||||
|
if (passCounter > 253U)
|
||||||
|
networkInfoInitialized = false;
|
||||||
|
|
||||||
|
if (! networkInfoInitialized) {
|
||||||
|
//LogMessage("Initialize CNetworkInfo");
|
||||||
|
info[0]=0;
|
||||||
|
m_network = new CNetworkInfo;
|
||||||
|
m_network->getNetworkInterface(info);
|
||||||
|
m_ipaddress = (char*)info;
|
||||||
|
delete m_network;
|
||||||
|
|
||||||
|
if (m_modem != NULL)
|
||||||
|
m_modem->writeIPInfo(m_ipaddress);
|
||||||
|
|
||||||
|
networkInfoInitialized = true;
|
||||||
|
passCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::setErrorInt(const char* text)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::setLockoutInt()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::setQuitInt()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||||
|
{
|
||||||
|
if (m_modem != NULL)
|
||||||
|
m_modem->writeDMRInfo(slotNo, src, group, dst, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::clearDMRInt(unsigned int slotNo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::writeCWInt()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::clearCWInt()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCASTInfo::close()
|
||||||
|
{
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 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
|
||||||
|
@ -16,48 +16,41 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MobileGPS_H
|
#if !defined(CASTINFO_H)
|
||||||
#define MobileGPS_H
|
#define CASTINFO_H
|
||||||
|
|
||||||
#include "DMRNetwork.h"
|
#include "Display.h"
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(_WIN64)
|
#include "NetworkInfo.h"
|
||||||
#include <netdb.h>
|
#include "Modem.h"
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#else
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CMobileGPS {
|
class CCASTInfo : public CDisplay
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
CMobileGPS(const std::string& address, unsigned int port, CDMRNetwork* network);
|
CCASTInfo(CModem* modem);
|
||||||
~CMobileGPS();
|
virtual ~CCASTInfo();
|
||||||
|
|
||||||
bool open();
|
virtual bool open();
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
virtual void close();
|
||||||
|
|
||||||
void close();
|
protected:
|
||||||
|
virtual void setIdleInt();
|
||||||
|
virtual void setErrorInt(const char* text);
|
||||||
|
virtual void setLockoutInt();
|
||||||
|
virtual void setQuitInt();
|
||||||
|
|
||||||
|
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 writeCWInt();
|
||||||
|
virtual void clearCWInt();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CTimer m_idTimer;
|
CModem* m_modem;
|
||||||
in_addr m_address;
|
std::string m_ipaddress;
|
||||||
unsigned int m_port;
|
|
||||||
CUDPSocket m_socket;
|
|
||||||
CDMRNetwork* m_network;
|
|
||||||
|
|
||||||
bool pollGPS();
|
|
||||||
void sendReport();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
272
Conf.h
272
Conf.h
|
@ -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
|
||||||
|
@ -54,6 +54,7 @@ public:
|
||||||
unsigned int getLogFileLevel() const;
|
unsigned int getLogFileLevel() const;
|
||||||
std::string getLogFilePath() const;
|
std::string getLogFilePath() const;
|
||||||
std::string getLogFileRoot() const;
|
std::string getLogFileRoot() const;
|
||||||
|
bool getLogFileRotate() const;
|
||||||
|
|
||||||
// The CW ID section
|
// The CW ID section
|
||||||
bool getCWIdEnabled() const;
|
bool getCWIdEnabled() const;
|
||||||
|
@ -64,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;
|
||||||
|
@ -89,37 +92,25 @@ 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 getModemAX25TXLevel() const;
|
||||||
std::string getModemRSSIMappingFile() const;
|
std::string getModemRSSIMappingFile() const;
|
||||||
|
bool getModemUseCOSAsLockout() const;
|
||||||
bool getModemTrace() const;
|
bool getModemTrace() const;
|
||||||
bool getModemDebug() const;
|
bool getModemDebug() const;
|
||||||
|
|
||||||
// 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;
|
|
||||||
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;
|
||||||
bool getDMRBeacons() const;
|
DMR_BEACONS getDMRBeacons() const;
|
||||||
unsigned int getDMRBeaconInterval() const;
|
unsigned int getDMRBeaconInterval() const;
|
||||||
unsigned int getDMRBeaconDuration() const;
|
unsigned int getDMRBeaconDuration() const;
|
||||||
unsigned int getDMRId() const;
|
unsigned int getDMRId() const;
|
||||||
|
@ -135,51 +126,15 @@ public:
|
||||||
unsigned int getDMRCallHang() const;
|
unsigned int getDMRCallHang() const;
|
||||||
unsigned int getDMRTXHang() const;
|
unsigned int getDMRTXHang() const;
|
||||||
unsigned int getDMRModeHang() const;
|
unsigned int getDMRModeHang() 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;
|
|
||||||
bool getFusionDGIdEnabled() const;
|
|
||||||
unsigned char getFusionDGId() 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 getP25ModeHang() const;
|
|
||||||
|
|
||||||
// The NXDN section
|
|
||||||
bool getNXDNEnabled() const;
|
|
||||||
unsigned int getNXDNId() const;
|
|
||||||
unsigned int getNXDNRAN() const;
|
|
||||||
bool getNXDNSelfOnly() const;
|
|
||||||
bool getNXDNRemoteGateway() const;
|
|
||||||
unsigned int getNXDNModeHang() const;
|
|
||||||
|
|
||||||
// The POCSAG section
|
|
||||||
bool getPOCSAGEnabled() const;
|
|
||||||
unsigned int getPOCSAGFrequency() 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;
|
||||||
|
@ -188,42 +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 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;
|
||||||
|
|
||||||
|
@ -254,12 +174,12 @@ public:
|
||||||
bool getOLEDInvert() const;
|
bool getOLEDInvert() const;
|
||||||
bool getOLEDScroll() const;
|
bool getOLEDScroll() const;
|
||||||
bool getOLEDRotate() const;
|
bool getOLEDRotate() const;
|
||||||
bool getOLEDCast() const;
|
bool getOLEDLogoScreensaver() const;
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -268,14 +188,10 @@ public:
|
||||||
bool getLockFileEnabled() const;
|
bool getLockFileEnabled() const;
|
||||||
std::string getLockFileName() const;
|
std::string getLockFileName() const;
|
||||||
|
|
||||||
// The Mobile GPS section
|
|
||||||
bool getMobileGPSEnabled() const;
|
|
||||||
std::string getMobileGPSAddress() const;
|
|
||||||
unsigned int getMobileGPSPort() const;
|
|
||||||
|
|
||||||
// The Remote Control section
|
// The Remote Control section
|
||||||
bool getRemoteControlEnabled() const;
|
bool getRemoteControlEnabled() const;
|
||||||
unsigned int getRemoteControlPort() const;
|
std::string getRemoteControlAddress() const;
|
||||||
|
unsigned short getRemoteControlPort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_file;
|
std::string m_file;
|
||||||
|
@ -300,6 +216,7 @@ private:
|
||||||
unsigned int m_logFileLevel;
|
unsigned int m_logFileLevel;
|
||||||
std::string m_logFilePath;
|
std::string m_logFilePath;
|
||||||
std::string m_logFileRoot;
|
std::string m_logFileRoot;
|
||||||
|
bool m_logFileRotate;
|
||||||
|
|
||||||
bool m_cwIdEnabled;
|
bool m_cwIdEnabled;
|
||||||
unsigned int m_cwIdTime;
|
unsigned int m_cwIdTime;
|
||||||
|
@ -311,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;
|
||||||
|
@ -326,38 +249,20 @@ 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;
|
|
||||||
std::string m_modemRSSIMappingFile;
|
std::string m_modemRSSIMappingFile;
|
||||||
|
bool m_modemUseCOSAsLockout;
|
||||||
bool m_modemTrace;
|
bool m_modemTrace;
|
||||||
bool m_modemDebug;
|
bool m_modemDebug;
|
||||||
|
|
||||||
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;
|
|
||||||
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;
|
||||||
bool m_dmrBeacons;
|
DMR_BEACONS m_dmrBeacons;
|
||||||
unsigned int m_dmrBeaconInterval;
|
unsigned int m_dmrBeaconInterval;
|
||||||
unsigned int m_dmrBeaconDuration;
|
unsigned int m_dmrBeaconDuration;
|
||||||
unsigned int m_dmrId;
|
unsigned int m_dmrId;
|
||||||
|
@ -373,45 +278,14 @@ private:
|
||||||
unsigned int m_dmrCallHang;
|
unsigned int m_dmrCallHang;
|
||||||
unsigned int m_dmrTXHang;
|
unsigned int m_dmrTXHang;
|
||||||
unsigned int m_dmrModeHang;
|
unsigned int m_dmrModeHang;
|
||||||
|
DMR_OVCM_TYPES m_dmrOVCM;
|
||||||
bool m_fusionEnabled;
|
|
||||||
bool m_fusionLowDeviation;
|
|
||||||
bool m_fusionRemoteGateway;
|
|
||||||
bool m_fusionSelfOnly;
|
|
||||||
unsigned int m_fusionTXHang;
|
|
||||||
bool m_fusionDGIdEnabled;
|
|
||||||
unsigned char m_fusionDGId;
|
|
||||||
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_p25ModeHang;
|
|
||||||
|
|
||||||
bool m_nxdnEnabled;
|
|
||||||
unsigned int m_nxdnId;
|
|
||||||
unsigned int m_nxdnRAN;
|
|
||||||
bool m_nxdnSelfOnly;
|
|
||||||
bool m_nxdnRemoteGateway;
|
|
||||||
unsigned int m_nxdnModeHang;
|
|
||||||
|
|
||||||
bool m_pocsagEnabled;
|
|
||||||
unsigned int m_pocsagFrequency;
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -420,38 +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_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;
|
||||||
|
@ -478,11 +321,11 @@ private:
|
||||||
bool m_oledInvert;
|
bool m_oledInvert;
|
||||||
bool m_oledScroll;
|
bool m_oledScroll;
|
||||||
bool m_oledRotate;
|
bool m_oledRotate;
|
||||||
bool m_oledCast;
|
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;
|
||||||
|
@ -490,12 +333,9 @@ private:
|
||||||
bool m_lockFileEnabled;
|
bool m_lockFileEnabled;
|
||||||
std::string m_lockFileName;
|
std::string m_lockFileName;
|
||||||
|
|
||||||
bool m_mobileGPSEnabled;
|
|
||||||
std::string m_mobileGPSAddress;
|
|
||||||
unsigned int m_mobileGPSPort;
|
|
||||||
|
|
||||||
bool m_remoteControlEnabled;
|
bool m_remoteControlEnabled;
|
||||||
unsigned int m_remoteControlPort;
|
std::string m_remoteControlAddress;
|
||||||
|
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()) {
|
||||||
|
|
58
DMRCSBK.cpp
58
DMRCSBK.cpp
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020,2021,2022 by Jonathan Naylor G4KLX
|
||||||
|
* 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
|
||||||
* 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
|
||||||
|
@ -33,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];
|
||||||
}
|
}
|
||||||
|
@ -80,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;
|
||||||
|
|
||||||
|
@ -89,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;
|
||||||
|
|
||||||
|
@ -110,6 +114,39 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
||||||
CUtils::dump(1U, "Negative Acknowledge Response CSBK", m_data, 12U);
|
CUtils::dump(1U, "Negative Acknowledge Response CSBK", m_data, 12U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CSBKO_CALL_ALERT:
|
||||||
|
m_GI = false;
|
||||||
|
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];
|
||||||
|
m_dataContent = false;
|
||||||
|
m_CBF = 0U;
|
||||||
|
CUtils::dump(1U, "Call Alert CSBK", m_data, 12U);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CSBKO_CALL_ALERT_ACK:
|
||||||
|
m_GI = false;
|
||||||
|
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];
|
||||||
|
m_dataContent = false;
|
||||||
|
m_CBF = 0U;
|
||||||
|
CUtils::dump(1U, "Call Alert Ack CSBK", m_data, 12U);
|
||||||
|
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;
|
||||||
|
@ -149,6 +186,23 @@ unsigned char CDMRCSBK::getFID() const
|
||||||
return m_FID;
|
return m_FID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDMRCSBK::getOVCM() const
|
||||||
|
{
|
||||||
|
return m_OVCM;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRCSBK::setOVCM(bool ovcm)
|
||||||
|
{
|
||||||
|
if (m_CSBKO == CSBKO_UUVREQ || m_CSBKO == CSBKO_UUANSRSP) {
|
||||||
|
m_OVCM = ovcm;
|
||||||
|
|
||||||
|
if (ovcm)
|
||||||
|
m_data[2U] |= 0x04U;
|
||||||
|
else
|
||||||
|
m_data[2U] &= 0xFBU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CDMRCSBK::getGI() const
|
bool CDMRCSBK::getGI() const
|
||||||
{
|
{
|
||||||
return m_GI;
|
return m_GI;
|
||||||
|
|
24
DMRCSBK.h
24
DMRCSBK.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 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
|
||||||
|
@ -22,13 +22,16 @@
|
||||||
#include "DMRDefines.h"
|
#include "DMRDefines.h"
|
||||||
|
|
||||||
enum CSBKO {
|
enum CSBKO {
|
||||||
CSBKO_NONE = 0x00,
|
CSBKO_NONE = 0x00,
|
||||||
CSBKO_UUVREQ = 0x04,
|
CSBKO_UUVREQ = 0x04,
|
||||||
CSBKO_UUANSRSP = 0x05,
|
CSBKO_UUANSRSP = 0x05,
|
||||||
CSBKO_CTCSBK = 0x07,
|
CSBKO_CTCSBK = 0x07,
|
||||||
CSBKO_NACKRSP = 0x26,
|
CSBKO_CALL_ALERT = 0x1F,
|
||||||
CSBKO_BSDWNACT = 0x38,
|
CSBKO_CALL_ALERT_ACK = 0x20,
|
||||||
CSBKO_PRECCSBK = 0x3D
|
CSBKO_RADIO_CHECK = 0x24,
|
||||||
|
CSBKO_NACKRSP = 0x26,
|
||||||
|
CSBKO_BSDWNACT = 0x38,
|
||||||
|
CSBKO_PRECCSBK = 0x3D
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDMRCSBK
|
class CDMRCSBK
|
||||||
|
@ -45,6 +48,10 @@ public:
|
||||||
CSBKO getCSBKO() const;
|
CSBKO getCSBKO() const;
|
||||||
unsigned char getFID() const;
|
unsigned char getFID() const;
|
||||||
|
|
||||||
|
// Set/Get the OVCM bit in the supported CSBKs
|
||||||
|
bool getOVCM() const;
|
||||||
|
void setOVCM(bool ovcm);
|
||||||
|
|
||||||
// For BS Dwn Act
|
// For BS Dwn Act
|
||||||
unsigned int getBSId() const;
|
unsigned int getBSId() const;
|
||||||
|
|
||||||
|
@ -69,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) :
|
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,7 +38,14 @@ 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);
|
||||||
|
|
||||||
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, jitter);
|
//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);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDMRControl::~CDMRControl()
|
CDMRControl::~CDMRControl()
|
||||||
|
@ -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);
|
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
|
|
@ -44,11 +44,11 @@ void CDMREMB::putData(const unsigned char* data)
|
||||||
DMREMB[1U] = (data[18U] << 4) & 0xF0U;
|
DMREMB[1U] = (data[18U] << 4) & 0xF0U;
|
||||||
DMREMB[1U] |= (data[19U] >> 4) & 0x0FU;
|
DMREMB[1U] |= (data[19U] >> 4) & 0x0FU;
|
||||||
|
|
||||||
CQR1676::decode(DMREMB);
|
unsigned char code = CQR1676::decode(DMREMB);
|
||||||
|
|
||||||
m_colorCode = (DMREMB[0U] >> 4) & 0x0FU;
|
m_colorCode = (code >> 4) & 0x0FU;
|
||||||
m_PI = (DMREMB[0U] & 0x08U) == 0x08U;
|
m_PI = (code & 0x08U) == 0x08U;
|
||||||
m_LCSS = (DMREMB[0U] >> 1) & 0x03U;
|
m_LCSS = (code >> 1) & 0x03U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMREMB::getData(unsigned char* data) const
|
void CDMREMB::getData(unsigned char* data) const
|
||||||
|
|
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
|
42048
DMRIds.dat
42048
DMRIds.dat
File diff suppressed because it is too large
Load diff
15
DMRLC.cpp
15
DMRLC.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 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
|
||||||
|
@ -184,6 +184,19 @@ void CDMRLC::setFID(unsigned char fid)
|
||||||
m_FID = fid;
|
m_FID = fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDMRLC::getOVCM() const
|
||||||
|
{
|
||||||
|
return (m_options & 0x04U) == 0x04U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDMRLC::setOVCM(bool ovcm)
|
||||||
|
{
|
||||||
|
if (ovcm)
|
||||||
|
m_options |= 0x04U;
|
||||||
|
else
|
||||||
|
m_options &= 0xFBU;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int CDMRLC::getSrcId() const
|
unsigned int CDMRLC::getSrcId() const
|
||||||
{
|
{
|
||||||
return m_srcId;
|
return m_srcId;
|
||||||
|
|
5
DMRLC.h
5
DMRLC.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 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
|
||||||
|
@ -39,6 +39,9 @@ public:
|
||||||
FLCO getFLCO() const;
|
FLCO getFLCO() const;
|
||||||
void setFLCO(FLCO flco);
|
void setFLCO(FLCO flco);
|
||||||
|
|
||||||
|
bool getOVCM() const;
|
||||||
|
void setOVCM(bool ovcm);
|
||||||
|
|
||||||
unsigned char getFID() const;
|
unsigned char getFID() const;
|
||||||
void setFID(unsigned char fid);
|
void setFID(unsigned char fid);
|
||||||
|
|
||||||
|
|
138
DMRLookup.cpp
138
DMRLookup.cpp
|
@ -30,8 +30,8 @@ CThread(),
|
||||||
m_filename(filename),
|
m_filename(filename),
|
||||||
m_reloadTime(reloadTime),
|
m_reloadTime(reloadTime),
|
||||||
m_table(),
|
m_table(),
|
||||||
m_mutex(),
|
m_stop(false),
|
||||||
m_stop(false)
|
m_reload(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ CDMRLookup::~CDMRLookup()
|
||||||
|
|
||||||
bool CDMRLookup::read()
|
bool CDMRLookup::read()
|
||||||
{
|
{
|
||||||
bool ret = load();
|
bool ret = m_table.load(m_filename);
|
||||||
|
|
||||||
if (m_reloadTime > 0U)
|
if (m_reloadTime > 0U)
|
||||||
run();
|
run();
|
||||||
|
@ -49,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");
|
||||||
|
@ -60,9 +68,10 @@ void CDMRLookup::entry()
|
||||||
sleep(1000U);
|
sleep(1000U);
|
||||||
|
|
||||||
timer.clock();
|
timer.clock();
|
||||||
if (timer.hasExpired()) {
|
if (timer.hasExpired() || m_reload) {
|
||||||
load();
|
m_table.load(m_filename);
|
||||||
timer.start();
|
timer.start();
|
||||||
|
m_reload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,118 +90,47 @@ void CDMRLookup::stop()
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CDMRLookup::findWithName(unsigned int id)
|
void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry)
|
||||||
{
|
{
|
||||||
std::string callsign;
|
if (id == 0xFFFFFFFU) {
|
||||||
|
entry->clear();
|
||||||
if (id == 0xFFFFFFU)
|
entry->set(keyCALLSIGN, "ALL");
|
||||||
return std::string("ALL");
|
return;
|
||||||
|
|
||||||
m_mutex.lock();
|
|
||||||
|
|
||||||
try {
|
|
||||||
callsign = m_table.at(id);
|
|
||||||
LogDebug("FindWithName =%s",callsign.c_str());
|
|
||||||
|
|
||||||
} catch (...) {
|
|
||||||
char text[10U];
|
|
||||||
::sprintf(text, "%u", id);
|
|
||||||
callsign = std::string(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mutex.unlock();
|
if (m_table.lookup(id, entry)) {
|
||||||
|
LogDebug("FindWithName =%s %s", entry->get(keyCALLSIGN).c_str(), entry->get(keyFIRST_NAME).c_str());
|
||||||
|
} else {
|
||||||
|
entry->clear();
|
||||||
|
|
||||||
return callsign;
|
char text[10U];
|
||||||
|
::snprintf(text, sizeof(text), "%u", id);
|
||||||
|
entry->set(keyCALLSIGN, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CDMRLookup::find(unsigned int id)
|
std::string CDMRLookup::find(unsigned int id)
|
||||||
{
|
{
|
||||||
std::string callsign;
|
std::string callsign;
|
||||||
std::string b;
|
|
||||||
|
if (id == 0xFFFFFFFU)
|
||||||
|
|
||||||
if (id == 0xFFFFFFU)
|
|
||||||
return std::string("ALL");
|
return std::string("ALL");
|
||||||
|
|
||||||
m_mutex.lock();
|
class CUserDBentry entry;
|
||||||
|
if (m_table.lookup(id, &entry)) {
|
||||||
try {
|
callsign = entry.get(keyCALLSIGN);
|
||||||
b = m_table.at(id);
|
} else {
|
||||||
size_t n = b.find(" ");
|
|
||||||
if (n > 0) {
|
|
||||||
callsign = b.substr(0,n);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
LogDebug("b=%s",b.c_str());
|
|
||||||
callsign = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (...) {
|
|
||||||
char text[10U];
|
char text[10U];
|
||||||
::sprintf(text, "%u", id);
|
::snprintf(text, sizeof(text), "%u", id);
|
||||||
callsign = std::string(text);
|
callsign = std::string(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
return callsign;
|
return callsign;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDMRLookup::exists(unsigned int id)
|
bool CDMRLookup::exists(unsigned int id)
|
||||||
{
|
{
|
||||||
m_mutex.lock();
|
return m_table.lookup(id, NULL);
|
||||||
|
|
||||||
bool found = m_table.count(id) == 1U;
|
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDMRLookup::load()
|
|
||||||
{
|
|
||||||
FILE* fp = ::fopen(m_filename.c_str(), "rt");
|
|
||||||
if (fp == NULL) {
|
|
||||||
LogWarning("Cannot open the DMR Id lookup file - %s", m_filename.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mutex.lock();
|
|
||||||
|
|
||||||
// Remove the old entries
|
|
||||||
m_table.clear();
|
|
||||||
|
|
||||||
char buffer[100U];
|
|
||||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
|
||||||
if (buffer[0U] == '#')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char* p1 = ::strtok(buffer, " \t\r\n");
|
|
||||||
char* p2 = ::strtok(NULL, " \r\n"); // tokenize to eol to capture name as well
|
|
||||||
|
|
||||||
if (p1 != NULL && p2 != NULL) {
|
|
||||||
unsigned int id = (unsigned int)::atoi(p1);
|
|
||||||
for (char* p = p2; *p != 0x00U; p++) {
|
|
||||||
|
|
||||||
if(*p == 0x09U)
|
|
||||||
*p = 0x20U;
|
|
||||||
|
|
||||||
else
|
|
||||||
*p = ::toupper(*p);
|
|
||||||
|
|
||||||
}
|
|
||||||
m_table[id] = std::string(p2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
::fclose(fp);
|
|
||||||
|
|
||||||
size_t size = m_table.size();
|
|
||||||
if (size == 0U)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LogInfo("Loaded %u Ids to the DMR callsign lookup table", size);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
21
DMRLookup.h
21
DMRLookup.h
|
@ -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
|
||||||
|
@ -20,10 +20,9 @@
|
||||||
#define DMRLookup_H
|
#define DMRLookup_H
|
||||||
|
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "Mutex.h"
|
#include "UserDB.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
class CDMRLookup : public CThread {
|
class CDMRLookup : public CThread {
|
||||||
public:
|
public:
|
||||||
|
@ -32,23 +31,23 @@ 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);
|
||||||
std::string findWithName(unsigned int id);
|
void findWithName(unsigned int id, class CUserDBentry *entry);
|
||||||
|
|
||||||
bool exists(unsigned int id);
|
bool exists(unsigned int id);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
unsigned int m_reloadTime;
|
unsigned int m_reloadTime;
|
||||||
std::unordered_map<unsigned int, std::string> m_table;
|
class CUserDB m_table;
|
||||||
CMutex m_mutex;
|
bool m_stop;
|
||||||
bool m_stop;
|
bool m_reload;
|
||||||
|
|
||||||
bool load();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
657
DMRNetwork.cpp
657
DMRNetwork.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015-2020 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,659 +18,6 @@
|
||||||
|
|
||||||
#include "DMRNetwork.h"
|
#include "DMRNetwork.h"
|
||||||
|
|
||||||
#include "StopWatch.h"
|
IDMRNetwork::~IDMRNetwork()
|
||||||
#include "SHA256.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;
|
|
||||||
|
|
||||||
|
|
||||||
CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType) :
|
|
||||||
m_addressStr(address),
|
|
||||||
m_address(),
|
|
||||||
m_port(port),
|
|
||||||
m_id(NULL),
|
|
||||||
m_password(password),
|
|
||||||
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_status(WAITING_CONNECT),
|
|
||||||
m_retryTimer(1000U, 10U),
|
|
||||||
m_timeoutTimer(1000U, 60U),
|
|
||||||
m_buffer(NULL),
|
|
||||||
m_salt(NULL),
|
|
||||||
m_streamId(NULL),
|
|
||||||
m_rxData(1000U, "DMR Network"),
|
|
||||||
m_options(),
|
|
||||||
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_address = CUDPSocket::lookup(address);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
CStopWatch stopWatch;
|
|
||||||
::srand(stopWatch.start());
|
|
||||||
|
|
||||||
m_streamId[0U] = ::rand() + 1U;
|
|
||||||
m_streamId[1U] = ::rand() + 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
CDMRNetwork::~CDMRNetwork()
|
|
||||||
{
|
|
||||||
delete[] m_buffer;
|
|
||||||
delete[] m_salt;
|
|
||||||
delete[] m_streamId;
|
|
||||||
delete[] m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::setOptions(const std::string& options)
|
|
||||||
{
|
|
||||||
m_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::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 CDMRNetwork::open()
|
|
||||||
{
|
|
||||||
LogMessage("DMR, Opening DMR Network");
|
|
||||||
|
|
||||||
if (m_address.s_addr == INADDR_NONE)
|
|
||||||
m_address = CUDPSocket::lookup(m_addressStr);
|
|
||||||
|
|
||||||
m_status = WAITING_CONNECT;
|
|
||||||
m_timeoutTimer.stop();
|
|
||||||
m_retryTimer.start();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::enable(bool enabled)
|
|
||||||
{
|
|
||||||
if (!enabled && m_enabled)
|
|
||||||
m_rxData.clear();
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::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 CDMRNetwork::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;
|
|
||||||
|
|
||||||
unsigned int count = 1U;
|
|
||||||
|
|
||||||
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] = ::rand() + 1U;
|
|
||||||
count = 2U;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataType == DT_CSBK || dataType == DT_DATA_HEADER) {
|
|
||||||
m_streamId[slotIndex] = ::rand() + 1U;
|
|
||||||
count = 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "Network Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < count; i++)
|
|
||||||
write(buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeRadioPosition(unsigned int id, const unsigned char* data)
|
|
||||||
{
|
|
||||||
if (m_status != RUNNING)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned char buffer[20U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "DMRG", 4U);
|
|
||||||
|
|
||||||
::memcpy(buffer + 4U, m_id, 4U);
|
|
||||||
|
|
||||||
buffer[8U] = id >> 16;
|
|
||||||
buffer[9U] = id >> 8;
|
|
||||||
buffer[10U] = id >> 0;
|
|
||||||
|
|
||||||
::memcpy(buffer + 11U, data + 2U, 7U);
|
|
||||||
|
|
||||||
return write(buffer, 18U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::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);
|
|
||||||
|
|
||||||
::memcpy(buffer + 4U, m_id, 4U);
|
|
||||||
|
|
||||||
buffer[8U] = id >> 16;
|
|
||||||
buffer[9U] = id >> 8;
|
|
||||||
buffer[10U] = id >> 0;
|
|
||||||
|
|
||||||
buffer[11U] = type;
|
|
||||||
|
|
||||||
::memcpy(buffer + 12U, data + 2U, 7U);
|
|
||||||
|
|
||||||
return write(buffer, 19U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeHomePosition(float latitude, float longitude)
|
|
||||||
{
|
|
||||||
m_latitude = latitude;
|
|
||||||
m_longitude = longitude;
|
|
||||||
|
|
||||||
if (m_status != RUNNING)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char buffer[50U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "RPTG", 4U);
|
|
||||||
::memcpy(buffer + 4U, m_id, 4U);
|
|
||||||
|
|
||||||
::sprintf(buffer + 8U, "%08f%09f", latitude, longitude);
|
|
||||||
|
|
||||||
return write((unsigned char*)buffer, 25U);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDMRNetwork::close()
|
|
||||||
{
|
|
||||||
LogMessage("DMR, Closing DMR Network");
|
|
||||||
|
|
||||||
if (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 CDMRNetwork::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
if (m_status == WAITING_CONNECT) {
|
|
||||||
m_retryTimer.clock(ms);
|
|
||||||
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
|
||||||
bool ret = m_socket.open();
|
|
||||||
if (ret) {
|
|
||||||
ret = writeLogin();
|
|
||||||
if (!ret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_status = WAITING_LOGIN;
|
|
||||||
m_timeoutTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_retryTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_addr address;
|
|
||||||
unsigned int port;
|
|
||||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
|
|
||||||
if (length < 0) {
|
|
||||||
LogError("DMR, Socket has failed, retrying connection to the master");
|
|
||||||
close();
|
|
||||||
open();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (m_debug && length > 0)
|
|
||||||
// CUtils::dump(1U, "Network Received", m_buffer, length);
|
|
||||||
|
|
||||||
if (length > 0 && m_address.s_addr == address.s_addr && m_port == port) {
|
|
||||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
|
||||||
if (m_enabled) {
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
|
||||||
|
|
||||||
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();
|
|
||||||
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();
|
|
||||||
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("Unknown packet from the master", m_buffer, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_retryTimer.clock(ms);
|
|
||||||
if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) {
|
|
||||||
switch (m_status) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_timeoutTimer.clock(ms);
|
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
|
|
||||||
LogError("DMR, Connection to the master has timed out, retrying connection");
|
|
||||||
close();
|
|
||||||
open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::writeLogin()
|
|
||||||
{
|
|
||||||
unsigned char buffer[8U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "RPTL", 4U);
|
|
||||||
::memcpy(buffer + 4U, m_id, 4U);
|
|
||||||
|
|
||||||
return write(buffer, 8U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDMRNetwork::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 CDMRNetwork::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 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_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 CDMRNetwork::writePing()
|
|
||||||
{
|
|
||||||
unsigned char buffer[11U];
|
|
||||||
|
|
||||||
::memcpy(buffer + 0U, "RPTPING", 7U);
|
|
||||||
::memcpy(buffer + 7U, m_id, 4U);
|
|
||||||
|
|
||||||
return write(buffer, 11U);
|
|
||||||
}
|
|
||||||
|
|
||||||
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_address, m_port);
|
|
||||||
if (!ret) {
|
|
||||||
LogError("DMR, Socket has failed when writing data to the master, retrying connection");
|
|
||||||
m_socket.close();
|
|
||||||
open();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
91
DMRNetwork.h
91
DMRNetwork.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
|
||||||
|
@ -19,101 +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>
|
|
||||||
|
|
||||||
class CDMRNetwork
|
class IDMRNetwork
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType);
|
virtual ~IDMRNetwork() = 0;
|
||||||
~CDMRNetwork();
|
|
||||||
|
|
||||||
void setOptions(const std::string& options);
|
virtual void setOptions(const std::string& options) = 0;
|
||||||
|
|
||||||
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 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;
|
||||||
|
|
||||||
bool open();
|
virtual bool open() = 0;
|
||||||
|
|
||||||
void enable(bool enabled);
|
virtual void enable(bool enabled) = 0;
|
||||||
|
|
||||||
bool read(CDMRData& data);
|
virtual bool read(CDMRData& data) = 0;
|
||||||
|
|
||||||
bool write(const CDMRData& data);
|
virtual bool write(const CDMRData& data) = 0;
|
||||||
|
|
||||||
bool writeRadioPosition(unsigned int id, const unsigned char* data);
|
virtual bool writeRadioPosition(unsigned int id, const unsigned char* data) = 0;
|
||||||
|
|
||||||
bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data);
|
virtual bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data) = 0;
|
||||||
|
|
||||||
bool writeHomePosition(float latitude, float longitude);
|
virtual bool wantsBeacon() = 0;
|
||||||
|
|
||||||
bool wantsBeacon();
|
virtual void clock(unsigned int ms) = 0;
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
virtual bool isConnected() const = 0;
|
||||||
|
|
||||||
void close();
|
virtual void close(bool sayGoodbye) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_addressStr;
|
|
||||||
in_addr m_address;
|
|
||||||
unsigned int m_port;
|
|
||||||
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;
|
|
||||||
unsigned char* m_salt;
|
|
||||||
uint32_t* m_streamId;
|
|
||||||
|
|
||||||
CRingBuffer<unsigned char> m_rxData;
|
|
||||||
|
|
||||||
std::string m_options;
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
124
DMRSlot.cpp
124
DMRSlot.cpp
|
@ -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
|
||||||
|
@ -38,11 +38,12 @@ 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;
|
||||||
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
||||||
|
DMR_OVCM_TYPES CDMRSlot::m_ovcm = DMR_OVCM_OFF;
|
||||||
|
|
||||||
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
||||||
|
|
||||||
|
@ -141,10 +142,14 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
||||||
|
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
||||||
|
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
||||||
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("DMR Slot %u, RF voice transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
LogMessage("DMR Slot %u, RF voice transmission lost, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, RF voice transmission lost from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
if (m_rfTimeout) {
|
if (m_rfTimeout) {
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
|
@ -155,7 +160,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_DATA) {
|
if (data[0U] == TAG_LOST && m_rfState == RS_RF_DATA) {
|
||||||
LogMessage("DMR Slot %u, RF data transmission lost", m_slotNo);
|
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
||||||
|
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
||||||
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
|
LogMessage("DMR Slot %u, RF data transmission lost from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -215,15 +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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -327,7 +343,6 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
data[0U] = TAG_EOT;
|
data[0U] = TAG_EOT;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeNetworkRF(data, DT_TERMINATOR_WITH_LC);
|
|
||||||
writeNetworkRF(data, DT_TERMINATOR_WITH_LC);
|
writeNetworkRF(data, DT_TERMINATOR_WITH_LC);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
|
@ -336,10 +351,14 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string src = m_lookup->find(m_rfLC->getSrcId());
|
||||||
|
std::string dst = m_lookup->find(m_rfLC->getDstId());
|
||||||
|
FLCO flco = m_rfLC->getFLCO();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||||
else
|
else
|
||||||
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, received RF end of voice transmission from %s to %s%s, %.1f seconds, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||||
|
|
||||||
|
@ -365,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +429,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
LogMessage("DMR Slot %u, received RF data header from %s to %s%s, %u blocks", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str(), m_rfFrames);
|
LogMessage("DMR Slot %u, received RF data header from %s to %s%s, %u blocks", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str(), m_rfFrames);
|
||||||
|
|
||||||
if (m_rfFrames == 0U) {
|
if (m_rfFrames == 0U) {
|
||||||
LogMessage("DMR Slot %u, ended RF data transmission", m_slotNo);
|
LogMessage("DMR Slot %u, ended RF data transmission from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,6 +444,12 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
if (csbko == CSBKO_BSDWNACT)
|
if (csbko == CSBKO_BSDWNACT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// set the OVCM bit for the supported csbk
|
||||||
|
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();
|
||||||
unsigned int dstId = csbk.getDstId();
|
unsigned int dstId = csbk.getDstId();
|
||||||
|
@ -430,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,6 +501,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
case CSBKO_PRECCSBK:
|
case CSBKO_PRECCSBK:
|
||||||
LogMessage("DMR Slot %u, received RF %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG ": "", dst.c_str());
|
LogMessage("DMR Slot %u, received RF %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG ": "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
|
case CSBKO_CALL_ALERT:
|
||||||
|
LogMessage("DMR Slot %u, received RF Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
|
break;
|
||||||
|
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());
|
||||||
|
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;
|
||||||
|
@ -634,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) {
|
||||||
|
@ -653,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) {
|
||||||
|
@ -672,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) {
|
||||||
|
@ -691,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) {
|
||||||
|
@ -763,15 +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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -1027,6 +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);
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -1084,7 +1134,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
std::string cn = m_lookup->findWithName(srcId);
|
class CUserDBentry cn;
|
||||||
|
m_lookup->findWithName(srcId, &cn);
|
||||||
m_display->writeDMR(m_slotNo, cn, flco == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, flco == FLCO_GROUP, dst, "N");
|
||||||
|
|
||||||
#if defined(DUMP_DMR)
|
#if defined(DUMP_DMR)
|
||||||
|
@ -1100,6 +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();
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -1150,11 +1206,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RS_NET_AUDIO;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
class CUserDBentry cn;
|
||||||
|
m_lookup->findWithName(srcId, &cn);
|
||||||
|
|
||||||
m_display->writeDMR(m_slotNo, src, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1216,9 +1273,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
writeFile(data);
|
writeFile(data);
|
||||||
closeFile();
|
closeFile();
|
||||||
#endif
|
#endif
|
||||||
|
std::string src = m_lookup->find(m_netLC->getSrcId());
|
||||||
|
std::string dst = m_lookup->find(m_netLC->getDstId());
|
||||||
|
FLCO flco = m_netLC->getFLCO();
|
||||||
|
|
||||||
// We've received the voice header and terminator haven't we?
|
// We've received the voice header and terminator haven't we?
|
||||||
m_netFrames += 2U;
|
m_netFrames += 2U;
|
||||||
LogMessage("DMR Slot %u, received network end of voice transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
LogMessage("DMR Slot %u, received network end of voice transmission from %s to %s%s, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str(), float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
m_display->writeDMRTA(m_slotNo, NULL, " ");
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
} else if (dataType == DT_DATA_HEADER) {
|
} else if (dataType == DT_DATA_HEADER) {
|
||||||
|
@ -1271,7 +1332,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
LogMessage("DMR Slot %u, received network data header from %s to %s%s, %u blocks", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str(), m_netFrames);
|
LogMessage("DMR Slot %u, received network data header from %s to %s%s, %u blocks", m_slotNo, src.c_str(), gi ? "TG ": "", dst.c_str(), m_netFrames);
|
||||||
|
|
||||||
if (m_netFrames == 0U) {
|
if (m_netFrames == 0U) {
|
||||||
LogMessage("DMR Slot %u, ended network data transmission", m_slotNo);
|
LogMessage("DMR Slot %u, ended network data transmission from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
}
|
}
|
||||||
} else if (dataType == DT_VOICE_SYNC) {
|
} else if (dataType == DT_VOICE_SYNC) {
|
||||||
|
@ -1281,6 +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();
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -1343,8 +1409,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
class CUserDBentry cn;
|
||||||
|
m_lookup->findWithName(srcId, &cn);
|
||||||
|
|
||||||
m_display->writeDMR(m_slotNo, src, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
||||||
|
|
||||||
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network late entry from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1549,6 +1617,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
if (csbko == CSBKO_BSDWNACT)
|
if (csbko == CSBKO_BSDWNACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// set the OVCM bit for the supported csbk
|
||||||
|
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();
|
||||||
unsigned int dstId = csbk.getDstId();
|
unsigned int dstId = csbk.getDstId();
|
||||||
|
@ -1613,6 +1687,15 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
case CSBKO_PRECCSBK:
|
case CSBKO_PRECCSBK:
|
||||||
LogMessage("DMR Slot %u, received network %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network %s Preamble CSBK (%u to follow) from %s to %s%s", m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
break;
|
break;
|
||||||
|
case CSBKO_CALL_ALERT:
|
||||||
|
LogMessage("DMR Slot %u, received network Call Alert CSBK from %s to %s%s", m_slotNo, src.c_str(), gi ? "TG " : "", dst.c_str());
|
||||||
|
break;
|
||||||
|
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());
|
||||||
|
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;
|
||||||
|
@ -1853,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)
|
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);
|
||||||
|
@ -1869,6 +1952,7 @@ void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData
|
||||||
m_duplex = duplex;
|
m_duplex = duplex;
|
||||||
m_lookup = lookup;
|
m_lookup = lookup;
|
||||||
m_hangCount = callHang * 17U;
|
m_hangCount = callHang * 17U;
|
||||||
|
m_ovcm = ovcm;
|
||||||
|
|
||||||
m_rssiMapper = rssiMapper;
|
m_rssiMapper = rssiMapper;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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,11 +118,12 @@ 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;
|
||||||
static unsigned int m_hangCount;
|
static unsigned int m_hangCount;
|
||||||
|
static DMR_OVCM_TYPES m_ovcm;
|
||||||
|
|
||||||
static CRSSIInterpolator* m_rssiMapper;
|
static CRSSIInterpolator* m_rssiMapper;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ bool CDMRTA::decodeTA()
|
||||||
|
|
||||||
unsigned int TAformat = (talkerAlias[0] >> 6U) & 0x03U;
|
unsigned int TAformat = (talkerAlias[0] >> 6U) & 0x03U;
|
||||||
unsigned int TAsize = (talkerAlias[0] >> 1U) & 0x1FU;
|
unsigned int TAsize = (talkerAlias[0] >> 1U) & 0x1FU;
|
||||||
::strncpy(m_TA, "(could not decode)", sizeof(m_TA));
|
::strcpy(m_TA, "(could not decode)");
|
||||||
|
|
||||||
switch (TAformat) {
|
switch (TAformat) {
|
||||||
case 0U: // 7 bit
|
case 0U: // 7 bit
|
||||||
|
@ -96,7 +96,7 @@ bool CDMRTA::decodeTA()
|
||||||
|
|
||||||
case 1U: // ISO 8 bit
|
case 1U: // ISO 8 bit
|
||||||
case 2U: // UTF8
|
case 2U: // UTF8
|
||||||
::strncpy(m_TA, (char*)talkerAlias + 1U, sizeof(m_TA));
|
::memcpy(m_TA, talkerAlias + 1U, sizeof(m_TA));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3U: // UTF16 poor man's conversion
|
case 3U: // UTF16 poor man's conversion
|
||||||
|
@ -117,9 +117,9 @@ bool CDMRTA::decodeTA()
|
||||||
|
|
||||||
if (TAlen > TAsize) {
|
if (TAlen > TAsize) {
|
||||||
if (TAlen < 29U)
|
if (TAlen < 29U)
|
||||||
strcat(m_TA," ?");
|
strcat(m_TA, " ?");
|
||||||
else
|
else
|
||||||
strcpy(m_TA + 28U," ?");
|
strcpy(m_TA + 28U, " ?");
|
||||||
}
|
}
|
||||||
|
|
||||||
return TAlen >= TAsize;
|
return TAlen >= TAsize;
|
||||||
|
|
|
@ -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
|
|
1245
DStarControl.cpp
1245
DStarControl.cpp
File diff suppressed because it is too large
Load diff
128
DStarControl.h
128
DStarControl.h
|
@ -1,128 +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, 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;
|
|
||||||
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
|
|
336
DStarNetwork.cpp
336
DStarNetwork.cpp
|
@ -1,336 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,2016,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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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_address(),
|
|
||||||
m_port(gatewayPort),
|
|
||||||
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_address = CUDPSocket::lookup(gatewayAddress);
|
|
||||||
|
|
||||||
m_linkReflector = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH];
|
|
||||||
|
|
||||||
CStopWatch stopWatch;
|
|
||||||
::srand(stopWatch.start());
|
|
||||||
}
|
|
||||||
|
|
||||||
CDStarNetwork::~CDStarNetwork()
|
|
||||||
{
|
|
||||||
delete[] m_linkReflector;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDStarNetwork::open()
|
|
||||||
{
|
|
||||||
LogMessage("Opening D-Star network connection");
|
|
||||||
|
|
||||||
if (m_address.s_addr == INADDR_NONE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_pollTimer.start();
|
|
||||||
|
|
||||||
return m_socket.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
m_outId = (::rand() % 65535U) + 1U;
|
|
||||||
|
|
||||||
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_address, m_port);
|
|
||||||
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_address, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
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_address, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
in_addr address;
|
|
||||||
unsigned int port;
|
|
||||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, port);
|
|
||||||
if (length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if the data is for us
|
|
||||||
if (m_address.s_addr != address.s_addr || m_port != port) {
|
|
||||||
LogMessage("D-Star packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, m_port, port);
|
|
||||||
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,71 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,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 DStarNetwork_H
|
|
||||||
#define DStarNetwork_H
|
|
||||||
|
|
||||||
#include "DStarDefines.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
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;
|
|
||||||
in_addr m_address;
|
|
||||||
unsigned int m_port;
|
|
||||||
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;
|
|
||||||
|
|
||||||
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
|
|
29
Defines.h
29
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,12 +20,8 @@
|
||||||
#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_CW = 98U;
|
const unsigned char MODE_CW = 98U;
|
||||||
const unsigned char MODE_LOCKOUT = 99U;
|
const unsigned char MODE_LOCKOUT = 99U;
|
||||||
const unsigned char MODE_ERROR = 100U;
|
const unsigned char MODE_ERROR = 100U;
|
||||||
|
@ -36,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,
|
||||||
|
@ -44,7 +42,10 @@ enum HW_TYPE {
|
||||||
HWT_MMDVM_HS_DUAL_HAT,
|
HWT_MMDVM_HS_DUAL_HAT,
|
||||||
HWT_NANO_HOTSPOT,
|
HWT_NANO_HOTSPOT,
|
||||||
HWT_NANO_DV,
|
HWT_NANO_DV,
|
||||||
|
HWT_D2RG_MMDVM_HS,
|
||||||
HWT_MMDVM_HS,
|
HWT_MMDVM_HS,
|
||||||
|
HWT_OPENGD77_HS,
|
||||||
|
HWT_SKYBRIDGE,
|
||||||
HWT_UNKNOWN
|
HWT_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,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
|
||||||
|
@ -60,7 +62,22 @@ 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DMR_BEACONS {
|
||||||
|
DMR_BEACONS_OFF,
|
||||||
|
DMR_BEACONS_NETWORK,
|
||||||
|
DMR_BEACONS_TIMED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DMR_OVCM_TYPES {
|
||||||
|
DMR_OVCM_OFF,
|
||||||
|
DMR_OVCM_RX_ON,
|
||||||
|
DMR_OVCM_TX_ON,
|
||||||
|
DMR_OVCM_ON,
|
||||||
|
DMR_OVCM_FORCE_OFF
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
295
Display.cpp
295
Display.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 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,15 +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 "LCDproc.h"
|
#include "LCDproc.h"
|
||||||
#include "Nextion.h"
|
#include "Nextion.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)
|
||||||
|
@ -99,42 +99,6 @@ void CDisplay::setQuit()
|
||||||
setQuitInt();
|
setQuitInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -149,6 +113,29 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group,
|
||||||
writeDMRInt(slotNo, src, group, dst, type);
|
writeDMRInt(slotNo, src, group, dst, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDisplay::writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
||||||
|
{
|
||||||
|
assert(type != NULL);
|
||||||
|
|
||||||
|
if (slotNo == 1U) {
|
||||||
|
m_timer1.start();
|
||||||
|
m_mode1 = MODE_IDLE;
|
||||||
|
} else {
|
||||||
|
m_timer2.start();
|
||||||
|
m_mode2 = MODE_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int err = writeDMRIntEx(slotNo, src, group, dst, type)) {
|
||||||
|
std::string src_str = src.get(keyCALLSIGN);
|
||||||
|
if (err < 0 && !src.get(keyFIRST_NAME).empty()) {
|
||||||
|
// emulate the result of old CDMRLookup::findWithName()
|
||||||
|
// (it returned callsign and firstname)
|
||||||
|
src_str += " " + src.get(keyFIRST_NAME);
|
||||||
|
}
|
||||||
|
writeDMRInt(slotNo, src_str, group, dst, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi)
|
void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi)
|
||||||
{
|
{
|
||||||
if (rssi != 0U)
|
if (rssi != 0U)
|
||||||
|
@ -165,6 +152,7 @@ void CDisplay::writeDMRBER(unsigned int slotNo, float ber)
|
||||||
{
|
{
|
||||||
writeDMRBERInt(slotNo, ber);
|
writeDMRBERInt(slotNo, ber);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::clearDMR(unsigned int slotNo)
|
void CDisplay::clearDMR(unsigned int slotNo)
|
||||||
{
|
{
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
|
@ -186,126 +174,6 @@ void CDisplay::clearDMR(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeFusion(const char* source, const char* dest, 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, 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::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();
|
||||||
|
@ -319,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;
|
||||||
|
@ -376,12 +219,18 @@ void CDisplay::clockInt(unsigned int ms)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeDStarRSSIInt(unsigned char rssi)
|
int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDisplay::writeDStarBERInt(float ber)
|
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* return value:
|
||||||
|
* < 0 error condition (i.e. not supported)
|
||||||
|
* -> call writeXXXXInt() to display
|
||||||
|
* = 0 no error, writeXXXXIntEx() displayed whole status
|
||||||
|
* = 1 no error, writeXXXXIntEx() displayed partial status
|
||||||
|
* -> call writeXXXXInt() to display remain part
|
||||||
|
* > 1 reserved for future use
|
||||||
|
*/
|
||||||
|
return -1; // not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
||||||
|
@ -396,42 +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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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") {
|
if (type == "TFT Surenoo") {
|
||||||
std::string port = conf.getTFTSerialPort();
|
std::string port = conf.getTFTSerialPort();
|
||||||
unsigned int brightness = conf.getTFTSerialBrightness();
|
unsigned int brightness = conf.getTFTSerialBrightness();
|
||||||
|
|
||||||
|
@ -440,11 +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, SERIAL_9600);
|
serial = new CUARTController(port, 115200U);
|
||||||
|
|
||||||
display = new CTFTSerial(conf.getCallsign(), dmrid, serial, brightness);
|
display = new CTFTSurenoo(conf.getCallsign(), dmrid, serial, brightness, conf.getDuplex());
|
||||||
} 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();
|
||||||
|
@ -483,23 +309,16 @@ 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, conf.getLocation());
|
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, conf.getLocation());
|
|
||||||
} else {
|
|
||||||
LogInfo(" NullDisplay loaded");
|
|
||||||
display = new CNullDisplay;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SERIAL_SPEED baudrate = SERIAL_9600;
|
unsigned int baudrate = 9600U;
|
||||||
if (screenLayout==4U)
|
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, conf.getLocation());
|
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
||||||
}
|
}
|
||||||
} else if (type == "LCDproc") {
|
} else if (type == "LCDproc") {
|
||||||
std::string address = conf.getLCDprocAddress();
|
std::string address = conf.getLCDprocAddress();
|
||||||
|
@ -568,10 +387,12 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
||||||
bool invert = conf.getOLEDInvert();
|
bool invert = conf.getOLEDInvert();
|
||||||
bool scroll = conf.getOLEDScroll();
|
bool scroll = conf.getOLEDScroll();
|
||||||
bool rotate = conf.getOLEDRotate();
|
bool rotate = conf.getOLEDRotate();
|
||||||
bool cast = conf.getOLEDCast();
|
bool logosaver = conf.getOLEDLogoScreensaver();
|
||||||
|
|
||||||
display = new COLED(type, brightness, invert, scroll, rotate, conf.getDMRNetworkSlot1(), conf.getDMRNetworkSlot2(), cast ? modem : NULL);
|
display = new COLED(type, brightness, invert, scroll, rotate, logosaver, conf.getDuplex());
|
||||||
#endif
|
#endif
|
||||||
|
} else if (type == "CAST") {
|
||||||
|
display = new CCASTInfo(modem);
|
||||||
} else {
|
} else {
|
||||||
LogWarning("No valid display found, disabling");
|
LogWarning("No valid display found, disabling");
|
||||||
display = new CNullDisplay;
|
display = new CNullDisplay;
|
||||||
|
|
56
Display.h
56
Display.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 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
|
||||||
|
@ -20,6 +20,8 @@
|
||||||
#define DISPLAY_H
|
#define DISPLAY_H
|
||||||
|
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "UserDBentry.h"
|
||||||
|
#include "Modem.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -27,7 +29,6 @@
|
||||||
|
|
||||||
class CConf;
|
class CConf;
|
||||||
class CModem;
|
class CModem;
|
||||||
class CUMP;
|
|
||||||
|
|
||||||
class CDisplay
|
class CDisplay
|
||||||
{
|
{
|
||||||
|
@ -41,43 +42,22 @@ public:
|
||||||
void setLockout();
|
void setLockout();
|
||||||
void setError(const char* text);
|
void setError(const char* text);
|
||||||
void setQuit();
|
void setQuit();
|
||||||
|
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 writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
|
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
|
||||||
void writeDMRBER(unsigned int slotNo, float ber);
|
void writeDMRBER(unsigned int slotNo, float ber);
|
||||||
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, 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 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;
|
||||||
|
@ -85,35 +65,13 @@ protected:
|
||||||
virtual void setErrorInt(const char* text) = 0;
|
virtual void setErrorInt(const char* text) = 0;
|
||||||
virtual void setQuitInt() = 0;
|
virtual void setQuitInt() = 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 void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||||
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||||
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, 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 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
|
||||||
|
|
374
HD44780.cpp
374
HD44780.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 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
|
||||||
|
@ -399,6 +400,37 @@ void CHD44780::setQuitInt()
|
||||||
m_dmr = false;
|
m_dmr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHD44780::setFMInt()
|
||||||
|
{
|
||||||
|
m_clockDisplayTimer.stop();
|
||||||
|
::lcdClear(m_fd);
|
||||||
|
|
||||||
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
|
adafruitLCDColour(AC_WHITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_pwm) {
|
||||||
|
if (m_pwmPin != 1U)
|
||||||
|
::softPwmWrite(m_pwmPin, m_pwmDim);
|
||||||
|
else
|
||||||
|
::pwmWrite(m_pwmPin, (m_pwmDim / 100) * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print callsign and ID at on top row for all screen sizes
|
||||||
|
::lcdPosition(m_fd, 0, 0);
|
||||||
|
::lcdPrintf(m_fd, "%-6s", m_callsign.c_str());
|
||||||
|
::lcdPosition(m_fd, m_cols - 7, 0);
|
||||||
|
::lcdPrintf(m_fd, "%7u", m_dmrid);
|
||||||
|
|
||||||
|
// Print MMDVM and Idle on bottom row for all screen sizes
|
||||||
|
::lcdPosition(m_fd, 0, m_rows - 1);
|
||||||
|
::lcdPuts(m_fd, "MMDVM");
|
||||||
|
::lcdPosition(m_fd, m_cols - 4, m_rows - 1);
|
||||||
|
::lcdPuts(m_fd, "FM"); // Gets overwritten by clock on 2 line screen
|
||||||
|
|
||||||
|
m_dmr = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
||||||
{
|
{
|
||||||
assert(my1 != NULL);
|
assert(my1 != NULL);
|
||||||
|
@ -408,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
|
||||||
|
@ -432,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);
|
||||||
|
|
||||||
|
@ -462,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()
|
||||||
|
@ -568,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);
|
||||||
|
@ -591,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) {
|
||||||
|
@ -616,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);
|
||||||
|
@ -628,38 +655,38 @@ 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)
|
||||||
{
|
{
|
||||||
if (m_rows > 2) {
|
if (m_rows > 2) {
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
if (m_rssiCount1 == 0U) {
|
if (m_rssiCount1 == 0U) {
|
||||||
::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 >= DMR_RSSI_COUNT)
|
if (m_rssiCount1 >= DMR_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
} else {
|
} else {
|
||||||
if (m_rssiCount2 == 0U) {
|
if (m_rssiCount2 == 0U) {
|
||||||
::lcdPosition(m_fd, (m_cols / 2), 3);
|
::lcdPosition(m_fd, (m_cols / 2), 3);
|
||||||
::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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,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);
|
||||||
|
@ -706,7 +732,7 @@ void CHD44780::clearDMRInt(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin)
|
void CHD44780::writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin)
|
||||||
{
|
{
|
||||||
assert(source != NULL);
|
assert(source != NULL);
|
||||||
assert(dest != NULL);
|
assert(dest != NULL);
|
||||||
|
@ -714,7 +740,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char*
|
||||||
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
|
||||||
|
@ -731,50 +757,46 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char*
|
||||||
::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);
|
||||||
|
|
||||||
::sprintf(m_buffer1, "%.10s", dest);
|
::sprintf(m_buffer1, "DG-ID %u", dgid);
|
||||||
::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);
|
||||||
|
|
||||||
::sprintf(m_buffer1, "%.10s", dest);
|
::sprintf(m_buffer1, "DG-ID %u", dgid);
|
||||||
::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 > %.10s", source, 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::writeFusionRSSIInt(unsigned char rssi)
|
void CHD44780::writeFusionRSSIInt(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 >= YSF_RSSI_COUNT)
|
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHD44780::clearFusionInt()
|
void CHD44780::clearFusionInt()
|
||||||
|
@ -782,7 +804,6 @@ void CHD44780::clearFusionInt()
|
||||||
#ifdef ADAFRUIT_DISPLAY
|
#ifdef ADAFRUIT_DISPLAY
|
||||||
adafruitLCDColour(AC_PURPLE);
|
adafruitLCDColour(AC_PURPLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
if (m_rows == 2U && m_cols == 16U) {
|
if (m_rows == 2U && m_cols == 16U) {
|
||||||
|
@ -818,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
|
||||||
|
@ -835,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);
|
||||||
|
@ -849,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);
|
||||||
|
@ -858,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);
|
||||||
|
@ -866,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()
|
||||||
|
@ -922,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
|
||||||
|
@ -939,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);
|
||||||
|
@ -953,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);
|
||||||
|
@ -962,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()
|
||||||
|
@ -1020,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()
|
||||||
|
@ -1050,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
69
HD44780.h
69
HD44780.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 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,46 +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 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, 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;
|
||||||
|
@ -161,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 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(YSFConvolution_H)
|
#if !defined(IIRDIRECTFORM1FILTER_H)
|
||||||
#define YSFConvolution_H
|
#define IIRDIRECTFORM1FILTER_H
|
||||||
|
|
||||||
#include <cstdint>
|
class CIIRDirectForm1Filter
|
||||||
|
{
|
||||||
class CYSFConvolution {
|
|
||||||
public:
|
public:
|
||||||
CYSFConvolution();
|
CIIRDirectForm1Filter(float b0, float b1, float b2, float, float a1, float a2, float additionalGaindB);
|
||||||
~CYSFConvolution();
|
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 |
182
LCDproc.cpp
182
LCDproc.cpp
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 by Tony Corbett G0WFV
|
* Copyright (C) 2016,2017,2018 by Tony Corbett G0WFV
|
||||||
* Copyright (C) 2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2018,2020 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
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#else
|
#else
|
||||||
#include <winsock.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BUFFER_MAX_LEN 128
|
#define BUFFER_MAX_LEN 128
|
||||||
|
@ -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),
|
||||||
|
@ -121,44 +122,53 @@ CLCDproc::~CLCDproc()
|
||||||
|
|
||||||
bool CLCDproc::open()
|
bool CLCDproc::open()
|
||||||
{
|
{
|
||||||
const char *server;
|
int err;
|
||||||
unsigned int port, localPort;
|
unsigned int addrlen;
|
||||||
struct sockaddr_in serverAddress, clientAddress;
|
std::string port, localPort;
|
||||||
struct hostent *h;
|
struct sockaddr_storage serverAddress, clientAddress;
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
|
||||||
server = m_address.c_str();
|
port = std::to_string(m_port);
|
||||||
port = m_port;
|
localPort = std::to_string(m_localPort);
|
||||||
localPort = m_localPort;
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
|
||||||
|
/* Lookup the hostname address */
|
||||||
|
hints.ai_flags = AI_NUMERICSERV;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
err = getaddrinfo(m_address.c_str(), port.c_str(), &hints, &res);
|
||||||
|
if (err) {
|
||||||
|
LogError("LCDproc, cannot lookup server");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(&serverAddress, res->ai_addr, addrlen = res->ai_addrlen);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
|
/* Lookup the client address (random port - need to specify manual port from ini file) */
|
||||||
|
hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
|
||||||
|
hints.ai_family = serverAddress.ss_family;
|
||||||
|
err = getaddrinfo(NULL, localPort.c_str(), &hints, &res);
|
||||||
|
if (err) {
|
||||||
|
LogError("LCDproc, cannot lookup client");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(&clientAddress, res->ai_addr, res->ai_addrlen);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
/* Create TCP socket */
|
/* Create TCP socket */
|
||||||
m_socketfd = socket(AF_INET, SOCK_STREAM, 0);
|
m_socketfd = socket(clientAddress.ss_family, SOCK_STREAM, 0);
|
||||||
if (m_socketfd == -1) {
|
if (m_socketfd == -1) {
|
||||||
LogError("LCDproc, failed to create socket");
|
LogError("LCDproc, failed to create socket");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets client address (random port - need to specify manual port from ini file?) */
|
|
||||||
clientAddress.sin_family = AF_INET;
|
|
||||||
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
//clientAddress.sin_port = htons(0);
|
|
||||||
clientAddress.sin_port = htons(localPort);
|
|
||||||
|
|
||||||
/* Bind the address to the socket */
|
/* Bind the address to the socket */
|
||||||
if (bind(m_socketfd, (struct sockaddr *)&clientAddress, sizeof(clientAddress)) == -1) {
|
if (bind(m_socketfd, (struct sockaddr *)&clientAddress, addrlen) == -1) {
|
||||||
LogError("LCDproc, error whilst binding address");
|
LogError("LCDproc, error whilst binding address");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup the hostname address */
|
/* Connect to server */
|
||||||
h = gethostbyname(server);
|
if (connect(m_socketfd, (struct sockaddr *)&serverAddress, addrlen) == -1) {
|
||||||
|
|
||||||
/* Sets server address */
|
|
||||||
serverAddress.sin_family = h->h_addrtype;
|
|
||||||
memcpy((char*)&serverAddress.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
|
|
||||||
serverAddress.sin_port = htons(port);
|
|
||||||
|
|
||||||
if (connect(m_socketfd, (struct sockaddr * )&serverAddress, sizeof(serverAddress))==-1) {
|
|
||||||
LogError("LCDproc, cannot connect to server");
|
LogError("LCDproc, cannot connect to server");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -179,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
|
||||||
}
|
}
|
||||||
|
@ -198,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
|
||||||
}
|
}
|
||||||
|
@ -215,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
|
||||||
}
|
}
|
||||||
|
@ -234,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
|
||||||
}
|
}
|
||||||
|
@ -241,6 +255,24 @@ void CLCDproc::setQuitInt()
|
||||||
m_dmr = false;
|
m_dmr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CLCDproc::setFMInt()
|
||||||
|
{
|
||||||
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
|
if (m_screensDefined) {
|
||||||
|
socketPrintf(m_socketfd, "screen_set DStar -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set DMR -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||||
|
socketPrintf(m_socketfd, "screen_set P25 -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, "output 0"); // Clear all LEDs
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dmr = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CLCDproc::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
void CLCDproc::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
||||||
{
|
{
|
||||||
assert(my1 != NULL);
|
assert(my1 != NULL);
|
||||||
|
@ -294,7 +326,7 @@ void CLCDproc::clearDStarInt()
|
||||||
{
|
{
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line4 1 4 15 4 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set DStar Line4 1 4 15 4 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "output 8"); // Set LED4 color green
|
socketPrintf(m_socketfd, "output 8"); // Set LED4 color green
|
||||||
|
@ -387,7 +419,7 @@ void CLCDproc::clearDMRInt(unsigned int slotNo)
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot2RSSI %u %u %*.s", (m_cols / 2) + 1, 4, m_cols / 2, " ");
|
socketPrintf(m_socketfd, "widget_set DMR Slot2RSSI %u %u %*.s", (m_cols / 2) + 1, 4, m_cols / 2, " ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot1 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set DMR Slot1 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot2 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set DMR Slot2 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot2RSSI %u %u %*.s", (m_cols / 2) + 1, 4, m_cols / 2, " ");
|
socketPrintf(m_socketfd, "widget_set DMR Slot2RSSI %u %u %*.s", (m_cols / 2) + 1, 4, m_cols / 2, " ");
|
||||||
}
|
}
|
||||||
|
@ -396,7 +428,7 @@ void CLCDproc::clearDMRInt(unsigned int slotNo)
|
||||||
|
|
||||||
// LED 3 Green 4 Red 64 Yellow 68
|
// LED 3 Green 4 Red 64 Yellow 68
|
||||||
|
|
||||||
void CLCDproc::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin)
|
void CLCDproc::writeFusionInt(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin)
|
||||||
{
|
{
|
||||||
assert(source != NULL);
|
assert(source != NULL);
|
||||||
assert(dest != NULL);
|
assert(dest != NULL);
|
||||||
|
@ -409,10 +441,10 @@ void CLCDproc::writeFusionInt(const char* source, const char* dest, const char*
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Mode 1 1 \"System Fusion\"");
|
socketPrintf(m_socketfd, "widget_set YSF Mode 1 1 \"System Fusion\"");
|
||||||
|
|
||||||
if (m_rows == 2U) {
|
if (m_rows == 2U) {
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"%.10s > %s%u\"", source, dest);
|
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"%.10s > DG-ID %u\"", source, dgid);
|
||||||
} else {
|
} else {
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"%.10s >\"", source);
|
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"%.10s >\"", source);
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"%s%u\"", dest);
|
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"DG-ID %u\"", dgid);
|
||||||
socketPrintf(m_socketfd, "output 64"); // Set LED3 color red
|
socketPrintf(m_socketfd, "output 64"); // Set LED3 color red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,20 +454,19 @@ void CLCDproc::writeFusionInt(const char* source, const char* dest, const char*
|
||||||
|
|
||||||
void CLCDproc::writeFusionRSSIInt(unsigned char rssi)
|
void CLCDproc::writeFusionRSSIInt(unsigned char rssi)
|
||||||
{
|
{
|
||||||
if (m_rssiCount1 == 0U) {
|
if (m_rssiCount1 == 0U)
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line4 1 4 %u 4 h 3 \"-%3udBm\"", m_cols - 1, rssi);
|
socketPrintf(m_socketfd, "widget_set YSF Line4 1 4 %u 4 h 3 \"-%3udBm\"", m_cols - 1, rssi);
|
||||||
}
|
|
||||||
|
|
||||||
m_rssiCount1++;
|
m_rssiCount1++;
|
||||||
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||||
m_rssiCount1 = 0U;
|
m_rssiCount1 = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLCDproc::clearFusionInt()
|
void CLCDproc::clearFusionInt()
|
||||||
{
|
{
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line4 1 4 15 4 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set YSF Line4 1 4 15 4 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "output 4"); // Set LED3 color green
|
socketPrintf(m_socketfd, "output 4"); // Set LED3 color green
|
||||||
|
@ -480,7 +511,7 @@ void CLCDproc::clearP25Int()
|
||||||
{
|
{
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line2 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set P25 Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line3 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set P25 Line3 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line4 1 4 15 4 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set P25 Line4 1 4 15 4 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "output 2"); // Set LED2 color green
|
socketPrintf(m_socketfd, "output 2"); // Set LED2 color green
|
||||||
|
@ -525,12 +556,57 @@ void CLCDproc::clearNXDNInt()
|
||||||
{
|
{
|
||||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||||
|
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line2 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set NXDN Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line3 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set NXDN Line3 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line4 1 4 15 4 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set NXDN Line4 1 4 15 4 h 3 \"\"");
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -752,7 +828,7 @@ void CLCDproc::defineScreens()
|
||||||
socketPrintf(m_socketfd, "widget_add DStar Line4 scroller");
|
socketPrintf(m_socketfd, "widget_add DStar Line4 scroller");
|
||||||
|
|
||||||
/* Do we need to pre-populate the values??
|
/* Do we need to pre-populate the values??
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 15 2 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 15 3 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 15 3 h 3 \"\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DStar Line4 1 4 15 4 h 3 \"\"");
|
socketPrintf(m_socketfd, "widget_set DStar Line4 1 4 15 4 h 3 \"\"");
|
||||||
*/
|
*/
|
||||||
|
@ -773,8 +849,8 @@ void CLCDproc::defineScreens()
|
||||||
/* Do we need to pre-populate the values??
|
/* Do we need to pre-populate the values??
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot1_ 1 %u 1", m_rows / 2);
|
socketPrintf(m_socketfd, "widget_set DMR Slot1_ 1 %u 1", m_rows / 2);
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot2_ 1 %u 2", m_rows / 2 + 1);
|
socketPrintf(m_socketfd, "widget_set DMR Slot2_ 1 %u 2", m_rows / 2 + 1);
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot1 3 1 15 1 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set DMR Slot1 3 1 15 1 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set DMR Slot2 3 2 15 2 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set DMR Slot2 3 2 15 2 h 3 \"Listening\"");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// The YSF Screen
|
// The YSF Screen
|
||||||
|
@ -788,7 +864,7 @@ void CLCDproc::defineScreens()
|
||||||
socketPrintf(m_socketfd, "widget_add YSF Line4 scroller");
|
socketPrintf(m_socketfd, "widget_add YSF Line4 scroller");
|
||||||
|
|
||||||
/* Do we need to pre-populate the values??
|
/* Do we need to pre-populate the values??
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line2 2 1 15 1 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set YSF Line2 2 1 15 1 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line3 3 1 15 1 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set YSF Line3 3 1 15 1 h 3 \" \"");
|
||||||
socketPrintf(m_socketfd, "widget_set YSF Line4 4 2 15 2 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set YSF Line4 4 2 15 2 h 3 \" \"");
|
||||||
*/
|
*/
|
||||||
|
@ -804,7 +880,7 @@ void CLCDproc::defineScreens()
|
||||||
socketPrintf(m_socketfd, "widget_add P25 Line4 scroller");
|
socketPrintf(m_socketfd, "widget_add P25 Line4 scroller");
|
||||||
|
|
||||||
/* Do we need to pre-populate the values??
|
/* Do we need to pre-populate the values??
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line3 2 1 15 1 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set P25 Line3 2 1 15 1 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line3 3 1 15 1 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set P25 Line3 3 1 15 1 h 3 \" \"");
|
||||||
socketPrintf(m_socketfd, "widget_set P25 Line4 4 2 15 2 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set P25 Line4 4 2 15 2 h 3 \" \"");
|
||||||
*/
|
*/
|
||||||
|
@ -820,10 +896,26 @@ void CLCDproc::defineScreens()
|
||||||
socketPrintf(m_socketfd, "widget_add NXDN Line4 scroller");
|
socketPrintf(m_socketfd, "widget_add NXDN Line4 scroller");
|
||||||
|
|
||||||
/* Do we need to pre-populate the values??
|
/* Do we need to pre-populate the values??
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line3 2 1 15 1 h 3 Listening");
|
socketPrintf(m_socketfd, "widget_set NXDN Line3 2 1 15 1 h 3 \"Listening\"");
|
||||||
socketPrintf(m_socketfd, "widget_set NXDN Line3 3 1 15 1 h 3 \" \"");
|
socketPrintf(m_socketfd, "widget_set NXDN Line3 3 1 15 1 h 3 \" \"");
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
14
LCDproc.h
14
LCDproc.h
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017 by Tony Corbett G0WFV
|
* Copyright (C) 2016,2017 by Tony Corbett G0WFV
|
||||||
* Copyright (C) 2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2018,2020 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,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();
|
||||||
|
@ -40,8 +40,8 @@ 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 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();
|
||||||
|
@ -50,7 +50,7 @@ protected:
|
||||||
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, 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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
88
Log.cpp
88
Log.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020 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,6 +22,7 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -34,8 +35,10 @@
|
||||||
static unsigned int m_fileLevel = 2U;
|
static unsigned int m_fileLevel = 2U;
|
||||||
static std::string m_filePath;
|
static std::string m_filePath;
|
||||||
static std::string m_fileRoot;
|
static std::string m_fileRoot;
|
||||||
|
static bool m_fileRotate = true;
|
||||||
|
|
||||||
static FILE* m_fpLog = NULL;
|
static FILE* m_fpLog = NULL;
|
||||||
|
static bool m_daemon = false;
|
||||||
|
|
||||||
static unsigned int m_displayLevel = 2U;
|
static unsigned int m_displayLevel = 2U;
|
||||||
|
|
||||||
|
@ -43,8 +46,10 @@ static struct tm m_tm;
|
||||||
|
|
||||||
static char LEVELS[] = " DMIWEF";
|
static char LEVELS[] = " DMIWEF";
|
||||||
|
|
||||||
static bool LogOpen()
|
static bool logOpenRotate()
|
||||||
{
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
if (m_fileLevel == 0U)
|
if (m_fileLevel == 0U)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -61,39 +66,90 @@ static bool LogOpen()
|
||||||
::fclose(m_fpLog);
|
::fclose(m_fpLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
char filename[100U];
|
char filename[200U];
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
::sprintf(filename, "%s\\%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
::sprintf(filename, "%s\\%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
||||||
#else
|
#else
|
||||||
::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_fpLog = ::fopen(filename, "a+t");
|
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
|
||||||
|
status = true;
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
|
if (m_daemon)
|
||||||
|
dup2(fileno(m_fpLog), fileno(stderr));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
m_tm = *tm;
|
m_tm = *tm;
|
||||||
|
|
||||||
return m_fpLog != NULL;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogInitialise(const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel)
|
static bool logOpenNoRotate()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if (m_fileLevel == 0U)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m_fpLog != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char filename[200U];
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
::sprintf(filename, "%s\\%s.log", m_filePath.c_str(), m_fileRoot.c_str());
|
||||||
|
#else
|
||||||
|
::sprintf(filename, "%s/%s.log", m_filePath.c_str(), m_fileRoot.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
|
||||||
|
status = true;
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
|
if (m_daemon)
|
||||||
|
dup2(fileno(m_fpLog), fileno(stderr));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LogOpen()
|
||||||
|
{
|
||||||
|
if (m_fileRotate)
|
||||||
|
return logOpenRotate();
|
||||||
|
else
|
||||||
|
return logOpenNoRotate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate)
|
||||||
{
|
{
|
||||||
m_filePath = filePath;
|
m_filePath = filePath;
|
||||||
m_fileRoot = fileRoot;
|
m_fileRoot = fileRoot;
|
||||||
m_fileLevel = fileLevel;
|
m_fileLevel = fileLevel;
|
||||||
m_displayLevel = displayLevel;
|
m_displayLevel = displayLevel;
|
||||||
return ::LogOpen();
|
m_daemon = daemon;
|
||||||
|
m_fileRotate = rotate;
|
||||||
|
|
||||||
|
if (m_daemon)
|
||||||
|
m_displayLevel = 0U;
|
||||||
|
|
||||||
|
return ::LogOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogFinalise()
|
void LogFinalise()
|
||||||
{
|
{
|
||||||
if (m_fpLog != NULL)
|
if (m_fpLog != NULL)
|
||||||
::fclose(m_fpLog);
|
::fclose(m_fpLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log(unsigned int level, const char* fmt, ...)
|
void Log(unsigned int level, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
assert(fmt != NULL);
|
assert(fmt != NULL);
|
||||||
|
|
||||||
char buffer[300U];
|
char buffer[501U];
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
::GetSystemTime(&st);
|
::GetSystemTime(&st);
|
||||||
|
@ -105,13 +161,13 @@ 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.%03lu ", 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 / 1000U);
|
::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;
|
||||||
va_start(vl, fmt);
|
va_start(vl, fmt);
|
||||||
|
|
||||||
::vsprintf(buffer + ::strlen(buffer), fmt, vl);
|
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
|
||||||
|
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|
||||||
|
@ -130,7 +186,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == 6U) { // Fatal
|
if (level == 6U) { // Fatal
|
||||||
::fclose(m_fpLog);
|
::fclose(m_fpLog);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
Log.h
4
Log.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2020 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,7 @@
|
||||||
|
|
||||||
extern void Log(unsigned int level, const char* fmt, ...);
|
extern void Log(unsigned int level, const char* fmt, ...);
|
||||||
|
|
||||||
extern bool LogInitialise(const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel);
|
extern bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate);
|
||||||
extern void LogFinalise();
|
extern void LogFinalise();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
155
MMDVM.ini
155
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
|
||||||
|
@ -13,12 +13,6 @@ Daemon=0
|
||||||
RXFrequency=435000000
|
RXFrequency=435000000
|
||||||
TXFrequency=435000000
|
TXFrequency=435000000
|
||||||
Power=1
|
Power=1
|
||||||
Latitude=0.0
|
|
||||||
Longitude=0.0
|
|
||||||
Height=0
|
|
||||||
Location=Nowhere
|
|
||||||
Description=Multi-Mode Repeater
|
|
||||||
URL=www.google.co.uk
|
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
# Logging levels, 0=No logging
|
# Logging levels, 0=No logging
|
||||||
|
@ -26,6 +20,7 @@ DisplayLevel=1
|
||||||
FileLevel=1
|
FileLevel=1
|
||||||
FilePath=.
|
FilePath=.
|
||||||
FileRoot=MMDVM
|
FileRoot=MMDVM
|
||||||
|
FileRotate=1
|
||||||
|
|
||||||
[CW Id]
|
[CW Id]
|
||||||
Enable=1
|
Enable=1
|
||||||
|
@ -36,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=\\.\COM3
|
|
||||||
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
|
||||||
|
@ -58,14 +60,9 @@ 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
|
|
||||||
RSSIMappingFile=RSSI.dat
|
RSSIMappingFile=RSSI.dat
|
||||||
|
UseCOSAsLockout=0
|
||||||
Trace=0
|
Trace=0
|
||||||
Debug=0
|
Debug=0
|
||||||
|
|
||||||
|
@ -76,28 +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
|
|
||||||
|
|
||||||
[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
|
||||||
|
@ -107,88 +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, 4=force off
|
||||||
[System Fusion]
|
# OVCM=0
|
||||||
Enable=1
|
|
||||||
LowDeviation=0
|
|
||||||
SelfOnly=0
|
|
||||||
TXHang=4
|
|
||||||
#DGID=1
|
|
||||||
RemoteGateway=0
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[P25]
|
|
||||||
Enable=1
|
|
||||||
NAC=293
|
|
||||||
SelfOnly=0
|
|
||||||
OverrideUIDCheck=0
|
|
||||||
RemoteGateway=0
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[NXDN]
|
|
||||||
Enable=1
|
|
||||||
RAN=1
|
|
||||||
SelfOnly=0
|
|
||||||
RemoteGateway=0
|
|
||||||
# ModeHang=10
|
|
||||||
|
|
||||||
[POCSAG]
|
|
||||||
Enable=1
|
|
||||||
Frequency=439987500
|
|
||||||
|
|
||||||
[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=44.131.4.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.
|
||||||
|
Type=Direct
|
||||||
|
LocalAddress=127.0.0.1
|
||||||
|
LocalPort=62032
|
||||||
|
RemoteAddress=127.0.0.1
|
||||||
|
RemotePort=62031
|
||||||
|
# Password=P@ssw0rd1234
|
||||||
Jitter=360
|
Jitter=360
|
||||||
# Local=62032
|
|
||||||
Password=PASSWORD
|
|
||||||
# Options=
|
|
||||||
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
|
|
||||||
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
|
||||||
|
|
||||||
|
@ -234,6 +150,7 @@ Invert=0
|
||||||
Scroll=1
|
Scroll=1
|
||||||
Rotate=0
|
Rotate=0
|
||||||
Cast=0
|
Cast=0
|
||||||
|
LogoScreensaver=1
|
||||||
|
|
||||||
[LCDproc]
|
[LCDproc]
|
||||||
Address=localhost
|
Address=localhost
|
||||||
|
@ -247,11 +164,7 @@ UTC=0
|
||||||
Enable=0
|
Enable=0
|
||||||
File=/tmp/MMDVM_Active.lck
|
File=/tmp/MMDVM_Active.lck
|
||||||
|
|
||||||
[Mobile GPS]
|
|
||||||
Enable=0
|
|
||||||
Address=127.0.0.1
|
|
||||||
Port=7834
|
|
||||||
|
|
||||||
[Remote Control]
|
[Remote Control]
|
||||||
Enable=0
|
Enable=0
|
||||||
|
Address=127.0.0.1
|
||||||
Port=7642
|
Port=7642
|
||||||
|
|
1259
MMDVMHost.cpp
1259
MMDVMHost.cpp
File diff suppressed because it is too large
Load diff
66
MMDVMHost.h
66
MMDVMHost.h
|
@ -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
|
||||||
|
@ -20,31 +20,34 @@
|
||||||
#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 "MobileGPS.h"
|
//#include "FMControl.h"
|
||||||
#include "Display.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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CMMDVMHost
|
class CMMDVMHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -53,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;
|
|
||||||
CNXDNNetwork* 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;
|
||||||
|
@ -92,16 +93,17 @@ 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_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;
|
||||||
bool m_lockFileEnabled;
|
bool m_lockFileEnabled;
|
||||||
std::string m_lockFileName;
|
std::string m_lockFileName;
|
||||||
CMobileGPS* m_mobileGPS;
|
|
||||||
CRemoteControl* m_remoteControl;
|
CRemoteControl* m_remoteControl;
|
||||||
bool m_fixedMode;
|
bool m_fixedMode;
|
||||||
|
|
||||||
|
@ -112,10 +114,14 @@ 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);
|
||||||
|
void processEnableCommand(bool& mode, bool enabled);
|
||||||
|
|
||||||
void setMode(unsigned char mode);
|
void setMode(unsigned char mode);
|
||||||
|
|
||||||
|
|
|
@ -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,336 +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.15063.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>v141</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</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>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>_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>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>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="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="MobileGPS.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="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="SHA256.h" />
|
|
||||||
<ClInclude Include="StopWatch.h" />
|
|
||||||
<ClInclude Include="Sync.h" />
|
|
||||||
<ClInclude Include="TFTSerial.h" />
|
|
||||||
<ClInclude Include="Thread.h" />
|
|
||||||
<ClInclude Include="Timer.h" />
|
|
||||||
<ClInclude Include="UDPSocket.h" />
|
|
||||||
<ClInclude Include="UMP.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="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="MobileGPS.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="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="SHA256.cpp" />
|
|
||||||
<ClCompile Include="StopWatch.cpp" />
|
|
||||||
<ClCompile Include="Sync.cpp" />
|
|
||||||
<ClCompile Include="TFTSerial.cpp" />
|
|
||||||
<ClCompile Include="Thread.cpp" />
|
|
||||||
<ClCompile Include="Timer.cpp" />
|
|
||||||
<ClCompile Include="UDPSocket.cpp" />
|
|
||||||
<ClCompile Include="UMP.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,542 +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="SHA256.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="MobileGPS.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NullModem.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="DMRTA.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="SHA256.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="MobileGPS.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NullModem.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DMRTA.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
47
Makefile
47
Makefile
|
@ -2,18 +2,18 @@
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
CXX = c++
|
CXX = c++
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
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 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 MobileGPS.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 NXDNLayer3.o NXDNLICH.o \
|
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.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 \
|
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||||
POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.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 \
|
||||||
Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
all: MMDVMHost RemoteCommand
|
||||||
|
|
||||||
|
@ -26,6 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
.PHONY install:
|
||||||
|
install: all
|
||||||
|
install -m 755 MMDVMHost /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
|
||||||
|
|
||||||
|
|
49
Makefile.Pi
49
Makefile.Pi
|
@ -1,19 +1,19 @@
|
||||||
# This makefile is for use with the Raspberry Pi. The wiringpi library is needed.
|
# This makefile is for use with the Raspberry Pi. The wiringpi library is needed.
|
||||||
|
|
||||||
CC = gcc
|
CC = cc
|
||||||
CXX = g++
|
CXX = c++
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -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 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 MobileGPS.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 NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.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 \
|
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||||
POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.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 \
|
||||||
UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||||
|
|
||||||
all: MMDVMHost RemoteCommand
|
all: MMDVMHost RemoteCommand
|
||||||
|
|
||||||
|
@ -26,6 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
.PHONY install:
|
||||||
|
install: all
|
||||||
|
install -m 755 MMDVMHost /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,39 +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 = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.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 MobileGPS.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 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 SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
|
||||||
Timer.o UDPSocket.o UMP.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 $@ $<
|
|
||||||
|
|
||||||
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,38 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an HD44780 compatible display. The wiringpi library is needed.
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.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 MobileGPS.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 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 SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
|
||||||
Timer.o UDPSocket.o UMP.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 $@ $<
|
|
||||||
|
|
||||||
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,38 +0,0 @@
|
||||||
# This makefile is for use with the Raspberry Pi when using an OLED display. The wiringpi library is needed.
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DOLED -I/usr/local/include
|
|
||||||
LIBS = -lArduiPi_OLED -lwiringPi -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.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 MobileGPS.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 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 SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
|
||||||
Timer.o UDPSocket.o UMP.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 $@ $<
|
|
||||||
|
|
||||||
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,39 +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 = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -DPCF8574_DISPLAY -I/usr/local/include
|
|
||||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
|
||||||
LDFLAGS = -g -L/usr/local/lib
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.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 MobileGPS.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 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 SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
|
|
||||||
Timer.o UDPSocket.o UMP.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 $@ $<
|
|
||||||
|
|
||||||
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,38 +0,0 @@
|
||||||
# This makefile is for Solaris using gcc
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CXX = g++
|
|
||||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
|
||||||
LIBS = -lpthread -lsocket
|
|
||||||
LDFLAGS = -g
|
|
||||||
|
|
||||||
OBJECTS = \
|
|
||||||
AMBEFEC.o BCH.o BPTC19696.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 LCDproc.o Log.o MMDVMHost.o MobileGPS.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 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 SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
|
|
||||||
UMP.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 $@ $<
|
|
||||||
|
|
||||||
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
|
|
101
MobileGPS.cpp
101
MobileGPS.cpp
|
@ -1,101 +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 "MobileGPS.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
CMobileGPS::CMobileGPS(const std::string& address, unsigned int port, CDMRNetwork* network) :
|
|
||||||
m_idTimer(1000U, 60U),
|
|
||||||
m_address(),
|
|
||||||
m_port(port),
|
|
||||||
m_socket(),
|
|
||||||
m_network(network)
|
|
||||||
{
|
|
||||||
assert(!address.empty());
|
|
||||||
assert(port > 0U);
|
|
||||||
assert(network != NULL);
|
|
||||||
|
|
||||||
m_address = CUDPSocket::lookup(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
CMobileGPS::~CMobileGPS()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMobileGPS::open()
|
|
||||||
{
|
|
||||||
bool ret = m_socket.open();
|
|
||||||
if (!ret)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_idTimer.start();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMobileGPS::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
m_idTimer.clock(ms);
|
|
||||||
|
|
||||||
if (m_idTimer.hasExpired()) {
|
|
||||||
pollGPS();
|
|
||||||
m_idTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
sendReport();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMobileGPS::close()
|
|
||||||
{
|
|
||||||
m_socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMobileGPS::pollGPS()
|
|
||||||
{
|
|
||||||
return m_socket.write((unsigned char*)"MMDVMHost", 9U, m_address, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMobileGPS::sendReport()
|
|
||||||
{
|
|
||||||
// Grab GPS data if it's available
|
|
||||||
unsigned char buffer[200U];
|
|
||||||
in_addr address;
|
|
||||||
unsigned int port;
|
|
||||||
int ret = m_socket.read(buffer, 200U, address, port);
|
|
||||||
if (ret <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
buffer[ret] = '\0';
|
|
||||||
|
|
||||||
// Parse the GPS data
|
|
||||||
char* pLatitude = ::strtok((char*)buffer, ",\n"); // Latitude
|
|
||||||
char* pLongitude = ::strtok(NULL, ",\n"); // Longitude
|
|
||||||
|
|
||||||
if (pLatitude == NULL || pLongitude == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float latitude = float(::atof(pLatitude));
|
|
||||||
float longitude = float(::atof(pLongitude));
|
|
||||||
|
|
||||||
m_network->writeHomePosition(latitude, longitude);
|
|
||||||
}
|
|
||||||
|
|
184
Modem.h
184
Modem.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2018 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,86 +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 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);
|
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);
|
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 setTransparentDataParams(unsigned int sendFrameType);
|
void setP25Params(unsigned int txHang);
|
||||||
|
void setNXDNParams(unsigned int txHang);
|
||||||
|
void setM17Params(unsigned int txHang);
|
||||||
|
void setAX25Params(int rxTwist, unsigned int txDelay, unsigned int slotTime, unsigned int pPersist);
|
||||||
|
void setTransparentDataParams(unsigned int sendFrameType);
|
||||||
|
|
||||||
virtual bool open();
|
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 setFMAckParams(const std::string& rfAck, unsigned int ackSpeed, unsigned int ackFrequency, unsigned int ackMinTime, unsigned int ackDelay, float ackLevel);
|
||||||
|
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 unsigned int readDStarData(unsigned char* data);
|
bool open();
|
||||||
virtual unsigned int readDMRData1(unsigned char* data);
|
|
||||||
virtual unsigned int readDMRData2(unsigned char* data);
|
|
||||||
virtual unsigned int readYSFData(unsigned char* data);
|
|
||||||
virtual unsigned int readP25Data(unsigned char* data);
|
|
||||||
virtual unsigned int readNXDNData(unsigned char* data);
|
|
||||||
virtual unsigned int readTransparentData(unsigned char* data);
|
|
||||||
|
|
||||||
virtual unsigned int readSerial(unsigned char* data, unsigned int length);
|
bool hasDStar() const;
|
||||||
|
bool hasDMR() const;
|
||||||
|
bool hasYSF() const;
|
||||||
|
bool hasP25() const;
|
||||||
|
bool hasNXDN() const;
|
||||||
|
bool hasM17() const;
|
||||||
|
bool hasPOCSAG() const;
|
||||||
|
bool hasFM() const;
|
||||||
|
bool hasAX25() const;
|
||||||
|
|
||||||
virtual bool hasDStarSpace() const;
|
unsigned int getVersion() const;
|
||||||
virtual bool hasDMRSpace1() const;
|
|
||||||
virtual bool hasDMRSpace2() const;
|
|
||||||
virtual bool hasYSFSpace() const;
|
|
||||||
virtual bool hasP25Space() const;
|
|
||||||
virtual bool hasNXDNSpace() const;
|
|
||||||
virtual bool hasPOCSAGSpace() const;
|
|
||||||
|
|
||||||
virtual bool hasTX() const;
|
unsigned int readDStarData(unsigned char* data);
|
||||||
virtual bool hasCD() const;
|
unsigned int readDMRData1(unsigned char* data);
|
||||||
|
unsigned int readDMRData2(unsigned char* data);
|
||||||
|
unsigned int readYSFData(unsigned char* data);
|
||||||
|
unsigned int readP25Data(unsigned char* data);
|
||||||
|
unsigned int readNXDNData(unsigned char* data);
|
||||||
|
unsigned int readM17Data(unsigned char* data);
|
||||||
|
unsigned int readFMData(unsigned char* data);
|
||||||
|
unsigned int readAX25Data(unsigned char* data);
|
||||||
|
|
||||||
virtual bool hasLockout() const;
|
bool hasDStarSpace() const;
|
||||||
virtual bool hasError() 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 writeDStarData(const unsigned char* data, unsigned int length);
|
bool hasTX() const;
|
||||||
virtual bool writeDMRData1(const unsigned char* data, unsigned int length);
|
bool hasCD() const;
|
||||||
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 hasLockout() const;
|
||||||
|
bool hasError() const;
|
||||||
|
|
||||||
virtual bool writeDStarInfo(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
bool writeConfig();
|
||||||
virtual bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
bool writeDMRData1(const unsigned char* data, unsigned int length);
|
||||||
virtual bool writeYSFInfo(const char* source, const char* dest, const char* type, const char* origin);
|
bool writeDMRData2(const unsigned char* data, unsigned int length);
|
||||||
virtual bool writeP25Info(const char* source, bool group, unsigned int dest, const char* type);
|
bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||||
virtual bool writeNXDNInfo(const char* source, bool group, unsigned int dest, const char* type);
|
bool writeIPInfo(const std::string& address);
|
||||||
virtual bool writePOCSAGInfo(unsigned int ric, const std::string& message);
|
|
||||||
virtual bool writeIPInfo(const std::string& address);
|
|
||||||
|
|
||||||
virtual bool writeDMRStart(bool tx);
|
bool writeDMRStart(bool tx);
|
||||||
virtual bool writeDMRShortLC(const unsigned char* lc);
|
bool writeDMRShortLC(const unsigned char* lc);
|
||||||
virtual bool writeDMRAbort(unsigned int slotNo);
|
bool writeDMRAbort(unsigned int slotNo);
|
||||||
|
|
||||||
virtual bool writeSerial(const unsigned char* data, unsigned int length);
|
bool writeTransparentData(const unsigned char* data, unsigned int length);
|
||||||
|
unsigned int readTransparentData(unsigned char* data);
|
||||||
|
|
||||||
virtual bool setMode(unsigned char mode);
|
bool writeSerial(const unsigned char* data, unsigned int length);
|
||||||
|
unsigned int readSerial(unsigned char* data, unsigned int length);
|
||||||
|
|
||||||
virtual bool sendCWId(const std::string& callsign);
|
unsigned char getMode() const;
|
||||||
|
bool setMode(unsigned char mode);
|
||||||
|
|
||||||
virtual HW_TYPE getHWType() const;
|
bool sendCWId(const std::string& callsign);
|
||||||
|
|
||||||
virtual void clock(unsigned int ms);
|
HW_TYPE getHWType() const;
|
||||||
|
|
||||||
virtual void close();
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
static CModem* createModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug);
|
void close();
|
||||||
|
|
||||||
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;
|
|
||||||
bool m_duplex;
|
bool m_duplex;
|
||||||
bool m_rxInvert;
|
bool m_rxInvert;
|
||||||
bool m_txInvert;
|
bool m_txInvert;
|
||||||
|
@ -120,66 +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_rfLevel;
|
float m_rfLevel;
|
||||||
|
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;
|
|
||||||
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;
|
||||||
HW_TYPE m_hwType;
|
HW_TYPE m_hwType;
|
||||||
|
unsigned char m_capabilities1;
|
||||||
|
unsigned char m_capabilities2;
|
||||||
|
|
||||||
bool readVersion();
|
bool readVersion();
|
||||||
bool readStatus();
|
bool readStatus();
|
||||||
bool setConfig();
|
bool setConfig1();
|
||||||
|
bool setConfig2();
|
||||||
bool setFrequency();
|
bool setFrequency();
|
||||||
|
bool setFMCallsignParams();
|
||||||
|
bool setFMAckParams();
|
||||||
|
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
|
|
1122
NXDNControl.cpp
1122
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-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(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, CNXDNNetwork* 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;
|
|
||||||
CNXDNNetwork* 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
|
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
160
NXDNLookup.cpp
160
NXDNLookup.cpp
|
@ -1,160 +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_mutex(),
|
|
||||||
m_stop(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNLookup::~CNXDNLookup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLookup::read()
|
|
||||||
{
|
|
||||||
bool ret = load();
|
|
||||||
|
|
||||||
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()) {
|
|
||||||
load();
|
|
||||||
timer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("Stopped the NXDN Id lookup reload thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNLookup::stop()
|
|
||||||
{
|
|
||||||
if (m_reloadTime == 0U) {
|
|
||||||
delete this;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stop = true;
|
|
||||||
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CNXDNLookup::find(unsigned int id)
|
|
||||||
{
|
|
||||||
std::string callsign;
|
|
||||||
|
|
||||||
if (id == 0xFFFFU)
|
|
||||||
return std::string("ALL");
|
|
||||||
|
|
||||||
m_mutex.lock();
|
|
||||||
|
|
||||||
try {
|
|
||||||
callsign = m_table.at(id);
|
|
||||||
} catch (...) {
|
|
||||||
char text[10U];
|
|
||||||
::sprintf(text, "%u", id);
|
|
||||||
callsign = std::string(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
return callsign;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLookup::exists(unsigned int id)
|
|
||||||
{
|
|
||||||
m_mutex.lock();
|
|
||||||
|
|
||||||
bool found = m_table.count(id) == 1U;
|
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNLookup::load()
|
|
||||||
{
|
|
||||||
FILE* fp = ::fopen(m_filename.c_str(), "rt");
|
|
||||||
if (fp == NULL) {
|
|
||||||
LogWarning("Cannot open the NXDN Id lookup file - %s", m_filename.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mutex.lock();
|
|
||||||
|
|
||||||
// Remove the old entries
|
|
||||||
m_table.clear();
|
|
||||||
|
|
||||||
char buffer[100U];
|
|
||||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
|
||||||
if (buffer[0U] == '#')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char* p1 = ::strtok(buffer, ",\t\r\n");
|
|
||||||
char* p2 = ::strtok(NULL, ",\t\r\n");
|
|
||||||
|
|
||||||
if (p1 != NULL && p2 != NULL) {
|
|
||||||
unsigned int id = (unsigned int)::atoi(p1);
|
|
||||||
if (id > 0U) {
|
|
||||||
for (char* p = p2; *p != 0x00U; p++)
|
|
||||||
*p = ::toupper(*p);
|
|
||||||
|
|
||||||
m_table[id] = std::string(p2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
::fclose(fp);
|
|
||||||
|
|
||||||
size_t size = m_table.size();
|
|
||||||
if (size == 0U)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LogInfo("Loaded %u Ids to the NXDN callsign lookup table", size);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
53
NXDNLookup.h
53
NXDNLookup.h
|
@ -1,53 +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 "Mutex.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
bool exists(unsigned int id);
|
|
||||||
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_filename;
|
|
||||||
unsigned int m_reloadTime;
|
|
||||||
std::unordered_map<unsigned int, std::string> m_table;
|
|
||||||
CMutex m_mutex;
|
|
||||||
bool m_stop;
|
|
||||||
|
|
||||||
bool load();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
169
NXDNNetwork.cpp
169
NXDNNetwork.cpp
|
@ -1,169 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "NXDNNetwork.h"
|
|
||||||
#include "Defines.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
const unsigned int BUFFER_LENGTH = 200U;
|
|
||||||
|
|
||||||
CNXDNNetwork::CNXDNNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug) :
|
|
||||||
m_socket(localAddress, localPort),
|
|
||||||
m_address(),
|
|
||||||
m_port(gatewayPort),
|
|
||||||
m_debug(debug),
|
|
||||||
m_enabled(false),
|
|
||||||
m_buffer(1000U, "NXDN Network")
|
|
||||||
{
|
|
||||||
assert(gatewayPort > 0U);
|
|
||||||
assert(!gatewayAddress.empty());
|
|
||||||
|
|
||||||
m_address = CUDPSocket::lookup(gatewayAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
CNXDNNetwork::~CNXDNNetwork()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNNetwork::open()
|
|
||||||
{
|
|
||||||
LogMessage("Opening NXDN network connection");
|
|
||||||
|
|
||||||
if (m_address.s_addr == INADDR_NONE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return m_socket.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNNetwork::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_address, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNNetwork::clock(unsigned int ms)
|
|
||||||
{
|
|
||||||
unsigned char buffer[BUFFER_LENGTH];
|
|
||||||
|
|
||||||
in_addr address;
|
|
||||||
unsigned int port;
|
|
||||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, port);
|
|
||||||
if (length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if the data is for us
|
|
||||||
if (m_address.s_addr != address.s_addr || port != m_port) {
|
|
||||||
LogMessage("NXDN packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, m_port, port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalid packet type?
|
|
||||||
if (::memcmp(buffer, "ICOM", 4U) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (length != 102)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "NXDN Network Data Received", buffer, length);
|
|
||||||
|
|
||||||
m_buffer.addData(buffer + 40U, 33U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CNXDNNetwork::read(unsigned char* data)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
|
|
||||||
if (m_buffer.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_buffer.getData(data, 33U);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNNetwork::reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNNetwork::close()
|
|
||||||
{
|
|
||||||
m_socket.close();
|
|
||||||
|
|
||||||
LogMessage("Closing NXDN network connection");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNXDNNetwork::enable(bool enabled)
|
|
||||||
{
|
|
||||||
if (enabled && !m_enabled)
|
|
||||||
reset();
|
|
||||||
else if (!enabled && m_enabled)
|
|
||||||
m_buffer.clear();
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2014,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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NXDNNetwork_H
|
|
||||||
#define NXDNNetwork_H
|
|
||||||
|
|
||||||
#include "NXDNDefines.h"
|
|
||||||
#include "RingBuffer.h"
|
|
||||||
#include "UDPSocket.h"
|
|
||||||
#include "Timer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
enum NXDN_NETWORK_MESSAGE_TYPE {
|
|
||||||
NNMT_VOICE_HEADER,
|
|
||||||
NNMT_VOICE_BODY,
|
|
||||||
NNMT_VOICE_TRAILER,
|
|
||||||
NNMT_DATA_HEADER,
|
|
||||||
NNMT_DATA_BODY,
|
|
||||||
NNMT_DATA_TRAILER
|
|
||||||
};
|
|
||||||
|
|
||||||
class CNXDNNetwork {
|
|
||||||
public:
|
|
||||||
CNXDNNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug);
|
|
||||||
~CNXDNNetwork();
|
|
||||||
|
|
||||||
bool open();
|
|
||||||
|
|
||||||
void enable(bool enabled);
|
|
||||||
|
|
||||||
bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type);
|
|
||||||
|
|
||||||
bool read(unsigned char* data);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void close();
|
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CUDPSocket m_socket;
|
|
||||||
in_addr m_address;
|
|
||||||
unsigned int m_port;
|
|
||||||
bool m_debug;
|
|
||||||
bool m_enabled;
|
|
||||||
CRingBuffer<unsigned char> m_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#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
|
|
|
@ -26,13 +26,18 @@
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if !defined(_WIN32) && !defined(_WIN64)
|
#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#else
|
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#endif
|
||||||
|
#elif defined(_WIN32) || defined(_WIN64)
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#pragma comment(lib, "iphlpapi.lib")
|
#pragma comment(lib, "iphlpapi.lib")
|
||||||
|
@ -61,17 +66,16 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||||
|
|
||||||
::strcpy((char*)info, "(address unknown)");
|
::strcpy((char*)info, "(address unknown)");
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(_WIN64)
|
#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
const unsigned int IFLISTSIZ = 25U;
|
char* dflt = NULL;
|
||||||
|
|
||||||
FILE* fp = ::fopen("/proc/net/route" , "r");
|
#if defined(__linux__)
|
||||||
|
FILE* fp = ::fopen("/proc/net/route" , "r"); // IPv4 routing
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
LogError("Unabled to open /proc/route");
|
LogError("Unabled to open /proc/route");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* dflt = NULL;
|
|
||||||
|
|
||||||
char line[100U];
|
char line[100U];
|
||||||
while (::fgets(line, 100U, fp)) {
|
while (::fgets(line, 100U, fp)) {
|
||||||
char* p1 = strtok(line , " \t");
|
char* p1 = strtok(line , " \t");
|
||||||
|
@ -87,11 +91,60 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||||
|
|
||||||
::fclose(fp);
|
::fclose(fp);
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
|
int mib[] = {
|
||||||
|
CTL_NET,
|
||||||
|
PF_ROUTE,
|
||||||
|
0, // protocol
|
||||||
|
AF_INET, // IPv4 routing
|
||||||
|
NET_RT_DUMP,
|
||||||
|
0, // show all routes
|
||||||
|
#if defined(__OpenBSD__) || defined(__FreeBSD__)
|
||||||
|
0, // table id
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
const int cnt = sizeof(mib) / sizeof(int);
|
||||||
|
size_t size;
|
||||||
|
char ifname[IF_NAMESIZE] = {};
|
||||||
|
|
||||||
|
if (::sysctl(mib, cnt, NULL, &size, NULL, 0) == -1 || size <= 0) {
|
||||||
|
LogError("Unable to estimate routing table size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = new char[size];
|
||||||
|
if (::sysctl(mib, cnt, buf, &size, NULL, 0) == -1) {
|
||||||
|
LogError("Unable to get routing table");
|
||||||
|
delete[] buf;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rt_msghdr *rtm;
|
||||||
|
for (char *p = buf; p < buf + size; p += rtm->rtm_msglen) {
|
||||||
|
rtm = (struct rt_msghdr *)p;
|
||||||
|
if (rtm->rtm_version != RTM_VERSION)
|
||||||
|
continue;
|
||||||
|
#if defined(__OpenBSD__)
|
||||||
|
struct sockaddr_in *sa = (struct sockaddr_in *)(p + rtm->rtm_hdrlen);
|
||||||
|
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
|
struct sockaddr_in *sa = (struct sockaddr_in *)(rtm + 1);
|
||||||
|
#endif
|
||||||
|
if (sa->sin_addr.s_addr == INADDR_ANY) {
|
||||||
|
::if_indextoname(rtm->rtm_index, ifname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
if (::strlen(ifname))
|
||||||
|
dflt = ifname;
|
||||||
|
#endif
|
||||||
if (dflt == NULL) {
|
if (dflt == NULL) {
|
||||||
LogError("Unable to find the default route");
|
LogError("Unable to find the default route");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned int IFLISTSIZ = 25U;
|
||||||
char interfacelist[IFLISTSIZ][50+INET6_ADDRSTRLEN];
|
char interfacelist[IFLISTSIZ][50+INET6_ADDRSTRLEN];
|
||||||
for (unsigned int n = 0U; n < IFLISTSIZ; n++)
|
for (unsigned int n = 0U; n < IFLISTSIZ; n++)
|
||||||
interfacelist[n][0] = 0;
|
interfacelist[n][0] = 0;
|
||||||
|
@ -119,12 +172,13 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||||
if (family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host);
|
::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host);
|
||||||
LogInfo(" IPv4: %s", interfacelist[ifnr]);
|
LogInfo(" IPv4: %s", interfacelist[ifnr]);
|
||||||
|
ifnr++;
|
||||||
} else {
|
} else {
|
||||||
::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host);
|
::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host);
|
||||||
LogInfo(" IPv6: %s", interfacelist[ifnr]);
|
LogInfo(" IPv6: %s", interfacelist[ifnr]);
|
||||||
|
// due to default routing is for IPv4, other
|
||||||
|
// protocols are not candidate to display.
|
||||||
}
|
}
|
||||||
|
|
||||||
ifnr++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +198,7 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info)
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(" IP to show: %s", info);
|
LogInfo(" IP to show: %s", info);
|
||||||
#else
|
#elif defined(_WIN32) || defined(_WIN64)
|
||||||
PMIB_IPFORWARDTABLE pIpForwardTable = (MIB_IPFORWARDTABLE *)::malloc(sizeof(MIB_IPFORWARDTABLE));
|
PMIB_IPFORWARDTABLE pIpForwardTable = (MIB_IPFORWARDTABLE *)::malloc(sizeof(MIB_IPFORWARDTABLE));
|
||||||
if (pIpForwardTable == NULL) {
|
if (pIpForwardTable == NULL) {
|
||||||
LogError("Error allocating memory");
|
LogError("Error allocating memory");
|
||||||
|
|
475
Nextion.cpp
475
Nextion.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018,2020 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,20 +25,21 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
//#include <unistd.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF, const std::string& location) :
|
#define LAYOUT_COMPAT_MASK (7 << 0) // compatibility for old setting
|
||||||
|
#define LAYOUT_TA_ENABLE (1 << 4) // enable Talker Alias (TA) display
|
||||||
|
#define LAYOUT_TA_COLOUR (1 << 5) // TA display with font colour change
|
||||||
|
#define LAYOUT_TA_FONTSIZE (1 << 6) // TA display with font size change
|
||||||
|
#define LAYOUT_DIY (1 << 7) // use ON7LDS-DIY layout
|
||||||
|
|
||||||
|
// bit[3:2] is used in Display.cpp to set connection speed for LCD panel.
|
||||||
|
// 00:low, others:high-speed. bit[2] is overlapped with LAYOUT_COMPAT_MASK.
|
||||||
|
#define LAYOUT_HIGHSPEED (3 << 2)
|
||||||
|
|
||||||
|
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF) :
|
||||||
CDisplay(),
|
CDisplay(),
|
||||||
m_callsign(callsign),
|
m_callsign(callsign),
|
||||||
m_ipaddress("(ip unknown)"),
|
m_ipaddress("(ip unknown)"),
|
||||||
|
@ -49,7 +50,7 @@ m_mode(MODE_IDLE),
|
||||||
m_displayClock(displayClock),
|
m_displayClock(displayClock),
|
||||||
m_utc(utc),
|
m_utc(utc),
|
||||||
m_idleBrightness(idleBrightness),
|
m_idleBrightness(idleBrightness),
|
||||||
m_screenLayout(screenLayout),
|
m_screenLayout(0),
|
||||||
m_clockDisplayTimer(1000U, 0U, 400U),
|
m_clockDisplayTimer(1000U, 0U, 400U),
|
||||||
m_rssiAccum1(0U),
|
m_rssiAccum1(0U),
|
||||||
m_rssiAccum2(0U),
|
m_rssiAccum2(0U),
|
||||||
|
@ -63,11 +64,27 @@ m_txFrequency(txFrequency),
|
||||||
m_rxFrequency(rxFrequency),
|
m_rxFrequency(rxFrequency),
|
||||||
m_fl_txFrequency(0.0F),
|
m_fl_txFrequency(0.0F),
|
||||||
m_fl_rxFrequency(0.0F),
|
m_fl_rxFrequency(0.0F),
|
||||||
m_displayTempInF(displayTempInF),
|
m_displayTempInF(displayTempInF)
|
||||||
m_location(location)
|
|
||||||
{
|
{
|
||||||
assert(serial != NULL);
|
assert(serial != NULL);
|
||||||
assert(brightness >= 0U && brightness <= 100U);
|
assert(brightness >= 0U && brightness <= 100U);
|
||||||
|
|
||||||
|
static const unsigned int feature_set[] = {
|
||||||
|
0, // 0: G4KLX
|
||||||
|
0, // 1: (reserved, low speed)
|
||||||
|
// 2: ON7LDS
|
||||||
|
LAYOUT_TA_ENABLE | LAYOUT_TA_COLOUR | LAYOUT_TA_FONTSIZE,
|
||||||
|
LAYOUT_TA_ENABLE | LAYOUT_DIY, // 3: ON7LDS-DIY
|
||||||
|
LAYOUT_TA_ENABLE | LAYOUT_DIY, // 4: ON7LDS-DIY (high speed)
|
||||||
|
0, // 5: (reserved, high speed)
|
||||||
|
0, // 6: (reserved, high speed)
|
||||||
|
0, // 7: (reserved, high speed)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (screenLayout & ~LAYOUT_COMPAT_MASK)
|
||||||
|
m_screenLayout = screenLayout & ~LAYOUT_COMPAT_MASK;
|
||||||
|
else
|
||||||
|
m_screenLayout = feature_set[screenLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
CNextion::~CNextion()
|
CNextion::~CNextion()
|
||||||
|
@ -94,15 +111,14 @@ bool CNextion::open()
|
||||||
sendCommand("bkcmd=0");
|
sendCommand("bkcmd=0");
|
||||||
sendCommandAction(0U);
|
sendCommandAction(0U);
|
||||||
|
|
||||||
m_fl_txFrequency = float(m_txFrequency) / 1000000.0F;
|
m_fl_txFrequency = double(m_txFrequency) / 1000000.0F;
|
||||||
m_fl_rxFrequency = float(m_rxFrequency) / 1000000.0F;
|
m_fl_rxFrequency = double(m_rxFrequency) / 1000000.0F;
|
||||||
|
|
||||||
setIdle();
|
setIdle();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CNextion::setIdleInt()
|
void CNextion::setIdleInt()
|
||||||
{
|
{
|
||||||
// a few bits borrowed from Lieven De Samblanx ON7LDS, NextionDriver
|
// a few bits borrowed from Lieven De Samblanx ON7LDS, NextionDriver
|
||||||
|
@ -119,18 +135,18 @@ void CNextion::setIdleInt()
|
||||||
::sprintf(command, "t0.txt=\"%s/%u\"", m_callsign.c_str(), m_dmrid);
|
::sprintf(command, "t0.txt=\"%s/%u\"", m_callsign.c_str(), m_dmrid);
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
|
|
||||||
if (m_screenLayout > 2U) {
|
if (m_screenLayout & LAYOUT_DIY) {
|
||||||
::sprintf(command, "t4.txt=\"%s\"", m_callsign.c_str());
|
::sprintf(command, "t4.txt=\"%s\"", m_callsign.c_str());
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
::sprintf(command, "t5.txt=\"%u\"", m_dmrid);
|
::sprintf(command, "t5.txt=\"%u\"", m_dmrid);
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
sendCommandAction(17U);
|
sendCommandAction(17U);
|
||||||
|
|
||||||
::sprintf(command, "t30.txt=\"%3.4f\"",m_fl_rxFrequency); // RX freq
|
::sprintf(command, "t30.txt=\"%3.6f\"",m_fl_rxFrequency); // RX freq
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
sendCommandAction(20U);
|
sendCommandAction(20U);
|
||||||
|
|
||||||
::sprintf(command, "t32.txt=\"%3.4f\"",m_fl_txFrequency); // TX freq
|
::sprintf(command, "t32.txt=\"%3.6f\"",m_fl_txFrequency); // TX freq
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
sendCommandAction(21U);
|
sendCommandAction(21U);
|
||||||
|
|
||||||
|
@ -153,10 +169,6 @@ void CNextion::setIdleInt()
|
||||||
sendCommandAction(22U);
|
sendCommandAction(22U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::sprintf(command, "t31.txt=\"%s\"", m_location.c_str()); // location
|
|
||||||
sendCommand(command);
|
|
||||||
sendCommandAction(23U);
|
|
||||||
} else {
|
} else {
|
||||||
sendCommandAction(17U);
|
sendCommandAction(17U);
|
||||||
}
|
}
|
||||||
|
@ -240,88 +252,6 @@ void CNextion::setQuitInt()
|
||||||
m_mode = MODE_QUIT;
|
m_mode = MODE_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -332,17 +262,21 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
|
|
||||||
|
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t2.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t2.font=4");
|
sendCommand("t2.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t2.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand("t2.txt=\"2 Listening\"");
|
sendCommand("t2.txt=\"2 Listening\"");
|
||||||
sendCommandAction(69U);
|
sendCommandAction(69U);
|
||||||
} else {
|
} else {
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t0.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t0.font=4");
|
sendCommand("t0.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t0.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand("t0.txt=\"1 Listening\"");
|
sendCommand("t0.txt=\"1 Listening\"");
|
||||||
|
@ -359,9 +293,11 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
::sprintf(text, "t0.txt=\"1 %s %s\"", type, src.c_str());
|
::sprintf(text, "t0.txt=\"1 %s %s\"", type, src.c_str());
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t0.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t0.font=4");
|
sendCommand("t0.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t0.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand(text);
|
sendCommand(text);
|
||||||
|
@ -373,9 +309,11 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
||||||
} else {
|
} else {
|
||||||
::sprintf(text, "t2.txt=\"2 %s %s\"", type, src.c_str());
|
::sprintf(text, "t2.txt=\"2 %s %s\"", type, src.c_str());
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t2.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t2.font=4");
|
sendCommand("t2.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t2.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand(text);
|
sendCommand(text);
|
||||||
|
@ -430,15 +368,17 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
||||||
|
|
||||||
void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
|
void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
|
||||||
{
|
{
|
||||||
if (m_screenLayout < 2U)
|
if (!(m_screenLayout & LAYOUT_TA_ENABLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type[0] == ' ') {
|
if (type[0] == ' ') {
|
||||||
if (slotNo == 1U) {
|
if (slotNo == 1U) {
|
||||||
if (m_screenLayout == 2U) sendCommand("t0.pco=33808");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
|
sendCommand("t0.pco=33808");
|
||||||
sendCommandAction(64U);
|
sendCommandAction(64U);
|
||||||
} else {
|
} else {
|
||||||
if (m_screenLayout == 2U) sendCommand("t2.pco=33808");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
|
sendCommand("t2.pco=33808");
|
||||||
sendCommandAction(72U);
|
sendCommandAction(72U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,33 +389,36 @@ void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, co
|
||||||
char text[50U];
|
char text[50U];
|
||||||
::sprintf(text, "t0.txt=\"1 %s %s\"", type, talkerAlias);
|
::sprintf(text, "t0.txt=\"1 %s %s\"", type, talkerAlias);
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE) {
|
||||||
if (::strlen((char*)talkerAlias) > (16U-4U))
|
if (::strlen((char*)talkerAlias) > (16U-4U))
|
||||||
sendCommand("t0.font=3");
|
sendCommand("t0.font=3");
|
||||||
if (::strlen((char*)talkerAlias) > (20U-4U))
|
if (::strlen((char*)talkerAlias) > (20U-4U))
|
||||||
sendCommand("t0.font=2");
|
sendCommand("t0.font=2");
|
||||||
if (::strlen((char*)talkerAlias) > (24U-4U))
|
if (::strlen((char*)talkerAlias) > (24U-4U))
|
||||||
sendCommand("t0.font=1");
|
sendCommand("t0.font=1");
|
||||||
|
|
||||||
sendCommand("t0.pco=1024");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
|
sendCommand("t0.pco=1024");
|
||||||
|
|
||||||
sendCommand(text);
|
sendCommand(text);
|
||||||
sendCommandAction(63U);
|
sendCommandAction(63U);
|
||||||
} else {
|
} else {
|
||||||
char text[50U];
|
char text[50U];
|
||||||
::sprintf(text, "t2.txt=\"2 %s %s\"", type, talkerAlias);
|
::sprintf(text, "t2.txt=\"2 %s %s\"", type, talkerAlias);
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE) {
|
||||||
if (::strlen((char*)talkerAlias) > (16U-4U))
|
if (::strlen((char*)talkerAlias) > (16U-4U))
|
||||||
sendCommand("t2.font=3");
|
sendCommand("t2.font=3");
|
||||||
if (::strlen((char*)talkerAlias) > (20U-4U))
|
if (::strlen((char*)talkerAlias) > (20U-4U))
|
||||||
sendCommand("t2.font=2");
|
sendCommand("t2.font=2");
|
||||||
if (::strlen((char*)talkerAlias) > (24U-4U))
|
if (::strlen((char*)talkerAlias) > (24U-4U))
|
||||||
sendCommand("t2.font=1");
|
sendCommand("t2.font=1");
|
||||||
|
|
||||||
sendCommand("t2.pco=1024");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
|
sendCommand("t2.pco=1024");
|
||||||
|
|
||||||
sendCommand(text);
|
sendCommand(text);
|
||||||
sendCommandAction(71U);
|
sendCommandAction(71U);
|
||||||
}
|
}
|
||||||
|
@ -517,9 +460,11 @@ void CNextion::clearDMRInt(unsigned int slotNo)
|
||||||
sendCommand("t0.txt=\"1 Listening\"");
|
sendCommand("t0.txt=\"1 Listening\"");
|
||||||
sendCommandAction(61U);
|
sendCommandAction(61U);
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t0.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t0.font=4");
|
sendCommand("t0.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t0.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand("t1.txt=\"\"");
|
sendCommand("t1.txt=\"\"");
|
||||||
|
@ -529,9 +474,11 @@ void CNextion::clearDMRInt(unsigned int slotNo)
|
||||||
sendCommand("t2.txt=\"2 Listening\"");
|
sendCommand("t2.txt=\"2 Listening\"");
|
||||||
sendCommandAction(69U);
|
sendCommandAction(69U);
|
||||||
|
|
||||||
if (m_screenLayout == 2U) {
|
if (m_screenLayout & LAYOUT_TA_ENABLE) {
|
||||||
sendCommand("t2.pco=0");
|
if (m_screenLayout & LAYOUT_TA_COLOUR)
|
||||||
sendCommand("t2.font=4");
|
sendCommand("t2.pco=0");
|
||||||
|
if (m_screenLayout & LAYOUT_TA_FONTSIZE)
|
||||||
|
sendCommand("t2.font=4");
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand("t3.txt=\"\"");
|
sendCommand("t3.txt=\"\"");
|
||||||
|
@ -540,264 +487,6 @@ void CNextion::clearDMRInt(unsigned int slotNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNextion::writeFusionInt(const char* source, const char* dest, 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=\"%.10s\"", dest);
|
|
||||||
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\"");
|
||||||
|
@ -844,7 +533,7 @@ void CNextion::close()
|
||||||
|
|
||||||
void CNextion::sendCommandAction(unsigned int status)
|
void CNextion::sendCommandAction(unsigned int status)
|
||||||
{
|
{
|
||||||
if (m_screenLayout<3U)
|
if (!(m_screenLayout & LAYOUT_DIY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char text[30U];
|
char text[30U];
|
||||||
|
@ -863,4 +552,4 @@ void CNextion::sendCommand(const char* command)
|
||||||
// we must add a bit of a delay to allow the display to process the commands, else some are getting mangled.
|
// we must add a bit of a delay to allow the display to process the commands, else some are getting mangled.
|
||||||
// 10 ms is just a guess, but seems to be sufficient.
|
// 10 ms is just a guess, but seems to be sufficient.
|
||||||
CThread::sleep(10U);
|
CThread::sleep(10U);
|
||||||
}
|
}
|
||||||
|
|
32
Nextion.h
32
Nextion.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2017,2018,2020 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
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
class CNextion : public CDisplay
|
class CNextion : public CDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF, const std::string& location);
|
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF);
|
||||||
virtual ~CNextion();
|
virtual ~CNextion();
|
||||||
|
|
||||||
virtual bool open();
|
virtual bool open();
|
||||||
|
@ -42,11 +42,6 @@ protected:
|
||||||
virtual void setLockoutInt();
|
virtual void setLockoutInt();
|
||||||
virtual void setQuitInt();
|
virtual void setQuitInt();
|
||||||
|
|
||||||
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);
|
||||||
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||||
|
@ -54,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, 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();
|
||||||
|
|
||||||
|
@ -99,10 +76,9 @@ private:
|
||||||
unsigned int m_berCount2;
|
unsigned int m_berCount2;
|
||||||
unsigned int m_txFrequency;
|
unsigned int m_txFrequency;
|
||||||
unsigned int m_rxFrequency;
|
unsigned int m_rxFrequency;
|
||||||
float m_fl_txFrequency;
|
double m_fl_txFrequency;
|
||||||
float m_fl_rxFrequency;
|
double m_fl_rxFrequency;
|
||||||
bool m_displayTempInF;
|
bool m_displayTempInF;
|
||||||
std::string m_location;
|
|
||||||
|
|
||||||
void sendCommand(const char* command);
|
void sendCommand(const char* command);
|
||||||
void sendCommandAction(unsigned int status);
|
void sendCommandAction(unsigned int status);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue