Compare commits

...

182 commits

Author SHA1 Message Date
Hibby 4f0df4999c Update to include the good stuff 2026-01-07 22:21:08 +00:00
Hibby 162b03be13 Release 2026-01-07 21:55:19 +00:00
Hibby b0660dea06 Remove Patch for TelnetV6, fixed upstream 2026-01-07 21:50:03 +00:00
Hibby 26f10ca1b6 Update upstream source from tag 'upstream/6.0.25.15+repack'
Update to upstream version '6.0.25.15+repack'
with Debian dir 72d93ed8ce
2026-01-07 21:45:17 +00:00
Hibby dae2bbc721 New upstream version 6.0.25.15+repack 2026-01-07 21:45:15 +00:00
Hibby b031f8dedf Release 2025-12-23 16:46:05 +00:00
Hibby 84b34add07 Patch TelnetV6 to build 2025-12-23 16:39:54 +00:00
Hibby d5f8de2e8f Update upstream source from tag 'upstream/6.0.25.13+repack'
Update to upstream version '6.0.25.13+repack'
with Debian dir 26b4e77a37
2025-12-23 16:30:09 +00:00
Hibby 559d5bbf7c New upstream version 6.0.25.13+repack 2025-12-23 16:30:05 +00:00
Hibby d7b0d25ddb 6.0.25.12 hacky merge due t it not ffing. 2025-11-23 11:51:15 +00:00
Hibby ee15c1a996 Release! 2025-11-22 15:14:42 +00:00
Hibby 944fdfc524 Update upstream source from tag 'upstream/6.0.25.12+repack'
Update to upstream version '6.0.25.12+repack'
with Debian dir 0b59d86e0b
2025-11-22 15:09:25 +00:00
Hibby 52e35f45b4 New upstream version 6.0.25.12+repack 2025-11-22 15:09:21 +00:00
Hibby 3fbe745ec9 Release 25.11 2025-11-11 21:53:27 +00:00
Hibby 1338e2c0a4 Update upstream source from tag 'upstream/6.0.25.11+repack'
Update to upstream version '6.0.25.11+repack'
with Debian dir 9c0f82ee4c
2025-11-11 21:50:49 +00:00
Hibby 85f200a46c New upstream version 6.0.25.11+repack 2025-11-11 21:50:47 +00:00
Hibby 9aad97786d 6.0.25.9 2025-11-11 21:42:35 +00:00
Hibby 8dc88bc829 Changelog update, release 2025-11-09 22:45:36 +00:00
Hibby 58ab380142 Refresh patches 2025-11-09 22:35:15 +00:00
Hibby 3c2c1cf9f8 Update upstream source from tag 'upstream/6.0.25.9+repack'
Update to upstream version '6.0.25.9+repack'
with Debian dir 15e3115d6f
2025-11-09 22:34:23 +00:00
Hibby 367ab8fb01 New upstream version 6.0.25.9+repack 2025-11-09 22:34:20 +00:00
Hibby e569b24f9a Changelog! 2025-10-24 00:48:59 +01:00
Hibby 272c31f62b Refresh patches with gbp pq! 2025-10-24 00:40:43 +01:00
Hibby f99a060918 Update upstream source from tag 'upstream/6.0.25.8+repack'
Update to upstream version '6.0.25.8+repack'
with Debian dir 34f11488df
2025-10-24 00:36:53 +01:00
Hibby 453f162d22 New upstream version 6.0.25.8+repack 2025-10-24 00:36:48 +01:00
Hibby 13c0b79af7 Don't forget about the changelog 2025-10-10 23:55:55 +01:00
Hibby 2e55f0a4ca Build on latest gcc standards 2025-10-10 23:54:35 +01:00
Hibby acbaf26ac1 New upstream 2025-10-10 23:51:40 +01:00
Hibby 70d9b41cc1 Update upstream source from tag 'upstream/6.0.25.06+repack'
Update to upstream version '6.0.25.06+repack'
with Debian dir 0466cb7b03
2025-10-10 23:37:36 +01:00
Hibby 96ac3e4a36 New upstream version 6.0.25.06+repack 2025-10-10 23:37:31 +01:00
Hibby c0425ff0e2 Migrate patches tp gbp pq 2025-09-20 15:58:22 +01:00
Hibby e4d8eadb91 Set c standard, it builds! 2025-09-20 15:41:51 +01:00
Hibby ac03394a07
First work on new version 2025-09-09 22:10:43 +01:00
Hibby d0f299bc02 Update upstream source from tag 'upstream/6.0.25.1+repack'
Update to upstream version '6.0.25.1+repack'
with Debian dir 5c600492d3
2025-09-04 22:52:15 +01:00
Hibby 7c796758d1 New upstream version 6.0.25.1+repack 2025-09-04 22:52:12 +01:00
Hibby 78f78927ab
Release new version 2025-08-17 22:40:01 +01:00
Hibby 27d95452b1 Update upstream source from tag 'upstream/6.0.24.82+repack'
Update to upstream version '6.0.24.82+repack'
with Debian dir a145ad04db
2025-08-17 22:31:33 +01:00
Hibby e925e16114 New upstream version 6.0.24.82+repack 2025-08-17 22:31:27 +01:00
Hibby d97d9d821b
Commit before next update! 2025-08-17 22:30:20 +01:00
Hibby a6b3c4bdc9 Update upstream source from tag 'upstream/6.0.24.80+repack'
Update to upstream version '6.0.24.80+repack'
with Debian dir 9e943f8d36
2025-08-12 20:09:07 +01:00
Hibby 7a5122a60f
Changelog for release, makefile patch refresh 2025-07-31 01:31:52 +01:00
Hibby 0013c3199a Update upstream source from tag 'upstream/6.0.24.78+repack'
Update to upstream version '6.0.24.78+repack'
with Debian dir 819c1fdecb
2025-07-31 01:28:57 +01:00
Hibby fa3201d982 New upstream version 6.0.24.78+repack 2025-07-31 01:28:54 +01:00
Hibby 5d30fbc104
New files to exclude 2025-07-31 01:28:13 +01:00
Hibby e21707174e
Release! 2025-07-22 21:52:16 +01:00
Hibby 26324bdc39
First build 2025-07-22 21:44:33 +01:00
Hibby 1cc87cf766 Update upstream source from tag 'upstream/6.0.24.77+repack'
Update to upstream version '6.0.24.77+repack'
with Debian dir bbbd57413e
2025-07-22 20:57:03 +01:00
Hibby 30b1e26a04
Did a port on minibuildd for +1, this is technically +2 2025-07-16 19:16:00 +01:00
Hibby 31bda6ce76
Trixie release 2025-07-16 19:11:08 +01:00
Hibby d2c3489aef
Release 2025-07-15 01:11:11 +01:00
Hibby 6371d5385a Update upstream source from tag 'upstream/6.0.24.75+repack'
Update to upstream version '6.0.24.75+repack'
with Debian dir 8aa30a6de8
2025-07-14 23:14:14 +01:00
Hibby b2315840b2 New upstream version 6.0.24.75+repack 2025-07-14 23:14:11 +01:00
Hibby 8d3874ec4e
Update d/copyright to ignore svn 2025-07-14 23:12:11 +01:00
Hibby 6a4b588a48
Release and autoport magic 2025-05-21 22:12:07 +01:00
Hibby 426f47ccb6
It builds successfully! 2025-05-21 21:45:54 +01:00
Hibby 3ecb593511 Update upstream source from tag 'upstream/6.0.24.71+repack'
Update to upstream version '6.0.24.71+repack'
with Debian dir d79186aef0
2025-05-21 21:33:54 +01:00
Hibby 0d3ee7fd56 New upstream version 6.0.24.71+repack 2025-05-21 21:33:52 +01:00
Hibby 96197688e7
New upstream version 6.0.24.69.1+repack 2025-05-21 21:32:18 +01:00
Hibby d3b4158645
New upstream version 6.0.24.69+repack 2025-05-21 21:32:18 +01:00
Hibby fec78cece5
Update changelog 2025-05-21 21:32:17 +01:00
Hibby bdf8a8367e
New upstream version 6.0.24.67+repack 2025-05-21 21:32:17 +01:00
Hibby f0ac0675f6
Release, try out some MINI_BUILDD_OPTIONS 2025-03-11 00:51:56 +00:00
Hibby 329e2f441d
Who knows at this point 2025-03-11 00:28:11 +00:00
Hibby 0b4a17004f
New upstream 2025-03-04 22:50:37 +00:00
Hibby f0b507a096 Update upstream source from tag 'upstream/6.0.24.66+repack'
Update to upstream version '6.0.24.66+repack'
with Debian dir 0a1e01b2c4
2025-03-04 22:46:54 +00:00
Hibby 9d0d20064d
Release! 2025-02-25 09:39:10 +00:00
Hibby ead72b2575
New import packaging 2025-02-25 09:35:39 +00:00
Hibby f1d8b647c7 Update upstream source from tag 'upstream/6.0.24.65+repack'
Update to upstream version '6.0.24.65+repack'
with Debian dir 324f0a8474
2025-02-25 09:32:59 +00:00
Hibby bfcf049c56
New packaging tweaks 2025-02-03 22:35:11 +00:00
Hibby 488e218d34 Update upstream source from tag 'upstream/6.0.24.59a+repack'
Update to upstream version '6.0.24.59a+repack'
with Debian dir 618298da94
2025-02-03 22:19:01 +00:00
Hibby 3efea8aa10
Release 2025-01-06 21:41:04 +00:00
Hibby 8e9260b52d
Updates for .56 2025-01-06 21:37:03 +00:00
Hibby 5105f0adf3 Update upstream source from tag 'upstream/6.0.24.56+repack'
Update to upstream version '6.0.24.56+repack'
with Debian dir 5e2bea687a
2025-01-06 21:26:32 +00:00
Hibby b060bf5d39
Update upstream source from tag 'upstream/6.0.24.55+repack'
Update to upstream version '6.0.24.55+repack'
with Debian dir ba150ac059
2025-01-05 23:35:13 +00:00
Hibby 33d8e6f75a
Release to unstable 2024-12-17 16:51:59 +00:00
Hibby 58d2baad53
New upstream and packaging tweaks 2024-12-17 16:45:51 +00:00
Hibby 1f73eb5601 Update upstream source from tag 'upstream/6.0.24.54+repack'
Update to upstream version '6.0.24.54+repack'
with Debian dir f571d496d3
2024-12-16 17:54:18 +00:00
Hibby a7d635fe2f New upstream version 6.0.24.54+repack 2024-12-16 17:54:16 +00:00
Hibby eab73bee95
.53 build 2024-12-09 10:06:20 +00:00
Hibby 745a9f8e88 Update upstream source from tag 'upstream/6.0.24.53+repack'
Update to upstream version '6.0.24.53+repack'
with Debian dir 64961bc210
2024-12-03 00:27:59 +00:00
Hibby dd84b546a0
Release 2024-11-30 22:14:12 +00:00
Hibby 3a600bee23 Update upstream source from tag 'upstream/6.0.24.52+repack'
Update to upstream version '6.0.24.52+repack'
with Debian dir 0b34b91ce1
2024-11-30 21:42:45 +00:00
Hibby d09a168608 Update upstream source from tag 'upstream/6.0.24.51.3+repack+really50'
Update to upstream version '6.0.24.51.3+repack+really50'
with Debian dir 0b34b91ce1
2024-11-30 11:27:30 +00:00
Hibby 757c658adc Update upstream source from tag 'upstream/6.0.24.51.2+repack+really.50'
Update to upstream version '6.0.24.51.2+repack+really.50'
with Debian dir 0b34b91ce1
2024-11-30 11:21:00 +00:00
Hibby 37bacc3178
Update required for build on trixie - I knew there was weirdness
somewhere!
2024-11-29 19:57:43 +00:00
Hibby 7690eb8f59
Release! 2024-11-29 19:33:20 +00:00
Hibby a675c89dc3 Update upstream source from tag 'upstream/6.0.24.51.1+repack'
Update to upstream version '6.0.24.51.1+repack'
with Debian dir 345d0bf3b0
2024-11-29 19:19:21 +00:00
Hibby 7433c77604
little tweaks before import 2024-11-29 19:18:48 +00:00
Hibby 6bd281ab30
Tweaks to get functionality 2024-11-29 16:13:51 +00:00
Hibby c0637b3841
Last batch of changes, ready for release! 2024-11-29 13:23:18 +00:00
Hibby 3a840054a7 Update upstream source from tag 'upstream/6.0.24.51+repack'
Update to upstream version '6.0.24.51+repack'
with Debian dir cbfe17e0e2
2024-11-29 12:56:28 +00:00
Hibby 8a18ca1868
pull more files out, update watch for repack 2024-11-29 12:55:39 +00:00
Hibby 49e27728c3
Removal of files I don't think we need to ship 2024-11-29 12:09:05 +00:00
Hibby 8e7a943558
This builds and links to system libs! 2024-11-29 12:04:09 +00:00
Hibby e35489a925
Latest revisions 2024-11-29 11:37:37 +00:00
Hibby c77b3e9f47
More updates, large makefile rewrite for dynamic linking and cleaner
build, WIP.
2024-11-29 02:24:20 +00:00
Hibby 1e83f7e725
First pass of fixes for new build 2024-11-28 22:50:13 +00:00
Hibby 5d8d8963ef Update upstream source from tag 'upstream/6.0.24.51'
Update to upstream version '6.0.24.51'
with Debian dir b28e5722f6
2024-11-28 22:34:01 +00:00
Hibby 96d6e87d12
Release! 2024-11-12 21:58:14 +00:00
Hibby 5bd018b10f
Little packaging tidies 2024-11-12 21:53:24 +00:00
Hibby 4d14474d92 Update upstream source from tag 'upstream/6.0.24.50'
Update to upstream version '6.0.24.50'
with Debian dir 3f4098912b
2024-11-12 21:20:03 +00:00
Hibby 1b40c8c7b5
Try files-excluded, Tidy up copyright! 2024-11-12 21:18:17 +00:00
Hibby a5ce8b2319
Release! 2024-11-05 22:09:13 +00:00
Hibby 6b795ee1f6
Patch Refresh and mqtt details 2024-11-05 21:46:27 +00:00
Hibby 5767c5f6e8 Update upstream source from tag 'upstream/6.0.24.49'
Update to upstream version '6.0.24.49'
with Debian dir 985e9a7aed
2024-11-05 21:03:23 +00:00
Hibby 61f49ee46b
Release for hibbian 2024-10-11 15:49:55 +01:00
Hibby 6e6693fde1
Refresh Patches 2024-10-11 15:46:34 +01:00
Hibby 1a7f29f7d7
Look at me, I am the master now 2024-10-11 15:42:39 +01:00
Hibby f527c60884
Merge branch 'debian/latest' into hibbian/latest 2024-10-11 15:42:00 +01:00
Hibby 3de6b0150f Update upstream source from tag 'upstream/6.0.24.45'
Update to upstream version '6.0.24.45'
with Debian dir 9a5822f2bb
2024-10-11 15:37:17 +01:00
Hibby 0d48067b82
Sneak in the 32bit fixes 2024-09-26 23:13:41 +01:00
Hibby b18a579b0c
Updates to .42 2024-09-25 01:37:12 +01:00
Hibby ba9f74d1b8
more tweaks to get to build 2024-08-30 12:38:57 +01:00
Hibby 550b4483cb
we can't build without this backup! 2024-08-30 12:25:12 +01:00
Hibby 383e238d61
32bit fix release 2024-08-30 12:23:59 +01:00
Hibby 371dac17ff
32bits isn't building 2024-08-30 12:21:15 +01:00
Hibby 24843bc9cd
Add additional group membership for ninotnc SMT users
Fixes: #1
2024-08-30 12:06:42 +01:00
Hibby f17801297c
Release 2024-08-30 11:54:54 +01:00
Hibby f62a0288be
Try hardening on for size 2024-08-30 11:54:32 +01:00
Hibby 85da9edc16
Try hardening on for size 2024-08-30 11:46:56 +01:00
Hibby 666c2aabb4
Start tidying up headers 2024-08-30 11:46:04 +01:00
Hibby a47cc11d8a
First build needs 2024-08-30 10:23:16 +01:00
Hibby b26c87817a Update upstream source from tag 'upstream/6.0.24.42'
Update to upstream version '6.0.24.42'
with Debian dir 41e80b6ddf
2024-08-30 10:15:03 +01:00
Hibby 60585818de
Move config back to /etc on install 2024-08-18 01:44:28 +01:00
Hibby 9dacd97014
Release 2024-07-07 16:09:46 +01:00
Hibby fc0275b903
Upstream revision 2024-07-07 16:08:01 +01:00
Hibby ca2a16b7fc Update upstream source from tag 'upstream/6.0.24.40'
Update to upstream version '6.0.24.40'
with Debian dir 5582820246
2024-07-07 16:06:15 +01:00
Hibby d122a87dd1
New patch to run secure-by-default until upstream patch 2024-07-05 08:35:03 +01:00
Hibby 5b3543c12a
Merge pull request #4 from Online-Amateur-Radio-Club-M0OUK/secure-by-default
Change default value for SECURETELNET from 0 to 1
2024-07-05 08:30:10 +01:00
Tom Fanning d37331205e Create secure-by-default.patch 2024-07-03 10:02:44 +01:00
Tom M0LTE 026ad61c90
Merge pull request #1 from mquin/patch-1
bpq32.cfg: Set SECURETELNET on Telnet port
2024-07-03 09:33:30 +01:00
Mike Quin 5d125856cd
bpq32.cfg: Set SECURETELNET on Telnet port
The SECURETELNET option restricts outbound telnet connections from the node to users who have authenticated.
2024-07-02 19:48:28 +01:00
Hibby a7ecf779fc
Let's fly 2024-06-09 22:38:58 +01:00
Hibby c26f6fe9d8
Packaging updates round 2 2024-06-09 22:34:46 +01:00
Hibby 91fc60e6f0
Packaging updates 2024-06-09 21:52:56 +01:00
Hibby 3b36ba2a06 Update upstream source from tag 'upstream/6.0.24.38'
Update to upstream version '6.0.24.38'
with Debian dir 05f0c663f1
2024-06-09 21:48:46 +01:00
Hibby ec1e97d985
Update bpq32.cfg
Based on feedback, chat app is now ID 2
2024-06-09 11:15:36 +01:00
Hibby 75eadc6bbe
Release -2 update 2024-04-08 22:27:43 +01:00
Hibby eaab24a3c0
Update postinst 2024-04-08 23:21:31 +02:00
Hibby 4b1144ed94
New upstream 2024-04-06 02:15:37 +01:00
Hibby 37b1c8b074 Update upstream source from tag 'upstream/6.0.24.34'
Update to upstream version '6.0.24.34'
with Debian dir e7ec7ee355
2024-04-06 02:10:15 +01:00
Hibby 0b5e0e5023
Merge branch 'debian/latest' of github.com:Online-Amateur-Radio-Club-M0OUK/oarc-bpqnode into debian/latest 2024-03-26 20:58:02 +00:00
Hibby 66ff00a200
Release 2024-03-26 20:57:34 +00:00
Hibby 566b839fd4
Release 2024-03-26 20:24:27 +00:00
Hibby 5f9fb109ff
New upstream & Packaging tidy 2024-03-26 01:28:08 +00:00
Hibby 94179f117a Update upstream source from tag 'upstream/6.0.24.33'
Update to upstream version '6.0.24.33'
with Debian dir 1cb47d2883
2024-03-26 00:53:01 +00:00
Hibby 831f4a75eb
Release 2024-02-23 23:25:02 +00:00
Hibby 3f1fd46905
Upstream revision 2024-02-23 21:38:02 +00:00
Hibby 5b1c61bd78 Update upstream source from tag 'upstream/6.0.24.30'
Update to upstream version '6.0.24.30'
with Debian dir 4f7e13431e
2024-02-23 21:36:42 +00:00
Hibby ee7345ce92
Release 2024-02-13 00:07:16 +00:00
Hibby 733afdfcbc
New upstream 2024-02-13 00:03:15 +00:00
Hibby 2dd6d1f7bf Update upstream source from tag 'upstream/6.0.24.29'
Update to upstream version '6.0.24.29'
with Debian dir ba277a512a
2024-02-12 23:26:50 +00:00
Dave Hibberd 6ee8a719cf
Release 2024-01-18 10:32:10 +00:00
Dave Hibberd d4d0aaa8ab
Update permissions post install on config to allow for web ui edits 2024-01-18 10:31:35 +00:00
Dave Hibberd 710cc6fde7
Release 2024-01-16 20:52:57 +00:00
Dave Hibberd eec767af84
First build of new revision 2024-01-16 20:44:01 +00:00
Dave Hibberd 0c8b9a1da7 Update upstream source from tag 'upstream/6.0.24.27'
Update to upstream version '6.0.24.27'
with Debian dir be0d74d7ed
2024-01-16 20:42:35 +00:00
Dave Hibberd 018d733dee
release 2023-12-28 10:45:07 +00:00
Dave Hibberd 851dcb6fd8
first build of new upstream 2023-12-28 10:44:40 +00:00
Dave Hibberd ce4f1b11b0 Update upstream source from tag 'upstream/6.0.24.25'
Update to upstream version '6.0.24.25'
with Debian dir c5f88a7af8
2023-12-28 10:31:16 +00:00
Dave Hibberd 1fbded9d3a
Tested final release for new layout 2023-12-16 14:40:33 +00:00
Dave Hibberd a4103962fc
bpq config move 2023-12-16 13:35:16 +00:00
Dave Hibberd 397da35dac
Release 2023-12-08 12:29:51 +00:00
Dave Hibberd 9c15385cb6
Upstream import 2023-12-08 12:27:53 +00:00
Dave Hibberd fd1249b1e2 Update upstream source from tag 'upstream/6.0.24.22'
Update to upstream version '6.0.24.22'
with Debian dir 0520fb299a
2023-12-08 12:26:59 +00:00
Dave Hibberd fda3d6ffac
Release! 2023-10-31 22:50:30 +00:00
Dave Hibberd 37a1ea33be
Update changelog 2023-10-31 22:47:35 +00:00
Dave Hibberd 78e830ab37 Update upstream source from tag 'upstream/6.0.24.16'
Update to upstream version '6.0.24.16'
with Debian dir 638c20d26e
2023-10-31 22:42:30 +00:00
Dave Hibberd 9155d3ba64
New control file 2023-10-31 22:42:17 +00:00
Dave Hibberd 6adcb91ee5
release 2023-10-15 21:45:42 +01:00
Dave Hibberd 77f96f5b63
Update and add conffiles 2023-10-15 21:40:20 +01:00
Dave Hibberd 6f53d92599
release after successful build 2023-10-10 22:20:19 +01:00
Dave Hibberd 46c6058d94
upstream revision 2023-10-10 22:17:39 +01:00
Dave Hibberd 3e029049d7 Update upstream source from tag 'upstream/6.0.24.15'
Update to upstream version '6.0.24.15'
with Debian dir 55d9f12f07
2023-10-10 22:07:21 +01:00
Dave Hibberd b6a50b9b6c
Release the first version into the wild 2023-08-28 23:21:21 +01:00
Dave Hibberd fc474c29fe
Adding run-as-user and a user with the folder as ~ 2023-08-28 23:18:58 +01:00
Dave Hibberd 6546bac3f5
Updates based on feedback from M0LTE 2023-08-28 21:00:50 +01:00
Dave Hibberd ee2ac63a82
Start with the new 6.0.24.2 from upstream 2023-08-28 20:40:52 +01:00
Dave Hibberd 95a6ab069f
Merge branch 'upstream/latest' into debian/latest 2023-08-28 20:39:34 +01:00
Dave Hibberd 055c1c1891 Tweaks to copyright so it's correct 2023-07-18 01:31:08 +01:00
Dave Hibberd 964b72495c Adding gbp.conf so it builds under gbp 2023-07-18 01:29:10 +01:00
Dave Hibberd acb26fd980 Added Debian packaging so far 2023-07-18 01:26:17 +01:00
88 changed files with 6225 additions and 1458 deletions

View file

@ -509,6 +509,14 @@ UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNo
return Output; return Output;
} }
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions // Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r "); Output += sprintf((char *)Output, " NET/ROM\r ");

View file

@ -3256,9 +3256,9 @@ static VOID ADSBConnect(void * unused)
{ {
err=WSAGetLastError(); err=WSAGetLastError();
#ifdef LINBPQ #ifdef LINBPQ
printf("Connect Failed for ADSB socket - error code = %d\n", err); // printf("Connect Failed for ADSB socket - error code = %d\n", err);
#else #else
Debugprintf("Connect Failed for ADSB socket - error code = %d", err); // Debugprintf("Connect Failed for ADSB socket - error code = %d", err);
#endif #endif
closesocket(TCPSock); closesocket(TCPSock);
ADSBConnected = FALSE; ADSBConnected = FALSE;

View file

@ -441,112 +441,6 @@ HANDLE hMapFile;
// Logging // Logging
static int LogAge = 14;
#ifdef WIN32
int DeleteAPRSLogFiles()
{
WIN32_FIND_DATA ffd;
char szDir[MAX_PATH];
char File[MAX_PATH];
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
LARGE_INTEGER ft;
time_t now = time(NULL);
int Age;
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
strcpy(szDir, GetLogDirectory());
strcat(szDir, "/logs/APRS*.log");
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
return dwError;
// Walk directory
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
OutputDebugString(ffd.cFileName);
}
else
{
ft.HighPart = ffd.ftCreationTime.dwHighDateTime;
ft.LowPart = ffd.ftCreationTime.dwLowDateTime;
ft.QuadPart -= 116444736000000000;
ft.QuadPart /= 10000000;
Age = (int)((now - ft.LowPart) / 86400);
if (Age > LogAge)
{
sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
Debugprintf("Deleting %s", File);
DeleteFile(File);
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
return dwError;
}
#else
#include <dirent.h>
int APRSFilter(const struct dirent * dir)
{
return (memcmp(dir->d_name, "APRS", 4) == 0 && strstr(dir->d_name, ".log"));
}
int DeleteAPRSLogFiles()
{
struct dirent **namelist;
int n;
struct stat STAT;
time_t now = time(NULL);
int Age = 0, res;
char FN[256];
n = scandir("logs", &namelist, APRSFilter, alphasort);
if (n < 0)
perror("scandir");
else
{
while(n--)
{
sprintf(FN, "logs/%s", namelist[n]->d_name);
if (stat(FN, &STAT) == 0)
{
Age = (now - STAT.st_mtime) / 86400;
if (Age > LogAge)
{
Debugprintf("Deleting %s\n", FN);
unlink(FN);
}
}
free(namelist[n]);
}
free(namelist);
}
return 0;
}
#endif
int APRSWriteLog(char * msg) int APRSWriteLog(char * msg)
{ {
FILE *file; FILE *file;
@ -646,8 +540,6 @@ Dll BOOL APIENTRY Init_APRS()
MobileBeaconInterval = 0; MobileBeaconInterval = 0;
BeaconInterval = 0; BeaconInterval = 0;
DeleteAPRSLogFiles();
memset(MHTABLE, 0, sizeof(MHTABLE)); memset(MHTABLE, 0, sizeof(MHTABLE));
ConvToAX25(MYNODECALL, MYCALL); ConvToAX25(MYNODECALL, MYCALL);
@ -7701,25 +7593,25 @@ VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE)
else else
sprintf(Retries, "%d", ptr->Retries); sprintf(Retries, "%d", ptr->Retries);
memcpy(ToLopped, ptr->ToCall, 10); memcpy(ToLopped, ptr->ToCall, 10);
strlop(ToLopped, ' '); strlop(ToLopped, ' ');
OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine, OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine,
ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text); ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text);
ptr = ptr->Next; ptr = ptr->Next;
if (OutputLen > 99000) if (OutputLen > 99000)
break; break;
} }
OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer); OutputLen += sprintf(&OutBuffer[OutputLen], "%s", WebTrailer);
HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen); HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
sendandcheck(sock, Header, HeaderLen); sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, OutBuffer, OutputLen); sendandcheck(sock, OutBuffer, OutputLen);
return; return;
} }

182
ARDOP.c
View file

@ -62,6 +62,12 @@ int (WINAPI FAR *EnumProcessesPtr)();
#include "tncinfo.h" #include "tncinfo.h"
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#define WSA_ACCEPT WM_USER + 1 #define WSA_ACCEPT WM_USER + 1
#define WSA_DATA WM_USER + 2 #define WSA_DATA WM_USER + 2
#define WSA_CONNECT WM_USER + 3 #define WSA_CONNECT WM_USER + 3
@ -460,114 +466,114 @@ static int ProcessLine(char * buf, int Port)
else else
return FALSE; // Must start with ADDR return FALSE; // Must start with ADDR
TNC->InitScript = malloc(1000); TNC->InitScript = malloc(1000);
TNC->InitScript[0] = 0; TNC->InitScript[0] = 0;
ptr = strtok(NULL, " \t\n\r"); ptr = strtok(NULL, " \t\n\r");
if (ptr) if (ptr)
{
if (_stricmp(ptr, "PTT") == 0)
{ {
if (_stricmp(ptr, "PTT") == 0) ptr = strtok(NULL, " \t\n\r");
{
ptr = strtok(NULL, " \t\n\r");
if (ptr)
{
DecodePTTString(TNC, ptr);
ptr = strtok(NULL, " \t\n\r");
}
}
}
if (ptr)
{
if (_memicmp(ptr, "PATH", 4) == 0)
{
p_cmd = strtok(NULL, "\n\r");
if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
}
}
TNC->MaxConReq = 10; // Default
TNC->OldMode = FALSE; // Default
// Read Initialisation lines
while(TRUE)
{
if (GetLine(buf) == 0)
return TRUE;
strcpy(errbuf, buf);
if (memcmp(buf, "****", 4) == 0)
return TRUE;
ptr = strchr(buf, ';');
if (ptr) if (ptr)
{ {
*ptr++ = 13; DecodePTTString(TNC, ptr);
*ptr = 0; ptr = strtok(NULL, " \t\n\r");
} }
}
}
if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0)) if (ptr)
{} // Ignore {
else if (_memicmp(ptr, "PATH", 4) == 0)
/* {
p_cmd = strtok(NULL, "\n\r");
if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
}
}
TNC->MaxConReq = 10; // Default
TNC->OldMode = FALSE; // Default
// Read Initialisation lines
while(TRUE)
{
if (GetLine(buf) == 0)
return TRUE;
strcpy(errbuf, buf);
if (memcmp(buf, "****", 4) == 0)
return TRUE;
ptr = strchr(buf, ';');
if (ptr)
{
*ptr++ = 13;
*ptr = 0;
}
if ((_memicmp(buf, "CAPTURE", 7) == 0) || (_memicmp(buf, "PLAYBACK", 8) == 0))
{} // Ignore
else
/*
if (_memicmp(buf, "PATH", 4) == 0) if (_memicmp(buf, "PATH", 4) == 0)
{ {
char * Context; char * Context;
p_cmd = strtok_s(&buf[5], "\n\r", &Context); p_cmd = strtok_s(&buf[5], "\n\r", &Context);
if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
} }
else else
*/ */
if (_memicmp(buf, "PACKETCHANNELS", 14) == 0) // Packet Channels if (_memicmp(buf, "PACKETCHANNELS", 14) == 0) // Packet Channels
TNC->PacketChannels = atoi(&buf[14]); TNC->PacketChannels = atoi(&buf[14]);
else else
if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect if (_memicmp(buf, "MAXCONREQ", 9) == 0) // Hold Time for Busy Detect
TNC->MaxConReq = atoi(&buf[9]); TNC->MaxConReq = atoi(&buf[9]);
else else
if (_memicmp(buf, "STARTINROBUST", 13) == 0) if (_memicmp(buf, "STARTINROBUST", 13) == 0)
TNC->StartInRobust = TRUE; TNC->StartInRobust = TRUE;
else else
if (_memicmp(buf, "ROBUST", 6) == 0) if (_memicmp(buf, "ROBUST", 6) == 0)
{ {
if (_memicmp(&buf[7], "TRUE", 4) == 0) if (_memicmp(&buf[7], "TRUE", 4) == 0)
TNC->Robust = TRUE; TNC->Robust = TRUE;
strcat (TNC->InitScript, buf); strcat (TNC->InitScript, buf);
} }
else else
if (_memicmp(buf, "LOGDIR ", 7) == 0) if (_memicmp(buf, "LOGDIR ", 7) == 0)
TNC->LogPath = _strdup(&buf[7]); TNC->LogPath = _strdup(&buf[7]);
else else
if (_memicmp(buf, "ENABLEPACKET", 12) == 0) if (_memicmp(buf, "ENABLEPACKET", 12) == 0)
{ {
if (TNC->PacketChannels == 0) if (TNC->PacketChannels == 0)
TNC->PacketChannels = 5; TNC->PacketChannels = 5;
// AddVirtualKISSPort(TNC, Port, buf); // AddVirtualKISSPort(TNC, Port, buf);
} }
// else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0) // else if (_memicmp(buf, "PAC ", 4) == 0 && _memicmp(buf, "PAC MODE", 8) != 0)
// { // {
// PAC MODE goes to TNC, others are parsed locally // PAC MODE goes to TNC, others are parsed locally
// //
// ConfigVirtualKISSPort(TNC, buf); // ConfigVirtualKISSPort(TNC, buf);
// } // }
else if (standardParams(TNC, buf) == FALSE) else if (standardParams(TNC, buf) == FALSE)
strcat(TNC->InitScript, buf); strcat(TNC->InitScript, buf);
} }
return (TRUE); return (TRUE);
} }
void ARDOPThread(struct TNCINFO * TNC); void ARDOPThread(VOID * Param);
VOID ARDOPProcessDataSocketData(int port); VOID ARDOPProcessDataSocketData(int port);
int ConnecttoARDOP(struct TNCINFO * TNC); int ConnecttoARDOP(struct TNCINFO * TNC);
static VOID ARDOPProcessReceivedData(struct TNCINFO * TNC); static VOID ARDOPProcessReceivedData(struct TNCINFO * TNC);
@ -1035,8 +1041,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{ {
TNC->Busy--; TNC->Busy--;
if (TNC->Busy == 0) if (TNC->Busy == 0)
{
MySetWindowText(TNC->xIDC_CHANSTATE, "Clear"); MySetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear");
}
} }
} }
@ -2312,12 +2320,13 @@ int ConnecttoARDOP(struct TNCINFO * TNC)
return 0; return 0;
} }
VOID ARDOPThread(struct TNCINFO * TNC) VOID ARDOPThread(VOID * Param)
{ {
// Opens sockets and looks for data on control and data sockets. // Opens sockets and looks for data on control and data sockets.
// Socket may be TCP/IP or Serial // Socket may be TCP/IP or Serial
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -5758,8 +5767,7 @@ VOID ARDOPSCSPoll(struct TNCINFO * TNC)
// Probably only for Teensy with ESP01. Runs SCS Emulator over a TCP Link // Probably only for Teensy with ESP01. Runs SCS Emulator over a TCP Link
VOID SerialConnecttoTCPThread(VOID * Param);
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC);
int SerialConnecttoTCP(struct TNCINFO * TNC) int SerialConnecttoTCP(struct TNCINFO * TNC)
{ {
@ -5767,9 +5775,9 @@ int SerialConnecttoTCP(struct TNCINFO * TNC)
return 0; return 0;
} }
VOID SerialConnecttoTCPThread(VOID * Param)
VOID SerialConnecttoTCPThread(struct TNCINFO * TNC)
{ {
struct TNCINFO * TNC = (struct TNCINFO *) Param;
char Msg[255]; char Msg[255];
int i; int i;
u_long param = 1; u_long param = 1;

View file

@ -118,6 +118,7 @@ void ReleaseWebMailStruct(WebMailInfo * WebMail);
VOID TidyWelcomeMsg(char ** pPrompt); VOID TidyWelcomeMsg(char ** pPrompt);
int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param, char * Token); int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param, char * Token);
void UndoTransparency(char * input); void UndoTransparency(char * input);
int GetMessageSlotFromMessageNumber(int msgno);
char UNC[] = ""; char UNC[] = "";
char CHKD[] = "checked=checked "; char CHKD[] = "checked=checked ";
@ -1455,7 +1456,7 @@ VOID SaveHousekeeping(struct HTTPConnectionInfo * Session, char * MsgPtr, char *
GetParam(input, "MaxAge=", Temp); GetParam(input, "MaxAge=", Temp);
MaxAge = atoi(Temp); MaxAge = atoi(Temp);
GetParam(input, "LogLife=", Temp); GetParam(input, "LogLife=", Temp);
LogAge = atoi(Temp); BBSLogAge = atoi(Temp);
GetParam(input, "UserLife=", Temp); GetParam(input, "UserLife=", Temp);
UserLifetime= atoi(Temp); UserLifetime= atoi(Temp);
@ -2442,8 +2443,8 @@ VOID ProcessMsgFwdUpdate(struct HTTPConnectionInfo * Session, char * MsgPtr, cha
set_fwd_bit(Msg->fbbs, BBSNumber); set_fwd_bit(Msg->fbbs, BBSNumber);
User->ForwardingInfo->MsgCount++; User->ForwardingInfo->MsgCount++;
clear_fwd_bit(Msg->forw, BBSNumber); clear_fwd_bit(Msg->forw, BBSNumber);
if (FirstMessageIndextoForward > Msg->number) if (FirstMessageIndextoForward > GetMessageSlotFromMessageNumber(Msg->number))
FirstMessageIndextoForward = Msg->number; FirstMessageIndextoForward = GetMessageSlotFromMessageNumber(Msg->number);
} }
*RLen = SendMessageDetails(Msg, Reply, Session->Key); *RLen = SendMessageDetails(Msg, Reply, Session->Key);
@ -2665,7 +2666,7 @@ VOID SendHouseKeeping(char * Reply, int * ReplyLen, char * Key)
*ReplyLen = sprintf(Reply, HousekeepingTemplate, *ReplyLen = sprintf(Reply, HousekeepingTemplate,
BBSName, Key, Key, Key, Key, Key, Key, Key, Key, Key, BBSName, Key, Key, Key, Key, Key, Key, Key, Key, Key,
MaintTime, MaintInterval, MaxMsgno, BidLifetime, LogAge, UserLifetime, MaintTime, MaintInterval, MaxMsgno, BidLifetime, BBSLogAge, UserLifetime,
(DeletetoRecycleBin) ? CHKD : UNC, (DeletetoRecycleBin) ? CHKD : UNC,
(SendNonDeliveryMsgs) ? CHKD : UNC, (SendNonDeliveryMsgs) ? CHKD : UNC,
(SuppressMaintEmail) ? CHKD : UNC, (SuppressMaintEmail) ? CHKD : UNC,

View file

@ -532,6 +532,19 @@ struct MsgInfo * GetMsgFromNumber(int msgno)
return MsgnotoMsg[msgno]; return MsgnotoMsg[msgno];
} }
int GetMessageSlotFromMessageNumber(int msgno)
{
int i;
for (i=1; i <= NumberofMessages; i++)
{
if (MsgHddrPtr[i]->number == msgno)
return i;
}
return 0;
}
struct UserInfo * AllocateUserRecord(char * Call) struct UserInfo * AllocateUserRecord(char * Call)
{ {
struct UserInfo * User = zalloc(sizeof (struct UserInfo)); struct UserInfo * User = zalloc(sizeof (struct UserInfo));
@ -3688,10 +3701,10 @@ void DoKillCommand(CIRCUIT * conn, struct UserInfo * user, char * Cmd, char * Ar
if (conn->sysop) if (conn->sysop)
{ {
if (Arg1) if (Arg1)
if (KillMessagesFrom(conn, user, Arg1) == 0); if (KillMessagesFrom(conn, user, Arg1) == 0)
BBSputs(conn, "No Messages found\r"); BBSputs(conn, "No Messages found\r");
return; return;
} }
} }
@ -6543,7 +6556,7 @@ nextline:
{ {
char APRS[128]; char APRS[128];
char Call[16]; char Call[16];
int SSID = user->flags >> 28; int SSID = (user->flags >> 28) & 15; // on some platforms this is treated as signed ??
if (SSID) if (SSID)
sprintf(Call, "%s-%d", Msg->to, SSID); sprintf(Call, "%s-%d", Msg->to, SSID);
@ -9926,8 +9939,8 @@ VOID SaveConfig(char * ConfigName)
SaveIntValue(group, "MaxMsgno", MaxMsgno); SaveIntValue(group, "MaxMsgno", MaxMsgno);
SaveIntValue(group, "BidLifetime", BidLifetime); SaveIntValue(group, "BidLifetime", BidLifetime);
SaveIntValue(group, "MaxAge", MaxAge); SaveIntValue(group, "MaxAge", MaxAge);
SaveIntValue(group, "LogLifetime", LogAge); SaveIntValue(group, "LogLifetime", BBSLogAge);
SaveIntValue(group, "LogLifetime", LogAge); SaveIntValue(group, "LogLifetime", BBSLogAge);
SaveIntValue(group, "MaintInterval", MaintInterval); SaveIntValue(group, "MaintInterval", MaintInterval);
SaveIntValue(group, "UserLifetime", UserLifetime); SaveIntValue(group, "UserLifetime", UserLifetime);
SaveIntValue(group, "MaintTime", MaintTime); SaveIntValue(group, "MaintTime", MaintTime);
@ -10588,7 +10601,7 @@ BOOL GetConfig(char * ConfigName)
LastHouseKeepingTime = GetIntValue(group, "LastHouseKeepingTime"); LastHouseKeepingTime = GetIntValue(group, "LastHouseKeepingTime");
LastTrafficTime = GetIntValue(group, "LastTrafficTime"); LastTrafficTime = GetIntValue(group, "LastTrafficTime");
MaxMsgno = GetIntValue(group, "MaxMsgno"); MaxMsgno = GetIntValue(group, "MaxMsgno");
LogAge = GetIntValue(group, "LogLifetime"); BBSLogAge = GetIntValue(group, "LogLifetime");
BidLifetime = GetIntValue(group, "BidLifetime"); BidLifetime = GetIntValue(group, "BidLifetime");
MaxAge = GetIntValue(group, "MaxAge"); MaxAge = GetIntValue(group, "MaxAge");
if (MaxAge == 0) if (MaxAge == 0)
@ -13382,7 +13395,7 @@ int DeleteRedundantMessages()
{ {
while(n--) while(n--)
{ {
if (stat(namelist[n]->d_name, &STAT) == 0); if (stat(namelist[n]->d_name, &STAT) == 0)
{ {
Msgno = atoi(&namelist[n]->d_name[2]); Msgno = atoi(&namelist[n]->d_name[2]);

857
BPQINP3.c

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -1155,6 +1155,7 @@
// Validate Mode and Frequency and fix formatting in Connected Message (71) // Validate Mode and Frequency and fix formatting in Connected Message (71)
// Fix using OpenBCM on other than Telnet connections (75) // Fix using OpenBCM on other than Telnet connections (75)
// Fix sending + in Webmail (80) // Fix sending + in Webmail (80)
// Fix forwarding problem when using Web interface to change message routing (73)
#include "bpqmail.h" #include "bpqmail.h"
#include "winstdint.h" #include "winstdint.h"

View file

@ -731,7 +731,7 @@ VOID WINAPI OnSelChanged(HWND hwndDlg)
SetDlgItemInt(pHdr->hwndDisplay, IDC_MAXMSG, MaxMsgno, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_MAXMSG, MaxMsgno, FALSE);
SetDlgItemInt(pHdr->hwndDisplay, IDC_BIDLIFETIME, BidLifetime, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_BIDLIFETIME, BidLifetime, FALSE);
SetDlgItemInt(pHdr->hwndDisplay, IDC_USERLIFETIME, UserLifetime, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_USERLIFETIME, UserLifetime, FALSE);
SetDlgItemInt(pHdr->hwndDisplay, IDC_LOGLIFETIME, LogAge, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_LOGLIFETIME, BBSLogAge, FALSE);
SetDlgItemInt(pHdr->hwndDisplay, IDC_MAINTINTERVAL, MaintInterval, FALSE); SetDlgItemInt(pHdr->hwndDisplay, IDC_MAINTINTERVAL, MaintInterval, FALSE);
sprintf(Time, "%04d", MaintTime); sprintf(Time, "%04d", MaintTime);
SetDlgItemText(pHdr->hwndDisplay, IDC_MAINTTIME, Time); SetDlgItemText(pHdr->hwndDisplay, IDC_MAINTTIME, Time);
@ -1979,7 +1979,7 @@ VOID SaveMAINTConfigFromDialog()
if (MaxMsgno > 99000) MaxMsgno = 99000; if (MaxMsgno > 99000) MaxMsgno = 99000;
BidLifetime = GetDlgItemInt(hwndDisplay, IDC_BIDLIFETIME, &OK1, FALSE); BidLifetime = GetDlgItemInt(hwndDisplay, IDC_BIDLIFETIME, &OK1, FALSE);
LogAge = GetDlgItemInt(hwndDisplay, IDC_LOGLIFETIME, &OK1, FALSE); BBSLogAge = GetDlgItemInt(hwndDisplay, IDC_LOGLIFETIME, &OK1, FALSE);
UserLifetime = GetDlgItemInt(hwndDisplay, IDC_USERLIFETIME, &OK1, FALSE); UserLifetime = GetDlgItemInt(hwndDisplay, IDC_USERLIFETIME, &OK1, FALSE);
MaintInterval = GetDlgItemInt(hwndDisplay, IDC_MAINTINTERVAL, &OK1, FALSE); MaintInterval = GetDlgItemInt(hwndDisplay, IDC_MAINTINTERVAL, &OK1, FALSE);
MaintTime = GetDlgItemInt(hwndDisplay, IDC_MAINTTIME, &OK1, FALSE); MaintTime = GetDlgItemInt(hwndDisplay, IDC_MAINTTIME, &OK1, FALSE);
@ -2657,7 +2657,7 @@ BOOL GetConfigFromRegistry()
Vallen=4; Vallen=4;
RegQueryValueEx(hKey,"LogLifetime",0, RegQueryValueEx(hKey,"LogLifetime",0,
(ULONG *)&Type,(UCHAR *)&LogAge,(ULONG *)&Vallen); (ULONG *)&Type,(UCHAR *)&BBSLogAge,(ULONG *)&Vallen);
Vallen=4; Vallen=4;
retCode += RegQueryValueEx(hKey,"BidLifetime",0, retCode += RegQueryValueEx(hKey,"BidLifetime",0,

View file

@ -45,6 +45,8 @@ extern VOID Q_ADD();
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
TRANSPORTENTRY * NRRSession; TRANSPORTENTRY * NRRSession;
int NRRID = 1; // Id to correlate requests and responses
/* /*
datagrams (and other things) to be transported in Netrom L3 frames. datagrams (and other things) to be transported in Netrom L3 frames.
@ -75,7 +77,9 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
{ {
UCHAR * BUFFER = GetBuff(); UCHAR * BUFFER = GetBuff();
UCHAR * ptr1; UCHAR * ptr1;
struct _MESSAGE * Msg; struct _MESSAGE * Msg1;
time_t Now = time(NULL);
int ID = (Msg->L4TXNO << 8) | Msg->L4RXNO;
if (BUFFER == NULL) if (BUFFER == NULL)
return; return;
@ -84,7 +88,18 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
*ptr1++ = 0xf0; // PID *ptr1++ = 0xf0; // PID
ptr1 += sprintf(ptr1, "NRR Response:");
if (BUFFER == NULL)
return;
ptr1 = &BUFFER[MSGHDDRLEN];
*ptr1++ = 0xf0; // PID
if (ID == NRRSession->NRRID)
ptr1 += sprintf(ptr1, "NRR Response in %d Secs:", (int)(Now - NRRSession->NRRTime));
else
ptr1 += sprintf(ptr1, "NRR Response:", (int)(Now - NRRSession->NRRTime));
Buff += 21 + MSGHDDRLEN; Buff += 21 + MSGHDDRLEN;
Len -= (21 + MSGHDDRLEN); Len -= (21 + MSGHDDRLEN);
@ -97,7 +112,7 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
if ((Buff[7] & 0x80) == 0x80) // Check turnround bit if ((Buff[7] & 0x80) == 0x80) // Check turnround bit
*ptr1++ = '*'; *ptr1++ = '*';
Buff+=8; Buff += 8;
Len -= 8; Len -= 8;
} }
@ -111,11 +126,11 @@ VOID NRRecordRoute(UCHAR * Buff, int Len)
Len = (int)(ptr1 - BUFFER); Len = (int)(ptr1 - BUFFER);
Msg = (struct _MESSAGE *)BUFFER; Msg1 = (struct _MESSAGE *)BUFFER;
Msg->LENGTH = Len; Msg1->LENGTH = Len;
Msg->CHAIN = NULL; Msg1->CHAIN = NULL;
C_Q_ADD(&NRRSession->L4TX_Q, (UINT *)BUFFER); C_Q_ADD(&NRRSession->L4TX_Q, (UINT *)BUFFER);
@ -183,11 +198,16 @@ VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
Msg->L4ID = 1; Msg->L4ID = 1;
Msg->L4INDEX = 0; Msg->L4INDEX = 0;
Msg->L4FLAGS = 0; Msg->L4FLAGS = 0;
Msg->L4TXNO = NRRID << 8;
Msg->L4RXNO = NRRID & 0xff;
memcpy(Msg->L4DATA, MYCALL, 7); memcpy(Msg->L4DATA, MYCALL, 7);
Msg->L4DATA[7] = Stream + 28; Msg->L4DATA[7] = Stream + 28;
Msg->LENGTH = 8 + 21 + MSGHDDRLEN; Msg->LENGTH = 8 + 21 + MSGHDDRLEN;
Session->NRRTime = time(NULL);
Session->NRRID = NRRID++;
C_Q_ADD(&DEST->DEST_Q, Msg); C_Q_ADD(&DEST->DEST_Q, Msg);
} }

View file

@ -2974,6 +2974,30 @@ LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
if (wParam == 0x7) // BEL (Ctrl/G)
{
// Get buffer, append 07 and write back
Cinfo->kbptr = SendMessage(Cinfo->hwndInput, WM_GETTEXT, INPUTLEN-1,
(LPARAM) (LPCSTR)Cinfo->kbbuf);
Cinfo->kbbuf[Cinfo->kbptr++] = 7;
Cinfo->kbbuf[Cinfo->kbptr] = 0;
SendMessage(Cinfo->hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) Cinfo->kbbuf);
// Send cursor right
for (i = 0; i < strlen(Cinfo->kbbuf); i++)
{
SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0);
SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0);
}
return 0;
}
} }
return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam); return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam);

218
Bpq32.c
View file

@ -1180,7 +1180,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix processing of the Winlink API /account/exists response (82) // Fix processing of the Winlink API /account/exists response (82)
// Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set // Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set
// Version 6.0.25.? // Version 6.0.25.1 Sept 2025
// Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers // Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers
// Add Chat PACLEN config (5) // Add Chat PACLEN config (5)
@ -1280,6 +1280,36 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix possible FRMR when RNR is cleared by SREJ (78) // Fix possible FRMR when RNR is cleared by SREJ (78)
// Fix error in .77 L4Compress fix (mine, not Steve's!) (78) // Fix error in .77 L4Compress fix (mine, not Steve's!) (78)
// Fix possible stuck L2 session when handling SREJ (79) // Fix possible stuck L2 session when handling SREJ (79)
// Allow sending CTRL/G From console (Windows) (80)
// Fix Webmail autorefresh extra threads problem (websock connection lost handling) (82)
// Fix overwriting application alias (83)
// Version 6.0.26.?
// Fix for compiling with gcc15 (2)
// Fix possble stuck L2 session caused by window being set to zero (3)
// Improvments to INP3 (4, 5)
// Add Node API /api/tcpqueues (5)
// Add sending link events to OARC API (disabled by default) (6)
// Add option to write monitor output to a file (6)
// Fix possible program error in Telnet_Connected (7)
// Close links when program is closed down (7)
// Fix possible problem with deleting routes when using both NODES and INP3 routing on same link (7)
// Add Paula's Netromx (allows connects to different applications using Node call) (8)
// Add Netrom over TCP (8)
// Fix FRMR caused by sending SREJ when no frames outstanding (8)
// Fix some issues with NetromX connects and Route Selection when running INP3 and NODES routing (9)
// Fix connecting to a netrom node with c p node command (10)
// Add validation of INP3 RTT messages and various INP3 fixes (12)
// Change NetromX connect syntax to Service@Node to fix passing commands to local applications (12)
// Add config file option to enable writing monitor data to a file at startup (13)
// Add option to use V2.0 on a route (14)
// Don't reset NS on RR R(F) following I(P) just on RR poll following timeout. Can get problems with delayed RR R(F) (reverted) (14)
// Ignore packets that would cause an FRMR and respond to FRMR with DM (14)
// Add option to send periodic INP3 RIF refresh (15)
#define CKernel #define CKernel
@ -1374,6 +1404,8 @@ void * HSMODEMExtInit(EXTPORTDATA * PortEntry);
void * FreeDataExtInit(EXTPORTDATA * PortEntry); void * FreeDataExtInit(EXTPORTDATA * PortEntry);
void * SIXPACKExtInit(EXTPORTDATA * PortEntry); void * SIXPACKExtInit(EXTPORTDATA * PortEntry);
VOID RealCloseAllPrograms();
extern char * ConfigBuffer; // Config Area extern char * ConfigBuffer; // Config Area
VOID REMOVENODE(dest_list * DEST); VOID REMOVENODE(dest_list * DEST);
DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall); DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall);
@ -1383,6 +1415,9 @@ VOID ADIFWriteFreqList();
void SaveAIS(); void SaveAIS();
void initAIS(); void initAIS();
void initADSB(); void initADSB();
int CloseAllSessions();
int CloseAllLinks();
void NETROMTCPResolve();
extern BOOL ADIFLogEnabled; extern BOOL ADIFLogEnabled;
@ -1390,6 +1425,8 @@ int CloseOnError = 0;
char UIClassName[]="UIMAINWINDOW"; // the main window class name char UIClassName[]="UIMAINWINDOW"; // the main window class name
char ClosingClassName[]="CLOSING"; // the main window class name
HWND UIhWnd; HWND UIhWnd;
extern char AUTOSAVE; extern char AUTOSAVE;
@ -1441,7 +1478,8 @@ extern char MYCALL[]; // 7 chars, ax.25 format
extern HWND hIPResWnd; extern HWND hIPResWnd;
extern BOOL IPMinimized; extern BOOL IPMinimized;
extern int NODESINPROGRESS; extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern VOID * CURRENTNODE; extern VOID * CURRENTNODE;
@ -1511,7 +1549,6 @@ extern char ReportDest[7];
extern UCHAR ConfigDirectory[260]; extern UCHAR ConfigDirectory[260];
extern uint64_t timeLoadedMS;
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...);
@ -1629,6 +1666,8 @@ BOOL IGateEnabled = TRUE;
extern int ISDelayTimer; // Time before trying to reopen APRS-IS link extern int ISDelayTimer; // Time before trying to reopen APRS-IS link
extern int ISPort; extern int ISPort;
int CLOSING = 0;
UINT * WINMORTraceQ = NULL; UINT * WINMORTraceQ = NULL;
UINT * SetWindowTextQ = NULL; UINT * SetWindowTextQ = NULL;
@ -1684,6 +1723,8 @@ BOOL ReconfigFlag = FALSE;
BOOL RigReconfigFlag = FALSE; BOOL RigReconfigFlag = FALSE;
BOOL APRSReconfigFlag = FALSE; BOOL APRSReconfigFlag = FALSE;
BOOL CloseAllNeeded = FALSE; BOOL CloseAllNeeded = FALSE;
int CloseAllTimer = 0;
BOOL NeedWebMailRefresh = FALSE; BOOL NeedWebMailRefresh = FALSE;
int AttachedPIDList[100] = {0}; int AttachedPIDList[100] = {0};
@ -2188,6 +2229,8 @@ VOID TimerProcX()
Start(); Start();
NETROMTCPResolve();
INITIALISEPORTS(); // Restart Ports INITIALISEPORTS(); // Restart Ports
SetApplPorts(); SetApplPorts();
@ -2365,6 +2408,52 @@ VOID TimerProcX()
CheckGuardZone(); CheckGuardZone();
if (CloseAllTimer == 50) // First entry
{
if (CloseAllSessions() == 0)
{
if (CloseAllLinks() == 0) // No sessions closed so close links now
CloseAllTimer = 1; // No Links so close now
else
CloseAllTimer = 39; // ~4 secs for links to close
}
}
if (CloseAllTimer == 40) // First entry
CloseAllLinks(); // No sessions closed so close links now
if (CloseAllTimer)
{
// See if any links left
struct _LINKTABLE * LINK = LINKS;
int i = MAXLINKS;
if (CloseAllTimer == 0)
RealCloseAllPrograms();
while (i--)
{
if (LINK->LINKCALL[0])
{
break;
}
if (i == 0)
{
CloseAllTimer = 0;
RealCloseAllPrograms();
return;
}
LINK++;
continue;
}
CloseAllTimer--;
if(CloseAllTimer == 0)
RealCloseAllPrograms();
}
return; return;
} }
@ -2400,8 +2489,6 @@ FirstInit()
EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses"); EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses");
} }
timeLoadedMS = GetTickCount();
srand(time(NULL)); srand(time(NULL));
INITIALISEPORTS(); INITIALISEPORTS();
@ -2558,6 +2645,7 @@ Check_Timer()
WSAStartup(MAKEWORD(2, 0), &WsaData); WSAStartup(MAKEWORD(2, 0), &WsaData);
// Load Psapi.dll if possible // Load Psapi.dll if possible
ExtDriver = LoadLibrary("Psapi.dll"); ExtDriver = LoadLibrary("Psapi.dll");
@ -2572,6 +2660,8 @@ Check_Timer()
Start(); Start();
NETROMTCPResolve();
INITIALISEPORTS(); INITIALISEPORTS();
OpenReportingSockets(); OpenReportingSockets();
@ -2739,6 +2829,12 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser
return 0; return 0;
} }
if (sizeof(struct NR_DEST_ROUTE_ENTRY) != sizeof(struct INP3_DEST_ROUTE_ENTRY))
{
MessageBox(NULL,"Route Entry mismatch - fix and rebuild", "BPQ32", MB_OK);
return 0;
}
GetSemaphore(&Semaphore, 4); GetSemaphore(&Semaphore, 4);
BPQHOSTVECPTR = &BPQHOSTVECTOR[0]; BPQHOSTVECPTR = &BPQHOSTVECTOR[0];
@ -2895,6 +2991,8 @@ BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReser
} }
else else
{ {
NETROMTCPResolve();
SetApplPorts(); SetApplPorts();
GetUIConfig(); GetUIConfig();
@ -4134,12 +4232,11 @@ int APIENTRY Restart()
hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TimerInst); hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TimerInst);
if (hProc) if (hProc)
{ {
TerminateProcess(hProc, 0); TerminateProcess(hProc, 0);
CloseHandle(hProc); CloseHandle(hProc);
} }
return 0; return 0;
} }
@ -5891,13 +5988,106 @@ DllExport VOID APIENTRY CreateNewTrayIcon()
trayMenu = NULL; trayMenu = NULL;
} }
void hookNodeClosing(char * Reason);
BOOL CALLBACK ClosaAllProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_CTLCOLORDLG:
return (LONG)bgBrush;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(0, 0, 0));
SetBkMode(hdcStatic, TRANSPARENT);
return (LONG)bgBrush;
}
case WM_COMMAND:
return 0;
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId)
{
case SC_RESTORE:
return (DefWindowProc(hWnd, message, wParam, lParam));
case SC_MINIMIZE:
if (MinimizetoTray)
return ShowWindow(hWnd, SW_HIDE);
else
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_CLOSE:
return(DestroyWindow(hWnd));
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
HWND hwndClosing = NULL; // Window handle of dialog box
DllExport VOID APIENTRY CloseAllPrograms() DllExport VOID APIENTRY CloseAllPrograms()
{ {
// HANDLE hProc; WNDCLASS wc;
CLOSING = TRUE;
// Close all attached BPQ32 programs // Tell BG to shut when all links are gone or after 5 secs
Closing = TRUE; CloseAllTimer = 50;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = ClosaAllProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClosingClassName;
RegisterClass(&wc);
hwndClosing = CreateDialog(hInstance, ClosingClassName, NULL, (DLGPROC)ClosaAllProc);
ShowWindow(hwndClosing, SW_SHOW);
}
VOID RealCloseAllPrograms()
{
hookNodeClosing("Shutdown");
Sleep(500);
Closing = 1;
ShowWindow(FrameWnd, SW_RESTORE); ShowWindow(FrameWnd, SW_RESTORE);

View file

@ -999,8 +999,11 @@ LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Send cursor right // Send cursor right
SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0); for (i = 0; i < strlen(Cinfo->kbbuf); i++)
SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0); {
SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0);
SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0);
}
return 0; return 0;
} }

535
Cmd.c
View file

@ -17,9 +17,7 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/ */
//
// C replacement for cmd.asm
//
#define Kernel #define Kernel
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
@ -44,8 +42,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "tncinfo.h" #include "tncinfo.h"
#include "telnetserver.h" #include "telnetserver.h"
//#include "GetVersion.h" //#include "GetVersion.h"
//#define DllImport __declspec( dllimport ) //#define DllImport __declspec( dllimport )
@ -73,7 +69,9 @@ int seeifInterlockneeded(struct PORTCONTROL * PORT);
int CompareNode(const void *a, const void *b); int CompareNode(const void *a, const void *b);
int CompareAlias(const void *a, const void *b); int CompareAlias(const void *a, const void *b);
int CompareRoutes(const void * a, const void * b); int CompareRoutes(const void * a, const void * b);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy, int Service);
VOID sendAlltoOneNeigbour(struct ROUTE * Route);
extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer); extern VOID KISSTX(struct KISSINFO * KISS, PMESSAGE Buffer);
@ -86,6 +84,8 @@ UCHAR SAVEDAPPLFLAGS = 0;
UCHAR ALIASINVOKED = 0; UCHAR ALIASINVOKED = 0;
extern int MONTOFILEFLAG;
extern int RIFInterval;
VOID * CMDPTR = 0; VOID * CMDPTR = 0;
@ -132,6 +132,8 @@ int NOBUFFCOUNT = 0;
int BUFFERWAITS = 0; int BUFFERWAITS = 0;
int MAXDESTS = 0; int MAXDESTS = 0;
int NUMBEROFNODES = 0; int NUMBEROFNODES = 0;
int L2CONNECTSOUT = 0;
int L2CONNECTSIN = 0;
int L4CONNECTSOUT = 0; int L4CONNECTSOUT = 0;
int L4CONNECTSIN = 0; int L4CONNECTSIN = 0;
int L4FRAMESTX = 0; int L4FRAMESTX = 0;
@ -155,13 +157,15 @@ char * ALIASPTR = &CMDALIAS[0][0];
extern int RigReconfigFlag; extern int RigReconfigFlag;
extern int DEBUGINP3;
extern int PREFERINP3ROUTES;
struct CMDX COMMANDS[]; struct CMDX COMMANDS[];
int CMDXLEN = sizeof (struct CMDX); int CMDXLEN = sizeof (struct CMDX);
VOID SENDNODESMSG(); VOID SENDNODESMSG(int Portnum);
VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID KISSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID STOPCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD); VOID STARTCMS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);
@ -187,6 +191,54 @@ VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
/* Paula's NetROMX includes a service number in a CREQX message which allows a node to host lots of applications without
filling the Nodes table with SSID's
I could make these (or some of them) BPQ Commands but some will clash (eg INFO) or match an existing APPL (eg BBS)
I could use C APPL@CALL for an extended call to a node
Maybe I can detect APPL NODE so Paula's syntax will work
or both??
Standard Services are:
*/
struct NETROMX SERVICES[] = {
{0, "CMD"}, // Normal connection to Node's command line
{1, "INFO"}, // Standard Information server
{2, "PMS"}, // Personal Message System
{3, "BBS"}, // (reserved for Bulletin Board System)
{4, "DX"}, // (reserved for DX cluster/dx-spot feed)
{5, "TPP"}, // (reserved for "Tampa Ping-Pong" chat)
{7, "ECHO"}, // Echoes data back to sender
{8, "XRCHAT"}, // XRChat server
{9, "DISCARD"}, // Data sink
{10, "RMS"}, // (reserved for winlink RMS}
{11, "CHAT"}, // (reserved for BPQ chat server)
{13, "DAYTIME"}, // Local date/time (similar to RFC867)
{14, "APRS"}, // APRS Server
{15, "CUSTINF"},// (reserved for custom information file server)
{16, "WX"}, // Local weather information
{17, "TELEM"}, // (reserved for Telemetry server)
{18, "SMS"}, // Short Message System server
{19, "CHARGEN"},// Generates a test pattern
{20, "NDATA"}, // (reserved for NFTP extension)
{21, "NFTP"}, // Netrom File Transfer Protocol
{22, "NSSH"}, // (reserved for secure login - if legal?)
{23, "TELNET"}, // Normal L4 login (same as 0)
{25, "SMTP"}, // (reserved for Simple Mail Transfer Protocol)
{26, "MHEARD"}, // MHEARD server (shows MH lists)
{27, "DXLIST"}, // DX List server (shows DX lists)
{79, "FINGER"}, // Finger server
{80, "HTTP"}, // NetromWeb (HTTP over Netrom) server
{87, "NTTY"}, // Netrom TTY - Keyboard to keyboard chat
{1883, "MQTT"} // MQTT server
};
int NUMBEROFSSERVICES = sizeof(SERVICES)/sizeof(struct NETROMX);
char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...) char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...)
{ {
@ -249,10 +301,111 @@ char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char
return Bufferptr + MsgLen; return Bufferptr + MsgLen;
} }
VOID POLLNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT = 0;
MESSAGE * Buffer;
UCHAR * ptr1;
if (Portnum)
PORT = GetPortTableEntryFromPortNum(Portnum);
if (Portnum == 0 || PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (PORT->PORTQUALITY == 0 || PORT->INP3ONLY)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Quality = 0 or INP3 Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Buffer = GetBuff();
if (Buffer == 0)
return;
Buffer->PORT = Portnum;
memcpy(Buffer->ORIGIN, NETROMCALL, 7);
memcpy(Buffer->DEST, NODECALL, 7);
Buffer->ORIGIN[6] |= 0x61; // SET CMD END AND RESERVED BITS
Buffer->CTL = UI;
Buffer->PID = 0xCF; // Netrom
ptr1 = &Buffer->L2DATA[0];
*(ptr1++) = 0xfe; // Nodes Poll Flag
memcpy(ptr1, MYALIASTEXT, 6);
ptr1+= 6;
Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer);
if (PORT->TNC && PORT->TNC->Hardware == H_VARA)
SendVARANetromNodes(PORT->TNC, Buffer);
else
PUT_ON_PORT_Q(PORT, Buffer);
strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
VOID SENDRIF(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
struct ROUTE * Route;
int Portnum = atoi(CmdTail);
unsigned char axCall[7];
char * Call = strlop(CmdTail, ' ');
if (Call && Portnum)
{
ConvToAX25(Call, axCall);
if (FindNeighbour(axCall, Portnum, &Route))
{
sendAlltoOneNeigbour(Route);
strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
Bufferptr = Cmdprintf(Session, Bufferptr, "Route not found\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) VOID SENDNODES(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{ {
SENDNODESMSG(); int Portnum = atoi(CmdTail);
struct PORTCONTROL * PORT;
if (Portnum)
{
PORT = GetPortTableEntryFromPortNum(Portnum);
if (PORT == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Port\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
}
SENDNODESMSG(Portnum);
strcpy(Bufferptr, OKMSG); strcpy(Bufferptr, OKMSG);
Bufferptr += (int)strlen(OKMSG); Bufferptr += (int)strlen(OKMSG);
@ -717,6 +870,120 @@ BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySess
return FALSE; return FALSE;
} }
void ConnecttoService(TRANSPORTENTRY * Session, char * Bufferptr, int Service, char * Node, int Stay)
{
struct DEST_LIST * Dest = DESTS;
int n = MAXDESTS;
int gotDest = 0;
unsigned char axcall[7];
char cmdName[80];
int i;
// Make Sure Node is Known
strcat(Node, " "); // Node table has 6 byte Aliases
while (n--)
{
if (memcmp(Dest->DEST_ALIAS, Node, 6) == 0)
{
gotDest = 1;
break;
}
Dest++;
}
if (gotDest == 0)
{
Dest = DESTS;
n = MAXDESTS;
ConvToAX25(Node, axcall);
while (n--)
{
if (CompareCalls(Dest->DEST_CALL, axcall))
{
gotDest = 1;
break;
}
Dest++;
}
}
strlop(Node, ' ');
if (gotDest == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Node %s not found\r", Node);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Session->STAYFLAG = Stay;
// Get command name if a named command
sprintf(cmdName, "%d", Service); // default to number
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (SERVICES[i].ServiceNo == Service)
{
strcpy(cmdName, SERVICES[i].ServiceName);
break;
}
}
Bufferptr = Cmdprintf(Session, Bufferptr, "Connecting to Service %s on Node %s \r", cmdName, Node);
DoNetromConnect(Session, Bufferptr, Dest, 0, Service);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
}
int checkifService(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{
char APPName[13];
int n = 12;
BOOL Stay = FALSE;
char * ptr, *Context;
int i;
char TailCopy[256];
strcpy(TailCopy, CmdTail);
ptr = strtok_s(TailCopy, " ", &Context);
// see if any param. if longer than two chars treat as remote node
if (ptr == 0 || strlen(ptr) < 3)
return 0;
memcpy(APPName, CMD->String, 13);
strlop(APPName, ' ');
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
// See if APPL is one of Paula's service
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(APPName, SERVICES[i].ServiceName) == 0)
{
ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, ptr, Stay);
return 1;
}
}
return 0;
}
VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{ {
BOOL CONFAILED = 0; BOOL CONFAILED = 0;
@ -747,8 +1014,44 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
if (CmdTail[0] == 'S') if (CmdTail[0] == 'S')
Stay = TRUE; Stay = TRUE;
Session->STAYFLAG = Stay; // could be Node for NETROMX connect or S flag
// We now use service@node, so can't get here
/*
if (ptr)
{
int i;
if (strlen(ptr) > 1)
{
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
// See if APPL is one of Paula's service
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(APPName, SERVICES[i].ServiceName) == 0)
{
ConnecttoService(Session, Bufferptr, i, ptr, Stay);
return;
}
}
// Not a service that can be accessed remotely
Bufferptr = Cmdprintf(Session, Bufferptr, "Connection to %s on a remote node is not possible\r", APPName);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
else if (ptr[0] == 'S')
Session->STAYFLAG = Stay;
}
*/
memcpy(Session->APPL, CMD->String, 12); memcpy(Session->APPL, CMD->String, 12);
// SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND
@ -830,6 +1133,9 @@ VOID APPLCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct
VOID CMDI00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD) VOID CMDI00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
{ {
if (checkifService(Session, Bufferptr, CmdTail, CMD)) // See can be used remotely
return;
Bufferptr = Cmdprintf(Session, Bufferptr, "%s", INFOMSG); Bufferptr = Cmdprintf(Session, Bufferptr, "%s", INFOMSG);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
} }
@ -1300,6 +1606,17 @@ VOID CMDL00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
else else
Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d Q=%d\r", Bufferptr = Cmdprintf(Session, Bufferptr, " S=%d P=%d T=%d V=%d Q=%d\r",
LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG, Count); LINK->L2STATE, LINK->LINKPORT->PORTNUMBER, LINK->LINKTYPE, 2 - LINK->VER1FLAG, Count);
if (Count > 16 || LINK->LINKWINDOW == 0)
{
// Dump Link State
int secs = time(NULL) - LINK->LASTFRAMESENT;
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: LINK->LINKNS %d LINK->LINKOWS %d SDTSLOT %d LINKWINDOW %d L2FLAGS %d\r", LINK->LINKNS, LINK->LINKOWS, LINK->SDTSLOT, LINK->LINKWINDOW, LINK->L2FLAGS);
Bufferptr = Cmdprintf(Session, Bufferptr, " Debug Info: Slots %x %x %x %x %x %x %x %x\r", LINK->FRAMES[0], LINK->FRAMES[1], LINK->FRAMES[2], LINK->FRAMES[3],
LINK->FRAMES[4], LINK->FRAMES[5], LINK->FRAMES[6], LINK->FRAMES[7]);
}
} }
LINK++; LINK++;
} }
@ -1622,12 +1939,16 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE *
if (Routes->INP3Node) // INP3 Enabled? if (Routes->INP3Node) // INP3 Enabled?
{ {
double srtt = Routes->SRTT/1000.0; double srtt = Routes->SRTT/100.0;
double nsrtt = Routes->NeighbourSRTT/1000.0; double nsrtt = Routes->NeighbourSRTT/100.0;
Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs", srtt, nsrtt); Bufferptr = Cmdprintf(Session, Bufferptr, " %4.2fs %4.2fs %X", srtt, nsrtt, Routes->Status);
} }
if (Routes->TCPPort)
Bufferptr = Cmdprintf(Session, Bufferptr, " %d", Routes->localport);
Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "\r");
} }
else else
@ -2144,7 +2465,7 @@ TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr)
} }
VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy) VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST * Dest, BOOL Spy, int Service)
{ {
TRANSPORTENTRY * NewSess; TRANSPORTENTRY * NewSess;
@ -2153,6 +2474,8 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
if (NewSess == NULL) if (NewSess == NULL)
return; // Tables Full return; // Tables Full
NewSess->Service = Service;
NewSess->L4CIRCUITTYPE = SESSION + DOWNLINK; NewSess->L4CIRCUITTYPE = SESSION + DOWNLINK;
NewSess->L4TARGET.DEST = Dest; NewSess->L4TARGET.DEST = Dest;
@ -2160,15 +2483,41 @@ VOID DoNetromConnect(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIS
NewSess->SPYFLAG = Spy; NewSess->SPYFLAG = Spy;
ReleaseBuffer((UINT *)REPLYBUFFER); if (Service == -1)
ReleaseBuffer((UINT *)REPLYBUFFER);
SENDL4CONNECT(NewSess); SENDL4CONNECT(NewSess, Service);
L4CONNECTSOUT++; L4CONNECTSOUT++;
return; return;
} }
BOOL CheckLink(UCHAR * LinkCall, UCHAR * OurCall, int Port)
{
// Check if a link exists betwwn a pair of calls on a port. Return TRUE if found
struct _LINKTABLE * LINK = LINKS;
int n = MAXLINKS;
while (n--)
{
if (LINK->LINKCALL[0] == 0) // Spare
{
LINK++;
continue;
}
if ((LINK->LINKPORT->PORTNUMBER == Port) && CompareCalls(LINK->LINKCALL, LinkCall) && CompareCalls(LINK->OURCALL, OurCall))
return TRUE;
LINK++;
}
// ENTRY NOT FOUND
return FALSE;
}
BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK) BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE ** REQLINK)
{ {
struct _LINKTABLE * LINK = LINKS; struct _LINKTABLE * LINK = LINKS;
@ -2194,6 +2543,7 @@ BOOL FindLink(UCHAR * LinkCall, UCHAR * OurCall, int Port, struct _LINKTABLE **
LINK++; LINK++;
} }
// ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL // ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL
*REQLINK = FIRSTSPARE; *REQLINK = FIRSTSPARE;
@ -2224,6 +2574,9 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
char PortString[10]; char PortString[10];
char cmdCopy[256]; char cmdCopy[256];
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT; struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
int Service = -1;
int haveService = 0;
int i = 0;
#ifdef EXCLUDEBITS #ifdef EXCLUDEBITS
@ -2271,6 +2624,56 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
return; return;
} }
// See if NETROMX connect c service@node
if (strchr(ptr, '@'))
{
// We now use service@node, unlike xr
char * Context1;
char * Cmd = strtok_s(ptr, "@", &Context1);
char * Node = strtok_s(NULL, " ", &Context1);
int i;
int Stay = 0;
if (Context1 && Context1[0] == 'S')
Session->STAYFLAG = Stay;
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(Cmd, SERVICES[i].ServiceName) == 0)
{
if (Node)
{
ConnecttoService(Session, Bufferptr, SERVICES[i].ServiceNo, Node, Stay);
return;
}
}
}
// May be numeric service
for (i = 0; i < strlen(Cmd); i++)
{
if (!isdigit(Cmd[i]))
break;
}
if (i == strlen(Cmd))
{
if (Node)
{
ConnecttoService(Session, Bufferptr, atoi(Cmd), Node, Stay);
return;
}
}
Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid NetromX command\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Port = atoi(ptr); Port = atoi(ptr);
if (Port) if (Port)
@ -2388,6 +2791,9 @@ NoPort:
// Convert to an APPL command, so any alias is actioned // Convert to an APPL command, so any alias is actioned
memcpy(Session->APPL,APPL->APPLCMD, 12);
// SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND // SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND
if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20) if (APPL->APPLHASALIAS && APPL->APPLALIASVAL[0] != 0x20)
@ -2431,7 +2837,7 @@ NoPort:
{ {
if (memcmp(Dest->DEST_ALIAS, TextCall, 6) == 0) if (memcmp(Dest->DEST_ALIAS, TextCall, 6) == 0)
{ {
DoNetromConnect(Session, Bufferptr, Dest, Spy); DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
return; return;
} }
Dest++; Dest++;
@ -2445,7 +2851,7 @@ NoPort:
{ {
if (CompareCalls(Dest->DEST_CALL, axcalls)) if (CompareCalls(Dest->DEST_CALL, axcalls))
{ {
DoNetromConnect(Session, Bufferptr, Dest, Spy); DoNetromConnect(Session, Bufferptr, Dest, Spy, Service);
return; return;
} }
Dest++; Dest++;
@ -2461,9 +2867,6 @@ Downlink:
// L2 NEEDS PORT NUMBER // L2 NEEDS PORT NUMBER
Bufferptr = Cmdprintf(Session, Bufferptr, "Downlink connect needs port number - C P CALLSIGN\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "Downlink connect needs port number - C P CALLSIGN\r");
// Send Port List
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return; return;
} }
@ -2939,7 +3342,7 @@ char * DoOneNode(TRANSPORTENTRY * Session, char * Bufferptr, struct DEST_LIST *
if (Neighbour) if (Neighbour)
{ {
double srtt = Route->SRTT/1000.0; double srtt = Route->STT/100.0;
len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall);
Normcall[len] = 0; Normcall[len] = 0;
@ -2959,7 +3362,7 @@ int DoViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor)
char Portcall[10]; char Portcall[10];
int len; int len;
if (Dest->NRROUTE[n].ROUT_NEIGHBOUR != 0 && Dest->NRROUTE[n].ROUT_NEIGHBOUR->INP3Node == 0) if (Dest->NRROUTE[n].ROUT_NEIGHBOUR != 0)
{ {
len=ConvFromAX25(Dest->NRROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); len=ConvFromAX25(Dest->NRROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall);
Portcall[len]=0; Portcall[len]=0;
@ -2988,7 +3391,7 @@ int DoINP3ViaEntry(struct DEST_LIST * Dest, int n, char * line, int cursor)
if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0) if (Dest->INP3ROUTE[n].ROUT_NEIGHBOUR != 0)
{ {
srtt = Dest->INP3ROUTE[n].SRTT/1000.0; srtt = Dest->INP3ROUTE[n].STT/100.0;
len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall); len=ConvFromAX25(Dest->INP3ROUTE[n].ROUT_NEIGHBOUR->NEIGHBOUR_CALL, Portcall);
Portcall[len]=0; Portcall[len]=0;
@ -3608,6 +4011,8 @@ VOID MHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CM
int len; int len;
char Digi = 0; char Digi = 0;
if (checkifService(Session, Bufferptr, CmdTail, CMD)) // See can be used remotely
return;
// Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find // Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find
// how many digis there are // how many digis there are
@ -4258,7 +4663,9 @@ struct CMDX COMMANDS[] =
"RIGRECONFIG ",8, &RIGRECONFIG, 0, "RIGRECONFIG ",8, &RIGRECONFIG, 0,
"RESTART ",7, &RESTART,0, "RESTART ",7, &RESTART,0,
"RESTARTTNC ",10,&RESTARTTNC,0, "RESTARTTNC ",10,&RESTARTTNC,0,
"POLLNODES ",8, &POLLNODES,0,
"SENDNODES ",8, &SENDNODES,0, "SENDNODES ",8, &SENDNODES,0,
"SENDRIF ",7, &SENDRIF,0,
"EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART), "EXTRESTART ",10, EXTPORTVAL, offsetof(EXTPORTDATA, EXTRESTART),
"TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY), "TXDELAY ",3, PORTVAL, offsetof(PORTCONTROLX, PORTTXDELAY),
"MAXFRAME ",3, PORTVAL, offsetof(PORTCONTROLX, PORTWINDOW), "MAXFRAME ",3, PORTVAL, offsetof(PORTCONTROLX, PORTWINDOW),
@ -4275,6 +4682,10 @@ struct CMDX COMMANDS[] =
"MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS), "MAXUSERS ",4,PORTVAL, offsetof(PORTCONTROLX, USERS),
"L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG), "L3ONLY ",6,PORTVAL, offsetof(PORTCONTROLX, PORTL3FLAG),
"BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG), "BBSALIAS ",4,PORTVAL, offsetof(PORTCONTROLX, PORTBBSFLAG),
"INP3ONLY ",8,PORTVAL, offsetof(PORTCONTROLX, INP3ONLY),
"ALLOWINP3 ",9,PORTVAL, offsetof(PORTCONTROLX, ALLOWINP3),
"ENABLEINP3 ",10,PORTVAL, offsetof(PORTCONTROLX, ENABLEINP3),
"MONTOFILE ",9,SWITCHVAL,(size_t)&MONTOFILEFLAG,
"VALIDCALLS ",5,VALNODES,0, "VALIDCALLS ",5,VALNODES,0,
"WL2KSYSOP ",5,WL2KSYSOP,0, "WL2KSYSOP ",5,WL2KSYSOP,0,
"STOPPORT ",4,STOPPORT,0, "STOPPORT ",4,STOPPORT,0,
@ -4286,6 +4697,7 @@ struct CMDX COMMANDS[] =
"KISS ",4,KISSCMD,0, "KISS ",4,KISSCMD,0,
"GETPORTCTEXT",9,GetPortCTEXT, 0, "GETPORTCTEXT",9,GetPortCTEXT, 0,
#ifdef EXCLUDEBITS #ifdef EXCLUDEBITS
"EXCLUDE ",4,ListExcludedCalls,0, "EXCLUDE ",4,ListExcludedCalls,0,
@ -4310,6 +4722,12 @@ struct CMDX COMMANDS[] =
"L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY, "L4DELAY ",7,SWITCHVAL,(size_t)&L4DELAY,
"L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW, "L4WINDOW ",6,SWITCHVAL,(size_t)&L4DEFAULTWINDOW,
"BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL, "BTINTERVAL ",5,SWITCHVAL,(size_t)&BTINTERVAL,
"DEBUGINP3 ",8,SWITCHVAL,(size_t)&DEBUGINP3,
"RIFINTERVAL ",11,SWITCHVALW,(size_t)&RIFInterval,
"MAXHOPS ",7,SWITCHVAL,(size_t)&MaxHops,
"PREFERINP3 ",10,SWITCHVAL,(size_t)&PREFERINP3ROUTES,
"MAXRTT ",6,SWITCHVALW,(size_t)&MAXRTT,
"MAXTT ",6,SWITCHVALW,(size_t)&MAXRTT,
"PASSWORD ", 8, PWDCMD, 0, "PASSWORD ", 8, PWDCMD, 0,
"************", 12, APPLCMD, 0, "************", 12, APPLCMD, 0,
@ -4343,7 +4761,7 @@ struct CMDX COMMANDS[] =
"************", 12, APPLCMD, 0, "************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0, "************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0, "************", 12, APPLCMD, 0,
"************", 12, APPLCMD, 0, // Apppl 32 is internal Terminal "************", 12, APPLCMD, 0, // Apppl 32 is internal Terminal on Windows
"*** LINKED ",10,LINKCMD,0, "*** LINKED ",10,LINKCMD,0,
"CQ ",2,CQCMD,0, "CQ ",2,CQCMD,0,
"CONNECT ",1,CMDC00,0, "CONNECT ",1,CMDC00,0,
@ -4736,6 +5154,9 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
struct DATAMESSAGE * Buffer = REPLYBUFFER; struct DATAMESSAGE * Buffer = REPLYBUFFER;
char * ptr1, * ptr2; char * ptr1, * ptr2;
int n; int n;
int i, Service = -1;
char * Cmd, *Node, *Context;
int Stay = 0;
ptr1 = &COMMANDBUFFER[0]; // ptr1 = &COMMANDBUFFER[0]; //
@ -4826,6 +5247,50 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
CMD++; CMD++;
}
// See if a NETROMX Service
// We now use service@node, unlike xr
if (strchr(ptr1, '@'))
{
Cmd = strtok_s(ptr1, "@", &Context);
Node = strtok_s(NULL, " ", &Context);
if (Cmd && Node)
{
if (Context && Context[0] == 'S')
Session->STAYFLAG = Stay;
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (strcmp(Cmd, SERVICES[i].ServiceName) == 0)
{
ConnecttoService(Session, ReplyPointer, SERVICES[i].ServiceNo, Node, Stay);
return;
}
}
// May be numeric service
for (i = 0; i < strlen(Cmd); i++)
{
if (!isdigit(Cmd[i]))
break;
}
if (i == strlen(Cmd))
{
ConnecttoService(Session, ReplyPointer, atoi(Cmd), Node, Stay);
return;
}
}
ReplyPointer = Cmdprintf(Session, ReplyPointer, "Invalid NetromX command\r");
SendCommandReply(Session, REPLYBUFFER, (int)(ReplyPointer - (char *)REPLYBUFFER));
return;
} }
Session->BADCOMMANDS++; Session->BADCOMMANDS++;
@ -4843,19 +5308,19 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
ptr1 += CMDERRLEN; ptr1 += CMDERRLEN;
SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer)); SendCommandReply(Session, Buffer, (int)(ptr1 - (char *)Buffer));
} }
VOID StatsTimer() VOID StatsTimer()
{
struct PORTCONTROL * PORT = PORTTABLE;
uint64_t sum, sum2;
// Interval is 60 secs
while(PORT)
{ {
int index = PORT->StatsPointer++; struct PORTCONTROL * PORT = PORTTABLE;
uint64_t sum, sum2;
// Interval is 60 secs
while(PORT)
{
int index = PORT->StatsPointer++;
if (index == 1439) if (index == 1439)
PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins) PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins)

View file

@ -49,6 +49,12 @@ extern struct CONFIGTABLE xxcfg;
#endif #endif
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
struct TNCINFO * TNCInfo[71]; // Records are Malloc'd struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
extern int ReportTimer; extern int ReportTimer;
@ -69,6 +75,8 @@ void printStack(void);
char * FormatMH(PMHSTRUC MH, char Format); char * FormatMH(PMHSTRUC MH, char Format);
void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode); void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendDataToPktMap(); void SendDataToPktMap();
void NETROMTCPResolve();
VOID FindLostBuffers();
extern BOOL LogAllConnects; extern BOOL LogAllConnects;
extern BOOL M0LTEMap; extern BOOL M0LTEMap;
@ -79,6 +87,7 @@ extern VOID * ENDBUFFERPOOL;
extern int PoolBuilt; extern int PoolBuilt;
extern int EnableOARCAPI;
// Read/Write length field in a buffer header // Read/Write length field in a buffer header
@ -557,6 +566,15 @@ VOID * _GetBuff(char * File, int Line)
Msg->Linkptr = NULL; Msg->Linkptr = NULL;
Msg->Padding[0] = 0; // Used for modem status info Msg->Padding[0] = 0; // Used for modem status info
} }
else if (QCOUNT != 0)
{
// Queue must be corrupt
Debugprintf("Fatal - Getbuff returned NULL and Q not empty - exit");
FindLostBuffers();
WriteMiniDump();
Restart();
}
else else
Debugprintf("Warning - Getbuff returned NULL"); Debugprintf("Warning - Getbuff returned NULL");
@ -3313,8 +3331,12 @@ SOCKADDR_IN reportdest = {0};
SOCKET ReportSocket = 0; SOCKET ReportSocket = 0;
SOCKET NodeAPISocket = 0 ;
SOCKADDR_IN Chatreportdest = {0}; SOCKADDR_IN Chatreportdest = {0};
SOCKADDR_IN UDPreportdest = {0};
extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON
extern char LOC[7]; // Maidenhead Locator for Reporting extern char LOC[7]; // Maidenhead Locator for Reporting
@ -3670,11 +3692,22 @@ pthread_t ResolveUpdateThreadId = 0;
char NodeMapServer[80] = "update.g8bpq.net"; char NodeMapServer[80] = "update.g8bpq.net";
char ChatMapServer[80] = "chatupdate.g8bpq.net"; char ChatMapServer[80] = "chatupdate.g8bpq.net";
char NodeAPIServer[80] = "node-api.packet.oarc.uk";
int NodeAPIPort = 13579;
int nodeStartedSent = 0;
extern time_t LastNodeStatus;
void hookNodeStarted();
VOID ResolveUpdateThread(void * Unused) VOID ResolveUpdateThread(void * Unused)
{ {
struct hostent * HostEnt1; struct hostent * HostEnt1;
struct hostent * HostEnt2; struct hostent * HostEnt2;
struct hostent * HostEnt3;
ResolveUpdateThreadId = GetCurrentThreadId(); ResolveUpdateThreadId = GetCurrentThreadId();
@ -3702,14 +3735,29 @@ VOID ResolveUpdateThread(void * Unused)
if (HostEnt2) if (HostEnt2)
memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4); memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4);
if (HostEnt1 && HostEnt2) Debugprintf("Resolving %s", NodeAPIServer);
HostEnt3 = gethostbyname(NodeAPIServer);
if (HostEnt3)
{ {
Sleep(1000 * 60 * 30); memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
continue;
if (nodeStartedSent == 0)
{
hookNodeStarted();
nodeStartedSent = 1;
LastNodeStatus = time(NULL);
}
} }
Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net"); NETROMTCPResolve();
Sleep(1000 * 60 * 5);
if (HostEnt1 && HostEnt2)
{
Sleep(1000 * 60 * 15);
continue;
}
} }
} }
@ -5194,14 +5242,14 @@ skipit:
} }
} }
void SendDataToPktMapThread(); void SendDataToPktMapThread(void * Param);
void SendDataToPktMap() void SendDataToPktMap()
{ {
_beginthread(SendDataToPktMapThread,2048000,0); _beginthread(SendDataToPktMapThread,2048000,0);
} }
void SendDataToPktMapThread() void SendDataToPktMapThread(void * Param)
{ {
char Return[256] = ""; char Return[256] = "";
char Request[64]; char Request[64];

21
DRATS.c
View file

@ -568,18 +568,19 @@ void DRATSConnectionLost(struct ConnectionInfo * sockptr)
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen) int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen)
{ {
int ret; int ret;
z_stream strm; z_stream strm;
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
strm.zfree = Z_NULL; strm.zfree = Z_NULL;
strm.opaque = Z_NULL; strm.opaque = Z_NULL;
strm.avail_in = 0; strm.avail_in = 0;
strm.next_in = Z_NULL; strm.next_in = Z_NULL;
ret = inflateInit(&strm); ret = inflateInit(&strm);
if (ret != Z_OK)
return ret; if (ret != Z_OK)
return ret;
strm.avail_in = Len; strm.avail_in = Len;
strm.next_in = source; strm.next_in = source;

1120
Events.c

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,12 @@ extern int (WINAPI FAR *EnumProcessesPtr)();
#include "bpq32.h" #include "bpq32.h"
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 0 #define VERSION_MINOR 0
@ -819,7 +825,7 @@ pollloop:
char outbuff[1000]; char outbuff[1000];
int newlen; int newlen;
buff->L2DATA[-1] = 6; // KISS Control buff->PID = 6; // KISS Control (PID is just before Data)
newlen = KissEncode(&buff->L2DATA[-1], outbuff, txlen); newlen = KissEncode(&buff->L2DATA[-1], outbuff, txlen);
sendto(TNC->TCPDataSock, outbuff, newlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr)); sendto(TNC->TCPDataSock, outbuff, newlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr));

View file

@ -43,6 +43,11 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
int KillTNC(struct TNCINFO * TNC); int KillTNC(struct TNCINFO * TNC);
static int RestartTNC(struct TNCINFO * TNC); static int RestartTNC(struct TNCINFO * TNC);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern int (WINAPI FAR *GetModuleFileNameExPtr)(); extern int (WINAPI FAR *GetModuleFileNameExPtr)();
extern int (WINAPI FAR *EnumProcessesPtr)(); extern int (WINAPI FAR *EnumProcessesPtr)();
static int Socket_Data(int sock, int error, int eventcode); static int Socket_Data(int sock, int error, int eventcode);
@ -4182,7 +4187,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC)
SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in destaddr; struct sockaddr_in destaddr;
Debugprintf("trying to restart TNC %s", TNC->ProgramPath); // Debugprintf("trying to restart TNC %s", TNC->ProgramPath);
if (sock == INVALID_SOCKET) if (sock == INVALID_SOCKET)
return 0; return 0;
@ -4205,7 +4210,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC)
n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr));
Debugprintf("Restart TNC - sendto returned %d", n); // Debugprintf("Restart TNC - sendto returned %d", n);
Sleep(100); Sleep(100);
closesocket(sock); closesocket(sock);

View file

@ -147,9 +147,15 @@ char IndexNoAPRS[] = "<meta http-equiv=\"refresh\" content=\"0;url=/Node/NodeInd
char Tail[] = "</body></html>"; char Tail[] = "</body></html>";
char RouteHddr[] = "<h2 align=center>Routes</h2><table align=center border=2 style=font-family:monospace bgcolor=white>" char RouteHddr[] = "<h2 align=center>Routes</h2><table align=center border=2 style=font-family:monospace bgcolor=white>"
"<tr><th>Port</th><th>Call</th><th>Quality</th><th>Node Count</th><th>Frame Count</th><th>Retries</th><th>Percent</th><th>Maxframe</th><th>Frack</th><th>Last Heard</th><th>Queued</th><th>Rem Qual</th></tr>"; "<tr><th>Port</th><th>Call</th><th>Quality</th><th>Node Count</th><th>Frame Count</th><th>Retries</th><th>Percent</th><th>Maxframe</th>"
"<th>Frack</th><th>Last Heard</th><th>Queued</th><th>Rem Qual</th><th>SRTT</th><th>Rem SRTT</th></tr>";
char RouteLine[] = "<tr><td>%s%d</td><td>%s%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d%</td><td>%d</td><td>%d</td>"
"<td>%02d:%02d<td>%d</td><td>%d</td></td><td></td><td></td></tr>";
char RouteLineINP3[] = "<tr><td>%s%d</td><td>%s%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d%</td><td>%d</td><td>%d</td>"
"<td>%02d:%02d</td><td>%d</td><td>%d</td><td>%4.2fs</td><td>%4.2fs</td></tr>";
char RouteLine[] = "<tr><td>%s%d</td><td>%s%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d%</td><td>%d</td><td>%d</td><td>%02d:%02d</td><td>%d</td><td>%d</td></tr>";
char xNodeHddr[] = "<align=center><form align=center method=get action=/Node/Nodes.html>" char xNodeHddr[] = "<align=center><form align=center method=get action=/Node/Nodes.html>"
"<table align=center bgcolor=white>" "<table align=center bgcolor=white>"
"<tr><td><input type=submit class='btn' name=a value=\"Nodes Sorted by Alias\"></td><td>" "<tr><td><input type=submit class='btn' name=a value=\"Nodes Sorted by Alias\"></td><td>"
@ -1390,23 +1396,23 @@ int SetupNodeMenu(char * Buff, int LOCAL)
char SigninBit[] = "<td><a href=/Node/Signon.html>SYSOP Signin</a></td>"; char SigninBit[] = "<td><a href=/Node/Signon.html>SYSOP Signin</a></td>";
char NodeTail[] = char NodeTail[] =
"<td><a href=/Node/EditCfg.html>Edit Config</a></td>" "<td><a href=/Node/EditCfg.html>Edit Config</a></td>\
"<td><div onmouseover=myShow() class='dropdown'>" <td><div onmouseover=myShow() class='dropdown'>\
"<button class=\"dropbtn\">View Logs</button>" <button class=\"dropbtn\">View Logs</button>\
"<div id=\"myDropdown\" class=\"dropdown-content\">" <div id=\"myDropdown\" class=\"dropdown-content\">\
"<form id = doDate form action='/node/ShowLog.html'><label>" <form id = doDate form action='/node/ShowLog.html'><label>\
"Select Date: <input type='date' name='date' id=e>" Select Date: <input type='date' name='date' id=e>\
"<script>" <script>\
"document.getElementById('e').value = new Date().toISOString().substring(0, 10);" document.getElementById('e').value = new Date().toISOString().substring(0, 10);\
"</script></label>" </script></label>\
"<input type=submit class='btn' name='BBS' value='BBS Log'></br>" <input type=submit class='btn' name='BBS' value='BBS Log'></br>\
"<input type=submit class='btn' name='Debug' value='BBS Debug Log'></br>" <input type=submit class='btn' name='Debug' value='BBS Debug Log'></br>\
"<input type=submit class='btn' name='Telnet' value='Telnet Log'></br>" <input type=submit class='btn' name='Telnet' value='Telnet Log'></br>\
"<input type=submit class='btn' name='CMS' value='CMS Log'></br>" <input type=submit class='btn' name='CMS' value='CMS Log'></br>\
"<input type=submit class='btn' name='Chat' value='Chat Log'></br>" <input type=submit class='btn' name='Chat' value='Chat Log'></br>\
"</form></div>" </form></div>\
"</div>" </div>\
"</td></tr></table>"; </td></tr></table>";
Len = sprintf(Buff, NodeMenuHeader, Mycall); Len = sprintf(Buff, NodeMenuHeader, Mycall);
@ -1560,10 +1566,9 @@ VOID SaveConfigFile(SOCKET sock , char * MsgPtr, char * Rest, int LOCAL)
} }
ReplyLen = sprintf(Reply, "<html><script>alert(\"%s\");window.close();</script></html>", Mess); ReplyLen = sprintf(Reply, "<html><script>alert(\"%s\");window.close();</script></html>", Mess);
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen);
send(sock, Header, HeaderLen, 0); send(sock, Header, HeaderLen, 0);
send(sock, Reply, ReplyLen, 0); send(sock, Reply, ReplyLen, 0);
send(sock, Tail, (int)strlen(Tail), 0);
} }
return; return;
} }
@ -3942,9 +3947,21 @@ doHeader:
else else
Percent = 0; Percent = 0;
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLine, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, if (Routes->INP3Node) // INP3 Enabled?
Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, {
Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual); double srtt = Routes->SRTT/100.0;
double nsrtt = Routes->NeighbourSRTT/100.0;
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLineINP3, Active, Routes->NEIGHBOUR_PORT, Normcall, locked,
Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK,
Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual, srtt, nsrtt);
}
else
{
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLine, Active, Routes->NEIGHBOUR_PORT, Normcall, locked,
Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK,
Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual);
}
} }
Routes+=1; Routes+=1;
} }
@ -4839,7 +4856,14 @@ void ProcessWebmailWebSockThread(void * conn)
Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0); Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0);
while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max if (Sent == -1) // Connecton lost
{
closesocket(sockptr->socket);
free(conn);
return;
}
while (Sent != ReplyLen && Loops++ < 3000) // 90 secs max
{ {
if (Sent > 0) // something sent if (Sent > 0) // something sent
{ {
@ -4885,11 +4909,16 @@ void ProcessWebmailWebSockThread(void * conn)
CloseHandle(hPipe); CloseHandle(hPipe);
// ?? do we need a thread to handle write which may block
Sent = send(sockptr->socket, Reply, ReplyLen, 0); Sent = send(sockptr->socket, Reply, ReplyLen, 0);
while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max if (Sent == -1) // Connecton lost
{
free(conn);
closesocket(sockptr->socket);
return;
}
while (Sent != ReplyLen && Loops++ < 3000) // 90 secs max
{ {
// Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops);

View file

@ -426,7 +426,7 @@ VOID ChatExpandAndSendMessage(ChatCIRCUIT * conn, char * Msg, int LOG)
len = RemoveLF(NewMessage, (int)strlen(NewMessage)); len = RemoveLF(NewMessage, (int)strlen(NewMessage));
ChatWriteLogLine(conn, '>', NewMessage, len, LOG); ChatWriteLogLine(conn, '>', NewMessage, len, LOG_CHAT);
ChatQueueMsg(conn, NewMessage, len); ChatQueueMsg(conn, NewMessage, len);
} }
@ -1229,7 +1229,7 @@ void chkctl(ChatCIRCUIT *ckt_from, char * Buffer, int Len)
for (i = 1; i < (Len - 1); i++) for (i = 1; i < (Len - 1); i++)
{ {
if (Buffer[i] < 32) if (Buffer[i] < 32 && Buffer[i] != 7) // Accept BELL
{ {
if (Buffer[i] == 9) if (Buffer[i] == 9)
{ {

View file

@ -30,7 +30,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
char * APIENTRY GetBPQDirectory(); char * APIENTRY GetBPQDirectory();
int LogAge = 7; int BBSLogAge = 7;
BOOL DeletetoRecycleBin = FALSE; BOOL DeletetoRecycleBin = FALSE;
BOOL SuppressMaintEmail = FALSE; BOOL SuppressMaintEmail = FALSE;
@ -61,7 +61,7 @@ struct Override ** LTFROM;
struct Override ** LTTO; struct Override ** LTTO;
struct Override ** LTAT; struct Override ** LTAT;
int DeleteLogFiles(); int DeleteBBSLogFiles();
VOID SendNonDeliveryMessage(struct MsgInfo * OldMsg, BOOL Forwarded, int Age); VOID SendNonDeliveryMessage(struct MsgInfo * OldMsg, BOOL Forwarded, int Age);
int CreateWPMessage(); int CreateWPMessage();
@ -281,7 +281,7 @@ VOID DoHouseKeeping(BOOL Manual)
UpdateWP(); UpdateWP();
DeleteLogFiles(); DeleteBBSLogFiles();
RemoveKilledMessages(); RemoveKilledMessages();
ExpireMessages(); ExpireMessages();
@ -799,7 +799,7 @@ VOID MailHousekeepingResults()
extern UCHAR LogDirectory[260]; extern UCHAR LogDirectory[260];
int DeleteLogFiles() int DeleteBBSLogFiles()
{ {
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
@ -848,7 +848,7 @@ int DeleteLogFiles()
Age = (int)((now - ft.LowPart) / 86400); Age = (int)((now - ft.LowPart) / 86400);
if (Age > LogAge) if (Age > BBSLogAge)
{ {
sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0); sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
if (DeletetoRecycleBin) if (DeletetoRecycleBin)
@ -875,7 +875,7 @@ int Filter(const struct dirent * dir)
return memcmp(dir->d_name, "log", 3) == 0 && strstr(dir->d_name, ".txt"); return memcmp(dir->d_name, "log", 3) == 0 && strstr(dir->d_name, ".txt");
} }
int DeleteLogFiles() int DeleteBBSLogFiles()
{ {
struct dirent **namelist; struct dirent **namelist;
int n; int n;
@ -897,7 +897,7 @@ int DeleteLogFiles()
{ {
Age = (now - STAT.st_mtime) / 86400; Age = (now - STAT.st_mtime) / 86400;
if (Age > LogAge) if (Age > BBSLogAge)
{ {
printf("Deleting %s\n", FN); printf("Deleting %s\n", FN);
unlink(FN); unlink(FN);

View file

@ -50,6 +50,19 @@ BEGIN
LTEXT "Enable IGate",IDC_STATIC,5,2,49,10 LTEXT "Enable IGate",IDC_STATIC,5,2,49,10
END END
CLOSING DIALOG DISCARDABLE 300, 300, 200, 50
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU |
WS_THICKFRAME
CAPTION "BPQ32 Close All"
CLASS "CLOSING"
FONT 8, "Fixedsys"
BEGIN
LTEXT "Closing Links - Please wait....",IDC_BACKGROUND,22,20,337,273
END
CONFIG DIALOGEX 249, 200, 160, 118 CONFIG DIALOGEX 249, 200, 160, 118
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION
EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE

403
L2Code.c
View file

@ -20,6 +20,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// //
// C replacement for L2Code.asm // C replacement for L2Code.asm
// //
#define FRMRHACK
#define Kernel #define Kernel
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
@ -64,7 +67,7 @@ VOID L2SENDRESPONSE(struct _LINKTABLE * LINK, int CMD);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD); VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
VOID ACKMSG(struct _LINKTABLE * LINK); VOID ACKMSG(struct _LINKTABLE * LINK);
VOID InformPartner(struct _LINKTABLE * LINK, int Reason); VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
UINT RR_OR_RNR(struct _LINKTABLE * LINK); UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD);
VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT); VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT);
VOID CLEAROUTLINK(struct _LINKTABLE * LINK); VOID CLEAROUTLINK(struct _LINKTABLE * LINK);
VOID SENDFRMR(struct _LINKTABLE * LINK); VOID SENDFRMR(struct _LINKTABLE * LINK);
@ -99,6 +102,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK);
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID Q_IP_MSG(MESSAGE * Buffer); VOID Q_IP_MSG(MESSAGE * Buffer);
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT); VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT);
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT);
VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
BOOL CompareAliases(UCHAR * c1, UCHAR * c2); BOOL CompareAliases(UCHAR * c1, UCHAR * c2);
VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG);
@ -120,11 +124,18 @@ int CheckKissInterlock(struct PORTCONTROL * MYPORT, int Exclusive);
void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK); void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK); void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionConnected(struct _LINKTABLE * LINK);
int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len); int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len);
VOID DeleteINP3Routes(struct ROUTE * Route); VOID DeleteINP3Routes(struct ROUTE * Route);
VOID SendRTTMsg(struct ROUTE * Route);
void hookL2SessionStatus(struct _LINKTABLE * LINK);
void hookL2SessionClosed(struct _LINKTABLE * LINK, char * Reason, char * Direction);
int NETROMOpenConnection(struct ROUTE * Route);
extern int REALTIMETICKS; extern int REALTIMETICKS;
int linkStatusInterval = 300; // 5 mins
// MSGFLAG contains CMD/RESPONSE BITS // MSGFLAG contains CMD/RESPONSE BITS
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND #define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
@ -139,6 +150,7 @@ extern int REALTIMETICKS;
extern int L2Compress; extern int L2Compress;
extern int L2CompMaxframe; extern int L2CompMaxframe;
extern int L2CompPaclen; extern int L2CompPaclen;
extern BOOL CLOSING;
UCHAR NO_CTEXT = 0; UCHAR NO_CTEXT = 0;
UCHAR ALIASMSG = 0; UCHAR ALIASMSG = 0;
@ -446,6 +458,8 @@ TRYBBS:
{ {
ALIASMSG = 0; ALIASMSG = 0;
strcpy(LINK->ApplName, APPL->APPLCMD);
if (CompareCalls(Buffer->DEST, APPL->APPLCALL)) if (CompareCalls(Buffer->DEST, APPL->APPLCALL))
goto FORUS; goto FORUS;
@ -479,9 +493,9 @@ NOWTRY_NODES:
if (CompareCalls(Buffer->DEST, NODECALL)) if (CompareCalls(Buffer->DEST, NODECALL))
{ {
if (Buffer->L2DATA[0] == 0xff) // Valid NODES Broadcast if (Buffer->L2DATA[0] == 0xff) // Valid NODES Broadcast
{
PROCESSNODEMESSAGE(Buffer, PORT); PROCESSNODEMESSAGE(Buffer, PORT);
} else if (Buffer->L2DATA[0] == 0xfe) // Paula's NODES Poll (request Nodes broadcast on port)
PROCESSNODESPOLL(PORT);
} }
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
@ -808,7 +822,15 @@ VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buff
if (CTLlessPF == XID) if (CTLlessPF == XID)
{ {
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG); // We could possibly get an XID response if packet is badly delayed and we had timed out
if ((MSGFLAG & CMDBIT)) // Command
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
else
{
Debugprintf("Unexpected XID response with no session");
ReleaseBuffer(Buffer); // Ignore if not
}
return; return;
} }
@ -929,6 +951,7 @@ VOID ProcessXIDCommand(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESS
LINK->L2STATE = 1; // XID received LINK->L2STATE = 1; // XID received
LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID
LINK->L2TIME = PORT->PORTT1; LINK->L2TIME = PORT->PORTT1;
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->LINKPORT = PORT; LINK->LINKPORT = PORT;
@ -1067,6 +1090,7 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
if (CTLlessPF == DISC) if (CTLlessPF == DISC)
{ {
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
hookL2SessionClosed(LINK, "Normal", "In");
CLEAROUTLINK(LINK); CLEAROUTLINK(LINK);
L2SENDUA(PORT, Buffer, ADJBUFFER); L2SENDUA(PORT, Buffer, ADJBUFFER);
@ -1076,87 +1100,139 @@ VOID L2LINKACTIVE(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
return; return;
} }
if (CTLlessPF == XID)
if (LINK->L2STATE == 1)
{ {
// XID State. Should be XID response if 2.2 ok or DM/FRMR if not // XID command or response on active session.
if (MSGFLAG & RESP) // if Command and state = 2 then other end missed XID Response. Process command again
if ((MSGFLAG & CMDBIT))
{ {
if (CTLlessPF == DM || CTLlessPF == FRMR) if (LINK->L2STATE == 2)
{ {
// Doesn't support XID - Send SABM // I think we can just process as normal.
LINK->L2STATE = 2; ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
LINK->Ver2point2 = FALSE; return;
LINK->L2TIMER = 1; // Use retry to send SABM
} }
else if (CTLlessPF == XID)
if (LINK->L2STATE == 1) // We've just sent XID so is probably XID Collision
{ {
// Process response to make sure ok, Send SABM or DISC // I think we can just process as normal. If we don't send a response the other end may not switch to 2.2
LINK->L2STATE = 2; ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG);
LINK->Ver2point2 = TRUE;// Must support 2.2 if responded to XID return;
// if Compress enabled set it
ptr = &ADJBUFFER->PID;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 17:
// Compression
if (L2Compress)
LINK->AllowCompress = 1;
}
}
}
LINK->L2TIMER = 1; // Use retry to send SABM
} }
// XID Command on active session. Other end may be restarting. Reset session
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
LINK->CIRCUITPOINTER = 0;
// I think it is safer to ignore it. The retry will be processed normally as XID command with no session
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
return; return;
} }
// Command on existing session. Could be due to other end missing // XID Response
// the XID response, so if XID just resend response
// if Link State = 1 this is a normal response. Check it then send SABM
if (LINK->L2STATE == 1)
{
LINK->L2STATE = 2;
LINK->Ver2point2 = TRUE;// Must support 2.2 if responded to XID
// if Compress enabled set it
ptr = &ADJBUFFER->PID;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 17:
// Compression
if (L2Compress)
LINK->AllowCompress = 1;
}
}
}
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
LINK->L2TIMER = 1; // Use retry to send SABM
ReleaseBuffer(Buffer);
return;
}
// XID response, not in state 1.
// This "shouldn't happen"
Debugprintf("Unexpected XID response, State = %d", LINK->L2STATE);
// Discard
ReleaseBuffer(Buffer);
return;
} }
if (CTLlessPF == XID && (MSGFLAG & CMDBIT))
{
// XID Command on active session. Other end may be restarting. Send Response
ProcessXIDCommand(LINK, PORT, Buffer, ADJBUFFER, CTL, MSGFLAG); // Not XID
return;
// if state = 1 then unexpected response to XID
if (LINK->L2STATE == 1)
{
if (CTLlessPF == DM || CTLlessPF == FRMR)
{
// Doesn't support XID - Send SABM
LINK->L2STATE = 2;
LINK->Ver2point2 = FALSE;
LINK->L2TIMER = 1; // Use retry to send SABM
LINK->L2RETRIES--; // Make sure at least one is sent
// if an L3 link mark neighbour as not V2.2
if (LINK->LINKTYPE == 3)
{
struct ROUTE * ROUTE = LINK->NEIGHBOUR; // TO NEIGHBOUR
if (ROUTE)
ROUTE->noV2point2 = 1;
}
ReleaseBuffer(Buffer);
return;
}
} }
@ -1221,9 +1297,13 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
int CONERROR; int CONERROR;
struct ROUTE * ROUTE = NULL; struct ROUTE * ROUTE = NULL;
char toCall[12], fromCall[12]; char toCall[12], fromCall[12];
if (CLOSING)
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE
{ {
@ -1288,6 +1368,16 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
Debugprintf("INP3 Incoming connect from %s", fromCall); Debugprintf("INP3 Incoming connect from %s", fromCall);
DeleteINP3Routes(ROUTE); DeleteINP3Routes(ROUTE);
} }
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
} }
if (NO_CTEXT == 1) if (NO_CTEXT == 1)
@ -1388,6 +1478,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return; return;
} }
strcpy(Session->APPL, LINK->ApplName);
// NOW TRY A BBS CONNECT // NOW TRY A BBS CONNECT
// IF APPL CONNECT, SEE IF APPL HAS AN ALIAS // IF APPL CONNECT, SEE IF APPL HAS AN ALIAS
@ -1772,6 +1864,16 @@ BOOL InternalL2SETUPCROSSLINK(PROUTE ROUTE, int Retries)
struct PORTCONTROL * PORT; struct PORTCONTROL * PORT;
int FRACK; int FRACK;
// If it is NETROM Over TCP then check for existing connection
if (ROUTE->TCPPort)
{
if (strcmp(ROUTE->TCPHost, "0.0.0.0") == 0) // listening connection so wait for other end to connect
return FALSE;
return NETROMOpenConnection(ROUTE);
}
if (FindLink(ROUTE->NEIGHBOUR_CALL, NETROMCALL, ROUTE->NEIGHBOUR_PORT, &LINK)) if (FindLink(ROUTE->NEIGHBOUR_CALL, NETROMCALL, ROUTE->NEIGHBOUR_PORT, &LINK))
{ {
// SESSION ALREADY EXISTS // SESSION ALREADY EXISTS
@ -1813,7 +1915,7 @@ BOOL InternalL2SETUPCROSSLINK(PROUTE ROUTE, int Retries)
else else
LINK->LINKWINDOW = PORT->PORTWINDOW; LINK->LINKWINDOW = PORT->PORTWINDOW;
if (SUPPORT2point2) if (SUPPORT2point2 && (ROUTE->noV2point2 == 0))
LINK->L2STATE = 1; // Send XID LINK->L2STATE = 1; // Send XID
else else
LINK->L2STATE = 2; LINK->L2STATE = 2;
@ -1983,19 +2085,32 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
if (FindNeighbour(Buffer->ORIGIN, PORT->PORTNUMBER, &ROUTE)) if (FindNeighbour(Buffer->ORIGIN, PORT->PORTNUMBER, &ROUTE))
{ {
ROUTE->ConnectionAttempts = 0; // Reset counter
if (ROUTE->INP3Node) if (ROUTE->INP3Node)
{ {
Debugprintf("INP3 Route to %s connected", fromCall); Debugprintf("INP3 Route to %s connected", fromCall);
} }
else
{
if (PORT->ENABLEINP3)
{
// We will offer INP3 by sending an RTT probe.
SendRTTMsg(ROUTE);
}
}
} }
hookL2SessionConnected(LINK);
SendL2ToMonMap(PORT, fromCall, '+', 'O'); SendL2ToMonMap(PORT, fromCall, '+', 'O');
LINK->L2STATE = 5; LINK->L2STATE = 5;
LINK->L2TIMER = 0; // CANCEL TIMER LINK->L2TIMER = 0; // CANCEL TIMER
LINK->L2RETRIES = 0; LINK->L2RETRIES = 0;
LINK->L2SLOTIM, T3; // SET FRAME SENT RECENTLY LINK->L2SLOTIM = T3; // SET FRAME SENT RECENTLY
// IF VERSION 1 MSG, SET FLAG // IF VERSION 1 MSG, SET FLAG
@ -2015,6 +2130,8 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
if (LINK->L2STATE == 4) // DISCONNECTING? if (LINK->L2STATE == 4) // DISCONNECTING?
{ {
InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END InformPartner(LINK, NORMALCLOSE); // SEND DISC TO OTHER END
hookL2SessionClosed(LINK, "Normal", "Out");
CLEAROUTLINK(LINK); CLEAROUTLINK(LINK);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF) if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
@ -2053,7 +2170,27 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
// FRAME REJECT RECEIVED - LOG IT AND RESET LINK // FRAME REJECT RECEIVED - LOG IT AND RESET LINK
RESET2(LINK); //#ifdef FRMRHACK
// Treat as DM and break link
Debugprintf("BPQ32 FRMR received, disconnecting link");
InformPartner(LINK, LINKLOST); // SEND DISC TO OTHER END
L2SENDCOMMAND(LINK, DM);
CLEAROUTLINK(LINK);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
DetachKISSHF(PORT);
PORT->L2FRMRRX++;
return;
//#endif
/* RESET2(LINK);
LINK->L2STATE = 2; // INITIALISING LINK->L2STATE = 2; // INITIALISING
LINK->L2ACKREQ = 0; // DONT SEND ANYTHING ELSE LINK->L2ACKREQ = 0; // DONT SEND ANYTHING ELSE
@ -2063,7 +2200,7 @@ VOID L2_PROCESS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * B
L2SENDCOMMAND(LINK, SABM | PFBIT); L2SENDCOMMAND(LINK, SABM | PFBIT);
return; return;
*/
default: default:
// ANY OTHER - IGNORE // ANY OTHER - IGNORE
@ -2177,6 +2314,13 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
MESSAGE * Msg; MESSAGE * Msg;
MESSAGE * Buffer; MESSAGE * Buffer;
// it shouldn't be possible to get srej when all are acked (NS = Link->NS) but just in case...
if (NS == LINK->LINKNS)
{
Debugprintf ("SREJ for our NS");
goto treatasRR;
}
LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET
Msg = LINK->FRAMES[NS]; // is frame available? Msg = LINK->FRAMES[NS]; // is frame available?
@ -2236,6 +2380,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
LINK->L2TIMER = ONEMINUTE; // (RE)SET TIMER LINK->L2TIMER = ONEMINUTE; // (RE)SET TIMER
LINK->framesResent++;
PORT = LINK->LINKPORT; PORT = LINK->LINKPORT;
if (PORT) if (PORT)
@ -2254,6 +2401,9 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
return; return;
} }
treatasRR:
// VALID RR/RNR RECEIVED // VALID RR/RNR RECEIVED
LINK->L2FLAGS &= ~RNRSET; //CLEAR RNR LINK->L2FLAGS &= ~RNRSET; //CLEAR RNR
@ -2274,7 +2424,7 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
if (LINK->LAST_F_TIME + 15 > REALTIMETICKS) if (LINK->LAST_F_TIME + 15 > REALTIMETICKS)
return; // DISCARD return; // DISCARD
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, FALSE); // Sending response
CTL |= LINK->LINKNR << 5; // SHIFT N(R) TO TOP 3 BITS CTL |= LINK->LINKNR << 5; // SHIFT N(R) TO TOP 3 BITS
CTL |= PFBIT; CTL |= PFBIT;
@ -2339,6 +2489,20 @@ VOID SFRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, UCHAR CTL, UCHA
LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET LINK->L2FLAGS &= ~POLLSENT; // CLEAR I(P) or RR(P) SET
// ?? is this the place to do RTT?
if (LINK->lastPSent)
{
int RTT = GetTickCount() - LINK->lastPSent;
if (LINK->RTT)
LINK->RTT = ((LINK->RTT * 90) / 100) + RTT /10; // Smooth - 90% of old + 10% of new
else
LINK->RTT = RTT;
LINK->lastPSent = 0;
}
if ((CTL & 0xf) == RNR) if ((CTL & 0xf) == RNR)
{ {
// Dont Clear timer on receipt of RNR(F), spec says should poll for clearing of busy, // Dont Clear timer on receipt of RNR(F), spec says should poll for clearing of busy,
@ -2586,6 +2750,7 @@ VOID PROC_I_FRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
LINK->bytesRXed += Length; LINK->bytesRXed += Length;
LINK->Received += Length - 1; // Exclude PID LINK->Received += Length - 1; // Exclude PID
LINK->framesRXed++;
// Adjust for DIGIS // Adjust for DIGIS
@ -2813,6 +2978,8 @@ VOID RESETNS(struct _LINKTABLE * LINK, UCHAR NS)
{ {
int Resent = (LINK->LINKNS - NS) & 7; // FRAMES TO RESEND int Resent = (LINK->LINKNS - NS) & 7; // FRAMES TO RESEND
LINK->framesResent += Resent;
LINK->LINKNS = NS; // RESET N(S) LINK->LINKNS = NS; // RESET N(S)
if (LINK->LINKTYPE == 3) // mode-Node if (LINK->LINKTYPE == 3) // mode-Node
@ -2981,9 +3148,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
// **** Debug code **** look for stuck links // **** Debug code **** look for stuck links
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{ {
if (COUNT_AT_L2(LINK) > 16) if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{ {
// Dump Link State // Dump Link State
@ -3036,6 +3203,11 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->LASTFRAMESENT = time(NULL); LINK->LASTFRAMESENT = time(NULL);
LINK->LASTSENTQCOUNT = COUNT_AT_L2(LINK); LINK->LASTSENTQCOUNT = COUNT_AT_L2(LINK);
if (LINK->LASTSENTQCOUNT > LINK->maxQueued)
LINK->maxQueued = LINK->LASTSENTQCOUNT;
if (LINK->LASTSENTQCOUNT > LINK->intervalMaxQueued)
LINK->intervalMaxQueued = LINK->LASTSENTQCOUNT;
if (LINK->AllowCompress && Msg->LENGTH > 20 && LINK->TX_Q && Msg->PID == 240) // if short and no more not worth trying compression if (LINK->AllowCompress && Msg->LENGTH > 20 && LINK->TX_Q && Msg->PID == 240) // if short and no more not worth trying compression
{ {
@ -3162,6 +3334,10 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->SDTSLOT ++; LINK->SDTSLOT ++;
LINK->SDTSLOT &= 7; LINK->SDTSLOT &= 7;
LINK->framesTXed++;
LINK->bytesTXed += sendLen;
compdata += sendLen; compdata += sendLen;
complen -= sendLen; complen -= sendLen;
} }
@ -3174,6 +3350,9 @@ VOID SDETX(struct _LINKTABLE * LINK)
LINK->FRAMES[LINK->SDTSLOT] = Msg; LINK->FRAMES[LINK->SDTSLOT] = Msg;
LINK->SDTSLOT ++; LINK->SDTSLOT ++;
LINK->SDTSLOT &= 7; LINK->SDTSLOT &= 7;
LINK->framesTXed++;
LINK->bytesTXed += (Msg->LENGTH - (MSGHDDRLEN + 1));
} }
} }
@ -3231,6 +3410,7 @@ VOID SDETX(struct _LINKTABLE * LINK)
// FLAG BUFFER TO CAUSE TIMER TO BE RESET AFTER SEND (or ACK if ACKMODE) // FLAG BUFFER TO CAUSE TIMER TO BE RESET AFTER SEND (or ACK if ACKMODE)
Buffer->Linkptr = LINK; Buffer->Linkptr = LINK;
LINK->lastPSent = GetTickCount();
} }
} }
@ -3272,6 +3452,7 @@ VOID L2TimerProc()
int i = MAXLINKS; int i = MAXLINKS;
struct _LINKTABLE * LINK = LINKS; struct _LINKTABLE * LINK = LINKS;
struct PORTCONTROL * PORT = PORTTABLE; struct PORTCONTROL * PORT = PORTTABLE;
time_t Now = time(NULL);
while (i--) while (i--)
{ {
@ -3281,6 +3462,12 @@ VOID L2TimerProc()
continue; continue;
} }
// Check for Status report time
if (LINK->lastStatusSentTime && (Now - LINK->lastStatusSentTime) > linkStatusInterval)
hookL2SessionStatus(LINK);
// CHECK FOR TIMER EXPIRY OR BUSY CLEARED // CHECK FOR TIMER EXPIRY OR BUSY CLEARED
PORT = LINK->LINKPORT; PORT = LINK->LINKPORT;
@ -3316,7 +3503,7 @@ VOID L2TimerProc()
{ {
// Was busy // Was busy
if (RR_OR_RNR(LINK) != RNR) // SEE IF STILL BUSY if (RR_OR_RNR(LINK, 0) != RNR) // SEE IF STILL BUSY
{ {
// Not still busy - tell other end // Not still busy - tell other end
@ -3375,7 +3562,7 @@ VOID L2TimerProc()
{ {
SendSupervisCmd(LINK); SendSupervisCmd(LINK);
LINK++; LINK++;
continue; continue;
} }
} }
@ -3432,7 +3619,7 @@ VOID SendSupervisCmd(struct _LINKTABLE * LINK)
LINK->L2ACKREQ = 0; // CLEAR ACK NEEDED LINK->L2ACKREQ = 0; // CLEAR ACK NEEDED
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, TRUE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK' // MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3450,7 +3637,7 @@ void SEND_RR_RESP(struct _LINKTABLE * LINK, UCHAR PF)
{ {
UCHAR CTL; UCHAR CTL;
CTL = RR_OR_RNR(LINK); CTL = RR_OR_RNR(LINK, FALSE);
// MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK' // MOV L2STATE[EBX],5 ; CANCEL REJ - ACTUALLY GOING TO 'PENDING ACK'
@ -3643,6 +3830,8 @@ VOID L2TIMEOUT(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT)
{ {
// RETRIED N TIMES SEND A COUPLE OF DISCS AND THEN CLOSE // RETRIED N TIMES SEND A COUPLE OF DISCS AND THEN CLOSE
hookL2SessionClosed(LINK, "Retried Out", "Out");
InformPartner(LINK, RETRIEDOUT); // TELL OTHER END ITS GONE InformPartner(LINK, RETRIEDOUT); // TELL OTHER END ITS GONE
LINK->L2RETRIES -= 1; // Just send one DISC LINK->L2RETRIES -= 1; // Just send one DISC
@ -3674,6 +3863,13 @@ VOID SENDFRMR(struct _LINKTABLE * LINK)
MESSAGE * Buffer; MESSAGE * Buffer;
UCHAR * ptr; UCHAR * ptr;
#ifdef FRMRHACK // Ignore any frames with invalid n(r). If spurious error retry should fix it. If not link will retry out and reset
if (LINK->SDREJF & SDNRER)
return;
#endif
Buffer = SETUPL2MESSAGE(LINK, FRMR); Buffer = SETUPL2MESSAGE(LINK, FRMR);
if (Buffer == NULL) if (Buffer == NULL)
@ -3801,6 +3997,7 @@ VOID L2SENDXID(struct _LINKTABLE * LINK)
if (PORT) if (PORT)
{ {
LINK->LINKWINDOW = PORT->PORTWINDOW; // Just in case!
Buffer->PORT = PORT->PORTNUMBER; Buffer->PORT = PORT->PORTNUMBER;
PUT_ON_PORT_Q(PORT, Buffer); PUT_ON_PORT_Q(PORT, Buffer);
} }
@ -3944,7 +4141,7 @@ VOID InformPartner(struct _LINKTABLE * LINK, int Reason)
} }
UINT RR_OR_RNR(struct _LINKTABLE * LINK) UINT RR_OR_RNR(struct _LINKTABLE * LINK, int CMD)
{ {
UCHAR Temp; UCHAR Temp;
TRANSPORTENTRY * Session; TRANSPORTENTRY * Session;
@ -4021,18 +4218,21 @@ stayinREJ2:
goto CheckNSLoop2; // See if OK or we have another saved frame goto CheckNSLoop2; // See if OK or we have another saved frame
} }
if (LINK->L2STATE == 6) if (LINK->L2STATE == 6)
{
// if we support SREJ send that instesd or REJ
// if we support SREJ send that instesd or REJ // Dont send SREJ if clearing RNR - causes FRMR
// Dont send SREJ if clearing RNR - causes FRMR // Latest Spec says shouldn't send SREJ as Command
if (SaveRNRSent) if (SaveRNRSent || CMD == 1)
return REJ; return REJ;
if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi if (LINK->Ver2point2) // We only allow 2.2 with SREJ Multi
return SREJ; return SREJ;
else else
return REJ; return REJ;
}
} }
return RR; return RR;
@ -4627,5 +4827,32 @@ int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len)
} }
int CloseAllLinks()
{
struct _LINKTABLE * LINK = LINKS;
int i = MAXLINKS;
int Closed = 0;
while (i--)
{
if (LINK->LINKCALL[0] == 0 || LINK->L2STATE !=5 )
{
LINK++;
continue;
}
// Close Link
InformPartner(LINK, NORMALCLOSE); // TELL OTHER END ITS GONE
LINK->L2RETRIES -= 1; // Just send one DISC
LINK->L2STATE = 4; // CLOSING
L2SENDCOMMAND(LINK, DISC | PFBIT);
Closed++;
}
return Closed;
}

111
L3Code.c
View file

@ -60,6 +60,12 @@ VOID L3TRYNEXTDEST(struct ROUTE * ROUTE);
VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall); VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall);
void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer); void SendVARANetromNodes(struct TNCINFO * TNC, MESSAGE *Buffer);
void SendVARANetromMsg(struct TNCINFO * TNC,L3MESSAGEBUFFER * Buffer); void SendVARANetromMsg(struct TNCINFO * TNC,L3MESSAGEBUFFER * Buffer);
VOID SENDNODESMSG(int Portnum);
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame);
extern int NODESINPROGRESS;
extern int NODESToOnePort;
extern int CLOSING;
extern BOOL NODESINPROGRESS ;; extern BOOL NODESINPROGRESS ;;
PPORTCONTROL L3CURRENTPORT; PPORTCONTROL L3CURRENTPORT;
@ -94,7 +100,15 @@ VOID L3BG()
{ {
ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR; ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR;
// if NetROM over VARA pass direct to the driver // if NetROM over VARA or NetROM over TCP pass direct to the driver
if (ROUTE && ROUTE->TCPPort)
{
PL3MESSAGEBUFFER Frame = (PL3MESSAGEBUFFER)Q_REM(&DEST->DEST_Q);
TCPNETROMSend(ROUTE, Frame);
ReleaseBuffer(Frame);
continue;
}
if (ROUTE) if (ROUTE)
{ {
@ -222,7 +236,7 @@ BOOL ACTIVATE_DEST(struct DEST_LIST * DEST)
return L2SETUPCROSSLINK(ROUTE); return L2SETUPCROSSLINK(ROUTE);
} }
// We umst be waiting for link to come up // We must be waiting for link to come up
return TRUE; return TRUE;
@ -241,6 +255,13 @@ char Call1[10];
char Call2[10]; char Call2[10];
char Call3[10]; char Call3[10];
VOID PROCESSNODESPOLL(struct PORTCONTROL * PORT)
{
// Pauls G8BPT's request NODES Broadcast
SENDNODESMSG(PORT->PORTNUMBER);
return;
}
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT) VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
{ {
// PROCESS A NET/ROM 'NODES' MESSAGE // PROCESS A NET/ROM 'NODES' MESSAGE
@ -277,7 +298,7 @@ VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
{ {
APPL=&APPLCALLTABLE[App]; APPL=&APPLCALLTABLE[App];
if (APPL->APPLHASALIAS == 0 && CompareCalls(Msg->ORIGIN, APPL->APPLCALL)) if (CompareCalls(Msg->ORIGIN, APPL->APPLCALL))
return; return;
} }
@ -454,10 +475,10 @@ VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
if (CheckExcludeList(ptr1) == 0) // Excluded if (CheckExcludeList(ptr1) == 0) // Excluded
continue; continue;
for (n = 0; n < 32; n++) for (n = 0; n < NumberofAppls; n++)
{ {
if (CompareCalls(ptr1, APPLCALLTABLE[n].APPLCALL)) if (CompareCalls(ptr1, APPLCALLTABLE[n].APPLCALL))
continue; goto IgnoreNode; // Don't update our applications
} }
// MAKE SURE ITS NOT CORRUPTED // MAKE SURE ITS NOT CORRUPTED
@ -566,7 +587,7 @@ VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
ptr1 += 7; ptr1 += 7;
// UPDATE ALIAS // UPDATE ALIAS#
memcpy(DEST->DEST_ALIAS, ptr1, 6); memcpy(DEST->DEST_ALIAS, ptr1, 6);
@ -599,16 +620,13 @@ VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual)
if (DEST->DEST_STATE & 0x80) // BBS ENTRY if (DEST->DEST_STATE & 0x80) // BBS ENTRY
return; return;
for (Index = 0; Index < 4; Index++) for (Index = 0; Index < 3; Index++)
{ {
if (DEST->NRROUTE[Index].ROUT_NEIGHBOUR == ROUTE) if (DEST->NRROUTE[Index].ROUT_NEIGHBOUR == ROUTE)
{ {
if (Index == 0) if (Index == 0)
{ {
// THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE // THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE
if (DEST->DEST_ROUTE > 1) // LEAVE IT IF NOT SELECTED OR ALREADY USING BEST
DEST->DEST_ROUTE = 1;
} }
goto UpdatateThisEntry; goto UpdatateThisEntry;
@ -674,6 +692,7 @@ UpdatateThisEntry:
// IT DID - THIS IS ALSO CALLED BY CHECKL3TABLES. TRY RESETING // IT DID - THIS IS ALSO CALLED BY CHECKL3TABLES. TRY RESETING
// OBS, BUT NOT QUALITY // OBS, BUT NOT QUALITY
if ((DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) == 0) if ((DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) == 0)
DEST->NRROUTE[Index].ROUT_OBSCOUNT = OBSINIT; // SET OBSOLESCENCE COUNT DEST->NRROUTE[Index].ROUT_OBSCOUNT = OBSINIT; // SET OBSOLESCENCE COUNT
@ -707,6 +726,8 @@ SORTROUTES:
goto SORTROUTES; // 1 AND 2 MAY NOW BE WRONG! goto SORTROUTES; // 1 AND 2 MAY NOW BE WRONG!
} }
DEST->DEST_ROUTE = 0; // OForce re-evaluation.
} }
int COUNTNODES(struct ROUTE * ROUTE) int COUNTNODES(struct ROUTE * ROUTE)
@ -744,12 +765,26 @@ VOID L3BG();
VOID SENDNEXTNODESFRAGMENT(); VOID SENDNEXTNODESFRAGMENT();
VOID SENDNODESMSG() VOID SENDNODESMSG(int Portnum)
{ {
if (NODESINPROGRESS) if (NODESINPROGRESS)
return; return;
L3CURRENTPORT = PORTTABLE; NODESToOnePort = Portnum;
if (Portnum) // Nodes to one port only
{
L3CURRENTPORT = GetPortTableEntryFromPortNum(Portnum);
if (L3CURRENTPORT == 0)
{
NODESToOnePort = 0;
return;
}
}
else
L3CURRENTPORT = PORTTABLE;
SENDNEXTNODESFRAGMENT(); SENDNEXTNODESFRAGMENT();
} }
@ -785,16 +820,19 @@ VOID SENDNEXTNODESFRAGMENT()
// No NODES to this port, so go to next // No NODES to this port, so go to next
PORT = PORT->PORTPOINTER; PORT = PORT->PORTPOINTER;
if (PORT == NULL)
if (PORT == NULL || NODESToOnePort)
{ {
// Finished // Finished
NODESToOnePort = 0;
NODESINPROGRESS = 0; NODESINPROGRESS = 0;
return; return;
} }
} }
L3CURRENTPORT = PORT; if (NODESToOnePort == 0) // CurrentPort already set if NODESToOnePort
L3CURRENTPORT = PORT;
DEST = CURRENTNODE = DESTS; // START OF LIST DEST = CURRENTNODE = DESTS; // START OF LIST
NODESINPROGRESS = 1; NODESINPROGRESS = 1;
@ -851,13 +889,24 @@ VOID SENDNEXTNODESFRAGMENT()
if (DEST >= ENDDESTLIST) if (DEST >= ENDDESTLIST)
{ {
CURRENTNODE = 0; // Finished on this port CURRENTNODE = 0; // Finished on this port
L3CURRENTPORT = PORT->PORTPOINTER;
if (L3CURRENTPORT == NULL)
{
// Finished
// if sending to only one port then stop
if (NODESToOnePort)
{
NODESToOnePort = 0;
NODESINPROGRESS = 0; NODESINPROGRESS = 0;
} }
else
{
L3CURRENTPORT = PORT->PORTPOINTER;
if (L3CURRENTPORT == NULL)
{
// Finished
NODESINPROGRESS = 0;
}
}
goto Sendit; goto Sendit;
} }
@ -951,7 +1000,9 @@ VOID CLEARACTIVEROUTE(struct ROUTE * ROUTE, int Reason)
dest_list * DEST; dest_list * DEST;
int n; int n;
if (Reason != NORMALCLOSE || ROUTE->INP3Node) // If a link restarts and is no longer inp3 we must still clear any inp3 routes
// if (Reason != NORMALCLOSE || ROUTE->INP3Node)
TellINP3LinkGone(ROUTE); TellINP3LinkGone(ROUTE);
DEST = DESTS; DEST = DESTS;
@ -991,7 +1042,8 @@ VOID L3TimerProc()
LINK = LINKS; LINK = LINKS;
i = MAXLINKS; i = MAXLINKS;
while (i--);
while (i--)
{ {
if (LINK->LINKTYPE == 3) // Only if Internode if (LINK->LINKTYPE == 3) // Only if Internode
{ {
@ -1044,7 +1096,7 @@ VOID L3TimerProc()
L3TIMER = L3INTERVAL; L3TIMER = L3INTERVAL;
UPDATEDESTLIST(); UPDATEDESTLIST();
SENDNODESMSG(); SENDNODESMSG(0);
} }
} }
@ -1082,6 +1134,11 @@ VOID L3FastTimer()
MESSAGE * Msg; MESSAGE * Msg;
struct PORTCONTROL * PORT = PORTTABLE; struct PORTCONTROL * PORT = PORTTABLE;
// Not if Node is closing
if (CLOSING)
return;
INP3TIMER(); INP3TIMER();
// Send Node faster if VARA // Send Node faster if VARA
@ -1254,6 +1311,9 @@ VOID REMOVENODE(dest_list * DEST)
while (DEST->DEST_Q) while (DEST->DEST_Q)
ReleaseBuffer(Q_REM(&DEST->DEST_Q)); ReleaseBuffer(Q_REM(&DEST->DEST_Q));
if (DEST->DEST_STATE & 0x80) // LOCKED DESTINATION
return;
// MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT, // MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT,
// AS THEY SHOULD HAVE TIMED OUT LONG AGO // AS THEY SHOULD HAVE TIMED OUT LONG AGO
@ -1373,7 +1433,8 @@ VOID L3TRYNEXTDEST(struct ROUTE * ROUTE)
{ {
// not Locked // not Locked
DEST->NRROUTE[ActiveRoute].ROUT_OBSCOUNT--; if (ActiveRoute < 3) // Not INP3 Route
DEST->NRROUTE[ActiveRoute].ROUT_OBSCOUNT--;
// if ROUTE HAS EXPIRED - WE SHOULD CLEAR IT, AND MOVE OTHERS (IF ANY) UP // if ROUTE HAS EXPIRED - WE SHOULD CLEAR IT, AND MOVE OTHERS (IF ANY) UP
} }
@ -1505,6 +1566,9 @@ struct DEST_LIST * CHECKL3TABLES(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * Msg
{ {
int Index = DEST->DEST_ROUTE -1; int Index = DEST->DEST_ROUTE -1;
if (Index > 2) // INP3 Route
return DEST;
if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) // Locked: if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) // Locked:
return DEST; return DEST;
@ -1533,6 +1597,9 @@ VOID REFRESHROUTE(TRANSPORTENTRY * Session)
Index--; Index--;
if (Index > 2) // INP3 Route
return;
if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80) if (DEST->NRROUTE[Index].ROUT_OBSCOUNT & 0x80)
return; // Locked return; // Locked

488
L4Code.c
View file

@ -49,7 +49,7 @@ BOOL FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewInde
int GETBUSYBIT(TRANSPORTENTRY * L4); int GETBUSYBIT(TRANSPORTENTRY * L4);
BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySessions); BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySessions);
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE); TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE, int Service);
extern char * ALIASPTR; extern char * ALIASPTR;
void SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER * L3MSG, BOOL BPQNODE, UINT Applmask, UCHAR * ApplCall); void SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER * L3MSG, BOOL BPQNODE, UINT Applmask, UCHAR * ApplCall);
void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG); void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG);
@ -69,6 +69,12 @@ void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendVARANetromMsg(struct TNCINFO * TNC, PL3MESSAGEBUFFER MSG); void SendVARANetromMsg(struct TNCINFO * TNC, PL3MESSAGEBUFFER MSG);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen); int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len); int L2Compressit(unsigned char * Out, int OutSize, unsigned char * In, int Len);
void OutgoingL4ConnectionEvent(TRANSPORTENTRY * L4);
void IncomingL4ConnectionEvent(TRANSPORTENTRY * L4);
void L4DisconnectEvent(TRANSPORTENTRY * L4, char * Direction, char * Reason);
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame);
void L4StatusSeport(TRANSPORTENTRY * L4);
static UINT APPLMASK; static UINT APPLMASK;
extern BOOL LogL4Connects; extern BOOL LogL4Connects;
@ -84,6 +90,8 @@ extern int L2Compress;
extern int L2CompMaxframe; extern int L2CompMaxframe;
extern int L2CompPaclen; extern int L2CompPaclen;
int sessionStatusInterval = 300; // 5 mins
// L4 Flags Values // L4 Flags Values
#define DISCPENDING 8 // SEND DISC WHEN ALL DATA ACK'ED #define DISCPENDING 8 // SEND DISC WHEN ALL DATA ACK'ED
@ -131,6 +139,14 @@ VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
return; return;
} }
// IS IT INP3 (L3RTT)
if (CompareCalls(L3MSG->L3DEST, L3RTT))
{
ProcessRTTMsg(LINK->NEIGHBOUR, L3MSG, L3MSG->LENGTH, L3MSG->Port);
return;
}
APPLMASK = 0; // NOT APPLICATION APPLMASK = 0; // NOT APPLICATION
if (NODE) // _NODE SUPPORT INCLUDED? if (NODE) // _NODE SUPPORT INCLUDED?
@ -167,14 +183,6 @@ VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
APPL++; APPL++;
} }
// IS IT INP3 (L3RTT)
if (CompareCalls(L3MSG->L3DEST, L3RTT))
{
ProcessRTTMsg(LINK->NEIGHBOUR, L3MSG, L3MSG->LENGTH, L3MSG->Port);
return;
}
L3MSG->L3TTL--; L3MSG->L3TTL--;
if (L3MSG->L3TTL == 0) if (L3MSG->L3TTL == 0)
@ -455,7 +463,7 @@ VOID Q_IP_MSG(MESSAGE * Buffer)
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
} }
VOID SENDL4CONNECT(TRANSPORTENTRY * Session) VOID SENDL4CONNECT(TRANSPORTENTRY * Session, int Service)
{ {
PL3MESSAGEBUFFER MSG = (PL3MESSAGEBUFFER)GetBuff(); PL3MESSAGEBUFFER MSG = (PL3MESSAGEBUFFER)GetBuff();
struct DEST_LIST * DEST = Session->L4TARGET.DEST; struct DEST_LIST * DEST = Session->L4TARGET.DEST;
@ -479,9 +487,18 @@ VOID SENDL4CONNECT(TRANSPORTENTRY * Session)
MSG->L4INDEX = Session->CIRCUITINDEX; MSG->L4INDEX = Session->CIRCUITINDEX;
MSG->L4ID = Session->CIRCUITID; MSG->L4ID = Session->CIRCUITID;
MSG->L4TXNO = 0;
MSG->L4RXNO = 0; if (Service == -1) // Normal CREQ
MSG->L4FLAGS = L4CREQ; {
MSG->L4RXNO = 0;
MSG->L4FLAGS = L4CREQ;
}
else
{
MSG->L4RXNO = Service << 8; // Paula's extended connect
MSG->L4TXNO = (Service & 0xff);
MSG->L4FLAGS = L4CREQX;
}
MSG->L4DATA[0] = L4DEFAULTWINDOW; // PROPOSED WINDOW MSG->L4DATA[0] = L4DEFAULTWINDOW; // PROPOSED WINDOW
@ -791,7 +808,7 @@ VOID L4BG()
complen = L2Compressit(Compressed, 8192, toCompress, toCompressLen); complen = L2Compressit(Compressed, 8192, toCompress, toCompressLen);
Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen); // Debugprintf("%d %d %d%%", toCompressLen, complen, ((toCompressLen - complen) * 100) / toCompressLen);
// Send compressed // Send compressed
@ -826,7 +843,7 @@ VOID L4BG()
Len = ChunkSize; Len = ChunkSize;
complen = L2Compressit(Compressed, 8192, CompressPtr, Len); complen = L2Compressit(Compressed, 8192, CompressPtr, Len);
Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len); // Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len);
sendChunk(L4, Compressed, complen, savePort); sendChunk(L4, Compressed, complen, savePort);
@ -858,8 +875,6 @@ VOID L4BG()
Msglen = Msg->LENGTH - (MSGHDDRLEN + 1); //Dont include PID Msglen = Msg->LENGTH - (MSGHDDRLEN + 1); //Dont include PID
LINK->bytesTXed += Msglen;
Paclen = L4->SESSPACLEN; Paclen = L4->SESSPACLEN;
if (Paclen == 0) if (Paclen == 0)
@ -1116,6 +1131,7 @@ VOID L4TimerProc()
TRANSPORTENTRY * L4 = L4TABLE; TRANSPORTENTRY * L4 = L4TABLE;
TRANSPORTENTRY * Partner; TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS; int MaxLinks = MAXLINKS;
time_t Now = time(NULL);
while (n--) while (n--)
{ {
@ -1125,6 +1141,12 @@ VOID L4TimerProc()
continue; continue;
} }
// Check for Status report time
if (L4->lastStatusSentTime && (Now - L4->lastStatusSentTime) > sessionStatusInterval)
L4StatusSeport(L4);
// CHECK FOR L4BUSY SET AND NO LONGER BUSY // CHECK FOR L4BUSY SET AND NO LONGER BUSY
if (L4->NAKBITS & L4BUSY) if (L4->NAKBITS & L4BUSY)
@ -1223,7 +1245,7 @@ VOID L4TIMEOUT(TRANSPORTENTRY * L4)
Debugprintf("Retrying L4 Connect Request"); Debugprintf("Retrying L4 Connect Request");
SENDL4CONNECT(L4); // Resend connect SENDL4CONNECT(L4, L4->Service); // Resend connect
return; return;
} }
@ -1258,10 +1280,13 @@ VOID L4TIMEOUT(TRANSPORTENTRY * L4)
// if compressed session display stats // if compressed session display stats
L4DisconnectEvent(L4, "outgoing", "Retried Out");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT) CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return; return;
} }
// RESEND ALL OUTSTANDING FRAMES // RESEND ALL OUTSTANDING FRAMES
L4->FLAGS &= 0x7F; // CLEAR CHOKED L4->FLAGS &= 0x7F; // CLEAR CHOKED
@ -1568,19 +1593,26 @@ void WriteL4LogLine(UCHAR * mycall, UCHAR * call, UCHAR * node)
fclose(L4LogHandle); fclose(L4LogHandle);
} }
VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT ApplMask, UCHAR * ApplCall) extern struct CMDX COMMANDS[];
extern int NUMBEROFCOMMANDS;
VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT ApplMask, UCHAR * ApplCall, int Service)
{ {
// CONNECT REQUEST - SEE IF EXISTING SESSION // CONNECT REQUEST - SEE IF EXISTING SESSION
// IF NOT, GET AND FORMAT SESSION TABLE ENTRY // IF NOT, GET AND FORMAT SESSION TABLE ENTRY
// SEND CONNECT ACK // SEND CONNECT ACK
// EDI = _BUFFER, EBX = LINK // Service is for Paula's CREQX - Connect to Service
TRANSPORTENTRY * L4; TRANSPORTENTRY * L4;
int BPQNODE = 0; // NOT ONE OF MINE int BPQNODE = 0; // NOT ONE OF MINE
char BPQPARAMS[10]; // Extended Connect Params from BPQ Node char BPQPARAMS[10]; // Extended Connect Params from BPQ Node
int CONERROR; int CONERROR;
int Index; int Index;
char APPLCMD[13] = "";
if (APPL)
memcpy(APPLCMD, APPL->APPLCMD, 13);
memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE memcpy(BPQPARAMS, &L4T1, 2); // SET DEFAULT T1 IN CASE NOT FROM ANOTHER BPQ NODE
@ -1608,8 +1640,9 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
} }
L4->CIRCUITINDEX = Index; L4->CIRCUITINDEX = Index;
L4->Service = Service;
SETUPNEWCIRCUIT(LINK, L3MSG, L4, BPQPARAMS, ApplMask, &BPQNODE); SETUPNEWCIRCUIT(LINK, L3MSG, L4, BPQPARAMS, ApplMask, &BPQNODE, Service);
if (L4->L4TARGET.DEST == 0) if (L4->L4TARGET.DEST == 0)
{ {
@ -1619,6 +1652,60 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
SendConNAK(LINK, L3MSG); SendConNAK(LINK, L3MSG);
return; return;
} }
// Check for NetromX Service
if (Service > 0 && Service != 23) // 0 is CMD Hander 23 is TELNET which also connects to node
{
int i;
for (i = 0; i < NUMBEROFSSERVICES; i++)
{
if (SERVICES[i].ServiceNo == Service)
{
// Check if we have this application
struct CMDX * CMD = NULL;
int n;
char * APP = &SERVICES[i].ServiceName[0];
int APPlen = strlen(APP);
for (n = PASSCMD; n < NUMBEROFCOMMANDS; n++) // Don't allow SYSOP Commands
{
CMD = &COMMANDS[n];
if (n == APPL1) // First APPL command
{
ApplMask = 1; // FOR APPLICATION ATTACH REQUESTS
ALIASPTR = &CMDALIAS[0][0];
}
// ptr1 is input command
if (memcmp(CMD->String, APP, APPlen) == 0)
{
// At the moment I only handle connects to appls. May support other node commands later.
memcpy(APPLCMD, CMD->String, 13);
if (n < APPL1 + NumberofAppls)
goto doAPPLConnect;
}
ApplMask <<= 1;
ALIASPTR += ALIASLEN;
}
}
}
// Not one of our applications - refuse connect
memset(L4, 0, sizeof (TRANSPORTENTRY));
SendConNAK(LINK, L3MSG);
return;
}
//
// IF CONNECT TO APPL, ALLOCATE BBS PORT // IF CONNECT TO APPL, ALLOCATE BBS PORT
if (ApplMask == 0 || BPQPARAMS[2] == 'Z') // Z is "Spy" Connect if (ApplMask == 0 || BPQPARAMS[2] == 'Z') // Z is "Spy" Connect
@ -1630,6 +1717,7 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
// IF APPL CONNECT, SEE IF APPL HAS AN ALIAS // IF APPL CONNECT, SEE IF APPL HAS AN ALIAS
doAPPLConnect:
if (ALIASPTR[0] > ' ') if (ALIASPTR[0] > ' ')
{ {
@ -1644,7 +1732,7 @@ VOID CONNECTREQUEST(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, UINT Appl
if (Msg) if (Msg)
{ {
Msg->PID = 0xf0; Msg->PID = 0xf0;
memcpy(Msg->L2DATA, APPL->APPLCMD, 12); memcpy(Msg->L2DATA, APPLCMD, 12);
Msg->L2DATA[12] = 13; Msg->L2DATA[12] = 13;
Msg->LENGTH = MSGHDDRLEN + 12 + 2; // 2 for PID and CR Msg->LENGTH = MSGHDDRLEN + 12 + 2; // 2 for PID and CR
@ -1747,10 +1835,17 @@ VOID SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER *
TNC = LINK->LINKPORT->TNC; TNC = LINK->LINKPORT->TNC;
if (TNC && TNC->NetRomMode) if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG); SendVARANetromMsg(TNC, L3MSG);
else else
C_Q_ADD(&LINK->TX_Q, L3MSG); C_Q_ADD(&LINK->TX_Q, L3MSG);
IncomingL4ConnectionEvent(L4);
} }
int FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewIndex) int FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewIndex)
@ -1827,33 +1922,63 @@ void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG)
memcpy(L3MSG->L3SRCE, L3MSG->L3DEST, 7); memcpy(L3MSG->L3SRCE, L3MSG->L3DEST, 7);
memcpy(L3MSG->L3DEST, Temp, 7); memcpy(L3MSG->L3DEST, Temp, 7);
L3MSG->L3DEST[6] &= 0x1E; // Mack EOA and CMD L3MSG->L3DEST[6] &= 0x1E; // Mask EOA and CMD
L3MSG->L3SRCE[6] &= 0x1E; L3MSG->L3SRCE[6] &= 0x1E;
L3MSG->L3SRCE[6] |= 1; // Set Last Call L3MSG->L3SRCE[6] |= 1; // Set Last Call
} }
void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
{ {
struct TNCINFO * TNC;
L3MSG->L4FLAGS = L4CACK | L4BUSY; // REJECT L3MSG->L4FLAGS = L4CACK | L4BUSY; // REJECT
L3MSG->L4DATA[0] = 0; // WINDOW L3MSG->L4DATA[0] = 0; // WINDOW
L3SWAPADDRESSES(L3MSG); L3SWAPADDRESSES(L3MSG);
L3MSG->L3TTL = L3LIVES; L3MSG->L3TTL = L3LIVES;
C_Q_ADD(&LINK->TX_Q, L3MSG); TNC = LINK->LINKPORT->TNC;
if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG);
else
C_Q_ADD(&LINK->TX_Q, L3MSG);
} }
VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
{ {
// Paula's extension // Paula's extension
struct TNCINFO * TNC;
L3MSG->L4RXNO = L3MSG->L4ID;
L3MSG->L4TXNO = L3MSG->L4INDEX;
L3MSG->L4FLAGS = L4RESET; L3MSG->L4FLAGS = L4RESET;
L3SWAPADDRESSES(L3MSG); L3SWAPADDRESSES(L3MSG);
L3MSG->L3TTL = L3LIVES; L3MSG->L3TTL = L3LIVES;
L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG); L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG);
C_Q_ADD(&LINK->TX_Q, L3MSG);
TNC = LINK->LINKPORT->TNC;
if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG);
else
C_Q_ADD(&LINK->TX_Q, L3MSG);
} }
@ -1863,7 +1988,7 @@ VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE) TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE, int Service)
{ {
struct DEST_LIST * DEST; struct DEST_LIST * DEST;
int Maxtries = 2; // Just in case int Maxtries = 2; // Just in case
@ -1882,10 +2007,10 @@ VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
L4->SESSIONT1 = L4T1; L4->SESSIONT1 = L4T1;
L4->L4WINDOW = (UCHAR)L4DEFAULTWINDOW; L4->L4WINDOW = L3MSG->L4DATA[0];
if (L3MSG->L4DATA[0] > L4DEFAULTWINDOW) if (L3MSG->L4DATA[0] > L4DEFAULTWINDOW)
L4->L4WINDOW = L3MSG->L4DATA[0]; L4->L4WINDOW = L4DEFAULTWINDOW;
memcpy(L4->L4USER, &L3MSG->L4DATA[1], 7); // Originator's call from Call Request memcpy(L4->L4USER, &L3MSG->L4DATA[1], 7); // Originator's call from Call Request
@ -1943,7 +2068,7 @@ TryAgain:
while (n--) while (n--)
{ {
if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0) // Not used and not INP3 if (DEST->DEST_COUNT == 0 && DEST->DEST_RTT == 0 && (DEST->DEST_STATE & 0x80) == 0) // Not used and not INP3 and not Appl
{ {
if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual) if (DEST->NRROUTE[0].ROUT_QUALITY < WorstQual)
{ {
@ -2020,6 +2145,8 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
char Call[10]; char Call[10];
struct TNCINFO * TNC; struct TNCINFO * TNC;
int Service = -1; // Paula's connect to service
L4FRAMESRX++; L4FRAMESRX++;
Opcode = L3MSG->L4FLAGS & 15; Opcode = L3MSG->L4FLAGS & 15;
@ -2048,9 +2175,13 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
ReleaseBuffer(L3MSG); ReleaseBuffer(L3MSG);
return; return;
case L4CREQX: // Paula's connect to service
Service = (L3MSG->L4RXNO << 8) | L3MSG->L4TXNO;
case L4CREQ: case L4CREQ:
CONNECTREQUEST(LINK, L3MSG, ApplMask, ApplCall); CONNECTREQUEST(LINK, L3MSG, ApplMask, ApplCall, Service);
return; return;
} }
@ -2067,7 +2198,8 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
while (n--) while (n--)
{ {
if (L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX) if ((L4->L4USER[0] && L4->FARID == L3MSG->L4RXNO && L4->FARINDEX == L3MSG->L4TXNO) || // Paula returns session in RX/TXNO, I sent in ID/INDEX
(L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX))
{ {
// Check L3 source call to be sure (should that be L4 source call?? // Check L3 source call to be sure (should that be L4 source call??
@ -2075,10 +2207,9 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
if (memcmp(L3MSG->L3SRCE, L4->L4TARGET.DEST->DEST_CALL, 7) == 0) if (memcmp(L3MSG->L3SRCE, L4->L4TARGET.DEST->DEST_CALL, 7) == 0)
{ {
L4DisconnectEvent(L4, "incoming", "RESET Received");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT) CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
} }
ReleaseBuffer(L3MSG);
return;
} }
L4++; L4++;
} }
@ -2156,6 +2287,9 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
L4->L4WINDOW = L3MSG->L4DATA[0]; L4->L4WINDOW = L3MSG->L4DATA[0];
strcpy(ReplyText, "Connected to"); strcpy(ReplyText, "Connected to");
OutgoingL4ConnectionEvent(L4);
} }
if (Partner == 0) if (Partner == 0)
@ -2164,6 +2298,14 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
return; return;
} }
// if connect to service don't send connected to node messsage as service will send own message
// if (L4->Service)
// {
// ReleaseBuffer(L3MSG);
// return;
// }
Msg = (PDATAMESSAGE)L3MSG; // reuse input buffer Msg = (PDATAMESSAGE)L3MSG; // reuse input buffer
Msg->PID = 0xf0; Msg->PID = 0xf0;
@ -2194,16 +2336,25 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
TNC = LINK->LINKPORT->TNC; TNC = LINK->LINKPORT->TNC;
if (TNC && TNC->NetRomMode) if (LINK->NEIGHBOUR && LINK->NEIGHBOUR->TCPPort)
{
TCPNETROMSend(LINK->NEIGHBOUR, L3MSG);
ReleaseBuffer(L3MSG);
}
else if (TNC && TNC->NetRomMode)
SendVARANetromMsg(TNC, L3MSG); SendVARANetromMsg(TNC, L3MSG);
else else
C_Q_ADD(&LINK->TX_Q, L3MSG); C_Q_ADD(&LINK->TX_Q, L3MSG);
L4DisconnectEvent(L4, "incoming", "DREQ Received");
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT) CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return; return;
case L4DACK: case L4DACK:
L4DisconnectEvent(L4, "outgoing", "DACK Received");
CLEARSESSIONENTRY(L4); CLEARSESSIONENTRY(L4);
ReleaseBuffer(L3MSG); ReleaseBuffer(L3MSG);
return; return;
@ -2640,241 +2791,32 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
} }
int CloseAllSessions()
{
/* int n = MAXCIRCUITS;
PUBLIC KILLSESSION TRANSPORTENTRY * L4 = L4TABLE;
KILLSESSION: TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS;
pushad int Closed = 0;
push ebx
CALL _CLEARSESSIONENTRY while (n--)
pop ebx {
popad if (L4->L4USER[0] == 0)
{
JMP L4CONN90 ; REJECT L4++;
continue;
PUBLIC CONNECTACK }
CONNECTACK:
; Closed++;
; EXTRACT EXTENDED PARAMS IF PRESENT
; Partner = L4->L4CROSSLINK;
CMP BYTE PTR MSGLENGTH[EDI],L4DATA+1 CLOSECURRENTSESSION(L4);
JE SHORT NOTBPQ
if (Partner)
MOV AL,L4DATA+1[EDI] CLOSECURRENTSESSION(Partner); // CLOSE THIS ONE
SUB AL,L3MONR[EDI]
ADD AL,41H ; HOPS TO DEST + 40H L4++;
}
MOV ESI,L4TARGET[EBX] return Closed;
AND DEST_STATE[ESI],80H }
OR DEST_STATE[ESI],AL ; SAVE
PUBLIC NOTBPQ
NOTBPQ:
;
; SEE IF SUCCESS OR FAIL
;
PUSH EDI
MOV ESI,L4TARGET[EBX] ; ADDR OF LINK/DEST ENTRY
LEA ESI,DEST_CALL[ESI]
CALL DECODENODENAME ; CONVERT TO ALIAS:CALL
MOV EDI,OFFSET32 CONACKCALL
MOV ECX,17
REP MOVSB
POP EDI
TEST L4FLAGS[EDI],L4BUSY
JNZ SHORT L4CONNFAILED
CMP L4STATE[EBX],5
JE SHORT CONNACK05 ; MUST BE REPEAT MSG - DISCARD
MOV AX,WORD PTR L4TXNO[EDI] ; HIS INDEX
MOV WORD PTR FARINDEX[EBX],AX
MOV L4STATE[EBX],5 ; ACTIVE
MOV L4TIMER[EBX],0 ; CANCEL TIMER
MOV L4RETRIES[EBX],0 ; CLEAR RETRY COUNT
MOV AL,L4DATA[EDI] ; WINDOW
MOV L4WINDOW[EBX],AL ; SET WINDOW
MOV EDX,L4CROSSLINK[EBX] ; POINT TO PARTNER
;
MOV ESI,OFFSET32 CONNECTEDMSG
MOV ECX,LCONNECTEDMSG
JMP SHORT L4CONNCOMM
PUBLIC L4CONNFAILED
L4CONNFAILED:
;
MOV EDX,L4CROSSLINK[EBX] ; SAVE PARTNER
pushad
push ebx
CALL _CLEARSESSIONENTRY
pop ebx
popad
PUSH EBX
MOV EBX,EDX
MOV L4CROSSLINK[EBX],0 ; CLEAR CROSSLINK
POP EBX
MOV ESI,OFFSET32 BUSYMSG ; ?? BUSY
MOV ECX,LBUSYMSG
PUBLIC L4CONNCOMM
L4CONNCOMM:
OR EDX,EDX
JNZ SHORT L4CONNOK10
;
; CROSSLINK HAS GONE?? - JUST CHUCK MESSAGE
;
PUBLIC CONNACK05
CONNACK05:
JMP L4DISCARD
PUBLIC L4CONNOK10
L4CONNOK10:
PUSH EBX
PUSH ESI
PUSH ECX
MOV EDI,_BUFFER
ADD EDI,7
MOV AL,0F0H
STOSB ; PID
CALL _SETUPNODEHEADER ; PUT IN _NODE ID
POP ECX
POP ESI
REP MOVSB
MOV ESI,OFFSET32 CONACKCALL
MOV ECX,17 ; MAX LENGTH ALIAS:CALL
REP MOVSB
MOV AL,0DH
STOSB
MOV ECX,EDI
MOV EDI,_BUFFER
SUB ECX,EDI
MOV MSGLENGTH[EDI],CX
MOV EBX,EDX ; CALLER'S SESSION
LEA ESI,L4TX_Q[EBX]
CALL _Q_ADD ; SEND MESSAGE TO CALLER
CALL _POSTDATAAVAIL
POP EBX ; ORIGINAL CIRCUIT TABLE
RET
PUBLIC SENDCONNECTREPLY
SENDCONNECTREPLY:
;
; LINK SETUP COMPLETE - EBX = LINK, EDI = _BUFFER
;
CMP LINKTYPE[EBX],3
JNE SHORT CONNECTED00
;
; _NODE - _NODE SESSION SET UP - DONT NEED TO DO ANYTHING (I THINK!)
;
CALL RELBUFF
RET
;
; UP/DOWN LINK
;
PUBLIC CONNECTED00
CONNECTED00:
CMP CIRCUITPOINTER[EBX],0
JNE SHORT CONNECTED01
CALL RELBUFF ; UP/DOWN WITH NO SESSION - NOONE TO TELL
RET ; NO CROSS LINK
PUBLIC CONNECTED01
CONNECTED01:
MOV _BUFFER,EDI
PUSH EBX
PUSH ESI
PUSH ECX
ADD EDI,7
MOV AL,0F0H
STOSB ; PID
CALL _SETUPNODEHEADER ; PUT IN _NODE ID
LEA ESI,LINKCALL[EBX]
PUSH EDI
CALL CONVFROMAX25 ; ADDR OF CALLED STATION
POP EDI
MOV EBX,CIRCUITPOINTER[EBX]
MOV L4STATE[EBX],5 ; SET LINK UP
MOV EBX,L4CROSSLINK[EBX] ; TO INCOMING LINK
cmp ebx,0
jne xxx
;
; NO LINK ???
;
MOV EDI,_BUFFER
CALL RELBUFF
POP ECX
POP ESI
POP EBX
RET
PUBLIC xxx
xxx:
POP ECX
POP ESI
REP MOVSB
MOV ESI,OFFSET32 _NORMCALL
MOVZX ECX,_NORMLEN
REP MOVSB
MOV AL,0DH
STOSB
MOV ECX,EDI
MOV EDI,_BUFFER
SUB ECX,EDI
MOV MSGLENGTH[EDI],CX
LEA ESI,L4TX_Q[EBX]
CALL _Q_ADD ; SEND MESSAGE TO CALLER
CALL _POSTDATAAVAIL
POP EBX
RET
*/

View file

@ -83,8 +83,9 @@ void RHPPoll();
VOID GetPGConfig(); VOID GetPGConfig();
void SendBBSDataToPktMap(); void SendBBSDataToPktMap();
void CloseAllLinks();
extern uint64_t timeLoadedMS; void hookNodeClosing(char * Reason);
void NETROMTCPResolve();
BOOL IncludesMail = FALSE; BOOL IncludesMail = FALSE;
BOOL IncludesChat = FALSE; BOOL IncludesChat = FALSE;
@ -262,9 +263,9 @@ extern char MailDir[MAX_PATH];
extern time_t MaintClock; // Time to run housekeeping extern time_t MaintClock; // Time to run housekeeping
#ifdef WIN32 #ifdef WIN32
BOOL KEEPGOING = 30; // 5 secs to shut down int KEEPGOING = 30; // 5 secs to shut down
#else #else
BOOL KEEPGOING = 50; // 5 secs to shut down int KEEPGOING = 50; // 5 secs to shut down
#endif #endif
BOOL Restarting = FALSE; BOOL Restarting = FALSE;
BOOL CLOSING = FALSE; BOOL CLOSING = FALSE;
@ -337,6 +338,7 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
// Handle the CTRL-C signal. // Handle the CTRL-C signal.
case CTRL_C_EVENT: case CTRL_C_EVENT:
printf( "Ctrl-C event\n\n" ); printf( "Ctrl-C event\n\n" );
CloseAllLinks();
CLOSING = TRUE; CLOSING = TRUE;
Beep( 750, 300 ); Beep( 750, 300 );
return( TRUE ); return( TRUE );
@ -344,7 +346,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
// CTRL-CLOSE: confirm that the user wants to exit. // CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT: case CTRL_CLOSE_EVENT:
CLOSING = TRUE; CloseAllLinks();
CLOSING = TRUE;
printf( "Ctrl-Close event\n\n" ); printf( "Ctrl-Close event\n\n" );
Sleep(20000); Sleep(20000);
Beep( 750, 300 ); Beep( 750, 300 );
@ -354,7 +357,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
case CTRL_BREAK_EVENT: case CTRL_BREAK_EVENT:
Beep( 900, 200 ); Beep( 900, 200 );
printf( "Ctrl-Break event\n\n" ); printf( "Ctrl-Break event\n\n" );
CLOSING = TRUE; CloseAllLinks();
CLOSING = TRUE;
Beep( 750, 300 ); Beep( 750, 300 );
return FALSE; return FALSE;
@ -366,7 +370,8 @@ BOOL CtrlHandler(DWORD fdwCtrlType)
case CTRL_SHUTDOWN_EVENT: case CTRL_SHUTDOWN_EVENT:
Beep( 750, 500 ); Beep( 750, 500 );
printf( "Ctrl-Shutdown event\n\n" ); printf( "Ctrl-Shutdown event\n\n" );
CLOSING = TRUE; CloseAllLinks();
CLOSING = TRUE;
Beep( 750, 300 ); Beep( 750, 300 );
return FALSE; return FALSE;
@ -399,6 +404,9 @@ static void segvhandler(int sig)
write(STDOUT_FILENO, msg, strlen(msg)); write(STDOUT_FILENO, msg, strlen(msg));
backtrace_symbols_fd(array, size, STDOUT_FILENO); backtrace_symbols_fd(array, size, STDOUT_FILENO);
hookNodeClosing("sigsegv");
Sleep(500);
exit(1); exit(1);
} }
@ -419,6 +427,9 @@ static void abrthandler(int sig)
write(STDOUT_FILENO, msg, strlen(msg)); write(STDOUT_FILENO, msg, strlen(msg));
backtrace_symbols_fd(array, size, STDOUT_FILENO); backtrace_symbols_fd(array, size, STDOUT_FILENO);
hookNodeClosing("sigabrt");
Sleep(500);
exit(1); exit(1);
} }
@ -427,12 +438,14 @@ static void sigterm_handler(int sig)
{ {
syslog(LOG_INFO, "terminating on SIGTERM\n"); syslog(LOG_INFO, "terminating on SIGTERM\n");
CLOSING = TRUE; CLOSING = TRUE;
CloseAllLinks();
} }
static void sigint_handler(int sig) static void sigint_handler(int sig)
{ {
printf("terminating on SIGINT\n"); printf("terminating on SIGINT\n");
CLOSING = TRUE; CLOSING = TRUE;
CloseAllLinks();
} }
@ -839,16 +852,13 @@ int main(int argc, char * argv[])
#endif #endif
#endif #endif
// Disable Console Terminal if stdout redirected // Disable Console Terminal if stdout redirected
// printf("STDOUT %d\n",isatty(STDOUT_FILENO)); // printf("STDOUT %d\n",isatty(STDOUT_FILENO));
// printf("STDIN %d\n",isatty(STDIN_FILENO)); // printf("STDIN %d\n",isatty(STDIN_FILENO));
if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)) if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO))
Redirected = 1; Redirected = 1;
timeLoadedMS = GetTickCount();
#endif #endif
printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring); printf("G8BPQ AX25 Packet Switch System Version %s %s\n", TextVerstring, Datestring);
@ -856,7 +866,6 @@ int main(int argc, char * argv[])
srand(time(NULL)); srand(time(NULL));
// look for optarg format parameters // look for optarg format parameters
{ {
@ -1002,6 +1011,8 @@ int main(int argc, char * argv[])
return (0); return (0);
} }
NETROMTCPResolve();
for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null
PWLen=i; PWLen=i;
@ -1534,6 +1545,8 @@ int main(int argc, char * argv[])
Start(); Start();
NETROMTCPResolve();
INITIALISEPORTS(); INITIALISEPORTS();
SetApplPorts(); SetApplPorts();
@ -1683,6 +1696,9 @@ int main(int argc, char * argv[])
Slowtimer = 0; Slowtimer = 0;
} }
hookNodeClosing("Shutdown");
Sleep(500);
printf("Closing Ports\n"); printf("Closing Ports\n");
CloseTNCEmulator(); CloseTNCEmulator();

0
MHSave.txt Normal file
View file

View file

@ -2098,13 +2098,12 @@ int CreateSMTPMessage(SocketConn * sockptr, int i, char * MsgTitle, time_t Date,
if (strcmp(Msg->to, "RMS") == 0) // Address is in via if (strcmp(Msg->to, "RMS") == 0) // Address is in via
strcpy(B2To, Msg->via); strcpy(B2To, Msg->via);
else
if (Msg->via[0])
sprintf(B2To, "%s@%s", Msg->to, Msg->via);
else else
strcpy(B2To, Msg->to); if (Msg->via[0])
sprintf(B2To, "%s@%s", Msg->to, Msg->via);
else
strcpy(B2To, Msg->to);
Msg->B2Flags = B2Msg | Attachments; Msg->B2Flags = B2Msg | Attachments;
@ -3934,12 +3933,12 @@ int CreatePOP3Message(char * From, char * To, char * MsgTitle, time_t Date, char
if (strcmp(Msg->to, "RMS") == 0) // Address is in via if (strcmp(Msg->to, "RMS") == 0) // Address is in via
strcpy(B2To, Msg->via); strcpy(B2To, Msg->via);
else
if (Msg->via[0])
sprintf(B2To, "%s@%s", Msg->to, Msg->via);
else else
strcpy(B2To, Msg->to); if (Msg->via[0])
sprintf(B2To, "%s@%s", Msg->to, Msg->via);
else
strcpy(B2To, Msg->to);
Msg->B2Flags = B2Msg | Attachments; Msg->B2Flags = B2Msg | Attachments;

111
Moncode.c
View file

@ -59,7 +59,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#define NODES_SIG 0xFF #define NODES_SIG 0xFF
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, unsigned int msglen); UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, int msglen);
char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen); char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen);
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen); UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
@ -655,12 +655,13 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
char Node[10]; char Node[10];
UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window; UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window;
UCHAR * ptr = &ADJBUFFER->L2DATA[0]; UCHAR * ptr = &ADJBUFFER->L2DATA[0];
int service = 0;
int netromx = 0; // Set if Paula's connect to service
if (ADJBUFFER->L2DATA[0] == NODES_SIG) if (ADJBUFFER->L2DATA[0] == NODES_SIG)
{ {
// Display NODES // Display NODES
// If an INP3 RIF (type <> UI) decode as such // If an INP3 RIF (type <> UI) decode as such
if (ADJBUFFER->CTL != 3) // UI if (ADJBUFFER->CTL != 3) // UI
@ -691,6 +692,14 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
return Output; return Output;
} }
if (ADJBUFFER->L2DATA[0] == 0xfe) // Paula's Nodes Poll
{
memcpy(Alias, ++ptr, 6);
Output += sprintf((char *)Output, " NODES POLL from %s\r", Alias);
return Output;
}
// Display normal NET/ROM transmissions // Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r "); Output += sprintf((char *)Output, " NET/ROM\r ");
@ -714,6 +723,12 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
switch (OpCode) switch (OpCode)
{ {
case L4CREQX: // Paula's connect to service
netromx = 1;
service = (RXNO << 8) | TXNO;
case L4CREQ: case L4CREQ:
Window = *(ptr++); Window = *(ptr++);
@ -722,7 +737,10 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
Node[ConvFromAX25(ptr, Node)] = 0; Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7; ptr +=7;
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node); if (netromx)
Output += sprintf((char *)Output, "<CON REQX> w=%d %d@%s at %s", Window, service, Dest, Node);
else
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
if (MsgLen > 38) // BPQ Extended Params if (MsgLen > 38) // BPQ Extended Params
{ {
@ -737,7 +755,7 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
if (Flags & L4BUSY) // BUSY RETURNED if (Flags & L4BUSY) // BUSY RETURNED
return Output + sprintf((char *)Output, " <CON NAK> - BUSY"); return Output + sprintf((char *)Output, " <CON NAK> - BUSY");
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[1], TXNO, RXNO); return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[0], TXNO, RXNO);
case L4DREQ: case L4DREQ:
@ -985,3 +1003,88 @@ char * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]); ptr[15], ptr[16], ptr[17], ptr[18], Dest, ptr[26], ptr[27], ptr[28], ptr[29]);
} }
char Lastpacketlog[256];
int PacketLogDelay = 30000;
extern BPQVECSTRUC * FILEMONVECTOR;
extern UCHAR LogDirectory[260];
void WritePacketLogThread(void * param)
{
char FN[256];
time_t T;
struct tm * tm;
FILE * Handle;
int MsgLen;
MESSAGE * MSG;
MESSAGE * Q;
char buffer[2048];
while(1)
{
BOOL SaveMTX = MTX;
BOOL SaveMCOM = MCOM;
BOOL SaveMUI = MUIONLY;
Sleep(PacketLogDelay);
// Get chain of queued packets under semaphore
GetSemaphore(&Semaphore, 101);
Q = FILEMONVECTOR->HOSTTRACEQ;
FILEMONVECTOR->HOSTTRACEQ = 0;
FreeSemaphore(&Semaphore);
if (Q == 0)
continue;
// Open log file and write decoded packets
T = time(NULL);
tm = gmtime(&T);
if (LogDirectory[0] == 0)
{
strcpy(FN, "logs/PacketLog");
}
else
{
strcpy(FN, LogDirectory);
strcat(FN, "/");
strcat(FN, "logs/PacketLog");
}
sprintf(&FN[strlen(FN)], "_%04d%02d%02d.log", tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday);
Handle = fopen(FN, "ab");
if (Handle == NULL)
return;
while (Q)
{
MSG = Q;
Q = MSG->CHAIN; // get first
IntSetTraceOptionsEx(MMASK, 1, 1, 0);
MsgLen = IntDecodeFrame(MSG, buffer, MSG->Timestamp, 0xffffffffffffffff, FALSE, FALSE);
IntSetTraceOptionsEx(MMASK, SaveMTX, SaveMCOM, SaveMUI);
buffer[MsgLen++] = 0x0a; // Add lf
fwrite(buffer , 1, MsgLen, Handle);
GetSemaphore(&Semaphore, 101);
ReleaseBuffer(MSG);
FreeSemaphore(&Semaphore);
}
fclose(Handle);
}
return;
}

View file

@ -945,6 +945,30 @@ LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
if (wParam == 0x7) // BEL (Ctrl/G)
{
// Get buffer, append 07 and write back
Cinfo->kbptr = SendMessage(Cinfo->hwndInput, WM_GETTEXT, INPUTLEN-1,
(LPARAM) (LPCSTR)Cinfo->kbbuf);
Cinfo->kbbuf[Cinfo->kbptr++] = 7;
Cinfo->kbbuf[Cinfo->kbptr] = 0;
SendMessage(Cinfo->hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) Cinfo->kbbuf);
// Send cursor right
for (i = 0; i < strlen(Cinfo->kbbuf); i++)
{
SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0);
SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0);
}
return 0;
}
} }
return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam); return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam);

706
NETROMTCP.c Normal file
View file

@ -0,0 +1,706 @@
/*
Copyright 2001-2022 John Wiseman G8BPQ
This file is part of LinBPQ/BPQ32.
LinBPQ/BPQ32 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 3 of the License, or
(at your option) any later version.
LinBPQ/BPQ32 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 LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
/*
Netrom over TCP Support
This is intended for operation over radio links with an IP interface, eg New Packet Radio or possibly microwave links
To simplify interface to the rest of the oode dummy LINK and PORT records are created
Packet Format is Length (2 byte little endian) Call (10 bytes ASCII) NETROM L3/4 Packet, starting 0xcf (to detect framing errors).
A TCP message can contain multiple packets and/or partial packets
It uses the Telnet Server, with port defined in NETROMPORT
ROUTE definitions have an extra field, the TCP Port Number
*/
//#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
//#include "vmm.h"
#include "cheaders.h"
#include "asmstrucs.h"
#include "telnetserver.h"
#define NETROM_PID 0xCF
void NETROMConnectionLost(struct ConnectionInfo * sockptr);
int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo);
int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr);
void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info);
VOID SendRTTMsg(struct ROUTE * Route);
BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE);
VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG);
int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS);
VOID L3LINKCLOSED(struct _LINKTABLE * LINK, int Reason);
void NetromTCPTrace(struct _MESSAGE * Message, char * Dirn);
void NETROMCloseTCP(struct ROUTE * Route);
extern SOCKET NodeAPISocket;
struct NRTCPMsg
{
short Length;
char Call[10];
unsigned char PID;
char Packet[1024];
};
struct NRTCPSTRUCT
{
struct ConnectionInfo * sockptr;
struct _LINKTABLE * LINK; // Dummy Link Record for this ROUTE
struct ROUTE * Route; // May need backlink
char Call[10];
};
struct NRTCPSTRUCT * NRTCPInfo[256] = {0};
// Do we want to use normal TCP server connections, which are limited, or our own. Let's try our own for now
struct ConnectionInfo * AllocateNRTCPRec()
{
struct ConnectionInfo * sockptr = 0;
struct NRTCPSTRUCT * Info;
int i;
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
{
// only allocate as many as needed
Info = NRTCPInfo[i] = (struct NRTCPSTRUCT *)zalloc(sizeof(struct NRTCPSTRUCT));
Info->sockptr = (struct ConnectionInfo *)zalloc(sizeof(struct ConnectionInfo));
Info->LINK = (struct _LINKTABLE *)zalloc(sizeof(struct _LINKTABLE));
}
else
Info = NRTCPInfo[i];
Info->sockptr->Number = i;
sockptr = Info->sockptr;
if (sockptr->SocketActive == FALSE)
{
sockptr->SocketActive = TRUE;
sockptr->ConnectTime = sockptr->LastSendTime = time(NULL);
Debugprintf("NRTCP Allocated %d", i);
return sockptr;
}
}
return 0;
}
void checkNRTCPSockets(int portNo)
{
SOCKET sock;
int Active = 0;
SOCKET maxsock;
int retval;
int i;
time_t Now = time(NULL);
struct timeval timeout;
fd_set readfd, writefd, exceptfd;
struct ConnectionInfo * sockptr;
timeout.tv_sec = 0;
timeout.tv_usec = 0; // poll
maxsock = 0;
FD_ZERO(&readfd);
FD_ZERO(&writefd);
FD_ZERO(&exceptfd);
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
break; // only as many as have been used
sockptr = NRTCPInfo[i]->sockptr;
if (sockptr->SocketActive == 0)
continue;
if (sockptr->Connected && (Now - sockptr->LastReceiveTime) > 600)
{
struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number];
if (Info)
Debugprintf("NETROMTCP link to %s idle for too long, closing", Info->Call);
else
Debugprintf("NETROMTCP link idle for too long, closing");
NETROMConnectionLost(sockptr);
continue;
}
if (sockptr->Connecting)
{
// look for complete or failed
FD_SET(sockptr->socket, &writefd);
FD_SET(sockptr->socket, &exceptfd);
}
else
{
FD_SET(sockptr->socket, &readfd);
FD_SET(sockptr->socket, &exceptfd);
}
Active++;
if (sockptr->socket > maxsock)
maxsock = sockptr->socket;
}
if (Active)
{
retval = select((int)maxsock + 1, &readfd, &writefd, &exceptfd, &timeout);
if (retval == -1)
{
perror("data select");
Debugprintf("NRTCP Select Error %d Active %d", WSAGetLastError(), Active);
}
else
{
if (retval)
{
// see who has data
for (i = 0; i < 255; i++)
{
if (NRTCPInfo[i] == 0)
break;
sockptr = NRTCPInfo[i]->sockptr;
if (sockptr->SocketActive == 0)
continue;
sock = sockptr->socket;
if (FD_ISSET(sock, &writefd))
NETROMConnected(sockptr, sock, NRTCPInfo[i]);
if (FD_ISSET(sock, &readfd))
DataSocket_ReadNETROM(sockptr, sock, NRTCPInfo[i], portNo);
if (FD_ISSET(sock, &exceptfd))
NETROMConnectionLost(sockptr);
}
}
}
}
}
int NETROMOpenConnection(struct ROUTE * Route)
{
struct NRTCPSTRUCT * Info;
struct ConnectionInfo * sockptr;
char farCall[10];
farCall[ConvFromAX25(Route->NEIGHBOUR_CALL, farCall)] = 0;
sockptr = AllocateNRTCPRec();
if (sockptr == NULL)
return 0;
Debugprintf("Opening NRTCP Connection to %s index %d", farCall, sockptr->Number);
Info = Route->TCPSession = NRTCPInfo[sockptr->Number];
memcpy(Info->Call, farCall, 10);
Route->NEIGHBOUR_LINK = Info->LINK;
Info->Route = Route;
Info->LINK->NEIGHBOUR = Route;
Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(Route->NEIGHBOUR_PORT);
memcpy(Route->NEIGHBOUR_LINK->LINKCALL, Route->NEIGHBOUR_CALL, 7);
Route->NEIGHBOUR_LINK = Route->TCPSession->LINK; // Just in case!
return NETROMTCPConnect(Route, sockptr);
}
void NETROMTCPResolve()
{
struct ROUTE * Route = NEIGHBOURS;
int n = MAXNEIGHBOURS;
struct addrinfo hints, *res = 0;
char PortString[20];
int err;
while (n--)
{
if (Route->TCPAddress)
{
// try to resolve host
sprintf(PortString, "%d", Route->TCPPort);
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
getaddrinfo(Route->TCPHost, PortString, &hints, &res);
err = WSAGetLastError();
if (res)
{
Route->TCPAddress->ai_family = res->ai_family;
Route->TCPAddress->ai_socktype = res->ai_socktype;
Route->TCPAddress->ai_protocol = res->ai_protocol;
Route->TCPAddress->ai_addrlen = res->ai_addrlen;
memcpy(Route->TCPAddress->ai_addr, res->ai_addr, sizeof(struct sockaddr));
freeaddrinfo(res);
}
}
Route++;
}
}
int NETROMTCPConnect(struct ROUTE * Route, struct ConnectionInfo * sockptr)
{
int err;
u_long param=1;
BOOL bcopt=TRUE;
SOCKET sock;
struct sockaddr_in sinx;
int addrlen=sizeof(sinx);
char PortString[20];
struct addrinfo * res = Route->TCPAddress;
int Port = Route->TCPPort;
struct sockaddr_in my_addr;
socklen_t len = sizeof(my_addr);
struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number];
// Get my ip address and port
memset(&my_addr, 0, sizeof(my_addr));
getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len);
sprintf(PortString, "%d", Port);
// get host info, make socket, and connect it
if (res->ai_family == 0)
{
// err = WSAGetLastError();
// Debugprintf("Resolve HostName %s Failed - Error %d", Route->TCPHost, err);
return FALSE; // Resolve failed
}
sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == INVALID_SOCKET)
{
Debugprintf, ("Netrom over TCP Create Socket Failed");
return FALSE;
}
ioctl(sock, FIONBIO, &param);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0)
{
//
// Connected successful
//
sockptr->Connected = TRUE;
sockptr->LastReceiveTime = time(NULL);
return TRUE;
}
else
{
err=WSAGetLastError();
if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK
{
// Connect in Progress
sockptr->Connecting = TRUE;
// Get my ip address and port
memset(&my_addr, 0, sizeof(my_addr));
getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len);
Route->localport = htons(my_addr.sin_port);
Debugprintf("NRTCP Connection in progress %s local port %d", Info->Call, Route->localport);
return TRUE;
}
else
{
// Connect failed
closesocket(sockptr->socket);
return FALSE;
}
}
return FALSE;
}
void NETROMConnectionAccepted(struct ConnectionInfo * sockptr)
{
// Not sure we can do much here until first message arrives with callsign
struct sockaddr_in my_addr;
socklen_t len = sizeof(my_addr);
// Get my ip address and port
memset(&my_addr, 0, sizeof(my_addr));
// getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len);
Debugprintf("INP3 Accept() Local port %d", htons(sockptr->sin.sin_port));
sockptr->Connected = TRUE;
sockptr->LastReceiveTime = time(NULL);
// Debugprintf("NRTCP Connection Accepted");
}
void NETROMConnected(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info)
{
// Connection Complete
// Debugprintf("NRTCP Connected");
Debugprintf("NRTCP Connection Complete %s Local port %d", Info->Call, Info->Route->localport);
sockptr->Connecting = FALSE;
sockptr->Connected = TRUE;
sockptr->LastReceiveTime = time(NULL);
Info->LINK->L2STATE = 5;
if (Info->Route->INP3Node)
SendRTTMsg(Info->Route);
}
int DataSocket_ReadNETROM(struct ConnectionInfo * sockptr, SOCKET sock, struct NRTCPSTRUCT * Info, int portNo)
{
int len=0, maxlen;
struct NRTCPMsg * Msg;
struct _L3MESSAGEBUFFER * L3Msg;
struct ROUTE * Route;
UCHAR axCall[7];
PMESSAGE Buffer;
ioctl(sock,FIONREAD,&len);
maxlen = InputBufferLen - sockptr->InputLen;
if (len > maxlen) len = maxlen;
len = recv(sock, &sockptr->InputBuffer[sockptr->InputLen], len, 0);
if (len == SOCKET_ERROR || len == 0)
{
// Failed or closed - clear connection
NETROMConnectionLost(sockptr);
return 0;
}
sockptr->LastReceiveTime = time(NULL);
sockptr->InputLen += len;
// Process data
checkLen:
// See if we have a whole packet
Msg = (struct NRTCPMsg *)&sockptr->InputBuffer[0];
if (Msg->Length > sockptr->InputLen) // if not got whole frame wait
return 0;
if (Info->Call[0] == 0)
{
// first packet - do we need to do anything?
// This must be an incoming connection as Call is set before calling so need to find route record and set things up.
memcpy(Info->Call, Msg->Call, 10);
ConvToAX25(Msg->Call, axCall);
if (FindNeighbour(axCall, portNo, &Route))
{
Info->Route = Route;
Route->NEIGHBOUR_LINK = Info->LINK;
Route->NEIGHBOUR_PORT = portNo;
Info->LINK->NEIGHBOUR = Route;
Info->LINK->LINKPORT = GetPortTableEntryFromPortNum(portNo);
Route->TCPSession = Info;
Info->LINK->L2STATE = 5;
memcpy(Route->NEIGHBOUR_LINK->LINKCALL, axCall, 7);
Route->localport = htons(sockptr->sin.sin_port);
Debugprintf("New NRTCP Connection from %s port %d", Msg->Call, Route->localport);
if (Info->Route->INP3Node)
SendRTTMsg(Info->Route);
}
else
{
Debugprintf("Neighbour %s port %d not found - closing connection", Msg->Call, portNo);
closesocket(sockptr->socket);
sockptr->SocketActive = FALSE;
memset(sockptr, 0, sizeof(struct ConnectionInfo));
Info->Call[0] = 0;
return 0;
}
}
if (memcmp(Info->Call, Msg->Call, 10) != 0)
{
Debugprintf("NRTCP Mismatch - closing connection");
closesocket(sockptr->socket);
sockptr->SocketActive = FALSE;
memset(sockptr, 0, sizeof(struct ConnectionInfo));
Info->Call[0] = 0;
return 0;
}
// Format as if come from an ax.25 link
L3Msg = GetBuff();
if (L3Msg == 0)
goto seeifMore;
L3Msg->LENGTH = (Msg->Length - 12) + MSGHDDRLEN;
L3Msg->Next = 0;
L3Msg->Port = portNo;
L3Msg->L3PID = NETROM_PID;
memcpy(&L3Msg->L3SRCE, Msg->Packet, Msg->Length - 13);
// Create a dummy L2 message so we can trace it
Buffer = GetBuff();
if (Buffer)
{
Buffer->CHAIN = 0;
Buffer->CTL = 0;
Buffer->PORT = portNo;
ConvToAX25(Info->Call, Buffer->ORIGIN);
ConvToAX25(MYNETROMCALL, Buffer->DEST);
memcpy(Buffer->L2DATA, &L3Msg->L3SRCE[0], Msg->Length - 13);
Buffer->ORIGIN[6] |= 1; // Set end of calls
Buffer->PID = NETROM_PID;
Buffer->LENGTH = Msg->Length + 10;
time(&Buffer->Timestamp);
BPQTRACE(Buffer, FALSE);
if(NodeAPISocket)
NetromTCPTrace(Buffer, "rcvd");
ReleaseBuffer(Buffer);
}
Info->Route->NEIGHBOUR_LINK = Info->LINK; // Just in case!
NETROMMSG(Info->LINK, L3Msg);
seeifMore:
sockptr->InputLen -= Msg->Length;
if (sockptr->InputLen > 0)
{
memmove(sockptr->InputBuffer, &sockptr->InputBuffer[Msg->Length], sockptr->InputLen);
goto checkLen;
}
return 0;
}
VOID TCPNETROMSend(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Frame)
{
struct NRTCPMsg Msg;
unsigned char * Data = (unsigned char *)&Frame->L3SRCE[0];
int DataLen = Frame->LENGTH - (MSGHDDRLEN + 1); // Not including PID
int Ret;
PMESSAGE Buffer;
struct sockaddr_in my_addr;
socklen_t len = sizeof(my_addr);
struct ConnectionInfo * sockptr;
Msg.Length = DataLen + 13; // include PID
memcpy(Msg.Call, MYNETROMCALL, 10);
Msg.PID = NETROM_PID;
memcpy(Msg.Packet, Data, DataLen);
if (Route->TCPSession == 0)
return;
sockptr = Route->TCPSession->sockptr;
// Get other port
if (strcmp(Route->TCPHost, "0.0.0.0") == 0)
{
// incoming
// Debugprintf("INP3 Remote port %d", htons(sockptr->sin.sin_port));
if (Route->localport != htons(sockptr->sin.sin_port))
{
// Route is linked to wrong session. Close it
// Route->TCPSession = 0;
// Route->NEIGHBOUR_LINK = 0;
return;
}
}
else
{
// outgoing
memset(&my_addr, 0, sizeof(my_addr));
getsockname(sockptr->socket, (struct sockaddr *) &my_addr, &len);
// Debugprintf("INP3 Local port %d", htons(my_addr.sin_port));
if (Route->localport != htons(my_addr.sin_port))
{
// Route is linked to wrong session. Close it
// if (sockptr->Connecting == 0)
// {
// Route->TCPSession = 0;
// Route->NEIGHBOUR_LINK = 0;
// }
return;
}
}
Ret = send(Route->TCPSession->sockptr->socket, (char *)&Msg, DataLen + 13, 0);
// Create a dummy L2 message so we can trace it
Buffer = GetBuff();
if (Buffer)
{
Buffer->CHAIN = 0;
Buffer->CTL = 0;
Buffer->PORT = Route->NEIGHBOUR_PORT;
memcpy(Buffer->DEST, Route->NEIGHBOUR_CALL, 7);
ConvToAX25(MYNETROMCALL, Buffer->ORIGIN);
memcpy(Buffer->L2DATA, &Frame->L3SRCE[0], DataLen);
Buffer->ORIGIN[6] |= 1; // Set end of calls
Buffer->PID = NETROM_PID;
Buffer->LENGTH = DataLen + 15 + MSGHDDRLEN;
time(&Buffer->Timestamp);
if(NodeAPISocket)
NetromTCPTrace(Buffer, "sent");
Buffer->PORT = Route->NEIGHBOUR_PORT | 128; // TX Flag
BPQTRACE(Buffer, FALSE);
ReleaseBuffer(Buffer);
}
}
void NETROMConnectionLost(struct ConnectionInfo * sockptr)
{
struct NRTCPSTRUCT * Info = NRTCPInfo[sockptr->Number];
struct ROUTE * Route;
closesocket(sockptr->socket);
// If there is an attached route (there should be) clear all connections
if (Info)
{
Route = Info->Route;
if (Route)
{
Route->NEIGHBOUR_LINK = 0;
Route->TCPSession = 0;
Route->localport = 0;
}
Info->Call[0] = 0;
Info->LINK->L2STATE = 0;
}
sockptr->SocketActive = FALSE;
memset(sockptr, 0, sizeof(struct ConnectionInfo));
}
void NETROMCloseTCP(struct ROUTE * Route)
{
if (Route->TCPSession)
{
struct ConnectionInfo * sockptr = Route->TCPSession->sockptr;
NETROMConnectionLost(sockptr);
}
else
{
Route->NEIGHBOUR_LINK = 0;
}
}

6
RHP.c
View file

@ -387,6 +387,12 @@ int processRHCPOpen(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg,
if (_stricmp(pfam, "ax25") != 0) if (_stricmp(pfam, "ax25") != 0)
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0); return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
if (strlen(Local) > 10)
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 6, \"errText\": \"%s\"}", ID, 0, ErrCodes[6]);
if (strlen(Remote) > 10)
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 7, \"errText\": \"%s\"}", ID, 0, ErrCodes[7]);
if (_stricmp(Mode, "stream") == 0) if (_stricmp(Mode, "stream") == 0)
{ {
{ {

View file

@ -110,7 +110,7 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT);
int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr); int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr);
void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length); void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length);
VOID HAMLIBPoll(struct RIGPORTINFO * PORT); VOID HAMLIBPoll(struct RIGPORTINFO * PORT);
void HAMLIBSlaveThread(struct RIGINFO * RIG); void HAMLIBSlaveThread(VOID * Param);
void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT); void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT);
VOID RTLUDPPoll(struct RIGPORTINFO * PORT); VOID RTLUDPPoll(struct RIGPORTINFO * PORT);
VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT); VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT);
@ -122,8 +122,8 @@ VOID ProcessSDRRadioFrame(struct RIGPORTINFO * PORT, int Length);
VOID SDRRadioPoll(struct RIGPORTINFO * PORT); VOID SDRRadioPoll(struct RIGPORTINFO * PORT);
VOID SetupPortRIGPointers(); VOID SetupPortRIGPointers();
VOID PTTCATThread(struct RIGINFO *RIG); VOID PTTCATThread(void * Param);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT);
// ----- G7TAJ ---- // ----- G7TAJ ----
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT); VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT);
@ -2217,7 +2217,7 @@ int BittoInt(UINT BitMask)
return i; return i;
} }
extern char * RadioConfigMsg[36]; extern char * RadioConfigMsg[70];
struct TNCINFO RIGTNC; // Dummy TNC Record for Rigcontrol without a corresponding TNC struct TNCINFO RIGTNC; // Dummy TNC Record for Rigcontrol without a corresponding TNC
@ -5450,7 +5450,26 @@ void DecodeCM108(int Port, char * ptr)
hid_device *handle = NULL; hid_device *handle = NULL;
if (strlen(ptr) > 16) if (strlen(ptr) > 16)
CM108Device = _strdup(ptr); {
path_to_open = _strdup(ptr);
handle = hid_open_path(path_to_open);
if (handle)
{
hid_close(handle);
CM108Device = _strdup(path_to_open);
}
else
{
char msg[128];
sprintf(msg,"Port %d Unable to open CM108 device %s", Port, path_to_open);
WritetoConsole(msg);
}
}
else else
{ {
VID = strtol(ptr, &next, 0); VID = strtol(ptr, &next, 0);
@ -7465,8 +7484,9 @@ VOID SetupPortRIGPointers()
#ifdef WIN32 #ifdef WIN32
VOID PTTCATThread(struct RIGINFO *RIG) VOID PTTCATThread(void * Param)
{ {
struct RIGINFO * RIG = (struct RIGINFO *)Param;
DWORD dwLength = 0; DWORD dwLength = 0;
int Length, ret, i; int Length, ret, i;
UCHAR * ptr1; UCHAR * ptr1;
@ -8452,7 +8472,7 @@ int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr)
return 1; return 1;
} }
VOID HAMLIBThread(struct RIGPORTINFO * PORT); VOID HAMLIBThread(void * Param);
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT) VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
{ {
@ -8462,10 +8482,11 @@ VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID HAMLIBThread(struct RIGPORTINFO * PORT) VOID HAMLIBThread(void * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO * )Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -8587,10 +8608,11 @@ Lost:
void HAMLIBSlaveThread(struct RIGINFO * RIG) void HAMLIBSlaveThread(VOID * Param)
{ {
// Wait for connections and messages from HAMLIB Clients // Wait for connections and messages from HAMLIB Clients
struct RIGINFO * RIG = (struct RIGINFO *)Param;
fd_set readfs; fd_set readfs;
fd_set errorfs; fd_set errorfs;
struct timeval timeout; struct timeval timeout;
@ -8906,7 +8928,7 @@ VOID FLRIGSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value)
VOID FLRIGThread(struct RIGPORTINFO * PORT); VOID FLRIGThread(VOID * Param);
VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT) VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
{ {
@ -8915,10 +8937,11 @@ VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID FLRIGThread(struct RIGPORTINFO * PORT) VOID FLRIGThread(VOID * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;
@ -10158,7 +10181,7 @@ void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT)
VOID SDRANGELThread(struct RIGPORTINFO * PORT); VOID SDRANGELThread(VOID * Param);
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT) VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
{ {
@ -10167,9 +10190,11 @@ VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
return ; return ;
} }
VOID SDRANGELThread(struct RIGPORTINFO * PORT) VOID SDRANGELThread(VOID * Param)
{ {
// Opens sockets and looks for data // Opens sockets and looks for data
struct RIGPORTINFO * PORT = (struct RIGPORTINFO *)Param;
char Msg[512]; char Msg[512];
int err, i, ret; int err, i, ret;
u_long param=1; u_long param=1;

51
ScanHID.c Normal file
View file

@ -0,0 +1,51 @@
// ScanHID.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "hidapi.h"
int main(int argc, char* argv[])
{
char product[256];
char sernum[256] = "NULL";
struct hid_device_info *devs, *cur_dev;
const char *path_to_open = NULL;
hid_device *handle = NULL;
// Look for Device
devs = hid_enumerate(0,0); // so we list devices(USHORT)VID, (USHORT)PID);
cur_dev = devs;
while (cur_dev)
{
wcstombs(product, cur_dev->product_string, 255);
if (cur_dev->serial_number)
wcstombs(sernum, cur_dev->serial_number, 255);
if (product)
printf("HID Device %s VID %X PID %X Ser %s\r\n Path %s\r\n\r\n", product, cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
else
printf("HID Device %s VID %X PID %X Ser %s\r\n Path %s\r\n\r\n", "Missing Product", cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);
printf("Press any key to Exit");
_getch();
}

View file

@ -56,6 +56,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
extern UCHAR LogDirectory[]; extern UCHAR LogDirectory[];
extern int MONTOFILEFLAG;
static char ClassName[]="TELNETSERVER"; static char ClassName[]="TELNETSERVER";
static char WindowTitle[] = "Telnet Server"; static char WindowTitle[] = "Telnet Server";
@ -90,7 +91,7 @@ void RHPThread(void * Params);
void ProcessRHPWebSockClosed(SOCKET socket); void ProcessRHPWebSockClosed(SOCKET socket);
int ProcessSNMPPayload(UCHAR * Msg, int Len, UCHAR * Reply, int * OffPtr); int ProcessSNMPPayload(UCHAR * Msg, int Len, UCHAR * Reply, int * OffPtr);
int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE); int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
void checkNRTCPSockets(int portNo);
#ifndef LINBPQ #ifndef LINBPQ
extern HKEY REGTREE; extern HKEY REGTREE;
@ -172,80 +173,78 @@ VOID Tel_Format_Addr(struct ConnectionInfo * sockptr, char * dst);
VOID ProcessTrimodeCommand(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, char * MsgPtr); VOID ProcessTrimodeCommand(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, char * MsgPtr);
VOID ProcessTrimodeResponse(struct TNCINFO * TNC, struct STREAMINFO * STREAM, unsigned char * MsgPtr, int Msglen); VOID ProcessTrimodeResponse(struct TNCINFO * TNC, struct STREAMINFO * STREAM, unsigned char * MsgPtr, int Msglen);
VOID ProcessTriModeDataMessage(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCKET sock, struct STREAMINFO * STREAM); VOID ProcessTriModeDataMessage(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCKET sock, struct STREAMINFO * STREAM);
void processNETROMFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr);
void NETROMConnectionLost(struct ConnectionInfo * sockptr);
void NETROMConnectionAccepted(struct ConnectionInfo * sockptr);
struct ConnectionInfo * AllocateNRTCPRec();
int DeleteLogFile(char * Log, int KeepDays);
static int LogAge = 13; void DeleteLogFiles(int Age)
{
DeleteLogFile("Telnet", Age);
DeleteLogFile("CMSAccess_", Age);
DeleteLogFile("ConnectLog_",Age);
DeleteLogFile("APRS_", Age);
if (MONTOFILEFLAG)
DeleteLogFile("PacketLog_", MONTOFILEFLAG);
}
#ifdef WIN32 #ifdef WIN32
int DeleteLogFile(char * Log); int DeleteLogFile(char * Log, int KeepDays)
void DeleteTelnetLogFiles()
{ {
DeleteLogFile("/logs/Telnet*.log");
DeleteLogFile("/logs/CMSAccess_*.log");
DeleteLogFile("/logs/ConnectLog_*.log");
}
int DeleteLogFile(char * Log)
{
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
char szDir[MAX_PATH]; char szDir[MAX_PATH];
char File[MAX_PATH]; char File[MAX_PATH];
HANDLE hFind = INVALID_HANDLE_VALUE; HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0; DWORD dwError=0;
LARGE_INTEGER ft; LARGE_INTEGER ft;
time_t now = time(NULL); time_t now = time(NULL);
int Age; int Age;
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
strcpy(szDir, GetLogDirectory()); strcpy(szDir, GetLogDirectory());
strcat(szDir, Log); strcat(szDir, "/Logs/");
strcat(szDir, Log);
strcat(szDir, "*.log");
// Find the first file in the directory. // Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd); hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind) if (INVALID_HANDLE_VALUE == hFind)
return dwError; return dwError;
// List all the files in the directory with some info about them. do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
OutputDebugString(ffd.cFileName);
}
else
{
ft.HighPart = ffd.ftCreationTime.dwHighDateTime;
ft.LowPart = ffd.ftCreationTime.dwLowDateTime;
do ft.QuadPart -= 116444736000000000;
{ ft.QuadPart /= 10000000;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
OutputDebugString(ffd.cFileName);
}
else
{
ft.HighPart = ffd.ftCreationTime.dwHighDateTime;
ft.LowPart = ffd.ftCreationTime.dwLowDateTime;
ft.QuadPart -= 116444736000000000; Age = (int)((now - ft.LowPart) / 86400);
ft.QuadPart /= 10000000;
Age = (int)((now - ft.LowPart) / 86400); if (Age > KeepDays)
{
sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
Debugprintf("Deleting %s", File);
DeleteFile(File);
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
if (Age > LogAge) FindClose(hFind);
{ return dwError;
sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
Debugprintf("Deleting %s", File);
DeleteFile(File);
}
}
}
while (FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
return dwError;
} }
#else #else
@ -254,22 +253,19 @@ int DeleteLogFile(char * Log)
int TelFilter(const struct dirent * dir) int TelFilter(const struct dirent * dir)
{ {
return (memcmp(dir->d_name, "CMSAccess", 9) == 0 return strstr(dir->d_name, ".log") != 0;
|| memcmp(dir->d_name, "Telnet", 6) == 0
|| memcmp(dir->d_name, "ConnectLog", 6) == 0)
&& strstr(dir->d_name, ".log");
} }
int DeleteTelnetLogFiles() int DeleteLogFile(char * Log, int KeepDays)
{ {
struct dirent **namelist; struct dirent **namelist;
int n; int n;
struct stat STAT; struct stat STAT;
time_t now = time(NULL); time_t now = time(NULL);
int Age = 0, res; int Age = 0, res;
char FN[256]; char FN[256];
n = scandir("logs", &namelist, TelFilter, alphasort); n = scandir("logs", &namelist, TelFilter, alphasort);
if (n < 0) if (n < 0)
perror("scandir"); perror("scandir");
@ -277,21 +273,25 @@ int DeleteTelnetLogFiles()
{ {
while(n--) while(n--)
{ {
sprintf(FN, "logs/%s", namelist[n]->d_name); if (memcmp(namelist[n]->d_name, Log, strlen(Log)) == 0)
if (stat(FN, &STAT) == 0)
{ {
Age = (now - STAT.st_mtime) / 86400; sprintf(FN, "logs/%s", namelist[n]->d_name);
if (Age > LogAge) if (stat(FN, &STAT) == 0)
{ {
Debugprintf("Deleting %s\n", FN); Age = (now - STAT.st_mtime) / 86400;
unlink(FN);
if (Age > KeepDays)
{
Debugprintf("Deleting %s", FN);
unlink(FN);
}
} }
} }
free(namelist[n]); free(namelist[n]);
} }
free(namelist); free(namelist);
} }
return 0; return 0;
} }
#endif #endif
@ -318,7 +318,7 @@ void BuffertoNode(struct ConnectionInfo * sockptr, char * MsgPtr, int InputLen)
sockptr->InputLen = 0; sockptr->InputLen = 0;
return; return;
} }
BOOL SendAndCheck(struct ConnectionInfo * sockptr, unsigned char * MsgPtr, int len, int flags) BOOL SendAndCheck(struct ConnectionInfo * sockptr, unsigned char * MsgPtr, int len, int flags)
{ {
@ -542,6 +542,9 @@ int ProcessLine(char * buf, int Port)
else if (_stricmp(param,"HTTPPORT") == 0) else if (_stricmp(param,"HTTPPORT") == 0)
HTTPPort = TCP->HTTPPort = atoi(value); HTTPPort = TCP->HTTPPort = atoi(value);
else if (_stricmp(param,"NETROMPORT") == 0)
TCP->NETROMPort = atoi(value);
else if (_stricmp(param,"APIPORT") == 0) else if (_stricmp(param,"APIPORT") == 0)
TCP->APIPort = atoi(value); TCP->APIPort = atoi(value);
@ -1139,7 +1142,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
shutdown(TCP->FBBsock[n++], SD_BOTH); shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH); shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH); shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH); shutdown(TCP->HTTPsock6, SD_BOTH);
@ -1163,7 +1166,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
closesocket(TCP->Relaysock); closesocket(TCP->Relaysock);
closesocket(TCP->Relaysock6); closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock); closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6); closesocket(TCP->HTTPsock6);
// Save info from old TNC record // Save info from old TNC record
@ -1189,6 +1192,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC = TNCInfo[n]; TNC = TNCInfo[n];
TNC->Port = n; TNC->Port = n;
TNC->PortRecord = PortRecord;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET;
TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy
@ -1248,7 +1252,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
shutdown(TCP->FBBsock[n++], SD_BOTH); shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH); shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH); shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH); shutdown(TCP->HTTPsock6, SD_BOTH);
shutdown(TCP->sock6, SD_BOTH); shutdown(TCP->sock6, SD_BOTH);
@ -1275,7 +1279,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
closesocket(TCP->FBBsock6[n++]); closesocket(TCP->FBBsock6[n++]);
closesocket(TCP->Relaysock6); closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock); closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6); closesocket(TCP->HTTPsock6);
return (0); return (0);
@ -1440,8 +1444,6 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry)
} }
*/ */
DeleteTelnetLogFiles();
initUTF8(); initUTF8();
sprintf(msg,"Telnet Server "); sprintf(msg,"Telnet Server ");
@ -1713,11 +1715,14 @@ BOOL OpenSockets(struct TNCINFO * TNC)
} }
if (TCP->HTTPPort) if (TCP->HTTPPort)
TCP->HTTPsock = OpenSocket4(TNC, TCP->HTTPPort); TCP->HTTPSock = OpenSocket4(TNC, TCP->HTTPPort);
if (TCP->APIPort) if (TCP->APIPort)
TCP->APIsock = OpenSocket4(TNC, TCP->APIPort); TCP->APIsock = OpenSocket4(TNC, TCP->APIPort);
if (TCP->NETROMPort)
TCP->NETROMSock = OpenSocket4(TNC, TCP->NETROMPort);
if (TCP->SyncPort) if (TCP->SyncPort)
TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort); TCP->Syncsock = OpenSocket4(TNC, TCP->SyncPort);
@ -1836,6 +1841,9 @@ BOOL OpenSockets6(struct TNCINFO * TNC)
if (TCP->APIPort) if (TCP->APIPort)
TCP->APIsock6 = OpenSocket6(TNC, TCP->APIPort); TCP->APIsock6 = OpenSocket6(TNC, TCP->APIPort);
if (TCP->NETROMPort)
TCP->NETROMSock6 = OpenSocket6(TNC, TCP->NETROMPort);
if (TCP->SyncPort) if (TCP->SyncPort)
TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort); TCP->Syncsock6 = OpenSocket6(TNC, TCP->SyncPort);
@ -1888,7 +1896,7 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock; maxsock = sock;
} }
sock = TCP->HTTPsock; sock = TCP->HTTPSock;
if (sock) if (sock)
{ {
FD_SET(sock, readfd); FD_SET(sock, readfd);
@ -1904,6 +1912,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock; maxsock = sock;
} }
sock = TCP->NETROMSock;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->Syncsock; sock = TCP->Syncsock;
if (sock) if (sock)
{ {
@ -1979,6 +1995,14 @@ static VOID SetupListenSet(struct TNCINFO * TNC)
maxsock = sock; maxsock = sock;
} }
sock = TCP->NETROMSock6;
if (sock)
{
FD_SET(sock, readfd);
if (sock > maxsock)
maxsock = sock;
}
sock = TCP->DRATSsock6; sock = TCP->DRATSsock6;
if (sock) if (sock)
@ -2066,13 +2090,20 @@ VOID TelnetPoll(int Port)
Socket_Accept(TNC, sock, TCP->RelayPort); Socket_Accept(TNC, sock, TCP->RelayPort);
} }
sock = TCP->HTTPsock; sock = TCP->HTTPSock;
if (sock) if (sock)
{ {
if (FD_ISSET(sock, &readfd)) if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->HTTPPort); Socket_Accept(TNC, sock, TCP->HTTPPort);
} }
sock = TCP->NETROMSock;
if (sock)
{
if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->NETROMPort);
}
sock = TCP->DRATSsock; sock = TCP->DRATSsock;
if (sock) if (sock)
{ {
@ -2120,6 +2151,14 @@ VOID TelnetPoll(int Port)
Socket_Accept(TNC, sock, TCP->HTTPPort); Socket_Accept(TNC, sock, TCP->HTTPPort);
} }
sock = TCP->NETROMSock6;
if (sock)
{
if (FD_ISSET(sock, &readfd))
Socket_Accept(TNC, sock, TCP->NETROMPort);
}
sock = TCP->DRATSsock6; sock = TCP->DRATSsock6;
if (sock) if (sock)
{ {
@ -2247,9 +2286,12 @@ VOID TelnetPoll(int Port)
} }
} }
nosocks: nosocks:
// Poll TCPNR
checkNRTCPSockets(Port);
// Try SNMP // Try SNMP
if (TCP->SNMPsock) if (TCP->SNMPsock)
@ -3062,7 +3104,7 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
shutdown(TCP->FBBsock[n++], SD_BOTH); shutdown(TCP->FBBsock[n++], SD_BOTH);
shutdown(TCP->Relaysock, SD_BOTH); shutdown(TCP->Relaysock, SD_BOTH);
shutdown(TCP->HTTPsock, SD_BOTH); shutdown(TCP->HTTPSock, SD_BOTH);
shutdown(TCP->HTTPsock6, SD_BOTH); shutdown(TCP->HTTPsock6, SD_BOTH);
@ -3087,7 +3129,7 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
closesocket(TCP->Relaysock); closesocket(TCP->Relaysock);
closesocket(TCP->Relaysock6); closesocket(TCP->Relaysock6);
closesocket(TCP->HTTPsock); closesocket(TCP->HTTPSock);
closesocket(TCP->HTTPsock6); closesocket(TCP->HTTPsock6);
// Save info from old TNC record // Save info from old TNC record
@ -3256,6 +3298,35 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
return 0; return 0;
} }
// Netrom Over TCP uses its own Connection Entries
if (SocketId == TCP->NETROMSock || SocketId == TCP->NETROMSock6)
{
sockptr = AllocateNRTCPRec();
if (sockptr == 0)
{
// No entries - accept and close
sock = accept(SocketId, (struct sockaddr *)&sin6, &addrlen);
send(sock,"No Free Sessions\r\n", 18,0);
Debugprintf("No Free Netrom Telnet Sessions");
Sleep (500);
closesocket(sock);
return 0;
}
sock = accept(SocketId, (struct sockaddr *)&sockptr->sin, &addrlen);
sockptr->socket = sock;
ioctl(sock, FIONBIO, &param);
sockptr->NETROMMode = TRUE;
NETROMConnectionAccepted(sockptr);
return 0;
}
// Find a free Session // Find a free Session
for (n = 1; n <= TCP->MaxSessions; n++) for (n = 1; n <= TCP->MaxSessions; n++)
@ -3308,6 +3379,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
sockptr->HTTPMode = FALSE; sockptr->HTTPMode = FALSE;
sockptr->APIMode = FALSE; sockptr->APIMode = FALSE;
sockptr->NETROMMode = FALSE;
sockptr->SyncMode = FALSE; sockptr->SyncMode = FALSE;
sockptr->DRATSMode = FALSE; sockptr->DRATSMode = FALSE;
sockptr->FBBMode = FALSE; sockptr->FBBMode = FALSE;
@ -3322,9 +3394,12 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
memset(sockptr->ADIF, 0, sizeof(struct ADIF)); memset(sockptr->ADIF, 0, sizeof(struct ADIF));
if (SocketId == TCP->HTTPsock || SocketId == TCP->HTTPsock6) if (SocketId == TCP->HTTPSock || SocketId == TCP->HTTPsock6)
sockptr->HTTPMode = TRUE; sockptr->HTTPMode = TRUE;
if (SocketId == TCP->NETROMSock || SocketId == TCP->NETROMSock6)
sockptr->NETROMMode = TRUE;
if (SocketId == TCP->APIsock || SocketId == TCP->APIsock6) if (SocketId == TCP->APIsock || SocketId == TCP->APIsock6)
{ {
sockptr->HTTPMode = TRUE; // API is a type of HTTP socket sockptr->HTTPMode = TRUE; // API is a type of HTTP socket
@ -3796,12 +3871,14 @@ MsgLoop:
LFPtr=memchr(MsgPtr, 10, InputLen); LFPtr=memchr(MsgPtr, 10, InputLen);
if (LFPtr == 0) if (LFPtr == 0)
{
if (CRPtr) if (CRPtr)
{ {
LFPtr = ++CRPtr; LFPtr = ++CRPtr;
InputLen++; InputLen++;
} }
if (LFPtr == 0) }
if (LFPtr == 0)
{ {
// Check Paclen // Check Paclen
@ -3886,14 +3963,14 @@ MsgLoop:
case 0: case 0:
// Check Username // Check Username
// //
*(LFPtr-1)=0; // remove cr *(LFPtr-1)=0; // remove cr
// send(sock, NLMsg, 2, 0); // send(sock, NLMsg, 2, 0);
if (LogEnabled) if (LogEnabled)
{ {
char Addr[256]; char Addr[256];
@ -4493,7 +4570,8 @@ MsgLoop:
if (P8 == 1) if (P8 == 1)
SendPortsForMonitor(sock, sockptr->UserPointer->Secure); SendPortsForMonitor(sock, sockptr->UserPointer->Secure);
sockptr->InputLen = 0;
sockptr->InputLen = 0;
return 0; return 0;
} }
} }
@ -5018,23 +5096,20 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
{ {
// Failed or closed - clear connection // Failed or closed - clear connection
// if Websock connection till app // if Websock connection tell app
if (sockptr->WebSocks) if (sockptr->WebSocks)
{ {
if (memcmp(sockptr->WebURL, "rhp", 3) == 0) if (memcmp(sockptr->WebURL, "rhp", 3) == 0)
{
ProcessRHPWebSockClosed(sockptr->socket); ProcessRHPWebSockClosed(sockptr->socket);
DataSocket_Disconnect(TNC, sockptr);
return 0;
}
}
else
{
TNC->Streams[sockptr->Number].ReportDISC = TRUE; //Tell Node
DataSocket_Disconnect(TNC, sockptr); DataSocket_Disconnect(TNC, sockptr);
return 0; return 0;
} }
TNC->Streams[sockptr->Number].ReportDISC = TRUE; //Tell Node
DataSocket_Disconnect(TNC, sockptr);
return 0;
} }
MsgPtr = &sockptr->InputBuffer[0]; MsgPtr = &sockptr->InputBuffer[0];
@ -5274,6 +5349,7 @@ int DataSocket_ReadDRATS(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
} }
int DataSocket_Disconnect(struct TNCINFO * TNC, struct ConnectionInfo * sockptr) int DataSocket_Disconnect(struct TNCINFO * TNC, struct ConnectionInfo * sockptr)
{ {
int n; int n;
@ -5688,7 +5764,9 @@ int Telnet_Connected(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCK
} }
else else
{ {
if (TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK->APPL[0]) struct _TRANSPORTENTRY * CROSSLINK = TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK;
if (CROSSLINK && CROSSLINK->APPL[0])
buffptr->Len = sprintf(&buffptr->Data[0], "*** Connected to %s\r", buffptr->Len = sprintf(&buffptr->Data[0], "*** Connected to %s\r",
TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK->APPL); TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4CROSSLINK->APPL);
else else
@ -6308,10 +6386,10 @@ VOID SaveCMSHostInfo(int port, struct TCPINFO * TCP, int CMSNo)
char ip[256]; char ip[256];
int n; int n;
if (sizeof(time_t) == 4) if (sizeof(time_t) == 4)
n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip); n = sscanf(buf,"%s %d %s", addr, (int *)&t, ip);
else else
n = sscanf(buf, "%s %lld %s", addr, &t, ip); n = sscanf(buf, "%s %lld %s", addr, &t, ip);
if (n == 3) if (n == 3)
{ {

View file

@ -80,6 +80,11 @@ int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
VOID ProcessARQPacket(struct PORTCONTROL * PORT, MESSAGE * Buffer); VOID ProcessARQPacket(struct PORTCONTROL * PORT, MESSAGE * Buffer);
char * strlop(char * buf, char delim); char * strlop(char * buf, char delim);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern UCHAR BPQDirectory[]; extern UCHAR BPQDirectory[];
extern char MYALIASLOPPED[10]; extern char MYALIASLOPPED[10];

View file

@ -78,6 +78,11 @@ VOID ReleaseOtherPorts(struct TNCINFO * ThisTNC);
int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len); int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
int standardParams(struct TNCINFO * TNC, char * buf); int standardParams(struct TNCINFO * TNC, char * buf);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
extern UCHAR BPQDirectory[]; extern UCHAR BPQDirectory[];
#define MAXUZ7HOPORTS 16 #define MAXUZ7HOPORTS 16
@ -1581,81 +1586,81 @@ static int ProcessLine(char * buf, int Port)
if (TNC->TCPPort == 0) if (TNC->TCPPort == 0)
TNC->TCPPort = 8000; TNC->TCPPort = 8000;
TNC->destaddr.sin_family = AF_INET; TNC->destaddr.sin_family = AF_INET;
TNC->destaddr.sin_port = htons(TNC->TCPPort); TNC->destaddr.sin_port = htons(TNC->TCPPort);
TNC->HostName = malloc(strlen(p_ipad)+1); TNC->HostName = malloc(strlen(p_ipad)+1);
if (TNC->HostName == NULL) return TRUE; if (TNC->HostName == NULL) return TRUE;
strcpy(TNC->HostName,p_ipad); strcpy(TNC->HostName,p_ipad);
ptr = strtok(NULL, " \t\n\r"); ptr = strtok(NULL, " \t\n\r");
if (ptr) if (ptr)
{
if (_stricmp(ptr, "PTT") == 0)
{ {
if (_stricmp(ptr, "PTT") == 0) ptr = strtok(NULL, " \t\n\r");
if (ptr)
{ {
DecodePTTString(TNC, ptr);
ptr = strtok(NULL, " \t\n\r"); ptr = strtok(NULL, " \t\n\r");
if (ptr)
{
DecodePTTString(TNC, ptr);
ptr = strtok(NULL, " \t\n\r");
}
}
if (ptr &&_memicmp(ptr, "PATH", 4) == 0)
{
p_cmd = strtok(NULL, "\n\r");
if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
} }
} }
// Read Initialisation lines if (ptr &&_memicmp(ptr, "PATH", 4) == 0)
while(TRUE)
{ {
if (GetLine(buf) == 0) p_cmd = strtok(NULL, "\n\r");
return TRUE; if (p_cmd) TNC->ProgramPath = _strdup(p_cmd);
}
}
strcpy(errbuf, buf); // Read Initialisation lines
if (memcmp(buf, "****", 4) == 0) while(TRUE)
return TRUE; {
if (GetLine(buf) == 0)
return TRUE;
ptr = strchr(buf, ';'); strcpy(errbuf, buf);
if (ptr)
{
*ptr++ = 13;
*ptr = 0;
}
if (_memicmp(buf, "MAXSESSIONS", 11) == 0) if (memcmp(buf, "****", 4) == 0)
{ return TRUE;
AGW->MaxSessions = atoi(&buf[12]);
if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26; ptr = strchr(buf, ';');
} if (ptr)
if (_memicmp(buf, "CONTIMEOUT", 10) == 0) {
AGW->ConnTimeOut = atoi(&buf[11]) * 10; *ptr++ = 13;
else *ptr = 0;
}
if (_memicmp(buf, "MAXSESSIONS", 11) == 0)
{
AGW->MaxSessions = atoi(&buf[12]);
if (AGW->MaxSessions > 26 ) AGW->MaxSessions = 26;
}
if (_memicmp(buf, "CONTIMEOUT", 10) == 0)
AGW->ConnTimeOut = atoi(&buf[11]) * 10;
else
if (_memicmp(buf, "UPDATEMAP", 9) == 0) if (_memicmp(buf, "UPDATEMAP", 9) == 0)
TNC->PktUpdateMap = TRUE; TNC->PktUpdateMap = TRUE;
else else
if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session if (_memicmp(buf, "BEACONAFTERSESSION", 18) == 0) // Send Beacon after each session
TNC->RPBEACON = TRUE; TNC->RPBEACON = TRUE;
else else
if (_memicmp(buf, "WINDOW", 6) == 0) if (_memicmp(buf, "WINDOW", 6) == 0)
TNC->Window = atoi(&buf[7]); TNC->Window = atoi(&buf[7]);
else else
if (_memicmp(buf, "DEFAULTMODEM", 12) == 0) if (_memicmp(buf, "DEFAULTMODEM", 12) == 0)
TNC->AGWInfo->Modem = atoi(&buf[13]); TNC->AGWInfo->Modem = atoi(&buf[13]);
else else
if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0) if (_memicmp(buf, "MODEMCENTER", 11) == 0 || _memicmp(buf, "MODEMCENTRE", 11) == 0)
TNC->AGWInfo->CenterFreq = atoi(&buf[12]); TNC->AGWInfo->CenterFreq = atoi(&buf[12]);
else else
if (standardParams(TNC, buf) == FALSE) if (standardParams(TNC, buf) == FALSE)
strcat(TNC->InitScript, buf); strcat(TNC->InitScript, buf);
} }
return (TRUE); return (TRUE);

8
VARA.c
View file

@ -73,6 +73,11 @@ int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT); VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT);
VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); VOID NETROMMSG(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
#ifndef LINBPQ #ifndef LINBPQ
BOOL CALLBACK EnumVARAWindowsProc(HWND hwnd, LPARAM lParam); BOOL CALLBACK EnumVARAWindowsProc(HWND hwnd, LPARAM lParam);
#endif #endif
@ -418,8 +423,9 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{ {
TNC->Busy--; TNC->Busy--;
if (TNC->Busy == 0) if (TNC->Busy == 0)
SetWindowText(TNC->xIDC_CHANSTATE, "Clear"); { SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear");
}
} }
} }

View file

@ -10,15 +10,15 @@
#endif #endif
#define KVers 6,0,24,80 #define KVers 6,0,25,15
#define KVerstring "6.0.24.80\0" #define KVerstring "6.0.25.15\0"
#ifdef CKernel #ifdef CKernel
#define Vers KVers #define Vers KVers
#define Verstring KVerstring #define Verstring KVerstring
#define Datestring "July 2025" #define Datestring "December 2025"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring #define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0" #define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0" #define VerDesc "BPQ32 Switch\0"

View file

@ -105,6 +105,11 @@ int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
BOOL KillOldTNC(char * Path); BOOL KillOldTNC(char * Path);
int standardParams(struct TNCINFO * TNC, char * buf); int standardParams(struct TNCINFO * TNC, char * buf);
void hookL4SessionAttempt(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionAccepted(struct STREAMINFO * , char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);
static char ClassName[]="WINMORSTATUS"; static char ClassName[]="WINMORSTATUS";
static char WindowTitle[] = "WINMOR"; static char WindowTitle[] = "WINMOR";
static int RigControlRow = 165; static int RigControlRow = 165;
@ -613,8 +618,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{ {
TNC->Busy--; TNC->Busy--;
if (TNC->Busy == 0) if (TNC->Busy == 0)
{
SetWindowText(TNC->xIDC_CHANSTATE, "Clear"); SetWindowText(TNC->xIDC_CHANSTATE, "Clear");
strcpy(TNC->WEB_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear");
}
} }
} }
@ -2922,7 +2929,7 @@ BOOL RestartTNC(struct TNCINFO * TNC)
SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in destaddr; struct sockaddr_in destaddr;
Debugprintf("trying to restart TNC %s", TNC->ProgramPath); // Debugprintf("trying to restart TNC %s", TNC->ProgramPath);
if (sock == INVALID_SOCKET) if (sock == INVALID_SOCKET)
return 0; return 0;
@ -2945,7 +2952,7 @@ BOOL RestartTNC(struct TNCINFO * TNC)
n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr));
Debugprintf("Restart TNC - sendto returned %d", n); // Debugprintf("Restart TNC - sendto returned %d", n);
Sleep(100); Sleep(100);
closesocket(sock); closesocket(sock);

View file

@ -3311,7 +3311,7 @@ char * xxReadTemplate(char * FormSet, char * DirName, char *FileName)
while ((entry = readdir(dir)) != NULL) while ((entry = readdir(dir)) != NULL)
{ {
if (entry->d_type == DT_DIR) if (entry->d_type == DT_DIR)
continue; continue;
if (stristr(entry->d_name, FileName)) if (stristr(entry->d_name, FileName))
{ {
@ -5609,7 +5609,7 @@ char * CheckFile(struct HtmlFormDir * Dir, char * FN)
while ((entry = readdir(dir)) != NULL) while ((entry = readdir(dir)) != NULL)
{ {
if (entry->d_type == DT_DIR) if (entry->d_type == DT_DIR)
continue; continue;
if (stricmp(entry->d_name, FN) == 0) if (stricmp(entry->d_name, FN) == 0)
{ {

View file

@ -120,7 +120,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC)
SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in destaddr; struct sockaddr_in destaddr;
Debugprintf("trying to restart TNC %s", TNC->ProgramPath); // Debugprintf("trying to restart TNC %s", TNC->ProgramPath);
if (sock == INVALID_SOCKET) if (sock == INVALID_SOCKET)
return 0; return 0;
@ -143,7 +143,7 @@ static BOOL RestartTNC(struct TNCINFO * TNC)
n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr));
Debugprintf("Restart TNC - sendto returned %d", n); // Debugprintf("Restart TNC - sendto returned %d", n);
Sleep(100); Sleep(100);
closesocket(sock); closesocket(sock);

View file

@ -42,7 +42,7 @@ typedef int (FAR *FARPROCY)();
#define L4INFO 5 // INFORMATION #define L4INFO 5 // INFORMATION
#define L4IACK 6 // INFORMATION ACK #define L4IACK 6 // INFORMATION ACK
#define L4RESET 7 // Paula's extension #define L4RESET 7 // Paula's extension
#define L4CREQX 8 // Paula's extension
extern char MYCALL[]; // 7 chars, ax.25 format extern char MYCALL[]; // 7 chars, ax.25 format
extern char MYALIASTEXT[]; // 6 chars, not null terminated extern char MYALIASTEXT[]; // 6 chars, not null terminated
@ -64,15 +64,6 @@ extern int ENDOFDATA;
extern int L3LIVES; extern int L3LIVES;
extern int NUMBEROFNODES; extern int NUMBEROFNODES;
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
// VOID (*CMDPROC)(struct _TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
struct APPLCONFIG struct APPLCONFIG
{ {
@ -186,6 +177,20 @@ typedef struct _TRANSPORTENTRY
int Received; int Received;
int ReceivedAfterExpansion; int ReceivedAfterExpansion;
int segsSent;
int segsRcvd;
int segsResent;
int NRRID;
time_t NRRTime;
time_t ConnectTime;
char Direction[16]; // In or Out
int Service; // For Paula's Connnect to Service
int apiSeq; // for OARC event reporting
time_t lastStatusSentTime;
} TRANSPORTENTRY; } TRANSPORTENTRY;
@ -229,13 +234,15 @@ typedef struct ROUTE
BOOL INP3Node; BOOL INP3Node;
BOOL NoKeepAlive; // Suppress Keepalive Processing BOOL NoKeepAlive; // Suppress Keepalive Processing
int LastConnectAttempt; // To stop us trying too often int LastConnectAttempt; // To stop us trying too often
int ConnectionAttempts;
int Status; // int Status; //
int OldBPQ; // Set if other end is BPQ sending RIF in mS
int LastRTT; // Last Value Reported int LastRTT; // Last Value Reported
int RTT; // Current int RTT; // Current
int SRTT; // Smoothed RTT int SRTT; // Smoothed RTT
int NeighbourSRTT; // Other End SRTT int NeighbourSRTT; // Other End SRTT
// int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms int RTTIncrement; // Average of Ours and Neighbours SRTT in 10 ms - smoothed neighbor transport time (SNTT) in spec
int BCTimer; // Time to next L3RTT Broadcast int BCTimer; // Time to next L3RTT Broadcast
int Timeout; // Lost Response Timer int Timeout; // Lost Response Timer
int Retries; // Lost Response Count int Retries; // Lost Response Count
@ -244,6 +251,16 @@ typedef struct ROUTE
int OtherendsRouteQual; // Route quality used by other end. int OtherendsRouteQual; // Route quality used by other end.
int OtherendLocked; // Route quality locked by ROUTES entry. int OtherendLocked; // Route quality locked by ROUTES entry.
int FirstTimeFlag; // Set once quality has been set by direct receive int FirstTimeFlag; // Set once quality has been set by direct receive
int RemoteMAXRTT; // For INP3
int RemoteMAXHOPS;
char * TCPHost; // For NETROM over TCP
int TCPPort;
struct NRTCPSTRUCT * TCPSession;
struct addrinfo * TCPAddress; // Resolved Address
int localport; // for consistancy check
int recNum; // This entry's index it Routes table
int noV2point2; // Set to force V2.0 connect. Can be set in config or dynamically learned
} *PROUTE; } *PROUTE;
@ -251,10 +268,8 @@ typedef struct ROUTE
#define GotRTTRequest 1 // Other end has sent us a RTT Packet #define GotRTTRequest 1 // Other end has sent us a RTT Packet
#define GotRTTResponse 2 // Other end has sent us a RTT Response #define GotRTTResponse 2 // Other end has sent us a RTT Response
#define GotRIF 4 // Other end has sent RIF, so is probably an INP3 Node #define SentRTTRequest 4
// (could just be monitoring RTT for some reason #define SentOurRIF 8 // Set when we have sent a rif for our Call and any ApplCalls
#define SentRTTRequest 8
#define SentOurRIF 16 // Set when we have sent a rif for our Call and any ApplCalls
// (only sent when we have seen both a request and response) // (only sent when we have seen both a request and response)
#pragma pack(1) #pragma pack(1)
@ -466,18 +481,18 @@ typedef struct _APPLCALLS
typedef struct NR_DEST_ROUTE_ENTRY typedef struct NR_DEST_ROUTE_ENTRY
{ {
struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH
UCHAR ROUT_QUALITY; // QUALITY uint16_t * Dummy; // Padding so records are same length
UCHAR ROUT_QUALITY; // QUALITY
UCHAR ROUT_OBSCOUNT; UCHAR ROUT_OBSCOUNT;
UCHAR ROUT_LOCKED; UCHAR ROUT_LOCKED;
UCHAR Padding[4]; // So Entries are the same length
} *PNR_DEST_ROUTE_ENTRY; } *PNR_DEST_ROUTE_ENTRY;
typedef struct INP3_DEST_ROUTE_ENTRY typedef struct INP3_DEST_ROUTE_ENTRY
{ {
struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH
USHORT LastRTT; // Last Value Reported uint16_t * RouteLastTT; // Last time sent should be saved for each neighbour. Area is mallod'ed as needed
USHORT RTT; // Current USHORT STT; // Current time to dest from here (was called RTT but is one way not round trip.
USHORT SRTT; // Smoothed RTT // Is actually a smoothed value as is calculated from smoothed link times)
UCHAR Hops; UCHAR Hops;
} *PDEST_ROUTE_ENTRY; } *PDEST_ROUTE_ENTRY;
@ -701,7 +716,8 @@ typedef struct PORTCONTROL
BOOL NormalizeQuality; // Normalise Node Qualities BOOL NormalizeQuality; // Normalise Node Qualities
BOOL IgnoreUnlocked; // Ignore Unlocked routes BOOL IgnoreUnlocked; // Ignore Unlocked routes
BOOL INP3ONLY; // Default to INP3 and disallow NODES BOOL INP3ONLY; // Default to INP3 and disallow NODES
BOOL ALLOWINP3; BOOL ALLOWINP3; // Accept INP3 if offered by other end
BOOL ENABLEINP3; // Send INP3 RTT probes to discovered neighbours
void (* UIHook)(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); // Used for KISSARQ void (* UIHook)(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG); // Used for KISSARQ
struct PORTCONTROL * HookPort; struct PORTCONTROL * HookPort;
@ -728,6 +744,9 @@ typedef struct PORTCONTROL
UCHAR * BUSY; // % Active (Normally DCD active or TX) UCHAR * BUSY; // % Active (Normally DCD active or TX)
int Hardware; // TNC H_TYPE. Copied here for access from application context int Hardware; // TNC H_TYPE. Copied here for access from application context
int isRF; // For API reporting. -1 is unspecified
int SENDRIFTIMER;
time_t LastRIFTime;
} PORTCONTROLX, *PPORTCONTROL; } PORTCONTROLX, *PPORTCONTROL;
@ -966,6 +985,18 @@ typedef struct _LINKTABLE
time_t ConnectTime; // For session stats time_t ConnectTime; // For session stats
int bytesRXed; // Info bytes only int bytesRXed; // Info bytes only
int bytesTXed; int bytesTXed;
int framesRXed;
int framesTXed;
int framesResent;
time_t LastStatusTime;
int LastStatusbytesRXed;
int LastStatusbytesTXed;
int maxQueued;
int intervalMaxQueued;
uint64_t lastPSent; // Time last I frame with P bit sent in mS (for RTT Measurements)
int RTT;
// Now support compressing L2 Sessions. // Now support compressing L2 Sessions.
// We collect as much data as possible before compressing and re-packetizing // We collect as much data as possible before compressing and re-packetizing
@ -981,6 +1012,9 @@ typedef struct _LINKTABLE
int Received; int Received;
int ReceivedAfterExpansion; int ReceivedAfterExpansion;
char ApplName[16];
time_t lastStatusSentTime;
int apiSeq; // for OARC event reporting
} LINKTABLE; } LINKTABLE;
@ -1472,6 +1506,25 @@ struct AXIPPORTINFO
}; };
struct CMDX
{
char String[12]; // COMMAND STRING
UCHAR CMDLEN; // SIGNIFICANT LENGTH
VOID (*CMDPROC)(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD);// COMMAND PROCESSOR
// VOID (*CMDPROC)();// COMMAND PROCESSOR
size_t CMDFLAG; // FLAG/VALUE Offset
};
struct NETROMX
{
int ServiceNo;
char ServiceName[10];
};
extern struct NETROMX SERVICES[];
extern int NUMBEROFSSERVICES;
#define Disconnect(stream) SessionControl(stream,2,0) #define Disconnect(stream) SessionControl(stream,2,0)
#define Connect(stream) SessionControl(stream,1,0) #define Connect(stream) SessionControl(stream,1,0)

View file

@ -192,8 +192,8 @@ extern UCHAR BPQDirectory[];
extern int OffsetH, OffsetW; extern int OffsetH, OffsetW;
static void ResolveNames(struct AXIPPORTINFO * PORT); static void ResolveNames(VOID * Param);
void OpenSockets(struct AXIPPORTINFO * PORT); void OpenSockets(VOID * Param);
void CloseSockets(struct AXIPPORTINFO * PORT); void CloseSockets(struct AXIPPORTINFO * PORT);
@ -221,7 +221,7 @@ int KissDecode(UCHAR * inbuff, int len);
int Socket_Accept(int SocketId); int Socket_Accept(int SocketId);
int Socket_Connect(int SocketId, int Error); int Socket_Connect(int SocketId, int Error);
int Socket_Data(int sock, int error, int eventcode); int Socket_Data(int sock, int error, int eventcode);
VOID TCPConnectThread(struct arp_table_entry * arp); VOID TCPConnectThread(VOID * Param);
VOID __cdecl Debugprintf(const char * format, ...); VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...); VOID __cdecl Consoleprintf(const char * format, ...);
BOOL OpenListeningSocket(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp); BOOL OpenListeningSocket(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp);
@ -444,7 +444,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0; From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0) if (strstr(CantReplyList, From) == 0)
{ {
if (strlen(CantReplyList) < 500); if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From); strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]); Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
} }
@ -557,7 +557,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
From[ConvFromAX25(call, &From[1]) + 1] = 0; From[ConvFromAX25(call, &From[1]) + 1] = 0;
if (strstr(CantReplyList, From) == 0) if (strstr(CantReplyList, From) == 0)
{ {
if (strlen(CantReplyList) < 500); if (strlen(CantReplyList) < 500)
strcat(CantReplyList, From); strcat(CantReplyList, From);
Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]); Debugprintf("AXIP Packet from %s dropped - can't reply", &From[1]);
} }
@ -692,7 +692,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff)
else else
Consoleprintf("Failed to reread config file - leaving config unchanged"); Consoleprintf("Failed to reread config file - leaving config unchanged");
_beginthread(OpenSockets, 0, PORT ); _beginthread(OpenSockets, 0, PORT);
GetAXIPCache(PORT); GetAXIPCache(PORT);
@ -844,8 +844,9 @@ int InitAXIP(int Port)
return (TRUE); return (TRUE);
} }
void OpenSockets(struct AXIPPORTINFO * PORT) void OpenSockets(void * Param)
{ {
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
char Msg[255]; char Msg[255];
int err; int err;
u_long param=1; u_long param=1;
@ -1528,8 +1529,9 @@ static void CreateResolverWindow(struct AXIPPORTINFO * PORT)
extern HWND hWndPopup; extern HWND hWndPopup;
static void ResolveNames(struct AXIPPORTINFO * PORT) static void ResolveNames(VOID * Param)
{ {
struct AXIPPORTINFO * PORT = (struct AXIPPORTINFO *)Param;
int count = 0; int count = 0;
PORT->ResolveNamesThreadId = GetCurrentThreadId(); // Detect if another started PORT->ResolveNamesThreadId = GetCurrentThreadId(); // Detect if another started
@ -2996,8 +2998,9 @@ int KissDecode(UCHAR * inbuff, int len)
return txptr; return txptr;
} }
VOID TCPConnectThread(struct arp_table_entry * arp) VOID TCPConnectThread(void * Param)
{ {
struct arp_table_entry * arp = (struct arp_table_entry *)Param;
char Msg[255]; char Msg[255];
int err, i; int err, i;
u_long param=1; u_long param=1;

View file

@ -74,6 +74,7 @@
// Increase size of status display buffers (7) // Increase size of status display buffers (7)
// Allow sending BEL (CTRL/G) (79) // Allow sending BEL (CTRL/G) (79)
// Fix sending BEL (CTRL/G) (81)
#include "BPQChat.h" #include "BPQChat.h"

View file

@ -1591,7 +1591,7 @@ extern RECT DebugRect;
extern HWND hMonitor; extern HWND hMonitor;
//extern HWND hConsole; //extern HWND hConsole;
//extern RECT ConsoleRect; //extern RECT ConsoleRect;
extern int LogAge; extern int BBSLogAge;
extern BOOL DeletetoRecycleBin; extern BOOL DeletetoRecycleBin;
extern BOOL SuppressMaintEmail; extern BOOL SuppressMaintEmail;
extern BOOL SaveRegDuringMaint; extern BOOL SaveRegDuringMaint;

201
cMain.c
View file

@ -38,6 +38,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "cheaders.h" #include "cheaders.h"
#include "tncinfo.h" #include "tncinfo.h"
#include "mqtt.h" #include "mqtt.h"
#include "kiss.h"
VOID L2Routine(struct PORTCONTROL * PORT, PMESSAGE Buffer); VOID L2Routine(struct PORTCONTROL * PORT, PMESSAGE Buffer);
VOID ProcessIframe(struct _LINKTABLE * LINK, PDATAMESSAGE Buffer); VOID ProcessIframe(struct _LINKTABLE * LINK, PDATAMESSAGE Buffer);
@ -52,12 +53,33 @@ int CanPortDigi(int Port);
int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len); int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
void MQTTTimer(); void MQTTTimer();
void SaveMH(); void SaveMH();
VOID InformPartner(struct _LINKTABLE * LINK, int Reason);
VOID L2SENDCOMMAND(struct _LINKTABLE * LINK, int CMD);
void WritePacketLogThread(void * param);
void hookNodeStarted();
void hookNodeRunning();
void DeleteLogFiles(int Age);
void APIL2Trace(struct _MESSAGE * Message, char * Dirn);
#include "configstructs.h" #include "configstructs.h"
extern struct CONFIGTABLE xxcfg; extern struct CONFIGTABLE xxcfg;
extern BOOL needAIS; extern BOOL needAIS;
extern int needADSB; extern int needADSB;
extern int EnableOARCAPI;
extern SOCKET NodeAPISocket;
extern int nodeStartedSent;
extern SOCKADDR_IN UDPreportdest;
extern char NodeAPIServer[80];
extern int NodeAPIPort;
extern int RIFInterval;
time_t LastNodeStatus = 0;
int nodeStatusTimer = 20 * 60; // 20 mins
int LogAge = 10;
struct PORTCONFIG * PortRec; struct PORTCONFIG * PortRec;
@ -178,6 +200,7 @@ extern VOID * ENDPOOL;
extern void * APPL_Q; // Queue of frames for APRS Appl extern void * APPL_Q; // Queue of frames for APRS Appl
extern BOOL APRSActive; extern BOOL APRSActive;
extern int DEBUGINP3;
#define BPQHOSTSTREAMS 64 #define BPQHOSTSTREAMS 64
@ -191,9 +214,12 @@ BPQVECSTRUC * TELNETMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS];
BPQVECSTRUC * AGWMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 1]; BPQVECSTRUC * AGWMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 1];
BPQVECSTRUC * APRSMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 2]; BPQVECSTRUC * APRSMONVECPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 2];
BPQVECSTRUC * IPHOSTVECTORPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 3]; BPQVECSTRUC * IPHOSTVECTORPTR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 3];
BPQVECSTRUC * FILEMONVECTOR = &BPQHOSTVECTOR[BPQHOSTSTREAMS + 4];
int BPQVECLENGTH = sizeof(BPQVECSTRUC); int BPQVECLENGTH = sizeof(BPQVECSTRUC);
int MONTOFILEFLAG = 0;
int NODEORDER = 0; int NODEORDER = 0;
UCHAR LINKEDFLAG = 0; UCHAR LINKEDFLAG = 0;
@ -247,6 +273,8 @@ int CFLAG = 0; // C =HOST Command
VOID * IDMSG_Q = NULL; // ID/BEACONS WAITING TO BE SENT VOID * IDMSG_Q = NULL; // ID/BEACONS WAITING TO BE SENT
int NODESINPROGRESS = 0; int NODESINPROGRESS = 0;
int NODESToOnePort = 0; // Set to port num to send NODES to only one port.
VOID * CURRENTNODE = NULL; // NEXT _NODE TO SEND VOID * CURRENTNODE = NULL; // NEXT _NODE TO SEND
VOID * DESTHEADER = NULL; // HEAD OF SORTED NODES CHAIN VOID * DESTHEADER = NULL; // HEAD OF SORTED NODES CHAIN
@ -302,8 +330,8 @@ VOID LINKINIT(PEXTPORTDATA PORTVEC)
VOID LINKTX(PEXTPORTDATA PORTVEC, PMESSAGE Buffer) VOID LINKTX(PEXTPORTDATA PORTVEC, PMESSAGE Buffer)
{ {
// LOOP BACK TO SWITCH // LOOP BACK TO SWITCH
struct _LINKTABLE * LINK;
struct _LINKTABLE * LINK;
LINK = Buffer->Linkptr; LINK = Buffer->Linkptr;
if (LINK) if (LINK)
@ -652,6 +680,7 @@ BOOL Start()
struct CMDX * CMD; struct CMDX * CMD;
int PortSlot = 1; int PortSlot = 1;
uintptr_t int3; uintptr_t int3;
int index = 0; // Entry No. in ROUTES
unsigned char * ptr2 = 0, * ptr3, * ptr4; unsigned char * ptr2 = 0, * ptr3, * ptr4;
USHORT * CWPTR; USHORT * CWPTR;
@ -821,6 +850,10 @@ BOOL Start()
MAXLINKS = cfg->C_MAXLINKS; MAXLINKS = cfg->C_MAXLINKS;
MAXDESTS = cfg->C_MAXDESTS; MAXDESTS = cfg->C_MAXDESTS;
MAXNEIGHBOURS = cfg->C_MAXNEIGHBOURS; MAXNEIGHBOURS = cfg->C_MAXNEIGHBOURS;
if (MAXNEIGHBOURS == 0)
MAXNEIGHBOURS = 1;
MAXCIRCUITS = cfg->C_MAXCIRCUITS; MAXCIRCUITS = cfg->C_MAXCIRCUITS;
HIDENODES = cfg->C_HIDENODES; HIDENODES = cfg->C_HIDENODES;
@ -859,6 +892,14 @@ BOOL Start()
PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES; PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES;
DEBUGINP3 = cfg->C_DEBUGINP3;
EnableOARCAPI = cfg->C_OARCAPI;
MONTOFILEFLAG = cfg->C_MONTOFILE;
RIFInterval = cfg->C_RIFInterval;
if (cfg->C_OnlyVer2point0) if (cfg->C_OnlyVer2point0)
SUPPORT2point2 = 0; SUPPORT2point2 = 0;
@ -989,6 +1030,8 @@ BOOL Start()
PORT->IgnoreUnlocked = PortRec->IGNOREUNLOCKED; PORT->IgnoreUnlocked = PortRec->IGNOREUNLOCKED;
PORT->INP3ONLY = PortRec->INP3ONLY; PORT->INP3ONLY = PortRec->INP3ONLY;
PORT->ALLOWINP3 = PortRec->AllowINP3; PORT->ALLOWINP3 = PortRec->AllowINP3;
PORT->ENABLEINP3 = PortRec->EnableINP3;
PORT->isRF = PortRec->isRF;
PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME; PORT->PORTWINDOW = (UCHAR)PortRec->MAXFRAME;
@ -1331,6 +1374,7 @@ BOOL Start()
char * VIA; char * VIA;
char axcall[8]; char axcall[8];
ConvToAX25(Rcfg->call, ROUTE->NEIGHBOUR_CALL); ConvToAX25(Rcfg->call, ROUTE->NEIGHBOUR_CALL);
// if VIA convert digis // if VIA convert digis
@ -1363,18 +1407,21 @@ BOOL Start()
PORT = GetPortTableEntryFromPortNum(ROUTE->NEIGHBOUR_PORT); PORT = GetPortTableEntryFromPortNum(ROUTE->NEIGHBOUR_PORT);
if (Rcfg->pwind & 0x40) if (Rcfg->nokeepalives)
ROUTE->NoKeepAlive = 1; ROUTE->NoKeepAlive = 1;
else else
if (PORT != NULL) if (PORT != NULL)
ROUTE->NoKeepAlive = PORT->PortNoKeepAlive; ROUTE->NoKeepAlive = PORT->PortNoKeepAlive;
if (Rcfg->pwind & 0x80 || (PORT && PORT->INP3ONLY)) if (Rcfg->inp3 || (PORT && PORT->INP3ONLY))
{ {
ROUTE->INP3Node = 1; ROUTE->INP3Node = 1;
ROUTE->NoKeepAlive = 0; // Cant have INP3 and NOKEEPALIVES ROUTE->NoKeepAlive = 0; // Cant have INP3 and NOKEEPALIVES
} }
if (Rcfg->noV2point2)
ROUTE->noV2point2 = 1;
ROUTE->NBOUR_MAXFRAME = Rcfg->pwind & 0x3f; ROUTE->NBOUR_MAXFRAME = Rcfg->pwind & 0x3f;
FRACK = Rcfg->pfrack; FRACK = Rcfg->pfrack;
@ -1384,6 +1431,17 @@ BOOL Start()
ROUTE->NEIGHBOUR_FLAG = LOCKEDBYCONFIG; // Locked ROUTE->NEIGHBOUR_FLAG = LOCKEDBYCONFIG; // Locked
if (Rcfg->tcphost)
{
ROUTE->TCPHost = Rcfg->tcphost;
ROUTE->TCPPort = Rcfg->tcpport;
ROUTE->TCPAddress = (struct addrinfo *)zalloc(sizeof(struct addrinfo));
ROUTE->TCPAddress->ai_addr = (struct sockaddr *) zalloc(sizeof(struct sockaddr));
}
ROUTE->recNum = index++;
Rcfg++; Rcfg++;
ROUTE++; ROUTE++;
} }
@ -1543,6 +1601,11 @@ BOOL Start()
if (AUTOSAVEMH) if (AUTOSAVEMH)
ReadMH(); // Only if AutoSave configured ReadMH(); // Only if AutoSave configured
// Tidy Log Files
DeleteLogFiles(LogAge);
// set up stream number in BPQHOSTVECTOR // set up stream number in BPQHOSTVECTOR
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
@ -1561,8 +1624,34 @@ BOOL Start()
upnpInit(); upnpInit();
// Start Monitor to file thread
_beginthread(WritePacketLogThread, 0, NULL);
lastSaveSecs = CurrentSecs = lastSlowSecs = time(NULL); lastSaveSecs = CurrentSecs = lastSlowSecs = time(NULL);
// if EnableOARCAPI set try to resolve host here so we can send Node up event before anything else
if (EnableOARCAPI)
{
struct hostent * HostEnt3;
HostEnt3 = gethostbyname(NodeAPIServer);
NodeAPISocket = socket(AF_INET, SOCK_DGRAM, 0);
UDPreportdest.sin_family = AF_INET;
UDPreportdest.sin_port = htons(NodeAPIPort);
if (HostEnt3)
{
memcpy(&UDPreportdest.sin_addr.s_addr,HostEnt3->h_addr,4);
hookNodeStarted();
nodeStartedSent = 1;
LastNodeStatus = time(NULL);
}
}
return 0; return 0;
} }
@ -1591,14 +1680,19 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE)
{ {
struct ROUTE * ROUTE = NEIGHBOURS; struct ROUTE * ROUTE = NEIGHBOURS;
struct ROUTE * FIRSTSPARE = NULL; struct ROUTE * FIRSTSPARE = NULL;
int n = MAXNEIGHBOURS;
char Normcall[10]; char Normcall[10];
int n;
while (n--) for (n = 0; n < MAXNEIGHBOURS; n++)
{ {
if (ROUTE->NEIGHBOUR_CALL[0] == 0) // Spare if (ROUTE->NEIGHBOUR_CALL[0] == 0) // Spare
{
if (FIRSTSPARE == NULL) if (FIRSTSPARE == NULL)
{
FIRSTSPARE = ROUTE; FIRSTSPARE = ROUTE;
ROUTE->recNum = n;
}
}
if (ROUTE->NEIGHBOUR_PORT != Port) if (ROUTE->NEIGHBOUR_PORT != Port)
{ {
@ -1606,7 +1700,6 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE)
continue; continue;
} }
Normcall[ConvFromAX25(ROUTE->NEIGHBOUR_CALL, Normcall)] = 0; Normcall[ConvFromAX25(ROUTE->NEIGHBOUR_CALL, Normcall)] = 0;
if (CompareCalls(ROUTE->NEIGHBOUR_CALL, Call)) if (CompareCalls(ROUTE->NEIGHBOUR_CALL, Call))
@ -1620,6 +1713,7 @@ BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE)
// ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL // ENTRY NOT FOUND - FIRSTSPARE HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL
*REQROUTE = FIRSTSPARE; *REQROUTE = FIRSTSPARE;
return FALSE; return FALSE;
} }
@ -1968,7 +2062,7 @@ VOID ReadNodes()
ptr = strtok_s(NULL, seps, &Context); // INP3 ptr = strtok_s(NULL, seps, &Context); // INP3
if (ptr == NULL) continue; if (ptr == NULL) continue;
if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0) // Not LOCKED ROUTE
ROUTE->OtherendsRouteQual = atoi(ptr); ROUTE->OtherendsRouteQual = atoi(ptr);
ptr = strtok_s(NULL, seps, &Context); // INP3 ptr = strtok_s(NULL, seps, &Context); // INP3
@ -2156,6 +2250,12 @@ VOID TIMERINTERRUPT()
if (MQTT) if (MQTT)
MQTTTimer(); MQTTTimer();
if (LastNodeStatus && (time(NULL) - LastNodeStatus) > nodeStatusTimer)
{
LastNodeStatus = time(NULL);
hookNodeRunning();
}
/* /*
if (QCOUNT < 200) if (QCOUNT < 200)
{ {
@ -2211,6 +2311,10 @@ VOID TIMERINTERRUPT()
} }
Message = (struct _MESSAGE *)Buffer; Message = (struct _MESSAGE *)Buffer;
if(NodeAPISocket)
APIL2Trace(Message, "sent");
Message->PORT |= 0x80; // Set TX Bit Message->PORT |= 0x80; // Set TX Bit
BPQTRACE(Message, FALSE); // Dont send TX'ed frames to APRS BPQTRACE(Message, FALSE); // Dont send TX'ed frames to APRS
@ -2323,6 +2427,9 @@ L2Packet:
if (MQTT && PORT->PROTOCOL == 0) if (MQTT && PORT->PROTOCOL == 0)
MQTTKISSRX(Buffer); MQTTKISSRX(Buffer);
if(NodeAPISocket && PORT->PROTOCOL == 0)
APIL2Trace(Message, "rcvd");
// Bridge if requested // Bridge if requested
for (toPort = 1; toPort <= MaxBPQPortNo; toPort++) for (toPort = 1; toPort <= MaxBPQPortNo; toPort++)
@ -2511,9 +2618,9 @@ ENDOFLIST:
{ {
// Stuck link debug check // Stuck link debug check
if (LINK->LASTFRAMESENT && (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs if (LINK->LINKWINDOW == 0 || LINK->LASTFRAMESENT == 0 || (time(NULL) - LINK->LASTFRAMESENT) > 60) // No send for 60 secs
{ {
if (COUNT_AT_L2(LINK) > 16) if (COUNT_AT_L2(LINK) > 16 || LINK->LINKWINDOW == 0)
{ {
// Dump Link State // Dump Link State
@ -2672,6 +2779,18 @@ int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS)
L4++; L4++;
} }
// And to the Monitor to File system.
if (MONTOFILEFLAG) // Trace Enabled?
{
Buffer = GetBuff();
if (Buffer)
{
memcpy(&Buffer->PORT, &Msg->PORT, BUFFLEN - sizeof(void *)); // Dont copy chain word
C_Q_ADD(&FILEMONVECTOR->HOSTTRACEQ, Buffer);
}
}
return TRUE; return TRUE;
} }
; ;
@ -2680,6 +2799,7 @@ VOID INITIALISEPORTS()
{ {
char INITMSG[80]; char INITMSG[80];
struct PORTCONTROL * PORT = PORTTABLE; struct PORTCONTROL * PORT = PORTTABLE;
struct PORTCONTROL * SAVEPORT;
while (PORT) while (PORT)
{ {
@ -2687,7 +2807,68 @@ VOID INITIALISEPORTS()
WritetoConsoleLocal(INITMSG); WritetoConsoleLocal(INITMSG);
PORT->PORTINITCODE(PORT); PORT->PORTINITCODE(PORT);
PORT = PORT->PORTPOINTER; SAVEPORT=PORT;
// See if it is an RF port
if (PORT->isRF == -1) // Not set
{
// Try to determine if RF
if (PORT->PORTTYPE == 0)
{
struct KISSINFO * KISS = (struct KISSINFO *)PORT;
NPASYINFO Port;
if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
{
// Not first port on device
PORT = (struct PORTCONTROL *)KISS->FIRSTPORT;
}
Port = KISSInfo[PORT->PORTNUMBER];
if (Port)
{
// KISS like
if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE)
{
// KISS over UDP or TCP
if (PORT->KISSTCP)
PORT->isRF = 1; // Assume TCP is RF (software modem)
else
PORT->isRF = 0; // Assuem UDP is Internet
}
else
PORT->isRF = 1; // Serial port
}
}
else if (PORT->PORTTYPE == 14) // Loopback
PORT->isRF = 0;
else if (PORT->PORTTYPE == 16) // External
{
if (PORT->PROTOCOL == 10) // 'HF' Port
{
struct TNCINFO * TNC = TNCInfo[PORT->PORTNUMBER];
if (TNC && TNC->Hardware == H_TELNET)
PORT->isRF = 0;
else
PORT->isRF = 1; // ARDOP etc
}
else
{
// External but not HF - AXIP, BPQETHER VKISS, ??
PORT->isRF = 0;
}
}
}
PORT = SAVEPORT->PORTPOINTER;
} }
} }

View file

@ -18,5 +18,5 @@ Chat :
MonitorSize = "828,1644,148,770"; MonitorSize = "828,1644,148,770";
DebugSize = "0,0,0,0"; DebugSize = "0,0,0,0";
WindowSize = "231,835,254,602"; WindowSize = "231,835,254,602";
Version = "6,0,24,32"; Version = "6,0,24,81";
}; };

View file

@ -108,7 +108,7 @@ VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum); DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
int cCOUNT_AT_L2(struct _LINKTABLE * LINK); int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
VOID SENDL4CONNECT(TRANSPORTENTRY * Session); VOID SENDL4CONNECT(TRANSPORTENTRY * Session, int Service);
VOID CloseSessionPartner(TRANSPORTENTRY * Session); VOID CloseSessionPartner(TRANSPORTENTRY * Session);
int COUNTNODES(struct ROUTE * ROUTE); int COUNTNODES(struct ROUTE * ROUTE);
@ -445,7 +445,3 @@ DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz);
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK); void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK); void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK); void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK);
void hookL4SessionAttempt(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionAccepted(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);

View file

@ -25,6 +25,8 @@ Stuff to make compiling on WINDOWS and LINUX easier
#ifdef WIN32 #ifdef WIN32
#include <windows.h>
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
#define pthread_t uint32_t #define pthread_t uint32_t
@ -41,6 +43,7 @@ int pthread_equal(pthread_t T1, pthread_t T2)
#include <syslog.h> #include <syslog.h>
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h> #include <unistd.h>
#include <stdint.h>
#define BOOL int #define BOOL int
@ -188,3 +191,27 @@ void closesocket(int sock)
} }
#endif #endif
#ifdef WIN32
uint32_t GetTickCountINP3()
{
// Returns system uptime in 10 mS, lower 20 bits only
return (GetTickCount() / 10) & 0xfffff;
}
#else
uint64_t GetTickCount();
uint32_t GetTickCountINP3()
{
uint64_t Ticks = GetTickCount();
// Returns system uptime in 10 mS, lower 20 bits only
return (Ticks / 10) & 0xfffff;
}
#endif

View file

@ -24,6 +24,7 @@ Stuff to make compiling on WINDOWS and LINUX easier
#define strtoll _strtoi64 #define strtoll _strtoi64
#ifdef _WIN64 #ifdef _WIN64
#include "stdint.h" #include "stdint.h"
#else #else
@ -49,7 +50,39 @@ Stuff to make compiling on WINDOWS and LINUX easier
int pthread_equal(pthread_t T1, pthread_t T2); int pthread_equal(pthread_t T1, pthread_t T2);
uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist); uintptr_t _beginthread(void(__cdecl start_address)(void *), unsigned stack_size, void *arglist);
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif
#else #else
@ -152,9 +185,7 @@ int stricmp(const unsigned char * pStr1, const unsigned char *pStr2);
char * strupr(char* s); char * strupr(char* s);
char * strlwr(char* s); char * strlwr(char* s);
pthread_t _beginthread(void(*start_address)(), unsigned stack_size, VOID * arglist); pthread_t _beginthread(void(start_address)(void *), unsigned stack_size, VOID * arglist);
#define WSAGetLastError() errno #define WSAGetLastError() errno
#define GetLastError() errno #define GetLastError() errno
@ -189,7 +220,7 @@ typedef struct tagRECT
#endif #endif
uint32_t GetTickCountINP3();
#ifdef LINBPQ #ifdef LINBPQ

293
config.c
View file

@ -305,11 +305,14 @@ static char *keywords[] =
"APPL5ALIAS", "APPL6ALIAS", "APPL7ALIAS", "APPL8ALIAS", "APPL5ALIAS", "APPL6ALIAS", "APPL7ALIAS", "APPL8ALIAS",
"APPL1QUAL", "APPL2QUAL", "APPL3QUAL", "APPL4QUAL", "APPL1QUAL", "APPL2QUAL", "APPL3QUAL", "APPL4QUAL",
"APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL", "APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL",
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS", "LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS", "EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS",
"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", "L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe",
"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0" "L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0", "DEBUGINP3", "ENABLEOARCAPI", "MONTOFILE",
"RIFInterval"
}; /* parameter keywords */ }; /* parameter keywords */
static void * offset[] = static void * offset[] =
@ -328,11 +331,13 @@ static void * offset[] =
&xxcfg.C_APPL[4].ApplAlias, &xxcfg.C_APPL[5].ApplAlias, &xxcfg.C_APPL[6].ApplAlias, &xxcfg.C_APPL[7].ApplAlias, &xxcfg.C_APPL[4].ApplAlias, &xxcfg.C_APPL[5].ApplAlias, &xxcfg.C_APPL[6].ApplAlias, &xxcfg.C_APPL[7].ApplAlias,
&xxcfg.C_APPL[0].ApplQual, &xxcfg.C_APPL[1].ApplQual, &xxcfg.C_APPL[2].ApplQual, &xxcfg.C_APPL[3].ApplQual, &xxcfg.C_APPL[0].ApplQual, &xxcfg.C_APPL[1].ApplQual, &xxcfg.C_APPL[2].ApplQual, &xxcfg.C_APPL[3].ApplQual,
&xxcfg.C_APPL[4].ApplQual, &xxcfg.C_APPL[5].ApplQual, &xxcfg.C_APPL[6].ApplQual, &xxcfg.C_APPL[7].ApplQual, &xxcfg.C_APPL[4].ApplQual, &xxcfg.C_APPL[5].ApplQual, &xxcfg.C_APPL[6].ApplQual, &xxcfg.C_APPL[7].ApplQual,
&xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed
&xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed
&xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs, &xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs,
&xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS, &xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS,
&xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe, &xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe,
&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0}; /* offset for corresponding data in config file */ &xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0, &xxcfg.C_DEBUGINP3, &xxcfg.C_OARCAPI, &xxcfg.C_MONTOFILE,
&xxcfg.C_RIFInterval}; /* offset for corresponding data in config file */
static int routine[] = static int routine[] =
{ {
@ -350,11 +355,13 @@ static int routine[] =
13, 13 ,13, 13, 13, 13 ,13, 13,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14 ,14, 14, 14, 14 ,14, 14,
15, 0, 2, 9, 9,
15, 0, 2, 9, 9, 9,
2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 0, 1, 20, 20, 2, 2, 0, 1, 20, 20,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1} ; // Routine to process param 1, 1, 1, 1, 1, 1,
1}; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int); int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@ -376,7 +383,8 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY", "BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE", "UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE", "IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort", "ALLOWINP3"}; /* parameter keywords */ "SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort",
"ALLOWINP3", "ENABLEINP3", "isRF"}; /* parameter keywords */
static void * poffset[] = static void * poffset[] =
{ {
@ -390,7 +398,8 @@ static void * poffset[] =
&xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY, &xxp.BCALL, &xxp.DIGIMASK, &xxp.DefaultNoKeepAlives, &xxp.IOADDR, &xxp.DLLNAME, &xxp.WL2K, &xxp.UIONLY,
&xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize, &xxp.IOADDR, &xxp.IPADDR, &xxp.INTLEVEL, &xxp.IOADDR, &xxp.IOADDR, &xxp.ListenPort, &xxp.NoNormalize,
&xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide, &xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide,
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort, &xxp.AllowINP3}; /* offset for corresponding data in config file */ &xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort,
&xxp.AllowINP3, &xxp.EnableINP3, &xxp.isRF}; /* offset for corresponding data in config file */
static int proutine[] = static int proutine[] =
{ {
@ -404,7 +413,8 @@ static int proutine[] =
0, 1, 2, 18, 15, 16, 2, 0, 1, 2, 18, 15, 16, 2,
1, 17, 1, 1, 1, 1, 2, 1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 2, 2, 2, 1, 1, 19, 2,
1, 20, 1, 21, 22, 1, 1}; /* routine to process parameter */ 1, 20, 1, 21, 22, 1,
1, 1, 1}; /* routine to process parameter */
int PPARAMLIM = sizeof(proutine)/sizeof(int); int PPARAMLIM = sizeof(proutine)/sizeof(int);
@ -554,7 +564,6 @@ BOOL ProcessConfig()
heading = 1; heading = 1;
} }
paramok[6]=1; /* dont need BUFFERS */ paramok[6]=1; /* dont need BUFFERS */
paramok[8]=1; /* dont need TRANSDELAY */ paramok[8]=1; /* dont need TRANSDELAY */
paramok[13]=1; // NodeAlias paramok[13]=1; // NodeAlias
@ -601,36 +610,39 @@ BOOL ProcessConfig()
for (i=0;i<24;i++) for (i=0;i<24;i++)
paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */ paramok[45+i]=1; /* or APPLCALLS, APPLALIASS APPLQUAL */
paramok[69]=1; // BText optional paramok[69]=1; // BText optional
paramok[70]=1; // IPGateway optional paramok[70]=1; // NETROMCALL optional
paramok[71]=1; // C_IS_CHAT optional paramok[71]=1; // C_IS_CHAT optional
paramok[72]=1; // MAXRTT optional paramok[72]=1; // MAXRTT optional
paramok[73]=1; // MAXHOPS optional paramok[73]=1; // MAXTT optional
paramok[74]=1; // LogL4Connects optional paramok[74]=1; // MAXHOPS optional
paramok[75]=1; // LogAllConnects optional paramok[75]=1; // LogL4Connects optional
paramok[76]=1; // SAVEMH optional paramok[76]=1; // LogAllConnects optional
paramok[77]=1; // ENABLEADIFLOG optional paramok[77]=1; // SAVEMH optional
paramok[78]=1; // EnableEvents optional paramok[78]=1; // ENABLEADIFLOG optional
paramok[79]=1; // SaveAPRSMsgs optional paramok[79]=1; // EnableEvents optional
paramok[79]=1; // SaveAPRSMsgs optional paramok[80]=1; // SaveAPRSMsgs optional
paramok[80]=1; // EnableM0LTEMap optional paramok[81]=1; // EnableM0LTEMap optional
paramok[81]=1; // MQTT Params
paramok[82]=1; // MQTT Params paramok[82]=1; // MQTT Params
paramok[83]=1; // MQTT Params paramok[83]=1; // MQTT Params
paramok[84]=1; // MQTT Params paramok[84]=1; // MQTT Params
paramok[85]=1; // MQTT Params paramok[85]=1; // MQTT Params
paramok[86]=1; // L4Compress paramok[86]=1; // MQTT Params
paramok[87]=1; // L4Compress Maxframe paramok[87]=1; // L4Compress
paramok[88]=1; // L4Compress Paclen paramok[88]=1; // L4Compress Maxframe
paramok[89]=1; // L2Compress paramok[89]=1; // L4Compress Paclen
paramok[90]=1; // L2Compress Maxframe paramok[90]=1; // L2Compress
paramok[91]=1; // L2Compress Paclen paramok[91]=1; // L2Compress Maxframe
paramok[92]=1; // PREFERINP3ROUTES paramok[92]=1; // L2Compress Paclen
paramok[93]=1; // C_ONLYVer2point0 paramok[93]=1; // PREFERINP3ROUTES
paramok[94]=1; // ONLYVer2point0
paramok[95]=1; // DEBUGINP3
paramok[96]=1; // EnableOARCAPI
paramok[97]=1; // MONTOFILE
paramok[98]=1; // RIFInterval
for (i=0; i < PARAMLIM; i++) for (i=0; i < PARAMLIM; i++)
{ {
@ -642,7 +654,7 @@ BOOL ProcessConfig()
Consoleprintf("The following parameters were not correctly specified"); Consoleprintf("The following parameters were not correctly specified");
heading = 1; heading = 1;
} }
Consoleprintf(keywords[i]); Consoleprintf("%s", keywords[i]);
} }
} }
@ -1583,32 +1595,168 @@ int routes(int i)
// strtok and sscanf can't handle successive commas, so split up usig strchr // strtok and sscanf can't handle successive commas, so split up usig strchr
memset(Param, 0, 2048); // Now support keyword=value format
strlop(rec, 13);
strlop(rec, ';');
ptr1 = rec; if (strchr(rec, '='))
while (ptr1 && *ptr1 && n < 8)
{ {
ptr2 = strchr(ptr1, ','); // New format
if (ptr2) *ptr2++ = 0; // call quality port window frack paclen farquality inp3 nokeepalives tcp
strcpy(&Param[n++][0], ptr1); char * ptr, *context;
ptr1 = ptr2; char copy[512] = "";
while(ptr1 && *ptr1 && *ptr1 == ' ')
ptr1++; if (strlen(rec) < 512)
strcpy(copy, rec);
_strupr(rec);
ptr = strtok_s(rec, " ,=", &context);
while (ptr)
{
if (strcmp(ptr, "CALL") == 0)
{
char * Call = strtok_s(NULL, ",=", &context);
if (strlen(Call) < 80)
strcpy(Route->call, Call);
}
else if (strcmp(ptr, "PORT") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->port = atoi(val);
}
else if (strcmp(ptr, "QUALITY") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->quality = atoi(val);
}
else if (strcmp(ptr, "FRACK") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pfrack = atoi(val);
}
else if (strcmp(ptr, "PACLEN") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pwind = atoi(val);
}
else if (strcmp(ptr, "WINDOW") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->pwind = atoi(val);
}
else if (strcmp(ptr, "FARQUALITY") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->farQual = atoi(val);
}
else if (strcmp(ptr, "INP3") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->inp3 = atoi(val);
}
else if (strcmp(ptr, "NOKEEPALIVES") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->nokeepalives = atoi(val);
}
else if (strcmp(ptr, "NOV2.2") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
Route->noV2point2 = atoi(val);
}
else if (strcmp(ptr, "TCP") == 0)
{
char * val = strtok_s(NULL, " ,=", &context);
if (val)
{
char * port = strlop(val, ':');
Route->tcphost = _strdup(val);
if (port)
Route->tcpport = atoi(port);
else
Route->tcpport = 53119;
}
}
else
{
Consoleprintf("Bad Route %s\r\n",rec);
err_flag = 1;
break;
}
ptr = strtok_s(NULL, " ,=", &context);
}
} }
strcpy(Route->call, &Param[0][0]); else
{
Route->quality = atoi(Param[1]); memset(Param, 0, 2048);
Route->port = atoi(Param[2]); strlop(rec, 13);
Route->pwind = atoi(Param[3]); strlop(rec, ';');
Route->pfrack = atoi(Param[4]);
Route->ppacl = atoi(Param[5]); ptr1 = rec;
inp3 = atoi(Param[6]);
Route->farQual = atoi(Param[7]); while (ptr1 && *ptr1 && n < 8)
{
ptr2 = strchr(ptr1, ',');
if (ptr2) *ptr2++ = 0;
strcpy(&Param[n++][0], ptr1);
ptr1 = ptr2;
while(ptr1 && *ptr1 && *ptr1 == ' ')
ptr1++;
}
strcpy(Route->call, &Param[0][0]);
Route->quality = atoi(Param[1]);
Route->port = atoi(Param[2]);
Route->pwind = atoi(Param[3]);
Route->pfrack = atoi(Param[4]);
Route->ppacl = atoi(Param[5]);
inp3 = atoi(Param[6]);
Route->farQual = atoi(Param[7]);
if (inp3 & 1)
Route->inp3 = 1;
if (inp3 & 2)
Route->nokeepalives = 1;
}
if (Route->farQual < 0 || Route->farQual > 255) if (Route->farQual < 0 || Route->farQual > 255)
{ {
@ -1633,14 +1781,6 @@ int routes(int i)
err_flag = 1; err_flag = 1;
} }
// Use top bit of window as INP3 Flag, next as NoKeepAlive
if (inp3 & 1)
Route->pwind |= 0x80;
if (inp3 & 2)
Route->pwind |= 0x40;
if (err_flag == 1) if (err_flag == 1)
{ {
Consoleprintf("%s\r\n",rec); Consoleprintf("%s\r\n",rec);
@ -1694,6 +1834,7 @@ int ports(int i)
} }
xxp.SendtoM0LTEMap = 1; // Default to enabled xxp.SendtoM0LTEMap = 1; // Default to enabled
xxp.isRF = -1; // Default to undefined
while (endport == 0 && !feof(fp1)) while (endport == 0 && !feof(fp1))
{ {
@ -2939,13 +3080,39 @@ int simple(int i)
/* Set PARAMOK flags on all values that are defaulted */ /* Set PARAMOK flags on all values that are defaulted */
for (i=0; i < PARAMLIM; i++)
paramok[i]=1;
paramok[15] = 0; // Must have callsign paramok[15] = 0; // Must have callsign
paramok[45] = 0; // Dont Have Appl1Call paramok[45] = 0; // Dont Have Appl1Call
paramok[53] = 0; // or APPL1ALIAS paramok[53] = 0; // or APPL1ALIAS
// Set defined flag on defaulted params
paramok[0] = 1; // OBSINIT
paramok[1] = 1; // OBSMIN
paramok[2] = 1; // NODESINTERVAL
paramok[3] = 1; // L3TIMETOLIVE
paramok[4] = 1; // L4RETRIES
paramok[5] = 1; // L4TIMEOUT
paramok[7] = 1; // PACLEN
paramok[9] = 1; // T3
paramok[10] = 1; // IDLETIME
paramok[11] = 1; // BBS
paramok[12] = 1; // NODE
paramok[18] = 1; // IDMSG:
paramok[19] = 1; // INFOMSG:
paramok[22] = 1; // MAXLINKS
paramok[23] = 1; // MAXNODES
paramok[24] = 1; // MAXROUTES
paramok[25] = 1; // MAXCIRCUITS
paramok[26] = 1; // IDINTERVAL
paramok[27] = 1; // MINQUAL
paramok[28] = 1; // HIDENODES
paramok[29] = 1; // L4DELAY
paramok[30] = 1; // L4WINDOW
paramok[31] = 1; // BTINTERVAL
paramok[36] = 1; // CTEXT:
paramok[39] = 1; // ENABLE_LINKED
paramok[41] = 1; // FULL_CTEXT
return(1); return(1);
} }

View file

@ -82,6 +82,8 @@ struct PORTCONFIG
char * M0LTEMapInfo; char * M0LTEMapInfo;
int QtSMPort; int QtSMPort;
int AllowINP3; int AllowINP3;
int EnableINP3;
short isRF;
}; };
struct ROUTECONFIG struct ROUTECONFIG
@ -93,6 +95,11 @@ struct ROUTECONFIG
int pfrack; int pfrack;
int ppacl; int ppacl;
int farQual; int farQual;
int inp3;
int nokeepalives;
int noV2point2;
char * tcphost;
int tcpport;
}; };
struct CONFIGTABLE struct CONFIGTABLE
@ -179,6 +186,11 @@ struct CONFIGTABLE
int C_L2CompPaclen; int C_L2CompPaclen;
int C_PREFERINP3ROUTES; int C_PREFERINP3ROUTES;
int C_OnlyVer2point0; int C_OnlyVer2point0;
int C_DEBUGINP3;
int C_OARCAPI;
int C_MONTOFILE;
int C_RIFInterval;
//#define ApplOffset 80000 // Applications offset in config buffer //#define ApplOffset 80000 // Applications offset in config buffer

View file

@ -35,8 +35,11 @@ int RFOnly = 0;
int MAXRTT = 9000; // 90 secs int MAXRTT = 9000; // 90 secs
int MaxHops = 4; int MaxHops = 4;
int DEBUGINP3 = 0;
int RTTInterval = 24; // 4 Minutes int EnableOARCAPI = 0;
int RTTInterval = 30; // 10 second increments - 5 Minutes
BOOL IPRequired = FALSE; BOOL IPRequired = FALSE;
BOOL PMRequired = FALSE; BOOL PMRequired = FALSE;

11
debian/NEWS vendored Normal file
View file

@ -0,0 +1,11 @@
linbpq (6.0.24.22-2) unstable; urgency=medium
This is quite a big update, with config moving from /opt/oarc/bpq/bpq32.cfg to
/etc/bpq32.cfg. The system shall do this automatically for you, however
computers and their programmers are not perfect.
I strongly recommend at this point backing up your entire
/opt/oarc/bpq/ directory (cp -r /opt/oarc/bpq/ ~/bpq-backup/) before
proceeding with the upgrade
-- Dave Hibberd <d@vehibberd.com> Sat, 16 Dec 2023 13:30:06 +0000

23
debian/README.Debian vendored Normal file
View file

@ -0,0 +1,23 @@
README for linbpq on Debian
===========================
Please see https://wiki.oarc.uk/packet:linbpq-apt-installation for this guide
# Set config
Copy the config, edit it & set permissions.
The permissions are so linbpq web interface can edit the config.
sudo mv /usr/share/doc/linbpq/examples/bpq32.cfg /etc/bpq32.cfg
sudo nano /etc/bpq32.cfg
sudo chown :linbpq /etc/bpq32.cfg
sudo chmod 644 /etc/bpq32.cfg
# Start linbpq
sudo systemctl start linbpq
# Access your node
It shall be available by accessing http://localhost:8008 in the browser or telnet localhost 8010
-- Dave Hibberd <hibby@debian.org> Tue, 26 Mar 2024 00:53:42 +0000

50
debian/bpq32.cfg vendored Normal file
View file

@ -0,0 +1,50 @@
SIMPLE
NODECALL=MB7NAA
NODEALIAS=AANODE
LOCATOR=AA00aa
PASSWORD=xxxxxxxx
AUTOSAVE=1
NODESINTERVAL=10
MINQUAL=10
CTEXT:
Thanks for connecting.
Type ? for help.
***
PORT
PORTNUM=1
ID=VHF
TYPE=ASYNC
PROTOCOL=KISS
KISSOPTIONS=ACKMODE
COMPORT=/dev/ttyACM0
SPEED=57600
FRACK=4000
PACLEN=150
DIGIFLAG=0
QUALITY=192
MINQUAL=20
ENDPORT
PORT
PORTNUM=9
ID=Telnet
DRIVER=Telnet
CONFIG
LOGGING=1
CMS=1
DisconnectOnClose=1
SECURETELNET=1
TCPPORT=8010
FBBPORT=8011
HTTPPORT=8008
LOGINPROMPT=user:
PASSWORDPROMPT=password:
MAXSESSIONS=10
CTEXT=Thanks for connecting\n Enter ? for list of commands\n\n
USER=username,xxxxxxxx,m0aaa,,SYSOP
ENDPORT
LINCHAT
APPLICATION 2,CHAT,,MB7NAA-9,AACHAT,255

359
debian/changelog vendored Normal file
View file

@ -0,0 +1,359 @@
linbpq (6.0.25.15+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.15+repack
* Remove Patch for TelnetV6, fixed upstream
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Wed, 07 Jan 2026 21:53:20 +0000
linbpq (6.0.25.13+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* 6.0.25.12 hacky merge due t it not ffing.
* New upstream version 6.0.25.13+repack
* Patch TelnetV6 to build
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Tue, 23 Dec 2025 16:45:56 +0000
linbpq (6.0.25.12+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.12+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Sat, 22 Nov 2025 15:11:09 +0000
linbpq (6.0.25.11+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.11+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Tue, 11 Nov 2025 21:52:58 +0000
linbpq (6.0.25.9+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.9+repack
* Refresh patches
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Sun, 09 Nov 2025 22:45:07 +0000
linbpq (6.0.25.8+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* Build on latest gcc standards
* New upstream version 6.0.25.8+repack
* Refresh patches with gbp pq!
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Fri, 24 Oct 2025 00:45:16 +0100
linbpq (6.0.25.06+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.06+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Fri, 10 Oct 2025 23:42:04 +0100
linbpq (6.0.25.1+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.1+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Sat, 20 Sep 2025 15:43:32 +0100
linbpq (6.0.24.82+repack-1~hibbian13+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.24.82+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Sun, 17 Aug 2025 22:36:49 +0100
linbpq (6.0.24.78+repack-1~hibbian~TRIXIE+1) trixie-hibbian-unstable; urgency=medium
* New Upstream
* New files excluded
- No binaries in this release at all maybe!
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Thu, 31 Jul 2025 01:31:38 +0100
linbpq (6.0.24.77+repack-1~hibbian~TRIXIE+1) trixie-hibbian-unstable; urgency=medium
* New upstream version 6.0.24.77+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Tue, 22 Jul 2025 21:46:13 +0100
linbpq (6.0.24.75+repack-1~hibbian~TRIXIE+2) trixie-hibbian-unstable; urgency=medium
* First trixie release
* Drop hard-dep on hibbian-archive-keyring
-- Dave Hibberd <hibby@debian.org> Wed, 16 Jul 2025 19:10:33 +0100
linbpq (6.0.24.75+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream version 6.0.25.75+repack
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Tue, 15 Jul 2025 01:10:43 +0100
linbpq (6.0.24.71+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream version 6.0.24.67+repack
* New upstream version 6.0.24.69+repack
* New upstream version 6.0.24.69.1+repack
* New upstream version 6.0.24.71+repack
* Okay that's a lot of updates.
* Refreshed d/p/makefile to reflect new CFLAG
* MINI_BUILDD_OPTION: auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Wed, 21 May 2025 21:45:59 +0100
linbpq (6.0.24.66+repack-1~hibbian+2) bookworm-hibbian-unstable; urgency=medium
* Update postinst script to be a little quieter
* MINI_BUILDD_OPTION:
auto-ports=trixie-packetrepo-unstable,bookworm-packetrepo-unstable,bullseye-packetrepo-unstable,noble-packetrepo-unstable,jammy-packetrepo-unstable
-- Dave Hibberd <hibby@debian.org> Tue, 11 Mar 2025 00:51:35 +0000
linbpq (6.0.24.66+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream version 6.0.24.66+repack
-- Dave Hibberd <hibby@debian.org> Tue, 04 Mar 2025 22:50:09 +0000
linbpq (6.0.24.65+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream
-- Dave Hibberd <hibby@debian.org> Tue, 25 Feb 2025 09:33:24 +0000
linbpq (6.0.24.59a+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream
* Little tweaks to makefile patch to account for new -rdynamic
-- Dave Hibberd <hibby@debian.org> Mon, 03 Feb 2025 22:32:11 +0000
linbpq (6.0.24.56+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream
-- Dave Hibberd <hibby@debian.org> Mon, 06 Jan 2025 21:37:44 +0000
linbpq (6.0.24.55+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream
* d/rules
- Increased hardening
-- Dave Hibberd <hibby@debian.org> Sun, 05 Jan 2025 23:35:06 +0000
linbpq (6.0.24.54+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream
* Drop AGW Patch
* Drop Spelling Patch
* Drop Dynamic Links patch
-- Dave Hibberd <hibby@debian.org> Tue, 17 Dec 2024 16:46:05 +0000
linbpq (6.0.24.53+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream
- Patches refreshed
- dropped some edits in ftbfs-gcc14
- dropped d/patches/headers.patch
-- Dave Hibberd <hibby@debian.org> Tue, 03 Dec 2024 00:57:57 +0000
linbpq (6.0.24.52+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream
- Patches happy
-- Dave Hibberd <hibby@debian.org> Sat, 30 Nov 2024 21:47:17 +0000
linbpq (6.0.24.51.1+repack-1~hibbian+2) bookworm-hibbian-unstable; urgency=medium
* Iron out an issue with time...
-- Dave Hibberd <hibby@debian.org> Fri, 29 Nov 2024 19:57:28 +0000
linbpq (6.0.24.51.1+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream import after bug report
* Roll back some ftbfs-gcc14 edits
* Remove some more lib headers
-- Dave Hibberd <hibby@debian.org> Fri, 29 Nov 2024 19:30:22 +0000
linbpq (6.0.24.51+repack-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream import
- Patches refreshed
* Upstream is now repacked to include less files
* Big build system review, now using Debian CFLAGS and LDFLAGS
- Hardening enabled, mostly
- A debug symbols package is now available
* Oh yeah, everything is now dynamic linking
- libpng
- libpaho-mqtt
- libjansson
- libminiupnpc
-- Dave Hibberd <hibby@debian.org> Fri, 29 Nov 2024 13:08:38 +0000
linbpq (6.0.24.50-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream import
* Files excluded at origtargz generation time for cleanliness
-- Dave Hibberd <hibby@debian.org> Tue, 12 Nov 2024 21:56:38 +0000
linbpq (6.0.24.49-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New Upstream import
* Patches refreshed
* Add mqtt requirements
-- Dave Hibberd <hibby@debian.org> Tue, 05 Nov 2024 21:52:29 +0000
linbpq (6.0.24.45-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* New upstream import
* Patches refreshed
-- Dave Hibberd <hibby@debian.org> Fri, 11 Oct 2024 15:48:41 +0100
linbpq (6.0.24.42-1~hibbian+3) bookworm-hibbian-unstable; urgency=medium
* 32bit build error
- Patch updated to fix hopefully
-- Dave Hibberd <hibby@debian.org> Fri, 30 Aug 2024 12:21:57 +0100
linbpq (6.0.24.42-1~hibbian+2) bookworm-hibbian-unstable; urgency=medium
* Forgot to fix the ninotnc-smt issue, fixed now
-- Dave Hibberd <hibby@debian.org> Fri, 30 Aug 2024 12:05:54 +0100
linbpq (6.0.24.42-1~hibbian+1) bookworm-hibbian-unstable; urgency=medium
* Install config to /etc
* New upstream update
* Patches refreshed
* Debian hardening enabled
- 2 new patches created that touch almost every file
- Considered experimental.
- gcc14 builds for Debian Trixie!
-- Dave Hibberd <hibby@debian.org> Fri, 30 Aug 2024 10:15:11 +0100
linbpq (6.0.24.40-1) unstable; urgency=medium
* Fresh upstream release
- Patches refreshed
* Secure by default patch
-- Dave Hibberd <hibby@debian.org> Sun, 07 Jul 2024 16:09:28 +0100
linbpq (6.0.24.38-1) unstable; urgency=medium
* New Upstream
* Tweak config file per recommendation from 2M0MQN to make first start simple
* Bump standards to 4.7.0.0
-- Dave Hibberd <hibby@debian.org> Sun, 09 Jun 2024 22:38:40 +0100
linbpq (6.0.24.34-2) unstable; urgency=medium
* Fix config permissions bug as reported by Alex 2E1PKY
-- Dave Hibberd <hibby@debian.org> Mon, 08 Apr 2024 22:27:02 +0100
linbpq (6.0.24.34-1) unstable; urgency=medium
* Upstream bump
-- Dave Hibberd <hibby@debian.org> Sat, 06 Apr 2024 02:15:28 +0100
linbpq (6.0.24.33-1) unstable; urgency=medium
* Upstream bump
* Moved config file to examples
* Updated service to fail on no config
* Added helpful README.Debian
-- Dave Hibberd <hibby@debian.org> Tue, 26 Mar 2024 20:24:08 +0000
linbpq (6.0.24.30-1) unstable; urgency=medium
* Upstream bump
-- Dave Hibberd <hibby@debian.org> Fri, 23 Feb 2024 23:24:46 +0000
linbpq (6.0.24.29-1) unstable; urgency=medium
* Upstream bump
* Added my new details
* Tidied up some packaging errors
-- Dave Hibberd <hibby@debian.org> Tue, 13 Feb 2024 00:06:33 +0000
linbpq (6.0.24.27-2) unstable; urgency=medium
* Permissions fix for web-config-editor users
-- Dave Hibberd <d@vehibberd.com> Thu, 18 Jan 2024 10:31:56 +0000
linbpq (6.0.24.27-1) unstable; urgency=medium
* New Upstream Release
-- Dave Hibberd <d@vehibberd.com> Tue, 16 Jan 2024 20:51:43 +0000
linbpq (6.0.24.25-1) unstable; urgency=medium
* New Upstream Release
-- Dave Hibberd <d@vehibberd.com> Thu, 28 Dec 2023 10:44:47 +0000
linbpq (6.0.24.22-2) unstable; urgency=medium
* Moved config file home, caused chaos
-- Dave Hibberd <d@vehibberd.com> Sat, 16 Dec 2023 14:40:20 +0000
linbpq (6.0.24.22-1) unstable; urgency=medium
* New Upstream Release
-- Dave Hibberd <d@vehibberd.com> Fri, 08 Dec 2023 12:29:40 +0000
linbpq (6.0.24.16-1) unstable; urgency=medium
* New Upstream release
-- Dave Hibberd <d@vehibberd.com> Tue, 31 Oct 2023 22:50:01 +0000
linbpq (6.0.24.15-2) unstable; urgency=medium
* debian/conffiles introduced to stop linbpq overwriting config files
- Thanks to Mark 2M0IIG for raising concern about this bug!
-- Dave Hibberd <d@vehibberd.com> Sun, 15 Oct 2023 21:45:24 +0100
linbpq (6.0.24.15-1) unstable; urgency=medium
* New upstream release
-- Dave Hibberd <d@vehibberd.com> Tue, 10 Oct 2023 22:19:48 +0100
linbpq (6.0.24.2-1) unstable; urgency=medium
* Initial release.
-- Dave Hibberd <d@vehibberd.com> Mon, 28 Aug 2023 23:20:45 +0100

20
debian/control vendored Normal file
View file

@ -0,0 +1,20 @@
Source: linbpq
Section: hamradio
Priority: optional
Maintainer: Dave Hibberd <hibby@debian.org>
Standards-Version: 4.7.2
Vcs-Browser: https://git.hibbian.org/Hibbian/linbpq
Vcs-Git: https://git.hibbian.org/Hibbian/linbpq.git
Homepage: https://www.cantab.net/users/john.wiseman/Documents/
Build-Depends: debhelper-compat (= 13)
Build-Depends-Arch: libssl-dev, libminiupnpc-dev, libpcap-dev, libconfig-dev, zlib1g-dev, libpaho-mqtt-dev, libjansson-dev, libpng-dev
Rules-Requires-Root: no
Package: linbpq
Architecture: linux-any
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
Description: Packet node and ax25 stack
LINBPQ is a Linux version of the BPQ32 Node, BBS and Chat Server components.
It is actively developed by John G8BPQ and contains a complete, independent
implementation of ax.25 and net/rom as well as BBS and Chat applications and
can be used either as a packet switch or as a full featured node.

37
debian/copyright vendored Normal file
View file

@ -0,0 +1,37 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: linBPQ
Upstream-Contact: John Wiseman G8BPQ <john.wiseman@cantab.net>
Source: https://www.cantab.net/users/john.wiseman/Documents/
Files-Excluded: *.vcproj* *.bak *.lib *.dll *.wav *.asm *.vcxproj* *.pdb *.exe
.gitignore XAprs zlib.h zconf.h MQTT* pcap.h miniupnpc.h upnpdev.h
igd_desc_parse.h upnpcommands.h upnperrors.h miniupnpctypes.h
*.svn-base *.db *.obj
Files: *
Copyright: 1990-2025 John Wiseman G8BPQ <john.wiseman@cantab.net>
License: GPL-3
Files: debian/*
Copyright: 2016-2025 Dave Hibberd <d@vehibberd.com>
License: GPL-3
Files: debian/linbpq.service
Copyright: 2024-2025 Tom Fanning M0LTE
License: GPL-3
License: GPL-3
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 3 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, see <http://www.gnu.org/licenses/>.
.
The GPL License which applies to this package can be found on your Debian
system at /usr/share/common-licenses/GPL-3.

2
debian/dirs vendored Normal file
View file

@ -0,0 +1,2 @@
usr/sbin
opt/oarc/bpq

3
debian/gbp.conf vendored Normal file
View file

@ -0,0 +1,3 @@
[DEFAULT]
debian-branch = hibbian/latest
upstream-branch = upstream/latest

6
debian/gitlab-ci.yml vendored Normal file
View file

@ -0,0 +1,6 @@
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
reprotest:
extends: .test-reprotest-diffoscope

1
debian/install vendored Normal file
View file

@ -0,0 +1 @@
debian/bpq32.cfg etc/

1
debian/linbpq.examples vendored Normal file
View file

@ -0,0 +1 @@
debian/bpq32.cfg

14
debian/linbpq.service vendored Normal file
View file

@ -0,0 +1,14 @@
[Unit]
Description=Linbpq systemd service file
After=network.target
ConditionPathExists=/etc/bpq32.cfg
[Service]
ExecStart=/usr/sbin/linbpq -c /etc -d /opt/oarc/bpq -l /opt/oarc/bpq
WorkingDirectory=/opt/oarc/bpq
Restart=always
User=linbpq
Group=linbpq
[Install]
WantedBy=multi-user.target

11
debian/lintian-overrides vendored Normal file
View file

@ -0,0 +1,11 @@
# weirdness from oarc packaging
linbpq: dir-or-file-in-opt [opt/oarc/]
linbpq: dir-or-file-in-opt [opt/oarc/bpq/]
# i know!
linbpq: no-manual-page [usr/sbin/linbpq]
# Directory is populated on first run
linbpq: package-contains-empty-directory [opt/oarc/bpq/]
# Code convenience
linbpq: spelling-error-in-binary Dont Don't [usr/sbin/linbpq]
linbpq: spelling-error-in-binary Paramters Parameters [usr/sbin/linbpq]
linbpq: spelling-error-in-binary lon long [usr/sbin/linbpq]

57
debian/patches/makefile vendored Normal file
View file

@ -0,0 +1,57 @@
From: Dave Hibberd <hibby@debian.org>
Date: Sat, 20 Sep 2025 15:42:15 +0100
Subject: makefile
---
makefile | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/makefile b/makefile
index 26403e5..0f15cc0 100644
--- a/makefile
+++ b/makefile
@@ -2,8 +2,7 @@
# To exclude i2c support run make noi2c
-OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pngwutil.o\
- pngread.o pngwrite.o png.o pngerror.o pngget.o pngmem.o APRSIconData.o AISCommon.o\
+OBJS = APRSIconData.o AISCommon.o\
upnp.o APRSStdPages.o HSMODEM.o WinRPR.o KISSHF.o TNCEmulators.o bpqhdlc.o SerialPort.o\
adif.o WebMail.o utf8Routines.o VARA.o LzFind.o Alloc.o LzmaDec.o LzmaEnc.o LzmaLib.o \
Multicast.o ARDOP.o IPCode.o FLDigi.o linether.o CMSAuth.o APRSCode.o BPQtoAGW.o KAMPactor.o\
@@ -17,12 +16,12 @@ OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pn
# Configuration:
-#Default to Linux
- CC = gcc
- LDFLAGS = -Xlinker -Map=output.map -lrt
+CFLAGS:=$(shell dpkg-buildflags --get CFLAGS)
+CFLAGS+=$(shell dpkg-buildflags --get CPPFLAGS)
+LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS)
-all: CFLAGS = -DLINBPQ -MMD -g -fcommon -fasynchronous-unwind-tables $(EXTRA_CFLAGS)
-all: LIBS = -lpaho-mqtt3a -ljansson -lminiupnpc -lm -lz -lpthread -lconfig -lpcap
+all: CFLAGS += -DLINBPQ -MMD -g -rdynamic -fcommon -fasynchronous-unwind-tables
+all: LIBS = -lpaho-mqtt3a -ljansson -lminiupnpc -lrt -lm -lz -lpthread -lconfig -lpcap -lpng
all: linbpq
#other OS
@@ -74,12 +73,11 @@ noi2c: linbpq
linbpq: $(OBJS)
- cc $(OBJS) $(CFLAGS) $(LDFLAGS) $(LIBS) -o linbpq
- sudo setcap "CAP_NET_ADMIN=ep CAP_NET_RAW=ep CAP_NET_BIND_SERVICE=ep" linbpq
+ $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) $(LIBS) -o linbpq
-include *.d
-clean :
- rm *.d
- rm linbpq $(OBJS)
+install:
+ install -b -m 755 -D -d debian/linbpq/usr/sbin
+ install -b -m 755 -p linbpq debian/linbpq/usr/sbin

2
debian/patches/series vendored Normal file
View file

@ -0,0 +1,2 @@
spelling-fixes.patch
makefile

21
debian/patches/spelling-fixes.patch vendored Normal file
View file

@ -0,0 +1,21 @@
From: Dave Hibberd <hibby@debian.org>
Date: Sat, 20 Sep 2025 15:42:15 +0100
Subject: spelling-fixes
---
UZ7HODrv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/UZ7HODrv.c b/UZ7HODrv.c
index 2adfe12..75e40ee 100644
--- a/UZ7HODrv.c
+++ b/UZ7HODrv.c
@@ -387,7 +387,7 @@ int UZ7HOSetFreq(int port, struct TNCINFO * TNC, struct AGWINFO * AGW, PDATAMESS
if (AGW->CenterFreq == 0)
{
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
return 1;
}

47
debian/postinst vendored Normal file
View file

@ -0,0 +1,47 @@
#!/bin/sh
set -e
if [ "$1" = configure ]; then
# if ! getent group linbpq >/dev/null; then
# addgroup --system --force-badname linbpq || true
# fi
echo "Creating/updating linbpq user account..."
adduser --system --group --home /opt/oarc/bpq \
--gecos "linbpq system user" --shell /bin/false \
--quiet --disabled-password linbpq || {
# adduser failed. Why?
if getent passwd linbpq >/dev/null ; then
echo "Non-system user linbpq found. I will not overwrite a non-system" >&2
echo "user. Remove the user and reinstall linbpq." >&2
exit 1
fi
# unknown adduser error, simply exit
exit 1
}
if ! id -nGz linbpq | grep -qzxF 'dialout' ; then
adduser linbpq dialout
fi
if ! id -nGz linbpq | grep -qzxF 'plugdev' ; then
adduser linbpq plugdev
fi
chown :linbpq /opt/oarc/bpq
chmod 775 /opt/oarc/bpq
# If we have setcap is installed, set the requirements
# which allows us to install our binaries without the setuid
# bit.
if command -v setcap > /dev/null; then
setcap "CAP_NET_ADMIN=ep CAP_NET_RAW=ep CAP_NET_BIND_SERVICE=ep" /usr/sbin/linbpq
else
echo "Setcap failed on /usr/sbin/linbpq, Features may be limited" >&2
fi
else
echo "Setcap is not installed, Features may be limited" >&2
fi
#DEBHELPER#

14
debian/preinst vendored Normal file
View file

@ -0,0 +1,14 @@
#!/bin/sh
set -e
confile="/etc/bpq32.cfg"
node="/opt/oarc/bpq/bpq32.cfg"
if [ -L $confile ]; then
rm $confile
cp $node $confile
mv $node $node.bak
fi
#DEBHELPER#

6
debian/rules vendored Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/make -f
export DEB_BUILD_MAINT_OPTIONS=hardening=+all
%:
dh $@

1
debian/source/format vendored Normal file
View file

@ -0,0 +1 @@
3.0 (quilt)

0
debian/source/include-binaries vendored Normal file
View file

0
debian/source/lintian-overrides vendored Normal file
View file

3
debian/watch vendored Normal file
View file

@ -0,0 +1,3 @@
version=4
opts="pgpmode=none,dversionmangle=s/\+repack//,repacksuffix=+repack,repack,compression=xz" \
http://127.0.0.1:8000/linbpq-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))

View file

@ -78,6 +78,8 @@ typedef struct _ETHARP
UCHAR TARGETHWADDR[6]; UCHAR TARGETHWADDR[6];
uint32_t TARGETIPADDR; uint32_t TARGETIPADDR;
char Padding[18]; // For min ether send of 60
} ETHARP, *PETHARP; } ETHARP, *PETHARP;
typedef struct _RIP2HDDR typedef struct _RIP2HDDR

10
kiss.c
View file

@ -1905,7 +1905,7 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO)
// KISS Over TCP Routines // KISS Over TCP Routines
VOID ConnecttoTCPThread(NPASYINFO ASY); VOID ConnecttoTCPThread(void * Param);
int ConnecttoTCP(NPASYINFO ASY) int ConnecttoTCP(NPASYINFO ASY)
{ {
@ -1914,8 +1914,9 @@ int ConnecttoTCP(NPASYINFO ASY)
return 0; return 0;
} }
VOID ConnecttoTCPThread(NPASYINFO ASY) VOID ConnecttoTCPThread(void * Param)
{ {
NPASYINFO ASY = (NPASYINFO)Param;
char Msg[255]; char Msg[255];
int err,i; int err,i;
u_long param=1; u_long param=1;
@ -2131,7 +2132,7 @@ int KISSGetTCPMessage(NPASYINFO ASY)
// Interface to QtSM Managmemt Interface // Interface to QtSM Managmemt Interface
VOID QtSMThread(struct PORTCONTROL * PORT); VOID QtSMThread(void * Param);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT) VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
{ {
@ -2141,11 +2142,12 @@ VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
return ; return ;
} }
VOID QtSMThread(struct PORTCONTROL * PORT) VOID QtSMThread(void * Param)
{ {
// This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq. // This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq.
// Also will collect link usage stats // Also will collect link usage stats
struct PORTCONTROL * PORT = (struct PORTCONTROL *)Param;
char Msg[255]; char Msg[255];
int err, i, ret; int err, i, ret;
u_long param = 1; u_long param = 1;

150
lzhuf32.c
View file

@ -487,124 +487,124 @@ static void reconst(void)
static void update(int c) static void update(int c)
{ {
int i, j, l; int i, j, l;
unsigned int k; unsigned int k;
if (freq[R] == MAX_FREQ) { if (freq[R] == MAX_FREQ) {
reconst(); reconst();
} }
c = prnt[c + T]; c = prnt[c + T];
do { do {
k = ++freq[c]; k = ++freq[c];
/* if the order is disturbed, exchange nodes */ /* if the order is disturbed, exchange nodes */
l = c + 1; l = c + 1;
if ((unsigned)k > freq[l]) if ((unsigned)k > freq[l])
{ {
while ((unsigned)k > freq[++l]); while ((unsigned)k > freq[++l]);
l--; l--;
freq[c] = freq[l]; freq[c] = freq[l];
freq[l] = k; freq[l] = k;
i = son[c]; i = son[c];
prnt[i] = l; prnt[i] = l;
if (i < T) prnt[i + 1] = l; if (i < T) prnt[i + 1] = l;
j = son[l]; j = son[l];
son[l] = i; son[l] = i;
prnt[j] = c; prnt[j] = c;
if (j < T) prnt[j + 1] = c; if (j < T) prnt[j + 1] = c;
son[c] = j; son[c] = j;
c = l; c = l;
} }
} while ((c = prnt[c]) != 0); /* repeat up to root */ } while ((c = prnt[c]) != 0); /* repeat up to root */
} }
unsigned code, len; unsigned code, len;
static void EncodeChar(unsigned int c) static void EncodeChar(unsigned int c)
{ {
unsigned int i; unsigned int i;
int j, k; int j, k;
i = 0; i = 0;
j = 0; j = 0;
k = prnt[c + T]; k = prnt[c + T];
/* travel from leaf to root */ /* travel from leaf to root */
do { do {
i >>= 1; i >>= 1;
/* if node's address is odd-numbered, choose bigger brother node */ /* if node's address is odd-numbered, choose bigger brother node */
if (k & 1) i += 0x8000; if (k & 1) i += 0x8000;
j++; j++;
} while ((k = prnt[k]) != R); } while ((k = prnt[k]) != R);
Putcode(j, i); Putcode(j, i);
code = i; code = i;
len = j; len = j;
update(c); update(c);
} }
static void EncodePosition(unsigned int c) static void EncodePosition(unsigned int c)
{ {
unsigned int i; unsigned int i;
/* output upper 6 bits by table lookup */ /* output upper 6 bits by table lookup */
i = c >> 6; i = c >> 6;
Putcode(p_len[i], (unsigned)p_code[i] << 8); Putcode(p_len[i], (unsigned)p_code[i] << 8);
/* output lower 6 bits verbatim */ /* output lower 6 bits verbatim */
Putcode(6, (c & 0x3f) << 10); Putcode(6, (c & 0x3f) << 10);
} }
static void EncodeEnd(void) static void EncodeEnd(void)
{ {
if (putlen) { if (putlen) {
if (crc_fputc(putbuf >> 8) == EOF) { if (crc_fputc(putbuf >> 8) == EOF) {
Error(wterr); Error(wterr);
} }
codesize++; codesize++;
} }
} }
int DecodeChar(void) int DecodeChar(void)
{ {
unsigned int c; unsigned int c;
c = son[R]; c = son[R];
/* travel from root to leaf, */ /* travel from root to leaf, */
/* choosing the smaller child node (son[]) if the read bit is 0, */ /* choosing the smaller child node (son[]) if the read bit is 0, */
/* the bigger (son[]+1} if 1 */ /* the bigger (son[]+1} if 1 */
while (c < T) { while (c < T) {
c += GetBit(); c += GetBit();
c = son[c]; c = son[c];
} }
c -= T; c -= T;
update(c); update(c);
return (int)c; return (int)c;
} }
int DecodePosition(void) int DecodePosition(void)
{ {
unsigned int i, j, c; unsigned int i, j, c;
/* recover upper 6 bits from table */ /* recover upper 6 bits from table */
i = GetByte(); i = GetByte();
c = (unsigned)d_code[i] << 6; c = (unsigned)d_code[i] << 6;
j = d_len[i]; j = d_len[i];
/* read lower 6 bits verbatim */ /* read lower 6 bits verbatim */
j -= 2; j -= 2;
while (j--) { while (j--) {
i = (i << 1) + GetBit(); i = (i << 1) + GetBit();
} }
return (int)(c | (i & 0x3f)); return (int)(c | (i & 0x3f));
} }
/* compression */ /* compression */

View file

@ -852,14 +852,14 @@ double LatFromLOC = 0;
double LonFromLOC = 0; double LonFromLOC = 0;
#endif #endif
void SendBBSDataToPktMapThread(); void SendBBSDataToPktMapThread(void * Param);
void SendBBSDataToPktMap() void SendBBSDataToPktMap()
{ {
_beginthread(SendBBSDataToPktMapThread, 0, 0); _beginthread(SendBBSDataToPktMapThread, 0, 0);
} }
void SendBBSDataToPktMapThread() void SendBBSDataToPktMapThread(void * Param)
{ {
char Request[64]; char Request[64];
char * Params; char * Params;

View file

@ -13,7 +13,7 @@ OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pn
MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \ MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \
NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \ NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \
SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \ SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o RHP.o DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o RHP.o NETROMTCP.o
# Configuration: # Configuration:

204
nodeapi.c
View file

@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "tncinfo.h" #include "tncinfo.h"
#include "asmstrucs.h" #include "asmstrucs.h"
#include "telnetserver.h"
#include "kiss.h" #include "kiss.h"
// Constants // Constants
@ -56,6 +57,7 @@ int sendUserList(char * response, char * token, char * Rest, int Local);
int sendInfo(char * response, char * token, char * Rest, int Local); int sendInfo(char * response, char * token, char * Rest, int Local);
int sendLinks(char * response, char * token, char * Rest, int Local); int sendLinks(char * response, char * token, char * Rest, int Local);
int sendPortMHList(char * response, char * token, char * Rest, int Local); int sendPortMHList(char * response, char * token, char * Rest, int Local);
int sendPortQState(char * response, char * token, char * Rest, int Local);
int sendWhatsPacState(char * response, char * token, char * param, int Local); int sendWhatsPacState(char * response, char * token, char * param, int Local);
int sendWhatsPacConfig(char * response, char * token, char * param, int Local); int sendWhatsPacConfig(char * response, char * token, char * param, int Local);
@ -74,6 +76,7 @@ struct API APIList[] =
"/api/links", 10, sendLinks, 0, "/api/links", 10, sendLinks, 0,
"/api/users", 10, sendUserList, 0, "/api/users", 10, sendUserList, 0,
"/api/mheard", 11, sendPortMHList, 0, "/api/mheard", 11, sendPortMHList, 0,
"/api/tcpqueues", 14, sendPortQState, 0,
"/api/v1/config", 14, sendWhatsPacConfig, AuthSysop, "/api/v1/config", 14, sendWhatsPacConfig, AuthSysop,
"/api/v1/state", 13, sendWhatsPacState, AuthSysop "/api/v1/state", 13, sendWhatsPacState, AuthSysop
}; };
@ -799,37 +802,192 @@ int sendLinks(char * response, char * token, char * param, int Local)
int sendPortMHList(char * response, char * token, char * param, int Local) int sendPortMHList(char * response, char * token, char * param, int Local)
{ {
struct PORTCONTROL * PORTVEC ; struct PORTCONTROL * PORTVEC ;
int n; int n;
int port = 0; int port = 0;
if (param[0] = '?' || param[0] == '/') if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]); port = atoi(&param[1]);
PORTVEC = GetPortTableEntryFromPortNum(port); PORTVEC = GetPortTableEntryFromPortNum(port);
response[0] = 0; response[0] = 0;
if (PORTVEC == 0) if (PORTVEC == 0)
return send_http_response(response, "401 Invalid API Call"); return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"mheard\":[\r\n"); n = sprintf(response,"{\"mheard\":[\r\n");
BuildPortMH(&response[n], PORTVEC ); BuildPortMH(&response[n], PORTVEC );
if (response[n] == 0) // No entries if (response[n] == 0) // No entries
{ {
response[strlen(response) - 2] = '\0'; // remove \r\n response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n"); strcat(response, "]}\r\n");
} }
else else
{ {
response[strlen(response)-3 ] = '\0'; // remove ,\r\n response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n"); strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response); // printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
} }
return strlen(response);
return strlen(response);
} }
int sendPortQState(char * response, char * token, char * param, int Local)
{
struct TNCINFO * TNC;
struct TCPINFO * TCP;
struct ConnectionInfo * Conn;
struct STREAMINFO * STREAM;
int Stream;
int tcpqueue;
int Queued;
int n;
int port = 0;
char Type[10];
char Appl[20];
int radioport = 0;
if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]);
TNC = TNCInfo[port];
// At the moment only supports Telnet Ports
if (TNC == 0 || TNC->Hardware != H_TELNET)
return send_http_response(response, "401 Invalid API Call");
response[0] = 0;
TCP = TNC->TCPInfo;
if (TCP == 0)
return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"QState\":[\r\n");
for (Stream = 0; Stream <= TCP->MaxSessions; Stream++)
{
char Call[10];
STREAM = &TNC->Streams[Stream];
Conn = TNC->Streams[Stream].ConnectionInfo;
// if connected to the node
if (Conn->SocketActive)
{
TRANSPORTENTRY * Sess1 = TNC->PortRecord->ATTACHEDSESSIONS[Stream];
TRANSPORTENTRY * Sess2 = NULL;
if (Sess1)
Sess2 = Sess1->L4CROSSLINK;
else
continue;
radioport = 0;
// Can't use TXCount - it is Semaphored=
Queued = C_Q_COUNT(&TNC->Streams[Stream].PACTORtoBPQ_Q);
Queued += C_Q_COUNT((UINT *)&TNC->PortRecord->PORTCONTROL.PORTRX_Q);
if (Sess2)
Queued += CountFramesQueuedOnSession(Sess2);
if (Sess1)
Queued += CountFramesQueuedOnSession(Sess1);
// CountFramesQueuedOnSession(TRANSPORTENTRY * Session)
tcpqueue = Conn->FromHostBuffPutptr - Conn->FromHostBuffGetptr;
if (Sess2)
Sess1 = Sess2;
Call[ConvFromAX25(Sess1->L4USER, Call)] = 0;
if (Sess1->L4CIRCUITTYPE & BPQHOST)
strcpy(Type, "Host");
else if (Sess1->L4CIRCUITTYPE & SESSION)
{
struct DEST_LIST * DEST = Sess1->L4TARGET.DEST;
strcpy(Type, "NETROM");
if (DEST)
{
int ActiveRoute = DEST->DEST_ROUTE;
if (ActiveRoute)
{
struct ROUTE * ROUTE = DEST->NRROUTE[ActiveRoute - 1].ROUT_NEIGHBOUR;
if (ROUTE)
{
struct _LINKTABLE * LINK = ROUTE->NEIGHBOUR_LINK;
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
}
}
}
else if (Sess1->L4CIRCUITTYPE & PACTOR)
{
// PACTOR Type - Frames are queued on the Port Entry
struct PORTCONTROL * PORT = Sess1->L4TARGET.PORT;
strcpy(Type, "HFLINK");
if (PORT)
radioport = PORT->PORTNUMBER;
}
else
{
struct _LINKTABLE * LINK = Sess1->L4TARGET.LINK;
strcpy(Type, "L2 Link");
if (LINK && LINK->LINKPORT)
radioport = LINK->LINKPORT->PORTNUMBER;
}
memcpy(Appl, Sess1->APPL, 16);
strlop(Appl, ' ');
n += sprintf(&response[n], "{\"APPL\": \"%s\", \"callSign\": \"%s\", \"type\": \"%s\", \"tcpqueue\": %d, \"packets\": %d, \"port\": %d},\r\n" , Appl, Call, Type, tcpqueue, Queued, radioport);
}
}
if (n < 20) // No entries
{
response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n");
}
else
{
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
}
return strlen(response);
}
// WhatsPac configuration interface // WhatsPac configuration interface
// WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module // WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module

View file

@ -350,10 +350,11 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
comp->output_ptr[i]=NULL; comp->output_ptr[i]=NULL;
} }
if (comp->max_output_ptr != 0) if (comp->max_output_ptr != 0)
png_free(png_ptr, comp->output_ptr); png_free(png_ptr, comp->output_ptr);
comp->output_ptr=NULL; comp->output_ptr=NULL;
/* write anything left in zbuf */ /* write anything left in zbuf */
if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
png_write_chunk_data(png_ptr, png_ptr->zbuf, png_write_chunk_data(png_ptr, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out); png_ptr->zbuf_size - png_ptr->zstream.avail_out);

View file

@ -38,6 +38,7 @@ struct ConnectionInfo
BOOL SyncMode; // RMS Relay Sync BOOL SyncMode; // RMS Relay Sync
BOOL HTTPMode; // HTTP Server BOOL HTTPMode; // HTTP Server
BOOL APIMode; // REST API Server BOOL APIMode; // REST API Server
BOOL NETROMMode;
BOOL TriMode; // Trimode emulation BOOL TriMode; // Trimode emulation
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
SOCKET TriModeDataSock; // Data Socket SOCKET TriModeDataSock; // Data Socket
@ -65,6 +66,7 @@ struct ConnectionInfo
char Signon[100]; // User/Pass/Appl for Outgoing Connects char Signon[100]; // User/Pass/Appl for Outgoing Connects
BOOL Keepalive; // For HOST (esp CCC) Keepalives BOOL Keepalive; // For HOST (esp CCC) Keepalives
time_t LastSendTime; time_t LastSendTime;
time_t LastReceiveTime;
BOOL NoCallsign; // Don't Send Callsign to host if no Signon BOOL NoCallsign; // Don't Send Callsign to host if no Signon
UCHAR * ResendBuffer; // Used if send() returns EWOULDBLOCK UCHAR * ResendBuffer; // Used if send() returns EWOULDBLOCK
int ResendLen; // Len to resend int ResendLen; // Len to resend
@ -73,6 +75,9 @@ struct ConnectionInfo
int WebSocks; int WebSocks;
char WebURL[32]; // URL for WebSocket Connection char WebURL[32]; // URL for WebSocket Connection
int WebSecure; // Set if secure session int WebSecure; // Set if secure session
int Connecting; // For outward connect
int Connected;
}; };

View file

@ -116,6 +116,7 @@ struct TCPINFO
int SNMPPort; int SNMPPort;
int DRATSPort; int DRATSPort;
int CMDPort[33]; int CMDPort[33];
int NETROMPort;
char RELAYHOST[64]; char RELAYHOST[64];
char CMSServer[64]; char CMSServer[64];
BOOL FallbacktoRelay; // Use Relsy if can't connect to CMS BOOL FallbacktoRelay; // Use Relsy if can't connect to CMS
@ -160,13 +161,14 @@ struct TCPINFO
SOCKET TCPSock; SOCKET TCPSock;
SOCKET FBBsock[100]; SOCKET FBBsock[100];
SOCKET Relaysock; SOCKET Relaysock;
SOCKET HTTPsock; SOCKET HTTPSock;
SOCKET APIsock; SOCKET APIsock;
SOCKET TriModeSock; SOCKET TriModeSock;
SOCKET TriModeDataSock; SOCKET TriModeDataSock;
SOCKET Syncsock; SOCKET Syncsock;
SOCKET DRATSsock; SOCKET DRATSsock;
SOCKET SNMPsock; SOCKET SNMPsock;
SOCKET NETROMSock;
struct ConnectionInfo * TriModeControlSession; struct ConnectionInfo * TriModeControlSession;
SOCKET sock6; SOCKET sock6;
@ -176,6 +178,7 @@ struct TCPINFO
SOCKET APIsock6; SOCKET APIsock6;
SOCKET Syncsock6; SOCKET Syncsock6;
SOCKET DRATSsock6; SOCKET DRATSsock6;
SOCKET NETROMSock6;
fd_set ListenSet; fd_set ListenSet;
SOCKET maxsock; SOCKET maxsock;