Compare commits
770 commits
jitter_buf
...
master
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 | ||
|
529fdf88eb | ||
|
1ed79d01c0 | ||
|
cd40f6602d | ||
|
1993262c52 | ||
|
bb0bd4bb46 | ||
|
ed79a7176a |
224 changed files with 45270 additions and 27984 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ RemoteCommand
|
|||
.vs
|
||||
*.ambe
|
||||
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
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include "Golay24128.h"
|
||||
#include "Hamming.h"
|
||||
#include "AMBEFEC.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#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_b = b;
|
||||
|
||||
unsigned int data = CGolay24128::decode24128(a);
|
||||
|
||||
a = CGolay24128::encode24128(data);
|
||||
unsigned int data;
|
||||
bool valid1 = CGolay24128::decode24128(a, data);
|
||||
if (!valid1)
|
||||
return 10U;
|
||||
|
||||
// The PRNG
|
||||
unsigned int p = PRNG_TABLE[data];
|
||||
|
||||
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 ^= p;
|
||||
|
||||
unsigned int errsA = 0U, errsB = 0U;
|
||||
|
||||
unsigned int v = a ^ orig_a;
|
||||
while (v != 0U) {
|
||||
v &= v - 1U;
|
||||
errsA++;
|
||||
}
|
||||
unsigned int errsA = CUtils::countBits(v);
|
||||
|
||||
v = b ^ orig_b;
|
||||
while (v != 0U) {
|
||||
v &= v - 1U;
|
||||
errsB++;
|
||||
}
|
||||
unsigned int errsB = CUtils::countBits(v);
|
||||
|
||||
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_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);
|
||||
|
||||
|
@ -847,19 +852,11 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
|
|||
|
||||
b ^= p;
|
||||
|
||||
unsigned int errsA = 0U, errsB = 0U;
|
||||
|
||||
unsigned int v = a ^ orig_a;
|
||||
while (v != 0U) {
|
||||
v &= v - 1U;
|
||||
errsA++;
|
||||
}
|
||||
unsigned int errsA = CUtils::countBits(v);
|
||||
|
||||
v = b ^ orig_b;
|
||||
while (v != 0U) {
|
||||
v &= v - 1U;
|
||||
errsB++;
|
||||
}
|
||||
unsigned int errsB = CUtils::countBits(v);
|
||||
|
||||
if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) {
|
||||
a = 0xF00292U;
|
||||
|
|
52
CASTInfo.cpp
52
CASTInfo.cpp
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -76,16 +76,6 @@ void CCASTInfo::setQuitInt()
|
|||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
m_modem->writeDStarInfo(my1, my2, your, type, reflector);
|
||||
}
|
||||
|
||||
void CCASTInfo::clearDStarInt()
|
||||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
|
@ -96,46 +86,6 @@ void CCASTInfo::clearDMRInt(unsigned int slotNo)
|
|||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
m_modem->writeYSFInfo(source, dest, type, origin);
|
||||
}
|
||||
|
||||
void CCASTInfo::clearFusionInt()
|
||||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
m_modem->writeP25Info(source, group, dest, type);
|
||||
}
|
||||
|
||||
void CCASTInfo::clearP25Int()
|
||||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
m_modem->writeNXDNInfo(source, group, dest, type);
|
||||
}
|
||||
|
||||
void CCASTInfo::clearNXDNInt()
|
||||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writePOCSAGInt(uint32_t ric, const std::string& message)
|
||||
{
|
||||
if (m_modem != NULL)
|
||||
m_modem->writePOCSAGInfo(ric, message);
|
||||
}
|
||||
|
||||
void CCASTInfo::clearPOCSAGInt()
|
||||
{
|
||||
}
|
||||
|
||||
void CCASTInfo::writeCWInt()
|
||||
{
|
||||
}
|
||||
|
|
20
CASTInfo.h
20
CASTInfo.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016,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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "NetworkInfo.h"
|
||||
#include "Modem.h"
|
||||
|
||||
class CCASTInfo : public CDisplay
|
||||
{
|
||||
public:
|
||||
|
@ -41,29 +42,14 @@ protected:
|
|||
virtual void setLockoutInt();
|
||||
virtual void setQuitInt();
|
||||
|
||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
||||
virtual void clearDStarInt();
|
||||
|
||||
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||
virtual void clearDMRInt(unsigned int slotNo);
|
||||
|
||||
virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin);
|
||||
virtual void clearFusionInt();
|
||||
|
||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual void clearP25Int();
|
||||
|
||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual void clearNXDNInt();
|
||||
|
||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||
virtual void clearPOCSAGInt();
|
||||
|
||||
virtual void writeCWInt();
|
||||
virtual void clearCWInt();
|
||||
|
||||
private:
|
||||
CModem* m_modem;
|
||||
CModem* m_modem;
|
||||
std::string m_ipaddress;
|
||||
};
|
||||
|
||||
|
|
270
Conf.h
270
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -54,6 +54,7 @@ public:
|
|||
unsigned int getLogFileLevel() const;
|
||||
std::string getLogFilePath() const;
|
||||
std::string getLogFileRoot() const;
|
||||
bool getLogFileRotate() const;
|
||||
|
||||
// The CW ID section
|
||||
bool getCWIdEnabled() const;
|
||||
|
@ -64,14 +65,16 @@ public:
|
|||
std::string getDMRIdLookupFile() const;
|
||||
unsigned int getDMRIdLookupTime() const;
|
||||
|
||||
// The NXDN Id section
|
||||
std::string getNXDNIdLookupFile() const;
|
||||
unsigned int getNXDNIdLookupTime() const;
|
||||
|
||||
// The Modem section
|
||||
std::string getModemPort() 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 getModemTXInvert() const;
|
||||
bool getModemPTTInvert() const;
|
||||
|
@ -89,37 +92,25 @@ public:
|
|||
float getModemYSFTXLevel() const;
|
||||
float getModemP25TXLevel() const;
|
||||
float getModemNXDNTXLevel() const;
|
||||
float getModemM17TXLevel() const;
|
||||
float getModemPOCSAGTXLevel() const;
|
||||
float getModemFMTXLevel() const;
|
||||
float getModemAX25TXLevel() const;
|
||||
std::string getModemRSSIMappingFile() const;
|
||||
bool getModemUseCOSAsLockout() const;
|
||||
bool getModemTrace() const;
|
||||
bool getModemDebug() const;
|
||||
|
||||
// The Transparent Data section
|
||||
bool getTransparentEnabled() const;
|
||||
std::string getTransparentRemoteAddress() const;
|
||||
unsigned int getTransparentRemotePort() const;
|
||||
unsigned int getTransparentLocalPort() const;
|
||||
unsigned short getTransparentRemotePort() const;
|
||||
unsigned short getTransparentLocalPort() const;
|
||||
unsigned int getTransparentSendFrameType() const;
|
||||
|
||||
// The UMP 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
|
||||
// The DMR section
|
||||
bool getDMREnabled() const;
|
||||
bool getDMRBeacons() const;
|
||||
DMR_BEACONS getDMRBeacons() const;
|
||||
unsigned int getDMRBeaconInterval() const;
|
||||
unsigned int getDMRBeaconDuration() const;
|
||||
unsigned int getDMRId() const;
|
||||
|
@ -135,52 +126,15 @@ public:
|
|||
unsigned int getDMRCallHang() const;
|
||||
unsigned int getDMRTXHang() const;
|
||||
unsigned int getDMRModeHang() const;
|
||||
bool getDMROVCM() const;
|
||||
DMR_OVCM_TYPES getDMROVCM() const;
|
||||
|
||||
// The System Fusion 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
|
||||
// The DMR Network section
|
||||
bool getDMRNetworkEnabled() const;
|
||||
std::string getDMRNetworkAddress() const;
|
||||
unsigned int getDMRNetworkPort() const;
|
||||
unsigned int getDMRNetworkLocal() const;
|
||||
std::string getDMRNetworkType() const;
|
||||
std::string getDMRNetworkRemoteAddress() const;
|
||||
unsigned short getDMRNetworkRemotePort() const;
|
||||
std::string getDMRNetworkLocalAddress() const;
|
||||
unsigned short getDMRNetworkLocalPort() const;
|
||||
std::string getDMRNetworkPassword() const;
|
||||
std::string getDMRNetworkOptions() const;
|
||||
bool getDMRNetworkDebug() const;
|
||||
|
@ -189,42 +143,7 @@ public:
|
|||
bool getDMRNetworkSlot2() const;
|
||||
unsigned int getDMRNetworkModeHang() const;
|
||||
|
||||
// The System Fusion Network 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
|
||||
// The TFTSERIAL section
|
||||
std::string getTFTSerialPort() const;
|
||||
unsigned int getTFTSerialBrightness() const;
|
||||
|
||||
|
@ -259,8 +178,8 @@ public:
|
|||
|
||||
// The LCDproc section
|
||||
std::string getLCDprocAddress() const;
|
||||
unsigned int getLCDprocPort() const;
|
||||
unsigned int getLCDprocLocalPort() const;
|
||||
unsigned short getLCDprocPort() const;
|
||||
unsigned short getLCDprocLocalPort() const;
|
||||
bool getLCDprocDisplayClock() const;
|
||||
bool getLCDprocUTC() const;
|
||||
bool getLCDprocDimOnIdle() const;
|
||||
|
@ -269,14 +188,10 @@ public:
|
|||
bool getLockFileEnabled() const;
|
||||
std::string getLockFileName() const;
|
||||
|
||||
// The Mobile GPS section
|
||||
bool getMobileGPSEnabled() const;
|
||||
std::string getMobileGPSAddress() const;
|
||||
unsigned int getMobileGPSPort() const;
|
||||
|
||||
// The Remote Control section
|
||||
bool getRemoteControlEnabled() const;
|
||||
unsigned int getRemoteControlPort() const;
|
||||
std::string getRemoteControlAddress() const;
|
||||
unsigned short getRemoteControlPort() const;
|
||||
|
||||
private:
|
||||
std::string m_file;
|
||||
|
@ -301,6 +216,7 @@ private:
|
|||
unsigned int m_logFileLevel;
|
||||
std::string m_logFilePath;
|
||||
std::string m_logFileRoot;
|
||||
bool m_logFileRotate;
|
||||
|
||||
bool m_cwIdEnabled;
|
||||
unsigned int m_cwIdTime;
|
||||
|
@ -312,9 +228,15 @@ private:
|
|||
std::string m_nxdnIdLookupFile;
|
||||
unsigned int m_nxdnIdLookupTime;
|
||||
|
||||
std::string m_modemPort;
|
||||
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_modemTXInvert;
|
||||
bool m_modemPTTInvert;
|
||||
|
@ -327,38 +249,20 @@ private:
|
|||
float m_modemRFLevel;
|
||||
float m_modemRXLevel;
|
||||
float m_modemCWIdTXLevel;
|
||||
float m_modemDStarTXLevel;
|
||||
float m_modemDMRTXLevel;
|
||||
float m_modemYSFTXLevel;
|
||||
float m_modemP25TXLevel;
|
||||
float m_modemNXDNTXLevel;
|
||||
float m_modemPOCSAGTXLevel;
|
||||
std::string m_modemRSSIMappingFile;
|
||||
bool m_modemUseCOSAsLockout;
|
||||
bool m_modemTrace;
|
||||
bool m_modemDebug;
|
||||
|
||||
bool m_transparentEnabled;
|
||||
std::string m_transparentRemoteAddress;
|
||||
unsigned int m_transparentRemotePort;
|
||||
unsigned int m_transparentLocalPort;
|
||||
unsigned short m_transparentRemotePort;
|
||||
unsigned short m_transparentLocalPort;
|
||||
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_dmrBeacons;
|
||||
DMR_BEACONS m_dmrBeacons;
|
||||
unsigned int m_dmrBeaconInterval;
|
||||
unsigned int m_dmrBeaconDuration;
|
||||
unsigned int m_dmrId;
|
||||
|
@ -374,46 +278,14 @@ private:
|
|||
unsigned int m_dmrCallHang;
|
||||
unsigned int m_dmrTXHang;
|
||||
unsigned int m_dmrModeHang;
|
||||
bool 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;
|
||||
DMR_OVCM_TYPES m_dmrOVCM;
|
||||
|
||||
bool m_dmrNetworkEnabled;
|
||||
std::string m_dmrNetworkAddress;
|
||||
unsigned int m_dmrNetworkPort;
|
||||
unsigned int m_dmrNetworkLocal;
|
||||
std::string m_dmrNetworkType;
|
||||
std::string m_dmrNetworkRemoteAddress;
|
||||
unsigned short m_dmrNetworkRemotePort;
|
||||
std::string m_dmrNetworkLocalAddress;
|
||||
unsigned short m_dmrNetworkLocalPort;
|
||||
std::string m_dmrNetworkPassword;
|
||||
std::string m_dmrNetworkOptions;
|
||||
bool m_dmrNetworkDebug;
|
||||
|
@ -422,38 +294,7 @@ private:
|
|||
bool m_dmrNetworkSlot2;
|
||||
unsigned int m_dmrNetworkModeHang;
|
||||
|
||||
bool m_fusionNetworkEnabled;
|
||||
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;
|
||||
std::string m_tftSerialPort;
|
||||
unsigned int m_tftSerialBrightness;
|
||||
|
||||
unsigned int m_hd44780Rows;
|
||||
|
@ -483,8 +324,8 @@ private:
|
|||
bool m_oledLogoScreensaver;
|
||||
|
||||
std::string m_lcdprocAddress;
|
||||
unsigned int m_lcdprocPort;
|
||||
unsigned int m_lcdprocLocalPort;
|
||||
unsigned short m_lcdprocPort;
|
||||
unsigned short m_lcdprocLocalPort;
|
||||
bool m_lcdprocDisplayClock;
|
||||
bool m_lcdprocUTC;
|
||||
bool m_lcdprocDimOnIdle;
|
||||
|
@ -492,12 +333,9 @@ private:
|
|||
bool m_lockFileEnabled;
|
||||
std::string m_lockFileName;
|
||||
|
||||
bool m_mobileGPSEnabled;
|
||||
std::string m_mobileGPSAddress;
|
||||
unsigned int m_mobileGPSPort;
|
||||
|
||||
bool m_remoteControlEnabled;
|
||||
unsigned int m_remoteControlPort;
|
||||
std::string m_remoteControlAddress;
|
||||
unsigned short m_remoteControlPort;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,7 +61,7 @@ bool CDMRAccessControl::validateSrcId(unsigned int id)
|
|||
return false;
|
||||
|
||||
unsigned int prefix = id / 10000U;
|
||||
if (prefix == 0U || prefix > 999U)
|
||||
if (prefix == 0U || prefix > 9999U)
|
||||
return false;
|
||||
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -33,7 +34,8 @@ m_bsId(0U),
|
|||
m_srcId(0U),
|
||||
m_dstId(0U),
|
||||
m_dataContent(false),
|
||||
m_CBF(0U)
|
||||
m_CBF(0U),
|
||||
m_OVCM(false)
|
||||
{
|
||||
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_dataContent = false;
|
||||
m_CBF = 0U;
|
||||
m_OVCM = (m_data[2U] & 0x04U) == 0x04U;
|
||||
CUtils::dump(1U, "Unit to Unit Service Request CSBK", m_data, 12U);
|
||||
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_dataContent = false;
|
||||
m_CBF = 0U;
|
||||
m_OVCM = (m_data[2U] & 0x04U) == 0x04U;
|
||||
CUtils::dump(1U, "Unit to Unit Service Answer Response CSBK", m_data, 12U);
|
||||
break;
|
||||
|
||||
|
@ -110,6 +114,39 @@ bool CDMRCSBK::put(const unsigned char* bytes)
|
|||
CUtils::dump(1U, "Negative Acknowledge Response CSBK", m_data, 12U);
|
||||
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:
|
||||
m_GI = false;
|
||||
m_srcId = 0U;
|
||||
|
@ -149,6 +186,23 @@ unsigned char CDMRCSBK::getFID() const
|
|||
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
|
||||
{
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,13 +22,16 @@
|
|||
#include "DMRDefines.h"
|
||||
|
||||
enum CSBKO {
|
||||
CSBKO_NONE = 0x00,
|
||||
CSBKO_UUVREQ = 0x04,
|
||||
CSBKO_UUANSRSP = 0x05,
|
||||
CSBKO_CTCSBK = 0x07,
|
||||
CSBKO_NACKRSP = 0x26,
|
||||
CSBKO_BSDWNACT = 0x38,
|
||||
CSBKO_PRECCSBK = 0x3D
|
||||
CSBKO_NONE = 0x00,
|
||||
CSBKO_UUVREQ = 0x04,
|
||||
CSBKO_UUANSRSP = 0x05,
|
||||
CSBKO_CTCSBK = 0x07,
|
||||
CSBKO_CALL_ALERT = 0x1F,
|
||||
CSBKO_CALL_ALERT_ACK = 0x20,
|
||||
CSBKO_RADIO_CHECK = 0x24,
|
||||
CSBKO_NACKRSP = 0x26,
|
||||
CSBKO_BSDWNACT = 0x38,
|
||||
CSBKO_PRECCSBK = 0x3D
|
||||
};
|
||||
|
||||
class CDMRCSBK
|
||||
|
@ -45,6 +48,10 @@ public:
|
|||
CSBKO getCSBKO() 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
|
||||
unsigned int getBSId() const;
|
||||
|
||||
|
@ -69,6 +76,7 @@ private:
|
|||
unsigned int m_dstId;
|
||||
bool m_dataContent;
|
||||
unsigned char m_CBF;
|
||||
bool m_OVCM;
|
||||
};
|
||||
|
||||
#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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,7 +21,7 @@
|
|||
#include <cassert>
|
||||
#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, bool ovcm) :
|
||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm) :
|
||||
m_colorCode(colorCode),
|
||||
m_modem(modem),
|
||||
m_network(network),
|
||||
|
@ -38,7 +38,14 @@ m_lookup(lookup)
|
|||
// Load black and white lists to DMRAccessControl
|
||||
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
|
||||
|
||||
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, ovcm);
|
||||
//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()
|
||||
|
@ -63,15 +70,17 @@ bool CDMRControl::processWakeup(const unsigned char* data)
|
|||
return false;
|
||||
|
||||
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);
|
||||
|
||||
bool ret = CDMRAccessControl::validateSrcId(srcId);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
class CDMRControl {
|
||||
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, bool ovcm);
|
||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
||||
~CDMRControl();
|
||||
|
||||
bool processWakeup(const unsigned char* data);
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
private:
|
||||
unsigned int m_colorCode;
|
||||
CModem* m_modem;
|
||||
CDMRNetwork* m_network;
|
||||
IDMRNetwork* m_network;
|
||||
CDMRSlot m_slot1;
|
||||
CDMRSlot m_slot2;
|
||||
CDMRLookup* m_lookup;
|
||||
|
|
13
DMRData.cpp
13
DMRData.cpp
|
@ -29,7 +29,6 @@ m_dstId(data.m_dstId),
|
|||
m_flco(data.m_flco),
|
||||
m_dataType(data.m_dataType),
|
||||
m_seqNo(data.m_seqNo),
|
||||
m_missing(data.m_missing),
|
||||
m_n(data.m_n),
|
||||
m_ber(data.m_ber),
|
||||
m_rssi(data.m_rssi)
|
||||
|
@ -46,7 +45,6 @@ m_dstId(0U),
|
|||
m_flco(FLCO_GROUP),
|
||||
m_dataType(0U),
|
||||
m_seqNo(0U),
|
||||
m_missing(false),
|
||||
m_n(0U),
|
||||
m_ber(0U),
|
||||
m_rssi(0U)
|
||||
|
@ -70,7 +68,6 @@ CDMRData& CDMRData::operator=(const CDMRData& data)
|
|||
m_flco = data.m_flco;
|
||||
m_dataType = data.m_dataType;
|
||||
m_seqNo = data.m_seqNo;
|
||||
m_missing = data.m_missing;
|
||||
m_n = data.m_n;
|
||||
m_ber = data.m_ber;
|
||||
m_rssi = data.m_rssi;
|
||||
|
@ -141,16 +138,6 @@ void CDMRData::setSeqNo(unsigned char seqNo)
|
|||
m_seqNo = seqNo;
|
||||
}
|
||||
|
||||
bool CDMRData::isMissing() const
|
||||
{
|
||||
return m_missing;
|
||||
}
|
||||
|
||||
void CDMRData::setMissing(bool missing)
|
||||
{
|
||||
m_missing = missing;
|
||||
}
|
||||
|
||||
unsigned char CDMRData::getN() const
|
||||
{
|
||||
return m_n;
|
||||
|
|
|
@ -45,9 +45,6 @@ public:
|
|||
unsigned char getDataType() const;
|
||||
void setDataType(unsigned char dataType);
|
||||
|
||||
bool isMissing() const;
|
||||
void setMissing(bool missing);
|
||||
|
||||
unsigned char getBER() const;
|
||||
void setBER(unsigned char ber);
|
||||
|
||||
|
@ -65,7 +62,6 @@ private:
|
|||
FLCO m_flco;
|
||||
unsigned char m_dataType;
|
||||
unsigned char m_seqNo;
|
||||
bool m_missing;
|
||||
unsigned char m_n;
|
||||
unsigned char m_ber;
|
||||
unsigned char m_rssi;
|
||||
|
|
|
@ -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
|
||||
* 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[19U] >> 4) & 0x0FU;
|
||||
|
||||
CQR1676::decode(DMREMB);
|
||||
unsigned char code = CQR1676::decode(DMREMB);
|
||||
|
||||
m_colorCode = (DMREMB[0U] >> 4) & 0x0FU;
|
||||
m_PI = (DMREMB[0U] & 0x08U) == 0x08U;
|
||||
m_LCSS = (DMREMB[0U] >> 1) & 0x03U;
|
||||
m_colorCode = (code >> 4) & 0x0FU;
|
||||
m_PI = (code & 0x08U) == 0x08U;
|
||||
m_LCSS = (code >> 1) & 0x03U;
|
||||
}
|
||||
|
||||
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
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2019 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2019,2021,2022 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
2
DMRLC.h
2
DMRLC.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2019 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2019,2021,2022 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
136
DMRLookup.cpp
136
DMRLookup.cpp
|
@ -30,8 +30,8 @@ CThread(),
|
|||
m_filename(filename),
|
||||
m_reloadTime(reloadTime),
|
||||
m_table(),
|
||||
m_mutex(),
|
||||
m_stop(false)
|
||||
m_stop(false),
|
||||
m_reload(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ CDMRLookup::~CDMRLookup()
|
|||
|
||||
bool CDMRLookup::read()
|
||||
{
|
||||
bool ret = load();
|
||||
bool ret = m_table.load(m_filename);
|
||||
|
||||
if (m_reloadTime > 0U)
|
||||
run();
|
||||
|
@ -49,6 +49,14 @@ bool CDMRLookup::read()
|
|||
return ret;
|
||||
}
|
||||
|
||||
void CDMRLookup::reload()
|
||||
{
|
||||
if (m_reloadTime == 0U)
|
||||
m_table.load(m_filename);
|
||||
else
|
||||
m_reload = true;
|
||||
}
|
||||
|
||||
void CDMRLookup::entry()
|
||||
{
|
||||
LogInfo("Started the DMR Id lookup reload thread");
|
||||
|
@ -60,9 +68,10 @@ void CDMRLookup::entry()
|
|||
sleep(1000U);
|
||||
|
||||
timer.clock();
|
||||
if (timer.hasExpired()) {
|
||||
load();
|
||||
if (timer.hasExpired() || m_reload) {
|
||||
m_table.load(m_filename);
|
||||
timer.start();
|
||||
m_reload = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,118 +90,47 @@ void CDMRLookup::stop()
|
|||
wait();
|
||||
}
|
||||
|
||||
std::string CDMRLookup::findWithName(unsigned int id)
|
||||
void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry)
|
||||
{
|
||||
std::string callsign;
|
||||
|
||||
if (id == 0xFFFFFFU)
|
||||
return std::string("ALL");
|
||||
|
||||
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);
|
||||
if (id == 0xFFFFFFFU) {
|
||||
entry->clear();
|
||||
entry->set(keyCALLSIGN, "ALL");
|
||||
return;
|
||||
}
|
||||
|
||||
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 callsign;
|
||||
std::string b;
|
||||
|
||||
|
||||
if (id == 0xFFFFFFU)
|
||||
if (id == 0xFFFFFFFU)
|
||||
return std::string("ALL");
|
||||
|
||||
m_mutex.lock();
|
||||
|
||||
try {
|
||||
b = m_table.at(id);
|
||||
size_t n = b.find(" ");
|
||||
if (n > 0) {
|
||||
callsign = b.substr(0,n);
|
||||
|
||||
} else {
|
||||
LogDebug("b=%s",b.c_str());
|
||||
callsign = b;
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
class CUserDBentry entry;
|
||||
if (m_table.lookup(id, &entry)) {
|
||||
callsign = entry.get(keyCALLSIGN);
|
||||
} else {
|
||||
char text[10U];
|
||||
::sprintf(text, "%u", id);
|
||||
::snprintf(text, sizeof(text), "%u", id);
|
||||
callsign = std::string(text);
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
return callsign;
|
||||
}
|
||||
|
||||
bool CDMRLookup::exists(unsigned int id)
|
||||
{
|
||||
m_mutex.lock();
|
||||
|
||||
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;
|
||||
return m_table.lookup(id, NULL);
|
||||
}
|
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,10 +20,9 @@
|
|||
#define DMRLookup_H
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
#include "UserDB.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class CDMRLookup : public CThread {
|
||||
public:
|
||||
|
@ -32,23 +31,23 @@ public:
|
|||
|
||||
bool read();
|
||||
|
||||
void reload();
|
||||
|
||||
virtual void entry();
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
std::string m_filename;
|
||||
unsigned int m_reloadTime;
|
||||
class CUserDB m_table;
|
||||
bool m_stop;
|
||||
bool m_reload;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
695
DMRNetwork.cpp
695
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,697 +18,6 @@
|
|||
|
||||
#include "DMRNetwork.h"
|
||||
|
||||
#include "StopWatch.h"
|
||||
#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, unsigned int jitter) :
|
||||
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_jitterBuffers(NULL),
|
||||
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_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)
|
||||
IDMRNetwork::~IDMRNetwork()
|
||||
{
|
||||
assert(!address.empty());
|
||||
assert(port > 0U);
|
||||
assert(id > 1000U);
|
||||
assert(!password.empty());
|
||||
assert(jitter > 0U);
|
||||
|
||||
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_jitterBuffers = new CJitterBuffer*[3U];
|
||||
|
||||
m_jitterBuffers[1U] = new CJitterBuffer("DMR Slot 1", 60U, DMR_SLOT_TIME, jitter, 256U, debug);
|
||||
m_jitterBuffers[2U] = new CJitterBuffer("DMR Slot 2", 60U, DMR_SLOT_TIME, jitter, 256U, debug);
|
||||
|
||||
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_jitterBuffers[1U];
|
||||
delete m_jitterBuffers[2U];
|
||||
|
||||
delete[] m_buffer;
|
||||
delete[] m_salt;
|
||||
delete[] m_streamId;
|
||||
delete[] m_id;
|
||||
|
||||
delete[] m_jitterBuffers;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
bool CDMRNetwork::read(CDMRData& data)
|
||||
{
|
||||
if (m_status != RUNNING)
|
||||
return false;
|
||||
|
||||
for (unsigned int slotNo = 1U; slotNo <= 2U; slotNo++) {
|
||||
unsigned int length = 0U;
|
||||
B_STATUS status = BS_NO_DATA;
|
||||
|
||||
status = m_jitterBuffers[slotNo]->getData(m_buffer, length);
|
||||
|
||||
if (status != BS_NO_DATA) {
|
||||
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);
|
||||
|
||||
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);
|
||||
data.setMissing(status == BS_MISSING);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
count = 2U;
|
||||
|
||||
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)
|
||||
{
|
||||
m_jitterBuffers[1U]->clock(ms);
|
||||
m_jitterBuffers[2U]->clock(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);
|
||||
receiveData(m_buffer, length);
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
void CDMRNetwork::reset(unsigned int slotNo)
|
||||
{
|
||||
assert(slotNo == 1U || slotNo == 2U);
|
||||
|
||||
if (slotNo == 1U) {
|
||||
m_jitterBuffers[1U]->reset();
|
||||
m_streamId[0U] = ::rand() + 1U;
|
||||
} else {
|
||||
m_jitterBuffers[2U]->reset();
|
||||
m_streamId[1U] = ::rand() + 1U;
|
||||
}
|
||||
}
|
||||
|
||||
void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
unsigned int slotNo = (data[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||
|
||||
// DMO mode slot disabling
|
||||
if (slotNo == 1U && !m_duplex)
|
||||
return;
|
||||
|
||||
// Individual slot disabling
|
||||
if (slotNo == 1U && !m_slot1)
|
||||
return;
|
||||
if (slotNo == 2U && !m_slot2)
|
||||
return;
|
||||
|
||||
unsigned char dataType = data[15U] & 0x3FU;
|
||||
if (dataType == (0x20U | DT_CSBK) ||
|
||||
dataType == (0x20U | DT_DATA_HEADER) ||
|
||||
dataType == (0x20U | DT_RATE_1_DATA) ||
|
||||
dataType == (0x20U | DT_RATE_34_DATA) ||
|
||||
dataType == (0x20U | DT_RATE_12_DATA)) {
|
||||
// Data & CSBK frames
|
||||
m_jitterBuffers[slotNo]->appendData(data, length);
|
||||
} else {
|
||||
// Voice frames
|
||||
unsigned char seqNo = data[4U];
|
||||
m_jitterBuffers[slotNo]->addData(data, length, seqNo);
|
||||
}
|
||||
}
|
||||
|
||||
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_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 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;
|
||||
}
|
||||
|
|
94
DMRNetwork.h
94
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,104 +19,40 @@
|
|||
#if !defined(DMRNetwork_H)
|
||||
#define DMRNetwork_H
|
||||
|
||||
#include "JitterBuffer.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
#include "DMRData.h"
|
||||
#include "Defines.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
class CDMRNetwork
|
||||
class IDMRNetwork
|
||||
{
|
||||
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, unsigned int jitter);
|
||||
~CDMRNetwork();
|
||||
virtual ~IDMRNetwork() = 0;
|
||||
|
||||
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 reset(unsigned int slotNo);
|
||||
|
||||
void close();
|
||||
virtual void close(bool sayGoodbye) = 0;
|
||||
|
||||
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;
|
||||
CJitterBuffer** m_jitterBuffers;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
void receiveData(const unsigned char* data, unsigned int length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
140
DMRSlot.cpp
140
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -38,15 +38,18 @@ bool CDMRSlot::m_embeddedLCOnly = false;
|
|||
bool CDMRSlot::m_dumpTAData = true;
|
||||
|
||||
CModem* CDMRSlot::m_modem = NULL;
|
||||
CDMRNetwork* CDMRSlot::m_network = NULL;
|
||||
IDMRNetwork* CDMRSlot::m_network = NULL;
|
||||
CDisplay* CDMRSlot::m_display = NULL;
|
||||
bool CDMRSlot::m_duplex = true;
|
||||
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
||||
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
||||
bool CDMRSlot::m_ovcm = true;
|
||||
DMR_OVCM_TYPES CDMRSlot::m_ovcm = DMR_OVCM_OFF;
|
||||
|
||||
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
||||
|
||||
unsigned int CDMRSlot::m_jitterTime = 360U;
|
||||
unsigned int CDMRSlot::m_jitterSlots = 6U;
|
||||
|
||||
unsigned char* CDMRSlot::m_idle = NULL;
|
||||
|
||||
FLCO CDMRSlot::m_flco1;
|
||||
|
@ -93,6 +96,7 @@ m_netN(0U),
|
|||
m_networkWatchdog(1000U, 0U, 1500U),
|
||||
m_rfTimeoutTimer(1000U, timeout),
|
||||
m_netTimeoutTimer(1000U, timeout),
|
||||
m_packetTimer(1000U, 0U, 50U),
|
||||
m_interval(),
|
||||
m_elapsed(),
|
||||
m_rfFrames(0U),
|
||||
|
@ -220,16 +224,22 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||
delete lc;
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
delete lc;
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
lc->setOVCM(m_ovcm);
|
||||
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;
|
||||
|
||||
// The standby LC data
|
||||
|
@ -333,7 +343,6 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
data[0U] = TAG_EOT;
|
||||
data[1U] = 0x00U;
|
||||
|
||||
writeNetworkRF(data, DT_TERMINATOR_WITH_LC);
|
||||
writeNetworkRF(data, DT_TERMINATOR_WITH_LC);
|
||||
|
||||
if (m_duplex) {
|
||||
|
@ -375,11 +384,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
|
||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -433,6 +444,12 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (csbko == CSBKO_BSDWNACT)
|
||||
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();
|
||||
unsigned int srcId = csbk.getSrcId();
|
||||
unsigned int dstId = csbk.getDstId();
|
||||
|
@ -440,11 +457,13 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (srcId != 0U || dstId != 0U) {
|
||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CDMRAccessControl::validateTGId(m_slotNo, gi, dstId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected for using TG %u", m_slotNo, srcId, dstId);
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -482,6 +501,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
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());
|
||||
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:
|
||||
LogWarning("DMR Slot %u, unhandled RF CSBK type - 0x%02X", m_slotNo, csbko);
|
||||
break;
|
||||
|
@ -644,7 +672,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
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");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
|
@ -663,7 +691,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
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");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
|
@ -682,7 +710,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
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");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
|
@ -701,7 +729,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
||||
if (m_rfTalkerId == TALKER_ID_NONE)
|
||||
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");
|
||||
|
||||
if (m_dumpTAData) {
|
||||
|
@ -773,16 +801,22 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||
delete lc;
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
delete lc;
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
return false;
|
||||
}
|
||||
|
||||
lc->setOVCM(m_ovcm);
|
||||
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;
|
||||
|
||||
// The standby LC data
|
||||
|
@ -932,9 +966,6 @@ void CDMRSlot::writeEndRF(bool writeEnd)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_network != NULL)
|
||||
m_network->reset(m_slotNo);
|
||||
|
||||
m_rfTimeoutTimer.stop();
|
||||
m_rfTimeout = false;
|
||||
|
||||
|
@ -985,11 +1016,9 @@ void CDMRSlot::writeEndNet(bool writeEnd)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_network != NULL)
|
||||
m_network->reset(m_slotNo);
|
||||
|
||||
m_networkWatchdog.stop();
|
||||
m_netTimeoutTimer.stop();
|
||||
m_packetTimer.stop();
|
||||
m_netTimeout = false;
|
||||
|
||||
m_netFrames = 0U;
|
||||
|
@ -1043,7 +1072,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),
|
||||
srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
||||
|
||||
lc->setOVCM(m_ovcm);
|
||||
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;
|
||||
|
||||
// The standby LC data
|
||||
|
@ -1085,6 +1118,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_modem->writeDMRAbort(m_slotNo);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < m_jitterSlots; i++)
|
||||
writeQueueNet(m_idle);
|
||||
|
||||
if (m_duplex) {
|
||||
for (unsigned int i = 0U; i < NO_HEADERS_DUPLEX; i++)
|
||||
writeQueueNet(data);
|
||||
|
@ -1098,7 +1134,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE);
|
||||
std::string src = m_lookup->find(srcId);
|
||||
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");
|
||||
|
||||
#if defined(DUMP_DMR)
|
||||
|
@ -1114,7 +1151,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int dstId = lc->getDstId();
|
||||
unsigned int srcId = lc->getSrcId();
|
||||
|
||||
lc->setOVCM(m_ovcm);
|
||||
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_lastFrameValid = false;
|
||||
|
@ -1127,6 +1168,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_modem->writeDMRAbort(m_slotNo);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < m_jitterSlots; i++)
|
||||
writeQueueNet(m_idle);
|
||||
|
||||
// Create a dummy start frame
|
||||
unsigned char start[DMR_FRAME_LENGTH_BYTES + 2U];
|
||||
|
||||
|
@ -1162,11 +1206,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_netState = RS_NET_AUDIO;
|
||||
|
||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE);
|
||||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
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());
|
||||
}
|
||||
|
@ -1297,7 +1342,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int dstId = lc->getDstId();
|
||||
unsigned int srcId = lc->getSrcId();
|
||||
|
||||
lc->setOVCM(m_ovcm);
|
||||
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;
|
||||
|
||||
// The standby LC data
|
||||
|
@ -1315,6 +1364,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_modem->writeDMRAbort(m_slotNo);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < m_jitterSlots; i++)
|
||||
writeQueueNet(m_idle);
|
||||
|
||||
// Create a dummy start frame
|
||||
unsigned char start[DMR_FRAME_LENGTH_BYTES + 2U];
|
||||
|
||||
|
@ -1357,8 +1409,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
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());
|
||||
}
|
||||
|
@ -1393,6 +1447,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
m_netEmbeddedData[m_netEmbeddedWriteN].reset();
|
||||
|
||||
m_packetTimer.start();
|
||||
m_elapsed.start();
|
||||
|
||||
m_netFrames++;
|
||||
|
@ -1539,6 +1594,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
writeQueueNet(data);
|
||||
}
|
||||
|
||||
m_packetTimer.start();
|
||||
m_elapsed.start();
|
||||
|
||||
m_netFrames++;
|
||||
|
@ -1561,6 +1617,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
if (csbko == CSBKO_BSDWNACT)
|
||||
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();
|
||||
unsigned int srcId = csbk.getSrcId();
|
||||
unsigned int dstId = csbk.getDstId();
|
||||
|
@ -1625,6 +1687,15 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
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());
|
||||
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:
|
||||
LogWarning("DMR Slot %u, unhandled network CSBK type - 0x%02X", m_slotNo, csbko);
|
||||
break;
|
||||
|
@ -1777,6 +1848,21 @@ void CDMRSlot::clock()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_netState == RS_NET_AUDIO) {
|
||||
m_packetTimer.clock(ms);
|
||||
|
||||
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
||||
unsigned int elapsed = m_elapsed.elapsed();
|
||||
if (elapsed >= m_jitterTime) {
|
||||
LogDebug("DMR Slot %u, lost audio for %ums filling in", m_slotNo, elapsed);
|
||||
insertSilence(m_jitterSlots);
|
||||
m_elapsed.start();
|
||||
}
|
||||
|
||||
m_packetTimer.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDMRSlot::writeQueueRF(const unsigned char *data)
|
||||
|
@ -1850,7 +1936,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
|
|||
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, bool ovcm)
|
||||
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm)
|
||||
{
|
||||
assert(modem != NULL);
|
||||
assert(display != NULL);
|
||||
|
@ -1870,6 +1956,11 @@ void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData
|
|||
|
||||
m_rssiMapper = rssiMapper;
|
||||
|
||||
m_jitterTime = jitter;
|
||||
|
||||
float jitter_tmp = float(jitter) / 360.0F;
|
||||
m_jitterSlots = (unsigned int) (std::ceil(jitter_tmp) * 6.0F);
|
||||
|
||||
m_idle = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U];
|
||||
::memcpy(m_idle, DMR_IDLE_DATA, DMR_FRAME_LENGTH_BYTES + 2U);
|
||||
|
||||
|
@ -2125,6 +2216,7 @@ void CDMRSlot::enable(bool enabled)
|
|||
|
||||
m_networkWatchdog.stop();
|
||||
m_netTimeoutTimer.stop();
|
||||
m_packetTimer.stop();
|
||||
m_netTimeout = false;
|
||||
|
||||
m_netFrames = 0U;
|
||||
|
|
12
DMRSlot.h
12
DMRSlot.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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
|
||||
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, bool ovcm);
|
||||
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
||||
|
||||
private:
|
||||
unsigned int m_slotNo;
|
||||
|
@ -89,6 +89,7 @@ private:
|
|||
CTimer m_networkWatchdog;
|
||||
CTimer m_rfTimeoutTimer;
|
||||
CTimer m_netTimeoutTimer;
|
||||
CTimer m_packetTimer;
|
||||
CStopWatch m_interval;
|
||||
CStopWatch m_elapsed;
|
||||
unsigned int m_rfFrames;
|
||||
|
@ -117,15 +118,18 @@ private:
|
|||
static bool m_dumpTAData;
|
||||
|
||||
static CModem* m_modem;
|
||||
static CDMRNetwork* m_network;
|
||||
static IDMRNetwork* m_network;
|
||||
static CDisplay* m_display;
|
||||
static bool m_duplex;
|
||||
static CDMRLookup* m_lookup;
|
||||
static unsigned int m_hangCount;
|
||||
static bool m_ovcm;
|
||||
static DMR_OVCM_TYPES m_ovcm;
|
||||
|
||||
static CRSSIInterpolator* m_rssiMapper;
|
||||
|
||||
static unsigned int m_jitterTime;
|
||||
static unsigned int m_jitterSlots;
|
||||
|
||||
static unsigned char* m_idle;
|
||||
|
||||
static FLCO m_flco1;
|
||||
|
|
|
@ -72,7 +72,7 @@ bool CDMRTA::decodeTA()
|
|||
|
||||
unsigned int TAformat = (talkerAlias[0] >> 6U) & 0x03U;
|
||||
unsigned int TAsize = (talkerAlias[0] >> 1U) & 0x1FU;
|
||||
::strncpy(m_TA, "(could not decode)", sizeof(m_TA));
|
||||
::strcpy(m_TA, "(could not decode)");
|
||||
|
||||
switch (TAformat) {
|
||||
case 0U: // 7 bit
|
||||
|
@ -96,7 +96,7 @@ bool CDMRTA::decodeTA()
|
|||
|
||||
case 1U: // ISO 8 bit
|
||||
case 2U: // UTF8
|
||||
::strncpy(m_TA, (char*)talkerAlias + 1U, sizeof(m_TA));
|
||||
::memcpy(m_TA, talkerAlias + 1U, sizeof(m_TA));
|
||||
break;
|
||||
|
||||
case 3U: // UTF16 poor man's conversion
|
||||
|
@ -117,9 +117,9 @@ bool CDMRTA::decodeTA()
|
|||
|
||||
if (TAlen > TAsize) {
|
||||
if (TAlen < 29U)
|
||||
strcat(m_TA," ?");
|
||||
strcat(m_TA, " ?");
|
||||
else
|
||||
strcpy(m_TA + 28U," ?");
|
||||
strcpy(m_TA + 28U, " ?");
|
||||
}
|
||||
|
||||
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
|
1266
DStarControl.cpp
1266
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
|
30
Defines.h
30
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,12 +20,8 @@
|
|||
#define Defines_H
|
||||
|
||||
const unsigned char MODE_IDLE = 0U;
|
||||
const unsigned char MODE_DSTAR = 1U;
|
||||
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_LOCKOUT = 99U;
|
||||
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_EOT = 0x03U;
|
||||
|
||||
const unsigned int DSTAR_MODEM_DATA_LEN = 220U;
|
||||
|
||||
enum HW_TYPE {
|
||||
HWT_MMDVM,
|
||||
HWT_DVMEGA,
|
||||
|
@ -46,6 +44,8 @@ enum HW_TYPE {
|
|||
HWT_NANO_DV,
|
||||
HWT_D2RG_MMDVM_HS,
|
||||
HWT_MMDVM_HS,
|
||||
HWT_OPENGD77_HS,
|
||||
HWT_SKYBRIDGE,
|
||||
HWT_UNKNOWN
|
||||
};
|
||||
|
||||
|
@ -53,6 +53,7 @@ enum RPT_RF_STATE {
|
|||
RS_RF_LISTENING,
|
||||
RS_RF_LATE_ENTRY,
|
||||
RS_RF_AUDIO,
|
||||
RS_RF_DATA_AUDIO,
|
||||
RS_RF_DATA,
|
||||
RS_RF_REJECTED,
|
||||
RS_RF_INVALID
|
||||
|
@ -61,13 +62,22 @@ enum RPT_RF_STATE {
|
|||
enum RPT_NET_STATE {
|
||||
RS_NET_IDLE,
|
||||
RS_NET_AUDIO,
|
||||
RS_NET_DATA_AUDIO,
|
||||
RS_NET_DATA
|
||||
};
|
||||
|
||||
enum B_STATUS {
|
||||
BS_NO_DATA,
|
||||
BS_DATA,
|
||||
BS_MISSING
|
||||
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
|
||||
|
|
290
Display.cpp
290
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,16 +18,15 @@
|
|||
|
||||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
#include "SerialController.h"
|
||||
#include "UARTController.h"
|
||||
#include "ModemSerialPort.h"
|
||||
#include "NullDisplay.h"
|
||||
#include "TFTSerial.h"
|
||||
#include "TFTSurenoo.h"
|
||||
#include "LCDproc.h"
|
||||
#include "Nextion.h"
|
||||
#include "CASTInfo.h"
|
||||
#include "Conf.h"
|
||||
#include "Modem.h"
|
||||
#include "UMP.h"
|
||||
#include "Log.h"
|
||||
|
||||
#if defined(HD44780)
|
||||
|
@ -100,42 +99,6 @@ void CDisplay::setQuit()
|
|||
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)
|
||||
{
|
||||
assert(type != NULL);
|
||||
|
@ -150,6 +113,29 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group,
|
|||
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)
|
||||
{
|
||||
if (rssi != 0U)
|
||||
|
@ -166,6 +152,7 @@ void CDisplay::writeDMRBER(unsigned int slotNo, float ber)
|
|||
{
|
||||
writeDMRBERInt(slotNo, ber);
|
||||
}
|
||||
|
||||
void CDisplay::clearDMR(unsigned int slotNo)
|
||||
{
|
||||
if (slotNo == 1U) {
|
||||
|
@ -187,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()
|
||||
{
|
||||
m_timer1.start();
|
||||
|
@ -320,36 +187,11 @@ void CDisplay::clock(unsigned int ms)
|
|||
m_timer1.clock(ms);
|
||||
if (m_timer1.isRunning() && m_timer1.hasExpired()) {
|
||||
switch (m_mode1) {
|
||||
case MODE_DSTAR:
|
||||
clearDStarInt();
|
||||
m_mode1 = MODE_IDLE;
|
||||
m_timer1.stop();
|
||||
break;
|
||||
case MODE_DMR:
|
||||
clearDMRInt(1U);
|
||||
m_mode1 = MODE_IDLE;
|
||||
m_timer1.stop();
|
||||
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:
|
||||
clearCWInt();
|
||||
m_mode1 = MODE_IDLE;
|
||||
|
@ -377,12 +219,18 @@ void CDisplay::clockInt(unsigned int ms)
|
|||
{
|
||||
}
|
||||
|
||||
void CDisplay::writeDStarRSSIInt(unsigned char rssi)
|
||||
{
|
||||
}
|
||||
|
||||
void CDisplay::writeDStarBERInt(float ber)
|
||||
int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type)
|
||||
{
|
||||
/*
|
||||
* 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)
|
||||
|
@ -397,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 */
|
||||
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();
|
||||
|
||||
LogInfo("Display Parameters");
|
||||
LogInfo(" Type: %s", type.c_str());
|
||||
|
||||
if (type == "TFT Serial") {
|
||||
if (type == "TFT Surenoo") {
|
||||
std::string port = conf.getTFTSerialPort();
|
||||
unsigned int brightness = conf.getTFTSerialBrightness();
|
||||
|
||||
|
@ -441,11 +266,11 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
|||
|
||||
ISerialPort* serial = NULL;
|
||||
if (port == "modem")
|
||||
serial = new CModemSerialPort(modem);
|
||||
serial = new IModemSerialPort(modem);
|
||||
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") {
|
||||
std::string port = conf.getNextionPort();
|
||||
unsigned int brightness = conf.getNextionBrightness();
|
||||
|
@ -484,23 +309,16 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
|||
}
|
||||
|
||||
if (port == "modem") {
|
||||
ISerialPort* serial = new CModemSerialPort(modem);
|
||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, conf.getLocation());
|
||||
} 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;
|
||||
}
|
||||
ISerialPort* serial = new IModemSerialPort(modem);
|
||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
||||
} else {
|
||||
SERIAL_SPEED baudrate = SERIAL_9600;
|
||||
if (screenLayout==4U)
|
||||
baudrate = SERIAL_115200;
|
||||
unsigned int baudrate = 9600U;
|
||||
if (screenLayout == 4U)
|
||||
baudrate = 115200U;
|
||||
|
||||
LogInfo(" Display baudrate: %u ",baudrate);
|
||||
ISerialPort* serial = new CSerialController(port, baudrate);
|
||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, conf.getLocation());
|
||||
LogInfo(" Display baudrate: %u ", baudrate);
|
||||
ISerialPort* serial = new CUARTController(port, baudrate);
|
||||
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
|
||||
}
|
||||
} else if (type == "LCDproc") {
|
||||
std::string address = conf.getLCDprocAddress();
|
||||
|
@ -571,7 +389,7 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem)
|
|||
bool rotate = conf.getOLEDRotate();
|
||||
bool logosaver = conf.getOLEDLogoScreensaver();
|
||||
|
||||
display = new COLED(type, brightness, invert, scroll, rotate, logosaver, conf.getDMRNetworkSlot1(), conf.getDMRNetworkSlot2());
|
||||
display = new COLED(type, brightness, invert, scroll, rotate, logosaver, conf.getDuplex());
|
||||
#endif
|
||||
} else if (type == "CAST") {
|
||||
display = new CCASTInfo(modem);
|
||||
|
|
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,6 +20,8 @@
|
|||
#define DISPLAY_H
|
||||
|
||||
#include "Timer.h"
|
||||
#include "UserDBentry.h"
|
||||
#include "Modem.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -27,7 +29,6 @@
|
|||
|
||||
class CConf;
|
||||
class CModem;
|
||||
class CUMP;
|
||||
|
||||
class CDisplay
|
||||
{
|
||||
|
@ -41,43 +42,22 @@ public:
|
|||
void setLockout();
|
||||
void setError(const char* text);
|
||||
void setQuit();
|
||||
|
||||
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 setFM();
|
||||
|
||||
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 writeDMRBER(unsigned int slotNo, float ber);
|
||||
void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||
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();
|
||||
|
||||
virtual void close() = 0;
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
static CDisplay* createDisplay(const CConf& conf, CUMP* ump, CModem* modem);
|
||||
static CDisplay* createDisplay(const CConf& conf, CModem* modem);
|
||||
|
||||
protected:
|
||||
virtual void setIdleInt() = 0;
|
||||
|
@ -85,35 +65,13 @@ protected:
|
|||
virtual void setErrorInt(const char* text) = 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 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 writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
|
||||
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
|
||||
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 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.
|
||||
*/
|
||||
|
||||
#include "Golay24128.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
@ -1089,20 +1090,25 @@ unsigned int CGolay24128::decode23127(unsigned int code)
|
|||
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];
|
||||
code <<= 8;
|
||||
code |= bytes[1U];
|
||||
code <<= 8;
|
||||
code |= bytes[2U];
|
||||
unsigned int code = (in[0U] << 16) | (in[1U] << 8) | (in[2U] << 0);
|
||||
|
||||
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
|
||||
* 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 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
|
||||
|
|
328
HD44780.cpp
328
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
|
||||
* 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 P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||
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) :
|
||||
CDisplay(),
|
||||
|
@ -211,12 +212,12 @@ void CHD44780::adafruitLCDSetup()
|
|||
::pinMode(AF_RW, OUTPUT);
|
||||
::digitalWrite(AF_RW, LOW);
|
||||
|
||||
m_rb = AF_RS;
|
||||
m_strb = AF_E;
|
||||
m_d0 = AF_D0;
|
||||
m_d1 = AF_D1;
|
||||
m_d2 = AF_D2;
|
||||
m_d3 = AF_D3;
|
||||
m_rb = AF_RS;
|
||||
m_strb = AF_E;
|
||||
m_d0 = AF_D0;
|
||||
m_d1 = AF_D1;
|
||||
m_d2 = AF_D2;
|
||||
m_d3 = AF_D3;
|
||||
}
|
||||
|
||||
void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour)
|
||||
|
@ -275,12 +276,12 @@ void CHD44780::pcf8574LCDSetup()
|
|||
::pcf8574Setup(AF_BASE, m_i2cAddress);
|
||||
|
||||
// Turn on backlight
|
||||
::pinMode (AF_BL, OUTPUT);
|
||||
::digitalWrite (AF_BL, 1);
|
||||
::pinMode(AF_BL, OUTPUT);
|
||||
::digitalWrite(AF_BL, 1);
|
||||
|
||||
// Set LCD to write mode.
|
||||
::pinMode (AF_RW, OUTPUT);
|
||||
::digitalWrite (AF_RW, 0);
|
||||
::pinMode(AF_RW, OUTPUT);
|
||||
::digitalWrite(AF_RW, 0);
|
||||
|
||||
m_rb = AF_RS;
|
||||
m_strb = AF_E;
|
||||
|
@ -297,7 +298,7 @@ void CHD44780::setIdleInt()
|
|||
::lcdClear(m_fd);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_WHITE);
|
||||
adafruitLCDColour(AC_WHITE);
|
||||
#endif
|
||||
|
||||
if (m_pwm) {
|
||||
|
@ -327,7 +328,7 @@ void CHD44780::setErrorInt(const char* text)
|
|||
assert(text != NULL);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_RED);
|
||||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
|
@ -399,6 +400,37 @@ void CHD44780::setQuitInt()
|
|||
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)
|
||||
{
|
||||
assert(my1 != NULL);
|
||||
|
@ -408,7 +440,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
|||
assert(reflector != NULL);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_RED);
|
||||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
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);
|
||||
::lcdPosition(m_fd, m_cols - 1, (m_rows / 2) - 1);
|
||||
|
||||
if (strcmp(type, "R") == 0) {
|
||||
if (strcmp(type, "R") == 0)
|
||||
::lcdPutchar(m_fd, 2);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 3);
|
||||
}
|
||||
|
||||
::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);
|
||||
|
||||
m_dmr = false;
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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);
|
||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||
}
|
||||
}
|
||||
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= DSTAR_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= DSTAR_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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);
|
||||
::lcdPuts(m_fd, " ");
|
||||
|
||||
if (group) {
|
||||
if (group)
|
||||
::lcdPutchar(m_fd, 5);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 4);
|
||||
}
|
||||
|
||||
if (strcmp(type, "R") == 0) {
|
||||
if (strcmp(type, "R") == 0)
|
||||
::lcdPutchar(m_fd, 2);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 3);
|
||||
}
|
||||
} else {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 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);
|
||||
else
|
||||
::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));
|
||||
::lcdPuts(m_fd, " ");
|
||||
|
||||
if (group) {
|
||||
if (group)
|
||||
::lcdPutchar(m_fd, 5);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 4);
|
||||
}
|
||||
|
||||
if (strcmp(type, "R") == 0) {
|
||||
if (strcmp(type, "R") == 0)
|
||||
::lcdPutchar(m_fd, 2);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 3);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2) - 1);
|
||||
|
||||
if (strcmp(type, "R") == 0) {
|
||||
if (strcmp(type, "R") == 0)
|
||||
::lcdPutchar(m_fd, 2);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 3);
|
||||
}
|
||||
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPutchar(m_fd, 1);
|
||||
|
@ -628,15 +655,15 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2));
|
||||
|
||||
if (group) {
|
||||
if (group)
|
||||
::lcdPutchar(m_fd, 5);
|
||||
} else {
|
||||
else
|
||||
::lcdPutchar(m_fd, 4);
|
||||
}
|
||||
}
|
||||
|
||||
m_dmr = true;
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount2 = 0U;
|
||||
m_rssiCount2 = 0U;
|
||||
}
|
||||
|
||||
void CHD44780::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
||||
|
@ -657,9 +684,9 @@ void CHD44780::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
|
|||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||
}
|
||||
|
||||
m_rssiCount2++;
|
||||
if (m_rssiCount2 >= DMR_RSSI_COUNT)
|
||||
m_rssiCount2 = 0U;
|
||||
m_rssiCount2++;
|
||||
if (m_rssiCount2 >= DMR_RSSI_COUNT)
|
||||
m_rssiCount2 = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -691,7 +718,6 @@ void CHD44780::clearDMRInt(unsigned int slotNo)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (m_rows > 2U) {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 2);
|
||||
::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(dest != NULL);
|
||||
|
@ -714,7 +740,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char*
|
|||
assert(origin != NULL);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_RED);
|
||||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
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");
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 20U) {
|
||||
char m_buffer1[20U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 2 && m_cols == 40U) {
|
||||
char m_buffer1[40U];
|
||||
::sprintf(m_buffer1, "%.10s > %.10s", source, dest);
|
||||
::sprintf(m_buffer1, "%.10s > DG-ID %u", source, dgid);
|
||||
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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);
|
||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||
}
|
||||
}
|
||||
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
void CHD44780::clearFusionInt()
|
||||
|
@ -782,7 +804,6 @@ void CHD44780::clearFusionInt()
|
|||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_PURPLE);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
|
||||
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);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_RED);
|
||||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
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");
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 20U) {
|
||||
char m_buffer1[20U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 2 && m_cols == 40U) {
|
||||
char m_buffer1[40U];
|
||||
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
||||
|
||||
::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_rssiCount1 = 0U;
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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);
|
||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||
}
|
||||
}
|
||||
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= P25_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= P25_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
void CHD44780::clearP25Int()
|
||||
|
@ -922,7 +939,7 @@ void CHD44780::writeNXDNInt(const char* source, bool group, unsigned int dest, c
|
|||
assert(type != NULL);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_RED);
|
||||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
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");
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 16U) {
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 20U) {
|
||||
char m_buffer1[20U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::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);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 2 && m_cols == 40U) {
|
||||
char m_buffer1[40U];
|
||||
::sprintf(m_buffer1, "%.10s > %s%u", source, group ? "TG" : "", dest);
|
||||
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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);
|
||||
::lcdPrintf(m_fd, "-%3udBm", rssi);
|
||||
}
|
||||
}
|
||||
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= NXDN_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= NXDN_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
::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()
|
||||
{
|
||||
::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()
|
||||
|
@ -1050,31 +1161,30 @@ void CHD44780::clockInt(unsigned int ms)
|
|||
|
||||
// Idle clock display
|
||||
if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) {
|
||||
time_t currentTime;
|
||||
struct tm *Time;
|
||||
time(¤tTime);
|
||||
time_t currentTime;
|
||||
struct tm *Time;
|
||||
::time(¤tTime);
|
||||
|
||||
if (m_utc) {
|
||||
Time = gmtime(¤tTime);
|
||||
} else {
|
||||
Time = localtime(¤tTime);
|
||||
}
|
||||
if (m_utc)
|
||||
Time = ::gmtime(¤tTime);
|
||||
else
|
||||
Time = ::localtime(¤tTime);
|
||||
|
||||
setlocale(LC_TIME,"");
|
||||
strftime(m_buffer1, 128, "%X", Time); // Time
|
||||
strftime(m_buffer2, 128, "%x", Time); // Date
|
||||
setlocale(LC_TIME,"");
|
||||
::strftime(m_buffer1, 128, "%X", Time); // Time
|
||||
::strftime(m_buffer2, 128, "%x", Time); // Date
|
||||
|
||||
if (m_cols == 16U && m_rows == 2U) {
|
||||
::lcdPosition(m_fd, m_cols - 10, 1);
|
||||
::lcdPrintf(m_fd, "%s%.*s", strlen(m_buffer1) > 8 ? "" : " ", 10, m_buffer1);
|
||||
} else {
|
||||
::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);
|
||||
::lcdPosition(m_fd, (m_cols - strlen(m_buffer2)) / 2, m_rows == 2 ? 0 : 1);
|
||||
::lcdPrintf(m_fd, "%s", m_buffer2);
|
||||
}
|
||||
if (m_cols == 16U && m_rows == 2U) {
|
||||
::lcdPosition(m_fd, m_cols - 10, 1);
|
||||
::lcdPrintf(m_fd, "%s%.*s", strlen(m_buffer1) > 8 ? "" : " ", 10, m_buffer1);
|
||||
} else {
|
||||
::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);
|
||||
::lcdPosition(m_fd, (m_cols - strlen(m_buffer2)) / 2, m_rows == 2 ? 0 : 1);
|
||||
::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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -89,46 +89,51 @@ enum ADAFRUIT_COLOUR {
|
|||
class CHD44780 : public CDisplay
|
||||
{
|
||||
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);
|
||||
virtual ~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);
|
||||
virtual ~CHD44780();
|
||||
|
||||
virtual bool open();
|
||||
virtual bool open();
|
||||
|
||||
virtual void close();
|
||||
virtual void close();
|
||||
|
||||
protected:
|
||||
virtual void setIdleInt();
|
||||
virtual void setErrorInt(const char* text);
|
||||
virtual void setLockoutInt();
|
||||
virtual void setQuitInt();
|
||||
virtual void setIdleInt();
|
||||
virtual void setErrorInt(const char* text);
|
||||
virtual void setLockoutInt();
|
||||
virtual void setQuitInt();
|
||||
virtual void setFMInt();
|
||||
|
||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
||||
virtual void writeDStarRSSIInt(unsigned char rssi);
|
||||
virtual void clearDStarInt();
|
||||
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 clearDStarInt();
|
||||
|
||||
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 clearDMRInt(unsigned int slotNo);
|
||||
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 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 clearFusionInt();
|
||||
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 clearFusionInt();
|
||||
|
||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual void writeP25RSSIInt(unsigned char rssi);
|
||||
virtual void clearP25Int();
|
||||
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual void writeP25RSSIInt(unsigned char rssi);
|
||||
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 clearNXDNInt();
|
||||
virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
||||
virtual void clearNXDNInt();
|
||||
|
||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||
virtual void clearPOCSAGInt();
|
||||
virtual void writeM17Int(const char* source, const char* dest, const char* type);
|
||||
virtual void writeM17RSSIInt(unsigned char rssi);
|
||||
virtual void clearM17Int();
|
||||
|
||||
virtual void writeCWInt();
|
||||
virtual void clearCWInt();
|
||||
virtual void writePOCSAGInt(uint32_t ric, const std::string& message);
|
||||
virtual void clearPOCSAGInt();
|
||||
|
||||
virtual void clockInt(unsigned int ms);
|
||||
virtual void writeCWInt();
|
||||
virtual void clearCWInt();
|
||||
|
||||
virtual void clockInt(unsigned int ms);
|
||||
|
||||
private:
|
||||
unsigned int m_rows;
|
||||
|
@ -161,12 +166,12 @@ private:
|
|||
*/
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
void adafruitLCDSetup();
|
||||
void adafruitLCDColour(ADAFRUIT_COLOUR colour);
|
||||
void adafruitLCDSetup();
|
||||
void adafruitLCDColour(ADAFRUIT_COLOUR colour);
|
||||
#endif
|
||||
|
||||
#ifdef PCF8574_DISPLAY
|
||||
void pcf8574LCDSetup();
|
||||
void pcf8574LCDSetup();
|
||||
#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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include "I2CController.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
@ -24,52 +26,18 @@
|
|||
#include <cassert>
|
||||
|
||||
#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/stat.h>
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#if defined(__linux__)
|
||||
#include <linux/i2c-dev.h>
|
||||
#endif
|
||||
|
||||
CI2CController::CI2CController(const std::string& device, SERIAL_SPEED speed, unsigned int address, bool assertRTS) :
|
||||
CSerialController(device, speed, assertRTS),
|
||||
m_address(address)
|
||||
CI2CController::CI2CController(const std::string& device, unsigned int address) :
|
||||
m_device(device),
|
||||
m_address(address),
|
||||
m_fd(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -81,7 +49,6 @@ bool CI2CController::open()
|
|||
{
|
||||
assert(m_fd == -1);
|
||||
|
||||
#if defined(__linux__)
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR);
|
||||
if (m_fd < 0) {
|
||||
LogError("Cannot open device - %s", m_device.c_str());
|
||||
|
@ -89,19 +56,16 @@ bool CI2CController::open()
|
|||
}
|
||||
|
||||
if (::ioctl(m_fd, I2C_TENBIT, 0) < 0) {
|
||||
LogError("CI2C: failed to set 7bitaddress");
|
||||
LogError("I2C: failed to set 7bitaddress");
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#warning "I2C controller supports Linux only"
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -117,7 +81,6 @@ int CI2CController::read(unsigned char* buffer, unsigned int length)
|
|||
unsigned int offset = 0U;
|
||||
|
||||
while (offset < length) {
|
||||
#if defined(__linux__)
|
||||
ssize_t n = ::read(m_fd, buffer + offset, 1U);
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
|
@ -128,7 +91,6 @@ int CI2CController::read(unsigned char* buffer, unsigned int length)
|
|||
|
||||
if (n > 0)
|
||||
offset += n;
|
||||
#endif
|
||||
}
|
||||
|
||||
return length;
|
||||
|
@ -144,10 +106,7 @@ int CI2CController::write(const unsigned char* buffer, unsigned int length)
|
|||
|
||||
unsigned int ptr = 0U;
|
||||
while (ptr < length) {
|
||||
ssize_t n = 0U;
|
||||
#if defined(__linux__)
|
||||
n = ::write(m_fd, buffer + ptr, 1U);
|
||||
#endif
|
||||
ssize_t n = ::write(m_fd, buffer + ptr, 1U);
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
LogError("Error returned from write(), errno=%d", errno);
|
||||
|
@ -162,4 +121,12 @@ int CI2CController::write(const unsigned char* buffer, unsigned int length)
|
|||
return length;
|
||||
}
|
||||
|
||||
void CI2CController::close()
|
||||
{
|
||||
assert(m_fd != -1);
|
||||
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
|
||||
#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
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -20,11 +20,16 @@
|
|||
#ifndef 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:
|
||||
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 bool open();
|
||||
|
@ -33,8 +38,14 @@ public:
|
|||
|
||||
virtual int write(const unsigned char* buffer, unsigned int length);
|
||||
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
std::string m_device;
|
||||
unsigned int m_address;
|
||||
int m_fd;
|
||||
};
|
||||
|
||||
#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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(YSFConvolution_H)
|
||||
#define YSFConvolution_H
|
||||
#if !defined(IIRDIRECTFORM1FILTER_H)
|
||||
#define IIRDIRECTFORM1FILTER_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CYSFConvolution {
|
||||
class CIIRDirectForm1Filter
|
||||
{
|
||||
public:
|
||||
CYSFConvolution();
|
||||
~CYSFConvolution();
|
||||
|
||||
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;
|
||||
CIIRDirectForm1Filter(float b0, float b1, float b2, float, float a1, float a2, float additionalGaindB);
|
||||
float filter(float sample);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
uint16_t* m_metrics1;
|
||||
uint16_t* m_metrics2;
|
||||
uint16_t* m_oldMetrics;
|
||||
uint16_t* m_newMetrics;
|
||||
uint64_t* m_decisions;
|
||||
uint64_t* m_dp;
|
||||
// delay line
|
||||
float m_x2; // x[n-2]
|
||||
float m_y2; // y[n-2]
|
||||
float m_x1; // x[n-1]
|
||||
float m_y1; // y[n-1]
|
||||
|
||||
// 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 |
236
JitterBuffer.cpp
236
JitterBuffer.cpp
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 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 "JitterBuffer.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
CJitterBuffer::CJitterBuffer(const std::string& name, unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug) :
|
||||
m_name(name),
|
||||
m_blockSize(blockSize),
|
||||
m_blockTime(blockTime),
|
||||
m_topSequenceNumber(topSequenceNumber),
|
||||
m_debug(debug),
|
||||
m_blockCount(0U),
|
||||
m_timer(1000U, 0U, jitterTime),
|
||||
m_stopWatch(),
|
||||
m_running(false),
|
||||
m_buffer(NULL),
|
||||
m_headSequenceNumber(0U),
|
||||
m_appendSequenceNumber(0U),
|
||||
m_lastData(NULL),
|
||||
m_lastDataLength(0U)
|
||||
{
|
||||
assert(blockSize > 0U);
|
||||
assert(blockTime > 0U);
|
||||
assert(jitterTime > 0U);
|
||||
assert(topSequenceNumber > 0U);
|
||||
|
||||
m_blockCount = topSequenceNumber / 2U;
|
||||
|
||||
m_buffer = new JitterEntry[m_blockCount];
|
||||
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
m_buffer[i].m_data = new unsigned char[m_blockSize];
|
||||
|
||||
m_lastData = new unsigned char[m_blockSize];
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
CJitterBuffer::~CJitterBuffer()
|
||||
{
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
delete[] m_buffer[i].m_data;
|
||||
|
||||
delete[] m_buffer;
|
||||
delete[] m_lastData;
|
||||
}
|
||||
|
||||
bool CJitterBuffer::addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
assert(length <= m_blockSize);
|
||||
|
||||
unsigned int headSequenceNumber = m_headSequenceNumber % m_topSequenceNumber;
|
||||
unsigned int tailSequenceNumber = (m_headSequenceNumber + m_blockCount) % m_topSequenceNumber;
|
||||
|
||||
// Is the data out of sequence?
|
||||
if (headSequenceNumber < tailSequenceNumber) {
|
||||
if (sequenceNumber < headSequenceNumber || sequenceNumber >= tailSequenceNumber) {
|
||||
LogDebug("%s, JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (sequenceNumber >= tailSequenceNumber && sequenceNumber < headSequenceNumber) {
|
||||
LogDebug("%s, JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int number;
|
||||
if (sequenceNumber >= headSequenceNumber)
|
||||
number = sequenceNumber - headSequenceNumber;
|
||||
else
|
||||
number = (sequenceNumber + m_blockCount) - headSequenceNumber;;
|
||||
|
||||
unsigned int index = (m_headSequenceNumber + number) % m_blockCount;
|
||||
|
||||
// Do we already have the data?
|
||||
if (m_buffer[index].m_length > 0U) {
|
||||
LogDebug("%s, JitterBuffer: rejecting duplicate frame with seqNo=%u, pos=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), sequenceNumber, index, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_debug)
|
||||
LogDebug("%s, JitterBuffer: adding frame with seqNo=%u, pos=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), sequenceNumber, index, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
|
||||
::memcpy(m_buffer[index].m_data, data, length);
|
||||
m_buffer[index].m_length = length;
|
||||
|
||||
if (!m_timer.isRunning()) {
|
||||
LogDebug("%s, JitterBuffer: starting the timer", m_name.c_str());
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CJitterBuffer::appendData(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
assert(length <= m_blockSize);
|
||||
|
||||
unsigned int headSequenceNumber = m_headSequenceNumber % m_topSequenceNumber;
|
||||
unsigned int tailSequenceNumber = (m_headSequenceNumber + m_blockCount) % m_topSequenceNumber;
|
||||
|
||||
// Is the data out of sequence?
|
||||
if (headSequenceNumber < tailSequenceNumber) {
|
||||
if (m_appendSequenceNumber < headSequenceNumber || m_appendSequenceNumber >= tailSequenceNumber) {
|
||||
LogDebug("%s, JitterBuffer: rejecting append frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (m_appendSequenceNumber >= tailSequenceNumber && m_appendSequenceNumber < headSequenceNumber) {
|
||||
LogDebug("%s, JitterBuffer: rejecting append frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int number;
|
||||
if (m_appendSequenceNumber >= headSequenceNumber)
|
||||
number = m_appendSequenceNumber - headSequenceNumber;
|
||||
else
|
||||
number = (m_appendSequenceNumber + m_blockCount) - headSequenceNumber;;
|
||||
|
||||
unsigned int index = (m_headSequenceNumber + number) % m_blockCount;
|
||||
|
||||
if (m_debug)
|
||||
LogDebug("%s, JitterBuffer: appending frame with seqNo=%u, pos=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, index, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber);
|
||||
|
||||
::memcpy(m_buffer[index].m_data, data, length);
|
||||
m_buffer[index].m_length = length;
|
||||
|
||||
if (!m_timer.isRunning()) {
|
||||
LogDebug("%s, JitterBuffer: starting the timer from append", m_name.c_str());
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
m_appendSequenceNumber++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
B_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (!m_running)
|
||||
return BS_NO_DATA;
|
||||
|
||||
unsigned int sequenceNumber = m_stopWatch.elapsed() / m_blockTime + 2U;
|
||||
if (m_headSequenceNumber > sequenceNumber)
|
||||
return BS_NO_DATA;
|
||||
|
||||
unsigned int head = m_headSequenceNumber % m_blockCount;
|
||||
|
||||
m_headSequenceNumber++;
|
||||
|
||||
if (m_buffer[head].m_length > 0U) {
|
||||
if (m_debug)
|
||||
LogDebug("%s, JitterBuffer: returning data, elapsed=%ums, raw=%u, head=%u", m_name.c_str(), m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head);
|
||||
|
||||
::memcpy(data, m_buffer[head].m_data, m_buffer[head].m_length);
|
||||
length = m_buffer[head].m_length;
|
||||
|
||||
// Save this data in case no more data is available next time
|
||||
::memcpy(m_lastData, m_buffer[head].m_data, m_buffer[head].m_length);
|
||||
m_lastDataLength = m_buffer[head].m_length;
|
||||
|
||||
m_buffer[head].m_length = 0U;
|
||||
|
||||
return BS_DATA;
|
||||
}
|
||||
|
||||
m_buffer[head].m_length = 0U;
|
||||
|
||||
LogDebug("%s, JitterBuffer: no data available, elapsed=%ums, raw=%u, head=%u", m_name.c_str(), m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head);
|
||||
|
||||
// Return the last data frame if we have it
|
||||
if (m_lastDataLength > 0U) {
|
||||
LogDebug("%s, JitterBuffer: returning the last received frame", m_name.c_str());
|
||||
::memcpy(data, m_lastData, m_lastDataLength);
|
||||
length = m_lastDataLength;
|
||||
|
||||
return BS_MISSING;
|
||||
}
|
||||
|
||||
return BS_NO_DATA;
|
||||
}
|
||||
|
||||
void CJitterBuffer::reset()
|
||||
{
|
||||
for (unsigned int i = 0U; i < m_blockCount; i++)
|
||||
m_buffer[i].m_length = 0U;
|
||||
|
||||
m_headSequenceNumber = 0U;
|
||||
m_appendSequenceNumber = 0U;
|
||||
|
||||
m_lastDataLength = 0U;
|
||||
|
||||
m_timer.stop();
|
||||
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void CJitterBuffer::clock(unsigned int ms)
|
||||
{
|
||||
m_timer.clock(ms);
|
||||
if (m_timer.isRunning() && m_timer.hasExpired()) {
|
||||
if (!m_running) {
|
||||
m_stopWatch.start();
|
||||
m_running = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 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(JITTERBUFFER_H)
|
||||
#define JITTERBUFFER_H
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "Defines.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class CJitterBuffer {
|
||||
public:
|
||||
CJitterBuffer(const std::string& name, unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug);
|
||||
~CJitterBuffer();
|
||||
|
||||
bool addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber);
|
||||
bool appendData(const unsigned char* data, unsigned int length);
|
||||
|
||||
B_STATUS getData(unsigned char* data, unsigned int& length);
|
||||
|
||||
void reset();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
unsigned int m_blockSize;
|
||||
unsigned int m_blockTime;
|
||||
unsigned int m_topSequenceNumber;
|
||||
bool m_debug;
|
||||
unsigned int m_blockCount;
|
||||
CTimer m_timer;
|
||||
CStopWatch m_stopWatch;
|
||||
bool m_running;
|
||||
|
||||
struct JitterEntry
|
||||
{
|
||||
unsigned char* m_data;
|
||||
unsigned int m_length;
|
||||
};
|
||||
|
||||
JitterEntry* m_buffer;
|
||||
unsigned int m_headSequenceNumber;
|
||||
|
||||
unsigned int m_appendSequenceNumber;
|
||||
|
||||
unsigned char* m_lastData;
|
||||
unsigned int m_lastDataLength;
|
||||
};
|
||||
|
||||
#endif
|
182
LCDproc.cpp
182
LCDproc.cpp
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -72,7 +72,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#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 P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
|
||||
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(),
|
||||
m_address(address),
|
||||
m_port(port),
|
||||
|
@ -121,44 +122,53 @@ CLCDproc::~CLCDproc()
|
|||
|
||||
bool CLCDproc::open()
|
||||
{
|
||||
const char *server;
|
||||
unsigned int port, localPort;
|
||||
struct sockaddr_in serverAddress, clientAddress;
|
||||
struct hostent *h;
|
||||
int err;
|
||||
unsigned int addrlen;
|
||||
std::string port, localPort;
|
||||
struct sockaddr_storage serverAddress, clientAddress;
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
server = m_address.c_str();
|
||||
port = m_port;
|
||||
localPort = m_localPort;
|
||||
port = std::to_string(m_port);
|
||||
localPort = std::to_string(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 */
|
||||
m_socketfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
m_socketfd = socket(clientAddress.ss_family, SOCK_STREAM, 0);
|
||||
if (m_socketfd == -1) {
|
||||
LogError("LCDproc, failed to create socket");
|
||||
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 */
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Lookup the hostname address */
|
||||
h = gethostbyname(server);
|
||||
|
||||
/* 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) {
|
||||
/* Connect to server */
|
||||
if (connect(m_socketfd, (struct sockaddr *)&serverAddress, addrlen) == -1) {
|
||||
LogError("LCDproc, cannot connect to server");
|
||||
return false;
|
||||
}
|
||||
|
@ -179,6 +189,7 @@ void CLCDproc::setIdleInt()
|
|||
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 Idle", m_cols - 3, m_rows);
|
||||
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 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 Error", m_cols - 4, m_rows);
|
||||
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 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 Lockout", m_cols - 6, m_rows);
|
||||
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 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 Stopped", m_cols - 6, m_rows);
|
||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||
}
|
||||
|
@ -241,6 +255,24 @@ void CLCDproc::setQuitInt()
|
|||
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)
|
||||
{
|
||||
assert(my1 != NULL);
|
||||
|
@ -294,7 +326,7 @@ void CLCDproc::clearDStarInt()
|
|||
{
|
||||
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 Line4 1 4 15 4 h 3 \"\"");
|
||||
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, " ");
|
||||
}
|
||||
} 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 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
|
||||
|
||||
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(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\"");
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -422,20 +454,19 @@ void CLCDproc::writeFusionInt(const char* source, const char* dest, const char*
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
m_rssiCount1++;
|
||||
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
if (m_rssiCount1 >= YSF_RSSI_COUNT)
|
||||
m_rssiCount1 = 0U;
|
||||
}
|
||||
|
||||
void CLCDproc::clearFusionInt()
|
||||
{
|
||||
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 Line4 1 4 15 4 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "output 4"); // Set LED3 color green
|
||||
|
@ -480,7 +511,7 @@ void CLCDproc::clearP25Int()
|
|||
{
|
||||
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 Line4 1 4 15 4 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "output 2"); // Set LED2 color green
|
||||
|
@ -525,12 +556,57 @@ void CLCDproc::clearNXDNInt()
|
|||
{
|
||||
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 Line4 1 4 15 4 h 3 \"\"");
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
@ -752,7 +828,7 @@ void CLCDproc::defineScreens()
|
|||
socketPrintf(m_socketfd, "widget_add DStar Line4 scroller");
|
||||
|
||||
/* 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 Line4 1 4 15 4 h 3 \"\"");
|
||||
*/
|
||||
|
@ -773,8 +849,8 @@ void CLCDproc::defineScreens()
|
|||
/* 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 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 Slot2 3 2 15 2 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\"");
|
||||
*/
|
||||
|
||||
// The YSF Screen
|
||||
|
@ -788,7 +864,7 @@ void CLCDproc::defineScreens()
|
|||
socketPrintf(m_socketfd, "widget_add YSF Line4 scroller");
|
||||
|
||||
/* 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 Line4 4 2 15 2 h 3 \" \"");
|
||||
*/
|
||||
|
@ -804,7 +880,7 @@ void CLCDproc::defineScreens()
|
|||
socketPrintf(m_socketfd, "widget_add P25 Line4 scroller");
|
||||
|
||||
/* 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 Line4 4 2 15 2 h 3 \" \"");
|
||||
*/
|
||||
|
@ -820,10 +896,26 @@ void CLCDproc::defineScreens()
|
|||
socketPrintf(m_socketfd, "widget_add NXDN Line4 scroller");
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
|
14
LCDproc.h
14
LCDproc.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,7 +28,7 @@
|
|||
class CLCDproc : public CDisplay
|
||||
{
|
||||
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 bool open();
|
||||
|
@ -40,7 +40,7 @@ protected:
|
|||
virtual void setErrorInt(const char* text);
|
||||
virtual void setLockoutInt();
|
||||
virtual void setQuitInt();
|
||||
|
||||
virtual void setFMInt();
|
||||
|
||||
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
|
||||
virtual void writeDStarRSSIInt(unsigned char rssi);
|
||||
|
@ -50,7 +50,7 @@ protected:
|
|||
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
|
||||
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 clearFusionInt();
|
||||
|
||||
|
@ -62,6 +62,10 @@ protected:
|
|||
virtual void writeNXDNRSSIInt(unsigned char rssi);
|
||||
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 clearPOCSAGInt();
|
||||
|
||||
|
@ -73,7 +77,7 @@ protected:
|
|||
private:
|
||||
std::string m_address;
|
||||
unsigned int m_port;
|
||||
unsigned int m_localPort;
|
||||
unsigned short m_localPort;
|
||||
std::string m_callsign;
|
||||
unsigned int m_dmrid;
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
|
@ -34,8 +35,10 @@
|
|||
static unsigned int m_fileLevel = 2U;
|
||||
static std::string m_filePath;
|
||||
static std::string m_fileRoot;
|
||||
static bool m_fileRotate = true;
|
||||
|
||||
static FILE* m_fpLog = NULL;
|
||||
static bool m_daemon = false;
|
||||
|
||||
static unsigned int m_displayLevel = 2U;
|
||||
|
||||
|
@ -43,8 +46,10 @@ static struct tm m_tm;
|
|||
|
||||
static char LEVELS[] = " DMIWEF";
|
||||
|
||||
static bool LogOpen()
|
||||
static bool logOpenRotate()
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if (m_fileLevel == 0U)
|
||||
return true;
|
||||
|
||||
|
@ -61,39 +66,90 @@ static bool LogOpen()
|
|||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
char filename[100U];
|
||||
char filename[200U];
|
||||
#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);
|
||||
#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);
|
||||
#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;
|
||||
|
||||
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_fileRoot = fileRoot;
|
||||
m_fileLevel = fileLevel;
|
||||
m_displayLevel = displayLevel;
|
||||
return ::LogOpen();
|
||||
m_daemon = daemon;
|
||||
m_fileRotate = rotate;
|
||||
|
||||
if (m_daemon)
|
||||
m_displayLevel = 0U;
|
||||
|
||||
return ::LogOpen();
|
||||
}
|
||||
|
||||
void LogFinalise()
|
||||
{
|
||||
if (m_fpLog != NULL)
|
||||
::fclose(m_fpLog);
|
||||
if (m_fpLog != NULL)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
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)
|
||||
SYSTEMTIME st;
|
||||
::GetSystemTime(&st);
|
||||
|
@ -105,13 +161,13 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
|
||||
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
|
||||
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
|
||||
::vsprintf(buffer + ::strlen(buffer), fmt, vl);
|
||||
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
|
@ -130,7 +186,7 @@ void Log(unsigned int level, const char* fmt, ...)
|
|||
}
|
||||
|
||||
if (level == 6U) { // Fatal
|
||||
::fclose(m_fpLog);
|
||||
exit(1);
|
||||
}
|
||||
::fclose(m_fpLog);
|
||||
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
|
||||
* 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 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();
|
||||
|
||||
#endif
|
||||
|
|
155
MMDVM.ini
155
MMDVM.ini
|
@ -1,6 +1,6 @@
|
|||
[General]
|
||||
Callsign=G9BF
|
||||
Id=123456
|
||||
Callsign=MUTRPT
|
||||
Id=1337
|
||||
Timeout=180
|
||||
Duplex=1
|
||||
# ModeHang=10
|
||||
|
@ -13,12 +13,6 @@ Daemon=0
|
|||
RXFrequency=435000000
|
||||
TXFrequency=435000000
|
||||
Power=1
|
||||
Latitude=0.0
|
||||
Longitude=0.0
|
||||
Height=0
|
||||
Location=Nowhere
|
||||
Description=Multi-Mode Repeater
|
||||
URL=www.google.co.uk
|
||||
|
||||
[Log]
|
||||
# Logging levels, 0=No logging
|
||||
|
@ -26,6 +20,7 @@ DisplayLevel=1
|
|||
FileLevel=1
|
||||
FilePath=.
|
||||
FileRoot=MMDVM
|
||||
FileRotate=1
|
||||
|
||||
[CW Id]
|
||||
Enable=1
|
||||
|
@ -36,16 +31,23 @@ Time=10
|
|||
File=DMRIds.dat
|
||||
Time=24
|
||||
|
||||
[NXDN Id Lookup]
|
||||
File=NXDN.csv
|
||||
Time=24
|
||||
|
||||
[Modem]
|
||||
# Port=/dev/ttyACM0
|
||||
# Port=/dev/ttyAMA0
|
||||
Port=\\.\COM3
|
||||
# Valid values are "null", "uart", "udp", and (on Linux) "i2c"
|
||||
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
|
||||
RXInvert=0
|
||||
PTTInvert=0
|
||||
|
@ -58,14 +60,9 @@ TXLevel=50
|
|||
RXDCOffset=0
|
||||
TXDCOffset=0
|
||||
RFLevel=100
|
||||
# CWIdTXLevel=50
|
||||
# D-StarTXLevel=50
|
||||
# DMRTXLevel=50
|
||||
# YSFTXLevel=50
|
||||
# P25TXLevel=50
|
||||
# NXDNTXLevel=50
|
||||
# POCSAGTXLevel=50
|
||||
DMRTXLevel=50
|
||||
RSSIMappingFile=RSSI.dat
|
||||
UseCOSAsLockout=0
|
||||
Trace=0
|
||||
Debug=0
|
||||
|
||||
|
@ -76,28 +73,12 @@ RemotePort=40094
|
|||
LocalPort=40095
|
||||
# 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]
|
||||
Enable=1
|
||||
Beacons=0
|
||||
BeaconInterval=60
|
||||
BeaconDuration=3
|
||||
ColorCode=1
|
||||
ColorCode=7
|
||||
SelfOnly=0
|
||||
EmbeddedLCOnly=0
|
||||
DumpTAData=1
|
||||
|
@ -107,89 +88,23 @@ DumpTAData=1
|
|||
CallHang=3
|
||||
TXHang=4
|
||||
# ModeHang=10
|
||||
OVCM=1
|
||||
|
||||
[System Fusion]
|
||||
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
|
||||
# OVCM Values, 0=off, 1=rx_on, 2=tx_on, 3=both_on, 4=force off
|
||||
# OVCM=0
|
||||
|
||||
[DMR Network]
|
||||
Enable=1
|
||||
Address=44.131.4.1
|
||||
Port=62031
|
||||
# Type may be either 'Direct' or 'Gateway'. When Direct you must provide the Master's
|
||||
# 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
|
||||
# Local=62032
|
||||
Password=PASSWORD
|
||||
# Options=
|
||||
Slot1=1
|
||||
Slot2=1
|
||||
# ModeHang=3
|
||||
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
|
||||
# Options=
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
|
@ -249,11 +164,7 @@ UTC=0
|
|||
Enable=0
|
||||
File=/tmp/MMDVM_Active.lck
|
||||
|
||||
[Mobile GPS]
|
||||
Enable=0
|
||||
Address=127.0.0.1
|
||||
Port=7834
|
||||
|
||||
[Remote Control]
|
||||
Enable=0
|
||||
Address=127.0.0.1
|
||||
Port=7642
|
||||
|
|
1262
MMDVMHost.cpp
1262
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,31 +20,34 @@
|
|||
#define MMDVMHOST_H
|
||||
|
||||
#include "RemoteControl.h"
|
||||
#include "POCSAGNetwork.h"
|
||||
#include "POCSAGControl.h"
|
||||
#include "DStarNetwork.h"
|
||||
#include "NXDNNetwork.h"
|
||||
#include "DStarControl.h"
|
||||
//#include "POCSAGNetwork.h"
|
||||
//#include "POCSAGControl.h"
|
||||
//#include "DStarNetwork.h"
|
||||
//#include "AX25Network.h"
|
||||
//#include "NXDNNetwork.h"
|
||||
//#include "DStarControl.h"
|
||||
//#include "AX25Control.h"
|
||||
#include "DMRControl.h"
|
||||
#include "YSFControl.h"
|
||||
#include "P25Control.h"
|
||||
#include "NXDNControl.h"
|
||||
#include "NXDNLookup.h"
|
||||
#include "YSFNetwork.h"
|
||||
#include "P25Network.h"
|
||||
//#include "YSFControl.h"
|
||||
//#include "P25Control.h"
|
||||
//#include "NXDNControl.h"
|
||||
//#include "M17Control.h"
|
||||
//#include "NXDNLookup.h"
|
||||
//#include "YSFNetwork.h"
|
||||
//#include "P25Network.h"
|
||||
#include "DMRNetwork.h"
|
||||
//#include "M17Network.h"
|
||||
//#include "FMNetwork.h"
|
||||
#include "DMRLookup.h"
|
||||
#include "MobileGPS.h"
|
||||
#include "Display.h"
|
||||
//#include "FMControl.h"
|
||||
//#include "Display.h"
|
||||
#include "Timer.h"
|
||||
#include "Modem.h"
|
||||
#include "Conf.h"
|
||||
#include "UMP.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
class CMMDVMHost
|
||||
{
|
||||
public:
|
||||
|
@ -53,35 +56,33 @@ public:
|
|||
|
||||
int run();
|
||||
|
||||
void buildNetworkStatusString(std::string &str);
|
||||
void buildNetworkHostsString(std::string &str);
|
||||
|
||||
private:
|
||||
CConf m_conf;
|
||||
CModem* m_modem;
|
||||
CDStarControl* m_dstar;
|
||||
CDMRControl* m_dmr;
|
||||
CYSFControl* m_ysf;
|
||||
CP25Control* m_p25;
|
||||
CNXDNControl* m_nxdn;
|
||||
CPOCSAGControl* m_pocsag;
|
||||
CDStarNetwork* m_dstarNetwork;
|
||||
CDMRNetwork* m_dmrNetwork;
|
||||
CYSFNetwork* m_ysfNetwork;
|
||||
CP25Network* m_p25Network;
|
||||
CNXDNNetwork* m_nxdnNetwork;
|
||||
CPOCSAGNetwork* m_pocsagNetwork;
|
||||
|
||||
IDMRNetwork* m_dmrNetwork;
|
||||
|
||||
CDisplay* m_display;
|
||||
CUMP* m_ump;
|
||||
unsigned char m_mode;
|
||||
unsigned int m_dstarRFModeHang;
|
||||
unsigned int m_dmrRFModeHang;
|
||||
unsigned int m_ysfRFModeHang;
|
||||
unsigned int m_p25RFModeHang;
|
||||
unsigned int m_nxdnRFModeHang;
|
||||
unsigned int m_m17RFModeHang;
|
||||
unsigned int m_fmRFModeHang;
|
||||
unsigned int m_dstarNetModeHang;
|
||||
unsigned int m_dmrNetModeHang;
|
||||
unsigned int m_ysfNetModeHang;
|
||||
unsigned int m_p25NetModeHang;
|
||||
unsigned int m_nxdnNetModeHang;
|
||||
unsigned int m_m17NetModeHang;
|
||||
unsigned int m_pocsagNetModeHang;
|
||||
unsigned int m_fmNetModeHang;
|
||||
CTimer m_modeTimer;
|
||||
CTimer m_dmrTXTimer;
|
||||
CTimer m_cwIdTimer;
|
||||
|
@ -92,16 +93,17 @@ private:
|
|||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
bool m_nxdnEnabled;
|
||||
bool m_m17Enabled;
|
||||
bool m_pocsagEnabled;
|
||||
bool m_fmEnabled;
|
||||
bool m_ax25Enabled;
|
||||
unsigned int m_cwIdTime;
|
||||
CDMRLookup* m_dmrLookup;
|
||||
CNXDNLookup* m_nxdnLookup;
|
||||
std::string m_callsign;
|
||||
unsigned int m_id;
|
||||
std::string m_cwCallsign;
|
||||
bool m_lockFileEnabled;
|
||||
std::string m_lockFileName;
|
||||
CMobileGPS* m_mobileGPS;
|
||||
CRemoteControl* m_remoteControl;
|
||||
bool m_fixedMode;
|
||||
|
||||
|
@ -112,10 +114,14 @@ private:
|
|||
bool createYSFNetwork();
|
||||
bool createP25Network();
|
||||
bool createNXDNNetwork();
|
||||
bool createM17Network();
|
||||
bool createPOCSAGNetwork();
|
||||
bool createFMNetwork();
|
||||
bool createAX25Network();
|
||||
|
||||
void remoteControl();
|
||||
void processModeCommand(unsigned char mode, unsigned int timeout);
|
||||
void processEnableCommand(bool& mode, bool enabled);
|
||||
|
||||
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,340 +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="CASTInfo.h" />
|
||||
<ClInclude Include="Conf.h" />
|
||||
<ClInclude Include="CRC.h" />
|
||||
<ClInclude Include="Defines.h" />
|
||||
<ClInclude Include="Display.h" />
|
||||
<ClInclude Include="DMRAccessControl.h" />
|
||||
<ClInclude Include="DMRControl.h" />
|
||||
<ClInclude Include="DMRCSBK.h" />
|
||||
<ClInclude Include="DMRData.h" />
|
||||
<ClInclude Include="DMRDataHeader.h" />
|
||||
<ClInclude Include="DMRDefines.h" />
|
||||
<ClInclude Include="DMREMB.h" />
|
||||
<ClInclude Include="DMREmbeddedData.h" />
|
||||
<ClInclude Include="DMRFullLC.h" />
|
||||
<ClInclude Include="DMRLC.h" />
|
||||
<ClInclude Include="DMRNetwork.h" />
|
||||
<ClInclude Include="DMRShortLC.h" />
|
||||
<ClInclude Include="DMRSlot.h" />
|
||||
<ClInclude Include="DMRSlotType.h" />
|
||||
<ClInclude Include="DMRTA.h" />
|
||||
<ClInclude Include="DMRTrellis.h" />
|
||||
<ClInclude Include="DStarControl.h" />
|
||||
<ClInclude Include="DStarDefines.h" />
|
||||
<ClInclude Include="DStarHeader.h" />
|
||||
<ClInclude Include="DStarNetwork.h" />
|
||||
<ClInclude Include="DStarSlowData.h" />
|
||||
<ClInclude Include="Golay2087.h" />
|
||||
<ClInclude Include="Golay24128.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="DMRLookup.h" />
|
||||
<ClInclude Include="I2CController.h" />
|
||||
<ClInclude Include="JitterBuffer.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="CASTInfo.cpp" />
|
||||
<ClCompile Include="Conf.cpp" />
|
||||
<ClCompile Include="CRC.cpp" />
|
||||
<ClCompile Include="Display.cpp" />
|
||||
<ClCompile Include="DMRAccessControl.cpp" />
|
||||
<ClCompile Include="DMRControl.cpp" />
|
||||
<ClCompile Include="DMRCSBK.cpp" />
|
||||
<ClCompile Include="DMRData.cpp" />
|
||||
<ClCompile Include="DMRDataHeader.cpp" />
|
||||
<ClCompile Include="DMREMB.cpp" />
|
||||
<ClCompile Include="DMREmbeddedData.cpp" />
|
||||
<ClCompile Include="DMRFullLC.cpp" />
|
||||
<ClCompile Include="DMRLC.cpp" />
|
||||
<ClCompile Include="DMRLookup.cpp" />
|
||||
<ClCompile Include="DMRNetwork.cpp" />
|
||||
<ClCompile Include="DMRShortLC.cpp" />
|
||||
<ClCompile Include="DMRSlot.cpp" />
|
||||
<ClCompile Include="DMRSlotType.cpp" />
|
||||
<ClCompile Include="DMRTA.cpp" />
|
||||
<ClCompile Include="DMRTrellis.cpp" />
|
||||
<ClCompile Include="DStarControl.cpp" />
|
||||
<ClCompile Include="DStarHeader.cpp" />
|
||||
<ClCompile Include="DStarNetwork.cpp" />
|
||||
<ClCompile Include="DStarSlowData.cpp" />
|
||||
<ClCompile Include="Golay2087.cpp" />
|
||||
<ClCompile Include="Golay24128.cpp" />
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="I2CController.cpp" />
|
||||
<ClCompile Include="JitterBuffer.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,554 +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="JitterBuffer.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>
|
||||
<ClInclude Include="CASTInfo.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="JitterBuffer.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>
|
||||
<ClCompile Include="CASTInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
47
Makefile
47
Makefile
|
@ -2,18 +2,18 @@
|
|||
|
||||
CC = cc
|
||||
CXX = c++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||
LIBS = -lpthread
|
||||
LDFLAGS = -g
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -I/usr/local/include
|
||||
LIBS = -lpthread -lutil
|
||||
LDFLAGS = -g -L/usr/local/lib
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o JitterBuffer.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
|
||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o Golay2087.o Golay24128.o\
|
||||
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.o \
|
||||
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.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 \
|
||||
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||
|
||||
all: MMDVMHost RemoteCommand
|
||||
|
||||
|
@ -26,6 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|||
%.o: %.cpp
|
||||
$(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:
|
||||
$(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.
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DRASPBERRY_PI -I/usr/local/include
|
||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
||||
CC = cc
|
||||
CXX = c++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -DRASPBERRY_PI -I/usr/local/include
|
||||
LIBS = -lwiringPi -lwiringPiDev -lpthread -lutil
|
||||
LDFLAGS = -g -L/usr/local/lib
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o JitterBuffer.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
|
||||
AMBEFEC.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o Golay2087.o Golay24128.o\
|
||||
Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o MMDVMHost.o \
|
||||
Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.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 \
|
||||
Timer.o UARTController.o UDPController.o UDPSocket.o UserDB.o UserDBentry.o Utils.o
|
||||
|
||||
all: MMDVMHost RemoteCommand
|
||||
|
||||
|
@ -26,6 +26,33 @@ RemoteCommand: Log.o RemoteCommand.o UDPSocket.o
|
|||
%.o: %.cpp
|
||||
$(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:
|
||||
$(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 CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o JitterBuffer.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 CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o JitterBuffer.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 CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o I2CController.o JitterBuffer.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 CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o JitterBuffer.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 CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \
|
||||
DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \
|
||||
DStarSlowData.o Golay2087.o Golay24128.o Hamming.o JitterBuffer.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);
|
||||
}
|
||||
|
63
MobileGPS.h
63
MobileGPS.h
|
@ -1,63 +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.
|
||||
*/
|
||||
|
||||
#ifndef MobileGPS_H
|
||||
#define MobileGPS_H
|
||||
|
||||
#include "DMRNetwork.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <netdb.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 {
|
||||
public:
|
||||
CMobileGPS(const std::string& address, unsigned int port, CDMRNetwork* network);
|
||||
~CMobileGPS();
|
||||
|
||||
bool open();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
CTimer m_idTimer;
|
||||
in_addr m_address;
|
||||
unsigned int m_port;
|
||||
CUDPSocket m_socket;
|
||||
CDMRNetwork* m_network;
|
||||
|
||||
bool pollGPS();
|
||||
void sendReport();
|
||||
};
|
||||
|
||||
#endif
|
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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MODEM_H
|
||||
#define MODEM_H
|
||||
#ifndef Modem_H
|
||||
#define Modem_H
|
||||
|
||||
#include "SerialController.h"
|
||||
#include "ModemPort.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "Defines.h"
|
||||
#include "Timer.h"
|
||||
|
@ -32,86 +32,107 @@ enum RESP_TYPE_MMDVM {
|
|||
RTM_ERROR
|
||||
};
|
||||
|
||||
enum SERIAL_STATE {
|
||||
SS_START,
|
||||
SS_LENGTH1,
|
||||
SS_LENGTH2,
|
||||
SS_TYPE,
|
||||
SS_DATA
|
||||
};
|
||||
|
||||
class CModem {
|
||||
public:
|
||||
CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug);
|
||||
virtual ~CModem();
|
||||
CModem(bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool useCOSAsLockout, bool trace, bool debug);
|
||||
~CModem();
|
||||
|
||||
virtual void setSerialParams(const std::string& protocol, unsigned int address);
|
||||
virtual void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel, unsigned int pocsagFrequency);
|
||||
virtual void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool pocsagEnabled);
|
||||
virtual void setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagLevel);
|
||||
virtual void setDMRParams(unsigned int colorCode);
|
||||
virtual void setYSFParams(bool loDev, unsigned int txHang);
|
||||
virtual void setTransparentDataParams(unsigned int sendFrameType);
|
||||
void setPort(IModemPort* port);
|
||||
void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel);
|
||||
void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool m17Enabled, bool pocsagEnabled, bool fmEnabled, bool ax25Enabled);
|
||||
void setLevels(float rxLevel, float cwIdTXLevel, float dmrTXLevel);
|
||||
void setDMRParams(unsigned int colorCode);
|
||||
void setYSFParams(bool loDev, unsigned int txHang);
|
||||
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);
|
||||
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);
|
||||
bool open();
|
||||
|
||||
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;
|
||||
virtual bool hasDMRSpace1() const;
|
||||
virtual bool hasDMRSpace2() const;
|
||||
virtual bool hasYSFSpace() const;
|
||||
virtual bool hasP25Space() const;
|
||||
virtual bool hasNXDNSpace() const;
|
||||
virtual bool hasPOCSAGSpace() const;
|
||||
unsigned int getVersion() const;
|
||||
|
||||
virtual bool hasTX() const;
|
||||
virtual bool hasCD() const;
|
||||
unsigned int readDStarData(unsigned char* data);
|
||||
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;
|
||||
virtual bool hasError() const;
|
||||
bool hasDStarSpace() 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);
|
||||
virtual bool writeDMRData1(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeDMRData2(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeYSFData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeP25Data(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeNXDNData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writePOCSAGData(const unsigned char* data, unsigned int length);
|
||||
bool hasTX() const;
|
||||
bool hasCD() const;
|
||||
|
||||
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);
|
||||
virtual bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||
virtual bool writeYSFInfo(const char* source, const char* dest, const char* type, const char* origin);
|
||||
virtual bool writeP25Info(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual bool writeNXDNInfo(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual bool writePOCSAGInfo(unsigned int ric, const std::string& message);
|
||||
virtual bool writeIPInfo(const std::string& address);
|
||||
bool writeConfig();
|
||||
bool writeDMRData1(const unsigned char* data, unsigned int length);
|
||||
bool writeDMRData2(const unsigned char* data, unsigned int length);
|
||||
bool writeDMRInfo(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
|
||||
bool writeIPInfo(const std::string& address);
|
||||
|
||||
virtual bool writeDMRStart(bool tx);
|
||||
virtual bool writeDMRShortLC(const unsigned char* lc);
|
||||
virtual bool writeDMRAbort(unsigned int slotNo);
|
||||
bool writeDMRStart(bool tx);
|
||||
bool writeDMRShortLC(const unsigned char* lc);
|
||||
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:
|
||||
std::string m_port;
|
||||
unsigned int m_protocolVersion;
|
||||
unsigned int m_dmrColorCode;
|
||||
bool m_ysfLoDev;
|
||||
unsigned int m_ysfTXHang;
|
||||
bool m_duplex;
|
||||
bool m_rxInvert;
|
||||
bool m_txInvert;
|
||||
|
@ -120,66 +141,55 @@ private:
|
|||
unsigned int m_dmrDelay;
|
||||
float m_rxLevel;
|
||||
float m_cwIdTXLevel;
|
||||
float m_dstarTXLevel;
|
||||
float m_dmrTXLevel;
|
||||
float m_ysfTXLevel;
|
||||
float m_p25TXLevel;
|
||||
float m_nxdnTXLevel;
|
||||
float m_pocsagTXLevel;
|
||||
float m_rfLevel;
|
||||
bool m_useCOSAsLockout;
|
||||
bool m_trace;
|
||||
bool m_debug;
|
||||
unsigned int m_rxFrequency;
|
||||
unsigned int m_txFrequency;
|
||||
unsigned int m_pocsagFrequency;
|
||||
bool m_dstarEnabled;
|
||||
bool m_dmrEnabled;
|
||||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
bool m_nxdnEnabled;
|
||||
bool m_pocsagEnabled;
|
||||
int m_rxDCOffset;
|
||||
int m_txDCOffset;
|
||||
CSerialController* m_serial;
|
||||
IModemPort* m_port;
|
||||
unsigned char* m_buffer;
|
||||
unsigned int m_length;
|
||||
unsigned int m_offset;
|
||||
CRingBuffer<unsigned char> m_rxDStarData;
|
||||
CRingBuffer<unsigned char> m_txDStarData;
|
||||
SERIAL_STATE m_state;
|
||||
unsigned char m_type;
|
||||
CRingBuffer<unsigned char> m_rxDMRData1;
|
||||
CRingBuffer<unsigned char> m_rxDMRData2;
|
||||
CRingBuffer<unsigned char> m_txDMRData1;
|
||||
CRingBuffer<unsigned char> m_txDMRData2;
|
||||
CRingBuffer<unsigned char> m_rxYSFData;
|
||||
CRingBuffer<unsigned char> m_txYSFData;
|
||||
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_rxSerialData;
|
||||
CRingBuffer<unsigned char> m_txSerialData;
|
||||
CRingBuffer<unsigned char> m_rxTransparentData;
|
||||
CRingBuffer<unsigned char> m_txTransparentData;
|
||||
unsigned int m_sendTransparentDataFrameType;
|
||||
CTimer m_statusTimer;
|
||||
CTimer m_inactivityTimer;
|
||||
CTimer m_playoutTimer;
|
||||
unsigned int m_dstarSpace;
|
||||
unsigned int m_dmrSpace1;
|
||||
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_cd;
|
||||
bool m_lockout;
|
||||
bool m_error;
|
||||
unsigned char m_mode;
|
||||
HW_TYPE m_hwType;
|
||||
unsigned char m_capabilities1;
|
||||
unsigned char m_capabilities2;
|
||||
|
||||
bool readVersion();
|
||||
bool readStatus();
|
||||
bool setConfig();
|
||||
bool setConfig1();
|
||||
bool setConfig2();
|
||||
bool setFrequency();
|
||||
bool setFMCallsignParams();
|
||||
bool setFMAckParams();
|
||||
bool setFMMiscParams();
|
||||
bool setFMExtParams();
|
||||
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(NXDNAudio_H)
|
||||
#define NXDNAudio_H
|
||||
#include "ModemPort.h"
|
||||
|
||||
class CNXDNAudio {
|
||||
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
|
||||
IModemPort::~IModemPort()
|
||||
{
|
||||
}
|
|
@ -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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(P25Audio_H)
|
||||
#define P25Audio_H
|
||||
#ifndef ModemPort_H
|
||||
#define ModemPort_H
|
||||
|
||||
#include "AMBEFEC.h"
|
||||
|
||||
class CP25Audio {
|
||||
class IModemPort {
|
||||
public:
|
||||
CP25Audio();
|
||||
~CP25Audio();
|
||||
virtual ~IModemPort() = 0;
|
||||
|
||||
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:
|
||||
CAMBEFEC m_fec;
|
||||
};
|
||||
|
||||
#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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,22 +21,22 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
CModemSerialPort::CModemSerialPort(CModem* modem) :
|
||||
IModemSerialPort::IModemSerialPort(CModem* modem) :
|
||||
m_modem(modem)
|
||||
{
|
||||
assert(modem != NULL);
|
||||
}
|
||||
|
||||
CModemSerialPort::~CModemSerialPort()
|
||||
IModemSerialPort::~IModemSerialPort()
|
||||
{
|
||||
}
|
||||
|
||||
bool CModemSerialPort::open()
|
||||
bool IModemSerialPort::open()
|
||||
{
|
||||
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(length > 0U);
|
||||
|
@ -46,7 +46,7 @@ int CModemSerialPort::write(const unsigned char* data, unsigned int length)
|
|||
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(length > 0U);
|
||||
|
@ -54,6 +54,6 @@ int CModemSerialPort::read(unsigned char* data, unsigned int 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,10 +22,10 @@
|
|||
#include "SerialPort.h"
|
||||
#include "Modem.h"
|
||||
|
||||
class CModemSerialPort : public ISerialPort {
|
||||
class IModemSerialPort : public ISerialPort {
|
||||
public:
|
||||
CModemSerialPort(CModem* modem);
|
||||
virtual ~CModemSerialPort();
|
||||
IModemSerialPort(CModem* modem);
|
||||
virtual ~IModemSerialPort();
|
||||
|
||||
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
|
1137
NXDNControl.cpp
1137
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
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue