Compare commits

...

401 Commits

Author SHA1 Message Date
Jonathan Naylor d0638f1f38
Merge pull request #483 from n7eal/patch-1
Update P25Hosts.txt
2024-02-17 17:51:17 +00:00
Jonathan Naylor 4f89e78549
Merge pull request #482 from k7pws/patch-6
Update P25Hosts.txt
2024-02-17 17:50:56 +00:00
n7eal f09db16f9b
Update P25Hosts.txt
added 7573
2024-02-16 23:08:14 -08:00
k7pws f3cc0a2d3a
Update P25Hosts.txt
Updated 31490 with new DNS and Port information.
2024-02-16 22:27:11 -07:00
Jonathan Naylor 9cabcecc89
Update P25Hosts.txt 2024-02-06 15:27:27 +00:00
Jonathan Naylor 486455c643
Update P25Hosts.txt 2024-02-06 15:00:46 +00:00
Jonathan Naylor 30879a0f04 Re-add IPv4 and IPv6 capabilities to the P25 network. 2024-01-29 19:46:47 +00:00
Jonathan Naylor 7c38895c01 Remove unneeded define. 2024-01-29 16:16:29 +00:00
Jonathan Naylor d82a7b9435 Simplify the UDP socket handling. 2024-01-29 16:12:41 +00:00
Jonathan Naylor 968e33740b
Merge pull request #478 from bduck014/patch-1
P25Hosts.txt
2024-01-18 18:28:47 +00:00
bduck014 77bffe88ad
P25Hosts.txt 2024-01-18 11:19:01 -06:00
bduck014 b1218dbc19
Update P25Hosts.txt
added new reflectors
2024-01-16 21:27:46 -06:00
Jonathan Naylor ec6fe93611
Update P25Hosts.txt 2024-01-12 12:38:49 +00:00
Jonathan Naylor cb8e757ada
Merge pull request #476 from KN4KNG/master
Update P25Hosts.txt
2024-01-06 19:32:21 +00:00
Alex Bowman 5bafa7fd95
Update P25Hosts.txt
Change KN4KNG Network and TAC Channels from FQDN to IPV4 addresses due to IPV6 conflicts.
2024-01-06 10:10:12 -05:00
Jonathan Naylor a8e242a598
Merge pull request #475 from maq1017/patch-1
Update P25Hosts.txt
2024-01-02 14:03:09 +00:00
Jonathan Naylor 9f96725981
Merge pull request #473 from kc1awv/patch-1
Update P25Hosts.txt
2024-01-02 14:02:44 +00:00
maq1017 a2798ad7c0
Update P25Hosts.txt
Updated 841 hostname
2023-12-30 16:56:03 +00:00
Steve Miller 06d2ee959c
Update P25Hosts.txt
Add URFM17 P25 reflector
2023-12-12 16:42:12 -05:00
Jonathan Naylor 29c68240fd
Merge pull request #472 from KN4KNG/master
Update P25Hosts.txt
2023-12-07 17:55:55 +00:00
Alex Bowman fc32920d30
Update P25Hosts.txt
Added TAC1, TAC2 TAC3 to KN4KNG Network for 27566 27567 27568
Updated FQDN from IP for kn4kng.com
2023-12-07 12:54:23 -05:00
Jonathan Naylor b10a554b0b
Merge pull request #471 from KN4KNG/master
Update P25Hosts.txt
2023-12-07 15:25:21 +00:00
Alex Bowman 3183f67d1c
Update P25Hosts.txt
add 304 for W8ARA P25
2023-12-07 08:58:24 -05:00
Jonathan Naylor 38d6777b16
Merge pull request #470 from PU5SMS/patch-1
Update P25Hosts.txt
2023-11-28 16:48:20 +00:00
PU5SMS 803b85887b
Update P25Hosts.txt
Request to add to P25 reflector list.
2023-11-28 12:15:29 -03:00
Jonathan Naylor e642ac05cc
Merge pull request #467 from mfiscus/kk7mnz/add-848
Add 848
2023-11-20 16:44:51 +00:00
Matt Fiscus f215fe4256
Updated 848 naming format in P25Hosts.txt 2023-11-20 09:42:40 -07:00
mfiscus 23ac7862d3 Update P25Hosts.txt 2023-11-19 14:51:14 -07:00
Jonathan Naylor 79c8e1749f
Update P25Hosts.txt 2023-11-14 14:56:43 +00:00
Jonathan Naylor ca951356a1
Merge pull request #466 from ds5qdr/master
Update P25Hosts.txt
2023-11-14 14:53:55 +00:00
Jonathan Naylor d966674fd1
Merge pull request #465 from M0JGX/patch-3
Update P25Hosts.txt
2023-11-14 10:38:38 +00:00
M0JGX 2740482618
Update P25Hosts.txt
Updated the description for 235 and added 23556 as a UK wide multimode on the DVSPH system
2023-11-13 17:48:38 +00:00
Heonmin Lee cebdbf136e
Update P25Hosts.txt
add 45001
2023-11-13 00:03:45 +09:00
Jonathan Naylor c44877a788
Update P25Hosts.txt 2023-11-01 11:59:12 +00:00
Jonathan Naylor 0ec79c3ddd
Update P25Hosts.txt 2023-11-01 11:57:47 +00:00
Jonathan Naylor fac3e3740f
Merge pull request #464 from ke8ane/patch-3
Update P25Hosts.txt
2023-11-01 11:56:20 +00:00
ke8ane 02cc5efe5d
Update P25Hosts.txt 2023-10-31 23:07:11 -04:00
Jonathan Naylor aabcf022c6
Merge pull request #461 from rowlc/patch-1
Patch 1
2023-10-16 15:18:50 +01:00
Chris Rowland 124b852a16
Update P25Hosts.txt 2023-10-16 19:41:37 +11:00
Chris Rowland a6fe4a16dd
Update P25Hosts.txt
New reflector
2023-10-16 17:50:52 +11:00
Jonathan Naylor 7a99bb1673
Merge pull request #459 from dl9cma/patch-1 2023-10-09 09:39:38 +01:00
dl9cma c342ce856b
Update P25Hosts.txt 2023-10-09 10:16:20 +02:00
Jonathan Naylor e73e585049
Merge pull request #458 from yl3im/master
Update the address of 43715 reflector.
2023-10-08 17:35:08 +01:00
Inga Muste 66a2bc7b5b Update the address of 43715 reflector. 2023-10-08 16:42:45 +03:00
Inga Muste 5ba0c3d73d
Merge pull request #2 from g4klx/master
Merge from upstream
2023-10-08 16:41:27 +03:00
Jonathan Naylor a459aa35d8
Update P25Hosts.txt 2023-10-02 14:54:50 +01:00
Jonathan Naylor dbdf56dbda
Merge pull request #457 from hp3icc/master
Update P25Hosts.txt
2023-10-02 14:53:52 +01:00
Esteban Mackay Q f543f2de05 Update P25Hosts.txt
add new reflector 7144 , Chiriqui Link Panama
2023-10-01 12:02:16 -05:00
Jonathan Naylor 19363eb9cb
Merge pull request #455 from mfiscus/847-update-url
Update P25Hosts.txt update 847 URL
2023-09-27 09:50:21 +01:00
mfiscus 09e6ac1949 Update P25Hosts.txt 2023-09-26 18:10:55 -07:00
Jonathan Naylor 80a9a3ce07
Update P25Hosts.txt 2023-09-26 13:56:41 +01:00
Jonathan Naylor 93e5778e21
Merge pull request #451 from modernham/patch-1
Add 946 FATS P25 Reflector
2023-09-26 13:55:05 +01:00
Jonathan Naylor 46a1ed4648
Merge pull request #454 from W2GLD/patch-4
Update P25Hosts.txt
2023-09-26 13:54:25 +01:00
Jonathan Naylor 4516ef92cf
Update P25Hosts.txt 2023-09-26 13:54:08 +01:00
W2GLD 6d36479868
Update P25Hosts.txt
Removed reflector that is no longer in-service #31266
2023-09-23 15:40:59 -04:00
Jonathan Naylor 048907c5c7
Merge pull request #453 from hb9fef/patch-4 2023-09-15 20:01:32 +01:00
hb9fef 3597fb3290
Update P25Hosts.txt
added TG 228 Switzerland reflector
2023-09-15 15:06:29 +02:00
modernham 136d3c6def
Add 946 FATS P25 Reflector
Added #946, for the Flag and torch Society P25 Reflector
2023-09-09 22:35:26 -05:00
Jonathan Naylor 4b284b8be3
Merge pull request #449 from yl3im/master
Change host for 43715.
2023-09-06 16:25:11 +01:00
Inga Muste d549b1832c Change host for 43715. 2023-09-06 15:38:55 +03:00
Inga Muste 0f6503b734
Merge pull request #1 from g4klx/master
Merge rom upstream.
2023-09-06 15:36:49 +03:00
Jonathan Naylor e607742ee3
Merge pull request #448 from M0JGX/patch-2 2023-09-05 13:40:12 +01:00
M0JGX 8b1fc4ec93
Update P25Hosts.txt 2023-09-05 10:46:07 +01:00
Jonathan Naylor 429fc13290
Merge pull request #447 from bg8ioi/patch-2
Update P25Hosts.txt
2023-08-27 14:37:26 +01:00
Jonathan Naylor 3702b95467
Merge pull request #446 from k0mgs/patch-2
Update P25Hosts.txt
2023-08-27 14:36:59 +01:00
Jonathan Naylor cccf421a07
Merge pull request #445 from wb6zsu/patch-1
Update P25Hosts.txt
2023-08-27 14:36:30 +01:00
bg8ioi dd2e8335f3
Update P25Hosts.txt
# 46023 P25 Link TG46023 bridge to BM TG46023, Chongqing, China
46023	119.3.248.195	41000
2023-08-27 13:32:50 +08:00
k0mgs 1b374cf412
Update P25Hosts.txt
Added 31291, 31297, and 31947
2023-08-26 22:08:31 -05:00
wb6zsu 0ba10e2ba6
Update P25Hosts.txt
Adding Arizona 900 P25 Reflector 10207
2023-08-26 12:11:01 -07:00
Jonathan Naylor 48540dd7be
Merge pull request #443 from mfiscus/master
Add 847
2023-08-20 13:35:21 +01:00
mfiscus 4e14c2c1c3 Update P25Hosts.txt 2023-08-20 00:53:15 -07:00
Jonathan Naylor 9ed5f4af16
Merge pull request #442 from jessebrownfl/master-1 2023-08-19 12:31:11 +01:00
Jesse Brown c050e51c88
Update P25Hosts.txt - Add 164 K4FSG
Adding talk group 164 - K4FSG to P25Hosts.txt for Florida Simulcast Group's Reflector
2023-08-18 20:45:13 -04:00
Jonathan Naylor fcb4271faf
Update P25Hosts.txt 2023-08-11 20:11:43 +01:00
Jonathan Naylor f31fba111d
Merge pull request #441 from vk7hse/master-1
Update P25Hosts.txt
2023-08-04 14:29:45 +01:00
Scott Evans 6e4ebfd18e
Update P25Hosts.txt
Remove 10444 as it's no longer in service
2023-08-04 12:59:15 +10:00
Jonathan Naylor b77d1997a1
Merge pull request #440 from tacoded/patch-1
Update P25Hosts.txt
2023-07-30 14:04:38 +01:00
Brock 77eabf8358
Update P25Hosts.txt 2023-07-29 22:52:22 -04:00
Jonathan Naylor 5554ccac12
Merge pull request #438 from ncerreto/patch-4
Update P25Hosts.txt
2023-07-28 16:51:46 +01:00
Jonathan Naylor 52cd8843e3
Merge pull request #439 from kd8lbs/patch-1
Update P25Hosts.txt
2023-07-28 16:51:27 +01:00
kd8lbs 513d29d671
Update P25Hosts.txt
server shutdown
2023-07-27 16:44:29 -04:00
ncerreto b878f6e8a9
Update P25Hosts.txt
In the right order now- Thanks Nick
2023-07-26 12:56:34 -04:00
Jonathan Naylor 04529bb3f7
Update P25Hosts.txt 2023-07-26 17:23:37 +01:00
Jonathan Naylor 99623a0865
Merge pull request #435 from dl5rfk/dl5rfk-ports-changed
Update P25Hosts.txt
2023-07-06 12:05:59 +01:00
Klaus 4288c2d0af
Update P25Hosts.txt
sorry, but i realised that the permissible P25 ports are from 41000 to 41010, so unfortunately this adjustment is necessary
2023-07-06 12:04:10 +02:00
Jonathan Naylor a9d576ee03
Update P25Hosts.txt 2023-07-05 11:41:25 +01:00
Jonathan Naylor 203f15e38f
Merge pull request #434 from dl5rfk/dl5rfk-add-TG925
Update P25Hosts.txt
2023-07-05 11:39:57 +01:00
Klaus 29184f4190
Update P25Hosts.txt
add new TG 925 for Motorola Chat EU
2023-07-05 10:46:59 +02:00
Jonathan Naylor ac4fb9313b
Merge pull request #432 from dbehnke/dbehnke/add70777 2023-07-02 20:55:39 +01:00
Dave Behnke fe69122740 add 60777 Who Cares ARG to host list 2023-07-01 23:33:10 -04:00
Dave Behnke b5c6f8eced add 70777 Who Cares ARG to host list 2023-07-01 13:16:46 -04:00
Jonathan Naylor e93eed8b6a
Merge pull request #430 from sigintsystems/patch-1 2023-06-30 15:36:52 +01:00
sigintsystems d219500ca9
Update P25Hosts.txt
Added tg 5000 "All the Comms"
2023-06-30 06:11:30 -06:00
Jonathan Naylor b63b72a76e
Merge pull request #429 from ShaYmez/patch-1
Update P25Hosts.txt
2023-06-29 10:57:52 +01:00
M0VUB 6ea9723227
Update P25Hosts.txt
Add ChatterBOX to hosts
2023-06-28 16:21:51 +01:00
Jonathan Naylor d8f25f8101
Merge pull request #428 from k7pws/patch-5
Update P25Hosts.txt
2023-06-20 15:36:02 +01:00
k7pws 2bdeb655e5
Update P25Hosts.txt
P25 to DMR TG 314900 bridge.
2023-06-19 16:23:41 -06:00
Jonathan Naylor a4beb6772d
Merge pull request #427 from m0glj/patch-10 2023-06-17 19:11:02 +01:00
M0GLJ 7cb13b39d0
Update P25Hosts.txt
Correct Typo
2023-06-17 18:23:09 +01:00
M0GLJ c8578216a9
Update P25Hosts.txt
New Reflector
2023-06-17 17:46:24 +01:00
Jonathan Naylor cdf8334ae5
Merge pull request #425 from kd8grn/patch-1 2023-06-15 21:14:01 +01:00
kd8grn b57d62f82d
Update P25Hosts.txt
added new OhioLink P24 reflector.
2023-06-15 13:53:05 -04:00
Jonathan Naylor 56de5aa1b9
Merge pull request #423 from KN4KNG/master 2023-06-14 11:49:08 +01:00
Jonathan Naylor 5e96359160
Merge pull request #424 from fabifri/master 2023-06-14 11:48:40 +01:00
Fabian F 0f0c5e486b
changed 23225 Austria server hostname
As maintainer of HAMNET and Servers in OE9 please update our hostname according to our pull request. 73! de OE9FRV and OE9MNR
2023-06-13 19:22:54 +02:00
Alex Bowman 30d6eb050c
Update P25Hosts.txt
Updating Reflectors 10209 and 10208 headings to match the formatting.
2023-06-12 16:00:37 -04:00
Jonathan Naylor 21ba2b683e
Merge pull request #422 from d3sl91/master
Update P25Hosts.txt
2023-06-11 10:20:58 +01:00
Ethan Gollehon e2a32d92c4
Update P25Hosts.txt
Added HRCC Link #621
2023-06-10 22:02:02 -07:00
Jonathan Naylor c40ddbc7d9
Merge pull request #421 from s-n-vandeneijkel/patch-2 2023-06-06 17:56:37 +01:00
s-n-vandeneijkel 4e5cd72cd5
Update P25Hosts.txt
Add NL IP to P25Hosts.txt
2023-06-06 16:10:30 +02:00
Jonathan Naylor 00b4cef3b5
Merge pull request #419 from bh1nyr/master
Update P25Hosts.txt
2023-06-05 22:31:00 +01:00
bh1nyr e8a6a2415f
Update P25Hosts.txt 2023-06-06 01:21:56 +08:00
Jonathan Naylor 8995a6d4ac
Merge pull request #418 from M0JGX/patch-1 2023-06-04 11:55:30 +01:00
M0JGX 108a9c37c5
Added 23556 - DVSPH Multimode 2023-06-04 11:51:57 +01:00
Jonathan Naylor fac6762be1
Merge pull request #417 from vk3jed/patch-2
Update P25Hosts.txt
2023-05-26 11:26:05 +01:00
Tony Langdon 92898fc992
Update P25Hosts.txt
Added reflector 9517
2023-05-26 20:14:29 +10:00
Jonathan Naylor e19b0af41c
Merge pull request #416 from m1geo/patch-2 2023-05-16 17:37:23 +01:00
Dr. George Smart 8db0401185
Update P25Hosts.txt for TG10100 on new server 2023-05-15 21:25:37 +01:00
Jonathan Naylor 1c43ec1d9d
Merge pull request #415 from yl3im/master
Update the address of 23225 reflector.
2023-05-14 21:15:20 +01:00
Inga Muste d33375496b Update the address of 23225 reflector. 2023-05-14 22:28:26 +03:00
Jonathan Naylor 691afb8a87
Update P25Hosts.txt 2023-04-30 13:13:44 +01:00
Jonathan Naylor ae6d52367f
Merge pull request #413 from k0mgs/patch-1 2023-04-23 12:03:52 +01:00
k0mgs dd31203efa
Update P25Hosts.txt
Add Reflector for America's Kansas City Wide.
2023-04-22 19:42:00 -05:00
Jonathan Naylor 8b7a5b6508
Merge pull request #412 from BI1LLM/patch-5 2023-04-19 08:32:08 +01:00
Jonathan Naylor ebc3febf25
Merge pull request #411 from firealarmss/patch-2 2023-04-19 08:31:51 +01:00
BI1LLM f004f90fbb
Update P25Hosts.txt
Update 10409 reflector server IP addr
2023-04-19 12:48:29 +08:00
KO4UYJ e54ee334a5
Change host URL for TG 31582 2023-04-18 13:15:15 -05:00
Jonathan Naylor cd704b3fbb
Merge pull request #410 from Kimberly-McBlaze/master
Update P25Hosts.txt
2023-04-13 12:12:25 +01:00
Kimberly McBlaze 64d306cf23
Update P25Hosts.txt
Removed "56987 Mother Owl" because I no longer host that reflector
Changed the hostname of "21909 PRIDE" due to moving to new host
2023-04-12 15:43:45 -07:00
Kimberly McBlaze 39581936f9
Update P25Hosts.txt 2023-04-12 15:39:39 -07:00
Kimberly McBlaze 7ecab80eda
Update P25Hosts.txt 2023-04-12 15:38:15 -07:00
Jonathan Naylor b1655028b4
Merge pull request #409 from pu4ron/patch-5 2023-04-09 10:16:17 +01:00
pu4ron 954ba17fb0
Update P25Hosts.txt
Hello! Please modify reflector P25 7245 address to:

pu4ron.dynv6.net

Grateful!
2023-04-08 23:40:12 -03:00
Jonathan Naylor c5d2643c33
Merge pull request #408 from tacoded/patch-1
Update P25Hosts.txt
2023-04-06 17:17:01 +01:00
tacoded 30ad9e8187
Update P25Hosts.txt
server shutdown
2023-04-06 12:13:53 -04:00
Jonathan Naylor ed1182c208 Update P25Hosts.txt 2023-03-13 21:11:57 +00:00
Jonathan Naylor 1390ae397f
Merge pull request #406 from m0glj/patch-9 2023-03-04 19:01:45 +00:00
M0GLJ 8ca56bcc8d
Update P25Hosts.txt 2023-03-03 18:47:32 +00:00
Jonathan Naylor 1745e16239
Merge pull request #404 from hb9fef/patch-3 2023-02-24 17:09:12 +00:00
hb9fef 38831e4fa7
Update P25Hosts.txt
- domain name of reflector changed
- URL of dashboard changed
2023-02-24 16:53:06 +01:00
Jonathan Naylor aa9ded66ab Remove the P25 Reflector. 2023-02-23 19:38:03 +00:00
Jonathan Naylor a842b8d94f
Added TG 23522 2023-02-23 19:18:58 +00:00
Jonathan Naylor ff2436d1d5
Merge pull request #401 from hb9fef/patch-2 2023-02-18 16:08:22 +00:00
hb9fef b14cd2839a
Update P25Hosts.txt
URL of dashboard added to description
2023-02-18 16:38:03 +01:00
Jonathan Naylor f12f5722a1
Merge pull request #400 from Merlinv3/patch-5 2023-02-15 18:22:02 +00:00
Merlinv3 fa6f7ae711
Update P25Hosts.txt
Update P25Hosts.txt new reflector
2023-02-15 09:06:13 +01:00
Jonathan Naylor 02d71b0594
Merge pull request #399 from n2wns/master
Update P25Hosts.txt
2023-02-06 20:15:24 +00:00
N2WNS 77f1499b61
Update P25Hosts.txt 2023-02-06 08:56:06 -05:00
N2WNS 7e4dc85a87
Update P25Hosts.txt 2023-02-05 21:42:49 -05:00
Jonathan Naylor 4bf807987c Update P265Hosts.txt 2023-02-04 20:19:12 +00:00
Jonathan Naylor 345cd4472b
Merge pull request #397 from tacoded/patch-1 2023-02-04 14:35:07 +00:00
tacoded 99d0c387be
Update P25Hosts.txt 2023-02-03 17:01:19 -05:00
Jonathan Naylor 10326dae87 Update P25Hosts.txt 2023-02-03 14:40:33 +00:00
Jonathan Naylor b19c842343
Merge pull request #394 from ovec-kd8lbs/patch-1 2023-01-31 11:34:48 +00:00
ovec-kd8lbs 8ca14aa3ba
Update P25Hosts.txt 2023-01-31 06:13:14 -05:00
Jonathan Naylor dfc6644610
Merge pull request #392 from tacoded/patch-1 2023-01-31 08:26:41 +00:00
tacoded 9528bf4026
Update P25Hosts.txt
Incorrect talkgroup listed on note line
2023-01-30 20:16:47 -05:00
Jonathan Naylor f08ade9bdc
Merge pull request #391 from RobertMTalbot/patch-6 2023-01-28 09:48:47 +00:00
BudT 5e675e9621
Update P25Hosts.txt
Removed deprecated TGs: 31088 and 31092
2023-01-27 15:43:16 -07:00
Jonathan Naylor a2350058dc
Merge pull request #390 from hb9fef/master 2023-01-27 09:42:45 +00:00
hb9fef 81fecd0904
Update P25Hosts.txt
adding TG 2284 P25 reflector for Basel, Switzerland
2023-01-23 09:56:20 +01:00
Jonathan Naylor fec2d798a5
Merge pull request #389 from W2GLD/patch-3 2023-01-22 14:18:16 +00:00
W2GLD ccc229c086
Update P25Hosts.txt
Modified line# 501/502, changed web hosting domain.  Also, inserted line# 504/505 for a new reflector being built today.
2023-01-21 14:27:09 -05:00
Jonathan Naylor 6deffb63bb
Merge pull request #388 from Hubok/patch-5 2023-01-17 08:09:46 +00:00
Hubok 64743ec332
Update P25Hosts.txt
Retiring old reflectors, renumbering 5621 -> 926
2023-01-17 01:43:37 -05:00
Jonathan Naylor 2932981833
Update P25Hosts.txt 2023-01-15 15:42:08 +00:00
Jonathan Naylor 39cae20424
Update P25Hosts.txt 2023-01-11 18:51:14 +00:00
Jonathan Naylor 7a550e0b74
Update P25Hosts.txt 2023-01-11 18:49:12 +00:00
Jonathan Naylor 82eb0ca77a
Update P25Hosts.txt 2023-01-08 13:36:57 +00:00
Jonathan Naylor fb963a409b
Merge pull request #383 from k7pws/patch-4 2022-12-27 20:12:31 +00:00
k7pws 66382679bc
Update P25Hosts.txt
Would like to add my reflector for Utah Statewide 3149.
2022-12-26 15:33:31 -07:00
Jonathan Naylor 446f8e0c8f
Merge pull request #382 from KN4KNG/patch-1 2022-12-23 22:12:27 +00:00
Alex Bowman 62d322a9d3
Add 27565 KN4KNG Network 2022-12-23 17:01:53 -05:00
Jonathan Naylor c869f53707
Merge pull request #380 from Gametch1018/patch-8 2022-12-03 18:19:16 +00:00
Gametch1018 accaf1972e
Update P25Hosts.txt
update to 31220 server
2022-12-02 18:59:18 -05:00
Jonathan Naylor 1ae30481cd
Merge pull request #379 from Gametch1018/patch-7
Update P25Hosts.txt
2022-12-01 07:01:33 +00:00
Jonathan Naylor 6e58c6d438
Merge pull request #378 from pu4ron/patch-4
Update P25Hosts.txt
2022-12-01 07:00:55 +00:00
Gametch1018 4b739aef08
Update P25Hosts.txt 2022-12-01 00:19:51 -05:00
pu4ron cf99f5535d
Update P25Hosts.txt 2022-11-30 20:52:27 -03:00
Jonathan Naylor 23071f53d0
Merge pull request #374 from dtyo-fla/patch-2
Update P25Hosts.txt
2022-11-17 07:32:26 +00:00
dtyo-fla 934e400c4a
Update P25Hosts.txt 2022-11-16 21:25:06 -05:00
Jonathan Naylor 2ac86631ee Update P25Hosts.txt 2022-11-16 21:59:28 +00:00
Jonathan Naylor c23122958e
Merge pull request #376 from F1PTL/patch-3
Update P25Hosts.txt
2022-11-16 19:24:04 +00:00
Bruno 74f82009b3
Update P25Hosts.txt
Update P25 France server
# P25 France
10208	p25.f5dan.fr	41000
2022-11-09 11:46:02 +01:00
dtyo-fla 4e5e66eea5
Update P25Hosts.txt
Motorola P25 system (XTS2500 specifically) configuration limits TG to 65535 groups. Requesting TG to be reassigned to 65101 (or numerically lower) to permit TG to be programmed into Motorola P25 equipment.
2022-11-03 09:36:44 -04:00
Jonathan Naylor 8b98ff85d5
Merge pull request #373 from dtyo-fla/patch-1 2022-11-02 20:29:44 +00:00
dtyo-fla 9900124f9b
Update P25Hosts.txt
request to add a new P25 reflector
2022-11-02 16:21:29 -04:00
Jonathan Naylor cc7a0be8a1
Merge pull request #372 from M0UPM/patch-1 2022-10-27 15:17:56 +01:00
M0UPM ba797c6549
Update P25Hosts.txt 2022-10-27 14:44:07 +01:00
Jonathan Naylor c97a5d22b6
Merge pull request #371 from pu4ron/patch-1 2022-10-25 11:38:14 +01:00
pu4ron 2c8410deea
Update P25Hosts.txt 2022-10-23 13:55:20 -03:00
Jonathan Naylor 692b87693d
Merge pull request #370 from maq1017/patch-1 2022-10-16 17:37:22 +01:00
maq1017 c947f04b69
Update P25Hosts.txt 2022-10-16 17:27:24 +01:00
Jonathan Naylor 2bb92ad441
Merge pull request #369 from dl5rfk/master 2022-10-16 14:52:34 +01:00
Jonathan Naylor 5fa8b33f88
Merge pull request #368 from m0glj/patch-8 2022-10-16 14:52:06 +01:00
M0GLJ 4a7b2a9928
Update P25Hosts.txt
Host Change
2022-10-16 13:25:32 +01:00
Klaus 6ac8b45e45
Update P25Hosts.txt
Added TG26285 for the german Oberbayern region
2022-10-16 14:24:47 +02:00
Klaus 672d532035
Merge pull request #1 from g4klx/master
update my fork
2022-10-16 14:17:42 +02:00
Jonathan Naylor 67ed67a27a
Update P25Hosts.txt 2022-10-02 18:34:54 +01:00
Jonathan Naylor b3cfcda190
Update P25Hosts.txt 2022-10-02 18:31:43 +01:00
Jonathan Naylor 36547c1a3b
Merge pull request #366 from Prondtoo/master
Update P25Hosts.txt
2022-10-02 18:28:19 +01:00
Pan 6de929c6f1
Update P25Hosts.txt
Update 10403	Pacific	TAC 3's domain.
2022-09-26 12:28:08 +08:00
Jonathan Naylor a9c981ac16
Update P25Hosts.txt 2022-09-21 17:55:34 +01:00
Jonathan Naylor c36635e07c
Merge pull request #363 from skynetgwds/master
Request Addition of new host
2022-09-18 15:16:47 +01:00
Gareth GM0WUR 517dda8aef
Addition of new host
Addition of CQ-North UK
2022-09-17 16:08:42 +01:00
Jonathan Naylor d95650bf2a
Merge pull request #362 from yl3im/master 2022-09-17 14:25:15 +01:00
Inga Muste 12b35776da Update P25 hosts with changing 74315 to 43715. 2022-09-17 16:07:31 +03:00
Jonathan Naylor 64e0fd412b
Merge pull request #361 from do5yam/patch-1 2022-09-16 14:05:31 +01:00
Marco 197c30c5c6
Update P25Hosts.txt
New P25 Reflector TG456 in Germany
2022-09-16 11:28:41 +02:00
Jonathan Naylor 81fba8a961
Merge pull request #360 from yl3im/master
Update P25 hosts with 25605 description.
2022-09-15 19:01:45 +01:00
Inga Muste 7518ad338f Update P25 hosts with 25605 description. 2022-09-15 20:19:19 +03:00
Jonathan Naylor 3eda9d0a1d
Merge pull request #359 from yl3im/master 2022-09-15 17:38:54 +01:00
Inga Muste 174aac3eee Update P25 hosts with 25605. 2022-09-15 19:34:19 +03:00
Inga Muste d1e5321d77 Update P25 hosts with 25605. 2022-09-15 19:33:02 +03:00
Inga Muste b7048420ea
Merge pull request #4 from g4klx/master
Update from upstream.
2022-09-15 19:22:41 +03:00
Jonathan Naylor 22730f7233
Merge pull request #358 from MW0MWZ/patch-1 2022-09-09 17:26:18 +01:00
MW0MWZ c522eea2fb
Update P25Hosts.txt
Update ICQ Podcast Host
2022-09-09 17:25:44 +01:00
Jonathan Naylor 51ab031166
Merge pull request #357 from ScottDIrwin/patch-1 2022-09-01 14:41:07 +01:00
ScottDIrwin b8623d56d9
Merge branch 'g4klx:master' into patch-1 2022-09-01 09:38:38 -04:00
Jonathan Naylor 0ceeb0a6f5
Merge pull request #356 from Merlinv3/patch-4 2022-09-01 08:37:47 +01:00
Merlinv3 46fc6accac
update P25Hosts.txt
update P25Hosts.txt thx
2022-08-31 19:03:40 +02:00
ScottDIrwin 8bb53473a3
Update P25Hosts.txt - Ref. 204
Update # 204 Technology First to # 204 W8UFO P25 Reflector
2022-08-28 18:38:27 -04:00
Jonathan Naylor fcf263c71e
Merge pull request #354 from Merlinv3/patch-3
Update P25Hosts.txt
2022-08-09 19:02:33 +01:00
Merlinv3 0c41a0a224
Update P25Hosts.txt
Update P25Hosts.txt new
2022-08-09 19:20:53 +02:00
Jonathan Naylor 54eb28cae6
Update P25Hosts.txt 2022-08-08 21:27:29 +01:00
Jonathan Naylor 853e4d1bc7
Merge pull request #352 from W2GLD/patch-2 2022-08-07 08:22:51 +01:00
W2GLD 409dc92b3a
Update P25Hosts.txt
Made description change to line# 456 for better clarity to users.
2022-08-06 11:19:24 -04:00
Jonathan Naylor 6f338caaf1
Merge pull request #351 from zsneese/patch-3 2022-08-06 11:52:21 +01:00
zsneese 8310541258
Update P25Hosts.txt
Updated domain name of reflector 762
2022-08-05 22:43:36 -04:00
Jonathan Naylor 4ae6fc10bd
Merge pull request #350 from Gametch1018/patch-4
Update P25Hosts.txt
2022-07-31 23:14:19 +01:00
Gametch1018 093471e0ef
Update P25Hosts.txt
Missing the "#" in front of 31220 on line 441
2022-07-31 18:12:46 -04:00
Jonathan Naylor 3c6b79f7c3
Merge pull request #349 from Gametch1018/patch-1
Update P25Hosts.txt
2022-07-31 16:04:33 +01:00
Gametch1018 40bcd03d5d
Update P25Hosts.txt 2022-07-30 19:33:03 -04:00
Jonathan Naylor 0960b0f92e
Merge pull request #348 from jriner63/master 2022-07-24 14:45:39 +01:00
jriner63 6622a01f60
Update P25Hosts.txt 2022-07-24 08:31:03 -04:00
Jonathan Naylor 91c5fd4784
Merge pull request #347 from N6DOZ/patch-9 2022-07-22 12:44:58 +01:00
Rudy 23b4ee1f69
Removed 31775 and added 31177 2022-07-21 15:13:02 -07:00
Jonathan Naylor ddfd8c9f37
Merge pull request #346 from Hubok/patch-4 2022-07-20 14:39:46 +01:00
Hubok bfc1b0dcad
Update P25Hosts.txt
Don't code while tired, this was sending P25 traffic to my NXDN reflector.
2022-07-20 08:46:04 -04:00
Jonathan Naylor 161f14aa25
Merge pull request #345 from bh1nyr/master 2022-07-19 08:13:30 +01:00
bh1nyr d563205870
Update P25Hosts.txt 2022-07-18 20:17:42 +08:00
bh1nyr 4e81354dcf
Merge pull request #2 from g4klx/master
update local
2022-07-18 20:09:12 +08:00
bh1nyr 5067d09571
Update P25Hosts.txt 2022-07-18 20:07:41 +08:00
Jonathan Naylor a39dfae962
Merge pull request #344 from Hubok/patch-3 2022-07-18 08:09:25 +01:00
Hubok 92df779fb0
Update P25Hosts.txt 2022-07-18 01:09:58 -04:00
Jonathan Naylor 6cfd2d5c8b
Merge pull request #343 from ku-mi/master 2022-07-17 18:26:11 +01:00
ku-mi 915bd9374a Moving TG 10260 Poland to a different server 2022-07-17 15:56:22 +02:00
Jonathan Naylor 8c558e4330
Merge pull request #342 from bh1nyr/master
P25Hosts.txt Update Request
2022-07-17 12:19:30 +01:00
bh1nyr d0643fd2dc
Update P25Hosts.txt 2022-07-16 23:13:31 +08:00
bh1nyr d7d9df82ac
Update P25Hosts.txt 2022-07-16 23:06:27 +08:00
bh1nyr 6313ad1489
Update P25Hosts.txt
update 2 and build 3 new reflectors for china ham in different regions.
2022-07-16 23:03:50 +08:00
bh1nyr f92e8bfa2c
Merge pull request #1 from g4klx/master
update upstream
2022-07-14 21:42:07 +08:00
Jonathan Naylor 4bf08b223c Reorder the TG ids. 2022-07-10 15:36:04 +01:00
Jonathan Naylor 2e23c576e0
Merge pull request #341 from bh1nyr/master
Update P25Host.txt
2022-07-10 15:33:01 +01:00
Jonathan Naylor 925ac33431
Merge pull request #340 from N2KMB/patch-1
Update P25Hosts.txt
2022-07-10 15:32:33 +01:00
bh1nyr f862ce8c48
Update P25Host.txt
Add new P25 Host bridge to BM TG46001 and change description for P25 bridge TG46010.
Thanks!
2022-07-10 17:19:10 +08:00
N2KMB 3ec7c3e84a
Update P25Hosts.txt 2022-07-09 06:31:19 -04:00
Jonathan Naylor 04a6f99025
Merge pull request #339 from N2KMB/patch-1
Update P25Hosts.txt
2022-07-08 08:09:51 +01:00
N2KMB b88a92beac
Update P25Hosts.txt 2022-07-07 15:38:55 -04:00
Jonathan Naylor 80c11fe7c5
Merge pull request #338 from bh1nyr/master 2022-07-01 10:28:58 +01:00
bh1nyr 2569a6e047
Update P25 Hosts
DNS resolve recovered.
2022-07-01 16:34:04 +08:00
Jonathan Naylor 81510786a7 Updated TG7941 2022-06-29 19:40:17 +01:00
Jonathan Naylor 9830b9c349 Add TG44000 2022-06-27 19:54:24 +01:00
Jonathan Naylor 2ee60e7212 Add two new reflectors. 2022-06-27 18:04:34 +01:00
Jonathan Naylor 253f5ce81b Update TG46010 2022-06-21 22:27:14 +01:00
Jonathan Naylor 0f8cd16694
Merge pull request #332 from Hubok/patch-1
Update P25Hosts.txt
2022-06-20 20:41:36 +01:00
Hubok f475ccc077
Update P25Hosts.txt 2022-06-20 07:38:37 -04:00
Jonathan Naylor 82d3415d83 Added TG46010 2022-06-17 16:27:03 +01:00
Jonathan Naylor ae87e0c207
Merge pull request #330 from N6DOZ/patch-8
Update P25Hosts.txt
2022-06-16 07:15:50 +01:00
Rudy 072d9023ef
Update P25Hosts.txt
Removed the 51522 PINOY-LINK
2022-06-15 16:46:09 -07:00
Jonathan Naylor c2afdf8654
Merge pull request #329 from Kimberly-McBlaze/master
Update P25Hosts.txt
2022-06-12 13:16:19 +01:00
Kimberly McBlaze ffbf0dd79e
Update P25Hosts.txt 2022-06-10 22:52:29 -07:00
Jonathan Naylor 598bf8e4b0
Merge pull request #328 from dl5rfk/master
update P25Hosts.txt add Talkgroup 26444
2022-06-03 16:31:45 +01:00
Klaus f4bef14c26
update P25Hosts.txt add Talkgroup 26444 2022-06-03 10:19:08 +02:00
Jonathan Naylor cd8c451b84
Merge pull request #327 from W2GLD/patch-1
Update P25Hosts.txt
2022-05-23 19:01:27 +01:00
W2GLD 0a73b231ac
Update P25Hosts.txt
Added lines 435-437, new P25 talkgroup reflector details.
2022-05-23 07:04:07 -04:00
Jonathan Naylor f3b93e904d
Merge pull request #325 from postmasterd1/patch-3 2022-05-17 10:42:57 +01:00
postmasterd1 068c31aacc
Editing 31581 & 31582
Editing TG names
2022-05-16 21:34:48 -04:00
Jonathan Naylor 2cbf4e9389
Merge pull request #324 from n2yqt/master 2022-05-15 16:27:30 +01:00
Ryan Tourge N2YQT 0acd8f65e2 changed domain name for TG 8200 2022-05-14 21:42:43 +00:00
Jonathan Naylor bd3f4cb16c
Merge pull request #323 from yl3im/master 2022-05-10 20:08:13 +01:00
Inga Muste 6f4072eff1 Add Kazakhstan P25 reflector. 2022-05-10 22:06:26 +03:00
Inga Muste 2b309643cc
Merge pull request #3 from g4klx/master
Update from upstream.
2022-05-10 22:00:00 +03:00
Jonathan Naylor d4fcfd2e59
Merge pull request #322 from citynetcomputing/patch-1
Update P25Hosts.txt
2022-05-03 20:00:36 +01:00
Jay 9db1622b7e
Update P25Hosts.txt
Added new host for WNY-DIGITAL.
2022-05-02 17:19:03 -04:00
Jonathan Naylor 73bb0c81c7
Merge pull request #321 from dandrzejewski/master 2022-04-29 07:14:44 +01:00
David Andrzejewski 26d7c88744 Update port. 2022-04-28 18:06:01 -04:00
Jonathan Naylor da9c8e6a7c
Merge pull request #320 from dandrzejewski/master 2022-04-27 15:32:44 +01:00
David Andrzejewski 317dd23f7c Add 10169 for N0DIP reflector 2022-04-27 09:46:31 -04:00
David Andrzejewski 69b6266a6f Move P25Hosts.txt back into P25Gateway
Looks like this may have been mistakenly moved to a new folder.
2022-04-27 09:44:39 -04:00
Jonathan Naylor 00d95a1e0b
Merge pull request #319 from BI1LLM/patch-4 2022-04-27 06:03:27 +01:00
BI1LLM a93bd4b17b
add 10409 Reflector
# 10409 Beijing City, China,Miyun-HAM-Club P25 Repeater bridged to DMR TG 46001
10409	43.138.30.198	41000
2022-04-27 06:38:10 +08:00
Jonathan Naylor 4304b21ed8 Update P25Hosts.txt 2022-04-21 07:08:47 +01:00
Jonathan Naylor b9c184173d Update P25Hosts.txt 2022-04-19 17:27:39 +01:00
Jonathan Naylor 7c8f2cb2d0
Merge pull request #318 from lwkoon/patch-5 2022-04-16 09:14:41 +01:00
9W2LWK 8fea7864c6
Update P25Hosts.txt
update to edone.no-ip.com
2022-04-16 13:25:50 +08:00
Jonathan Naylor 452282512e
Merge pull request #317 from KP4CA/patch-3 2022-04-14 13:57:10 +01:00
Carlos (KP4CA) 8943305132
Update P25Hosts.txt 2022-04-14 08:54:03 -04:00
Jonathan Naylor 2aaefd00ec Update P25Hosts.txt 2022-04-12 07:21:04 +01:00
Jonathan Naylor 20ff57bc3c
Merge pull request #314 from Kimberly-McBlaze/patch-1
Update P25Hosts.txt
2022-04-11 19:30:41 +01:00
Jonathan Naylor 49a980cc4c
Merge pull request #313 from VE3RD/patch-5
Update P25Hosts.txt
2022-04-11 19:30:23 +01:00
Jonathan Naylor e397be0540
Merge pull request #311 from 9V1LH/patch-2
Update P25Hosts.txt
2022-04-11 19:29:58 +01:00
Kimberly McBlaze f3edb9a304
Update P25Hosts.txt
Added my reflector to the list on lines 306 - 307 for TG 21909.
DE KJ7OMO
2022-04-09 05:18:26 -07:00
Philip Thompson 52a629f5d6
Update P25Hosts.txt
Moved to dynamic dns
2022-04-08 18:35:29 -04:00
Stephan 42924ffb7a
Update P25Hosts.txt 2022-03-31 16:40:35 +08:00
Jonathan Naylor 996904ad4b Update P25Hosts.txt 2022-03-29 20:51:10 +01:00
Jonathan Naylor 94417bd634
Merge pull request #310 from KP4CA/patch-2
Update P25Hosts.txt
2022-03-29 20:48:56 +01:00
Carlos (KP4CA) 11a2d711ae
Update P25Hosts.txt 2022-03-29 12:52:23 -04:00
Jonathan Naylor 4dbc172fc9 Update P25Hosts.txt 2022-03-15 21:12:16 +00:00
Jonathan Naylor 03c82ca594
Merge pull request #306 from zsneese/patch-2
Added TG762
2022-03-15 21:04:23 +00:00
Jonathan Naylor 46760576b2
Merge pull request #305 from VE3RD/patch-1
Update P25Hosts.txt
2022-03-15 21:04:12 +00:00
Jonathan Naylor 10820e1560
Merge pull request #304 from firealarmss/patch-1
Update P25Hosts.txt
2022-03-15 21:04:01 +00:00
Jonathan Naylor ae4f722391
Merge pull request #303 from GabeHC/patch-3
Update P25Hosts.txt
2022-03-15 21:03:51 +00:00
Jonathan Naylor a18090aa21
Merge pull request #301 from digilink/patch-1
Update P25Hosts.txt
2022-03-15 21:03:40 +00:00
zsneese 850bf7dbb6
Added TG762
Linked to BM 312486
2022-03-14 23:16:26 -04:00
Philip Thompson 1d8d36d804
Update P25Hosts.txt 2022-03-14 11:05:19 -04:00
firealarmss 8d95ecd3d8
Update P25Hosts.txt
Adding KO4UYJ reflector 31582
2022-03-13 22:14:50 -05:00
Gabriel Huang 68a510a2fe
Update P25Hosts.txt
Correct 10512 SHLK
2022-03-10 15:48:08 +08:00
Stephen Brown 44b2659ae8
Update P25Hosts.txt
Add talkgroup 3147 for Tennessee
2022-03-09 19:30:00 -05:00
Jonathan Naylor 138a090080 Update P25Hosts.txt 2022-03-06 20:28:40 +00:00
Jonathan Naylor 97ee42645e Update P25Hosts.txt 2022-03-06 20:13:36 +00:00
Jonathan Naylor 82c9df2fab Update P25Hosts.txt 2022-03-06 20:07:57 +00:00
Jonathan Naylor 61e72cfd58
Merge pull request #297 from nessenj/patch-2
Add TG 3160
2022-03-06 20:03:55 +00:00
Jonathan Naylor 8d46bde2a7
Merge pull request #296 from zsneese/patch-1
Update P25Hosts.txt
2022-03-06 20:03:39 +00:00
Jonathan Naylor c722b115d7
Merge pull request #294 from citynetcomputing/patch-2
Update P25Hosts.txt
2022-03-06 20:03:16 +00:00
Jonathan Naylor 081d737c02
Merge pull request #293 from GabeHC/patch-2
Update P25Hosts.txt
2022-03-06 20:02:58 +00:00
Jim Nessen 9dc2c08493
Add TG 3160 2022-03-03 09:18:45 -08:00
zsneese 34da1f107b
Update P25Hosts.txt
added ARFCOM reflector info
2022-03-02 20:02:08 -05:00
Jay 29d4c62c39
Update P25Hosts.txt 2022-02-24 15:18:52 -05:00
Gabriel Huang 3a01488968
Update P25Hosts.txt
Add in #10512 SHLK reflector Shanghai, China
2022-02-24 14:14:04 +08:00
Jonathan Naylor b15be2fe3c
Merge pull request #290 from yl3im/master
Change reflector 37500 hostname.
2022-02-09 18:02:00 +00:00
Inga Muste 4e1d83f29d Change reflector 37500 hostname. 2022-02-09 15:40:39 +02:00
Inga Muste 5fe32de534
Merge pull request #2 from g4klx/master
Merge from upstream.
2022-02-09 15:38:54 +02:00
Jonathan Naylor 0ec92004ae
Merge pull request #287 from kb5rir/master
Update P25Hosts.txt
2022-02-06 17:48:18 +00:00
kb5rir 2e12636f37
Update P25Hosts.txt
change line 76 from.  1007	43773.kb5rir.com	41000
                        to.      1007	43773.kb5rir.com	41003
2022-01-29 08:09:43 -06:00
Jonathan Naylor f3efdf6874
Merge pull request #282 from f1rmb/connection_status_to_static_at_startup 2022-01-25 22:50:28 +00:00
Daniel Caujolle-Bert bd98561201 Change negation checking coding style. 2022-01-25 18:44:37 +00:00
Daniel Caujolle-Bert 012456a340 Fix Static on startup.
If a static talkgroup is set in the configuration file is set, some 3 poll frames are sent, but replies are ignored, hence the connection status stays disconnected, and localnetwork won't get any data also.
2022-01-25 04:12:42 +00:00
Jonathan Naylor 46a2d6334d
Merge pull request #281 from f1rmb/network_status
Add new remote command:
2022-01-24 07:10:50 +00:00
Jonathan Naylor ec69b5315b Update P25Hosts.txt 2022-01-23 19:54:18 +00:00
Jonathan Naylor 8d5068f4a8
Merge pull request #280 from skyler440/patch-3
Update P25Hosts.txt
2022-01-23 19:50:49 +00:00
Jonathan Naylor bfd80f0c50
Merge pull request #278 from wb6dtb/patch-8
Update P25Hosts.txt
2022-01-23 19:50:37 +00:00
Jonathan Naylor 9742f63e93
Merge pull request #276 from skyler440/patch-1
Update P25Hosts.txt
2022-01-23 19:50:28 +00:00
Daniel Caujolle-Bert baa0271237 Add new remote command:
- status: displays network connection status (n/a, conn, disc), just like DMRGateway/MMDVMHost.
 - host: display connected host, or NONE if disconnected (surrounded with double quotes).
2022-01-23 18:07:55 +00:00
skyler440 7aa94c14bd
Update P25Hosts.txt 2022-01-22 11:59:08 -07:00
wb6dtb 2faf0c040f
Update P25Hosts.txt
Change America-RC reflector IP address to DNS name due to location change of reflector.
2022-01-20 08:22:53 -08:00
Jonathan Naylor d64d84d4cc
Merge pull request #277 from f1rmb/fix_remote_commands 2022-01-20 12:01:49 +00:00
Daniel Caujolle-Bert ccc744ec01
Expect a space between Talkgroup and its number. 2022-01-20 12:55:53 +01:00
skyler440 fe5bf211f1
Update P25Hosts.txt
SkyHub ( skyhublink.com)
2022-01-15 19:32:16 -07:00
Jonathan Naylor f692301cf6
Update P25Hosts.txt 2021-12-29 19:51:32 +00:00
Jonathan Naylor 8bdae1a246
Merge pull request #272 from f1shs/patch-1 2021-12-25 14:02:01 +00:00
f1shs 2b19b27f53
Update P25Hosts.txt 2021-12-25 13:53:25 +01:00
Jonathan Naylor 64e338e3cf
Merge pull request #271 from yl3im/master 2021-12-22 15:21:36 +00:00
Inga Muste e4cd11de76 Change reflector 37500 IP address to hostname. 2021-12-22 17:20:21 +02:00
Jonathan Naylor 3360f9733f
Merge pull request #270 from yl3im/master 2021-12-22 14:36:43 +00:00
Inga Muste 6b38a4b89c Add latvian reflector 63600 2021-12-22 16:27:56 +02:00
Inga Muste 895fac60a9
Merge pull request #1 from g4klx/master
Update from upstream.
2021-12-22 16:25:38 +02:00
Jonathan Naylor 2d54dd2d4e
Merge pull request #269 from N6DOZ/patch-7 2021-12-17 09:44:50 +00:00
Jonathan Naylor c50e588d77
Merge pull request #268 from N6DOZ/patch-6 2021-12-17 09:44:34 +00:00
Rudy 762510f559
Changed IP address of 55100 WWARAN #265
Changed the IP address of 55100 WWARAN based on issue #265 

from 140.82.3.34 to 45.63.6.57.

Reference:
https://github.com/g4klx/P25Clients/issues/265
2021-12-16 20:32:56 -08:00
Rudy 0f4e1e1f02
Updated based on Issue #261 - removed "port"
Removed the word "port" in the entry

37225	3.215.215.169 port	41011
to
37225	3.215.215.169	41011
2021-12-16 20:22:32 -08:00
Jonathan Naylor 0f6aa1df51
Merge pull request #267 from yl3im/master 2021-12-16 16:40:36 +00:00
Inga Muste 18e65fdee9 Update belarusian P25 reflector description 2021-12-16 17:52:09 +02:00
Jonathan Naylor 305b47c85c
Merge pull request #266 from yl3im/master 2021-12-16 15:05:07 +00:00
Inga Muste 152c79d65a Add belarusian P25 reflector 2021-12-16 16:44:24 +02:00
Jonathan Naylor 0f396fea38
Merge pull request #264 from N6DOZ/patch-5 2021-12-16 08:37:12 +00:00
Rudy 58564aa162
Added the KAPIHAN Network P25 Reflector
# 51547 KAPIHAN Network 
51547 p25.kapihan.net 41000
2021-12-15 18:00:55 -08:00
Jonathan Naylor a625d5eebc
Merge pull request #263 from N6DOZ/patch-4 2021-12-15 20:16:11 +00:00
Rudy 66db726fb9
Changed TG for Omega Communications 2021-12-15 11:55:40 -08:00
Jonathan Naylor f7611cc31b
Merge pull request #260 from dandrzejewski/patch-1 2021-12-14 10:04:50 +00:00
David Andrzejewski 174ce73336
Add Cleveland Skywarn Backbone reflector
Added Cleveland Skywarn Backbone reflector, TG 31395.
2021-12-14 01:50:28 -05:00
Jonathan Naylor ba510c70ff Update the README 2021-12-13 10:36:48 +00:00
Jonathan Naylor da2426a562 Update P25Hosts 2021-12-12 20:14:12 +00:00
Jonathan Naylor 6a2449ed53
Merge pull request #256 from RobertMTalbot/patch-5
Update P25Hosts.txt
2021-12-12 20:07:23 +00:00
Jonathan Naylor 5b66b433ba
Merge branch 'master' into patch-5 2021-12-12 20:04:31 +00:00
Jonathan Naylor 3ded268073
Merge pull request #259 from n9krg/patch-7
Update P25Hosts.txt
2021-12-12 20:02:27 +00:00
Jonathan Naylor 3afc189ea8
Merge pull request #255 from N6DOZ/patch-3
Update to P25Hosts.txt
2021-12-12 20:02:02 +00:00
n9krg 372056516b
Update P25Hosts.txt
Reflector 420 has a new host name. Can this be update? Thanks, 73.

p25.superfreqdigital.com
2021-12-11 20:54:50 -06:00
BudT bbacbbbce0
Update P25Hosts.txt
Adding "Sunflower Net" reflector on behalf of N1AJW and AE5ME
2021-12-05 16:21:14 -07:00
Rudy 19f5a4e9a6
Update P25Hosts.txt
added missing "p" in the address.
2021-12-05 08:07:01 -08:00
Rudy dedf546f56
Update P25Hosts.txt 2021-12-05 08:05:55 -08:00
Rudy bee98a740b
Update to P25Hosts.txt
Adding 311969 Omega Communications

# 311969 Omega Communications
311969 omega25.ddns.net 41000
2021-12-05 08:03:42 -08:00
Jonathan Naylor 397f9c87bf
Merge pull request #252 from vk3jed/patch-1 2021-12-01 10:05:13 +00:00
Tony Langdon ee95516a43
New P25 TG 50536
Added new reflector for P25 talkgroup 50536.  This is permanently linked to the FreeSTAR network.
2021-12-01 20:37:14 +11:00
Jonathan Naylor 69c7f3622a
Merge pull request #248 from Merlinv3/patch-2
Update P25Hosts.txt
2021-11-14 19:52:15 +00:00
Merlinv3 6f4bf10302
Update P25Hosts.txt
Update P25Hosts.txt new dns
2021-11-11 18:08:01 +01:00
Jonathan Naylor 0225928c4a
Merge pull request #247 from N6DOZ/patch-2 2021-11-09 06:35:30 +00:00
Rudy 1d9ba2416f
Update P25Hosts.txt
Added new reflector:

# 31775 FILAM HAMS P25 Reflector
31775 p25.filamhams.net 41000
2021-11-08 20:34:23 -08:00
Jonathan Naylor b914f82b54
Merge pull request #246 from elwood99/patch-2
Update P25Hosts.txt
2021-11-02 19:20:50 +00:00
elwood99 64f96d20cb
Update P25Hosts.txt
Added talk group 1701
2021-10-31 18:31:52 -05:00
Jonathan Naylor 469c5a1b40
Merge pull request #245 from lwkoon/patch-4
update TG50210 hostname
2021-10-31 18:42:20 +00:00
9W2LWK b257d52e51
update TG50210 hostname
update TG50210 hostname to 
50210	edone.lucifernet.com	41000
2021-10-31 15:25:17 +08:00
Jonathan Naylor 9aa4f51aee Update P25Hosts.txt 2021-10-26 19:05:06 +01:00
Jonathan Naylor a7f60dded3 Fix compiler warnings 2021-10-25 17:49:03 +01:00
Jonathan Naylor 48b1476147
Merge pull request #243 from citynetcomputing/patch-1 2021-10-21 06:00:33 +01:00
Jonathan Naylor 1bee405bcb
Merge pull request #242 from DO1OLI/patch-1 2021-10-21 06:00:02 +01:00
Jay 7009f4e71d
Update P25Hosts.txt 2021-10-20 19:00:00 -04:00
Jay 538733bd19
Update P25Hosts.txt 2021-10-20 18:46:42 -04:00
DO1OLI 09caaa48f7
Update P25Hosts.txt 2021-10-21 00:25:58 +02:00
Jonathan Naylor 49094b606e
Merge pull request #241 from N6DOZ/N6DOZ-51522-add
Update P25Hosts.txt
2021-10-17 20:47:52 +01:00
N6DOZ 0fbae781e3
Update P25Hosts.txt
Added the P25 Reflector 51522 for the PINOY-LINK Network
2021-10-16 22:28:11 -07:00
45 changed files with 698 additions and 112513 deletions

4
.gitignore vendored
View File

@ -13,6 +13,8 @@ x64
*.user
*.VC.db
.vs
P25Reflector/P25Reflector
P25Gateway/P25Gateway
P25Parrot/P25Parrot
P25Gateway/GitVersion.h
P25Parrot/GitVersion.h

View File

@ -1,4 +1,4 @@
SUBDIRS = P25Gateway P25Parrot P25Reflector
SUBDIRS = P25Gateway P25Parrot
CLEANDIRS = $(SUBDIRS:%=clean-%)
INSTALLDIRS = $(SUBDIRS:%=install-%)

View File

@ -1,14 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.31105.61
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P25Parrot", "P25Parrot\P25Parrot.vcxproj", "{2AE94EAA-FD57-45C9-8555-6425CFA777A3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P25Gateway", "P25Gateway\P25Gateway.vcxproj", "{8B7A5406-8560-4B40-ADDA-9B8EBF93E232}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P25Reflector", "P25Reflector\P25Reflector.vcxproj", "{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -33,14 +31,6 @@ Global
{8B7A5406-8560-4B40-ADDA-9B8EBF93E232}.Release|x64.Build.0 = Release|x64
{8B7A5406-8560-4B40-ADDA-9B8EBF93E232}.Release|x86.ActiveCfg = Release|Win32
{8B7A5406-8560-4B40-ADDA-9B8EBF93E232}.Release|x86.Build.0 = Release|Win32
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x64.ActiveCfg = Debug|x64
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x64.Build.0 = Debug|x64
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x86.ActiveCfg = Debug|Win32
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x86.Build.0 = Debug|Win32
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x64.ActiveCfg = Release|x64
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x64.Build.0 = Release|x64
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x86.ActiveCfg = Release|Win32
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -161,7 +161,7 @@ void Log(unsigned int level, const char* fmt, ...)
struct tm* tm = ::gmtime(&now.tv_sec);
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03ld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000L);
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03lld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000LL);
#endif
va_list vl;

View File

@ -1,6 +1,6 @@
CC = cc
CXX = c++
CFLAGS = -g -O3 -Wall -DHAVE_LOG_H -DUDP_SOCKET_MAX=2 -std=c++0x -pthread
CFLAGS = -g -O3 -Wall -DHAVE_LOG_H -std=c++0x -pthread
LIBS = -lpthread
LDFLAGS = -g

View File

@ -36,6 +36,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
@ -155,7 +156,7 @@ void CP25Gateway::run()
return;
}
// Double check it worked (AKA Paranoia)
// Double check it worked (AKA Paranoia)
if (setuid(0) != -1) {
::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n");
return;
@ -301,8 +302,18 @@ void CP25Gateway::run()
hangTimer.start();
}
} else if (currentTG == 0U) {
bool poll = false;
unsigned char pollReply[11U] = { 0xF0U };
std::string callsign = m_conf.getCallsign();
callsign.resize(10U, ' ');
// Build poll reply data
for (unsigned int i = 0U; i < 10U; i++)
pollReply[i + 1U] = callsign.at(i);
// Don't pass reflector control data through to the MMDVM
if (buffer[0U] != 0xF0U && buffer[0U] != 0xF1U) {
if ((buffer[0U] != 0xF0U && buffer[0U] != 0xF1U) || (poll = (::memcmp(buffer, pollReply, std::min(11U, len)) == 0))) {
// Find the static TG that this audio data belongs to
for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it) {
if (CUDPSocket::match(addr, (*it).m_addr)) {
@ -325,7 +336,8 @@ void CP25Gateway::run()
buffer[3U] = (currentTG >> 0) & 0xFFU;
}
localNetwork.write(buffer, len);
if (!poll)
localNetwork.write(buffer, len);
LogMessage("Switched to reflector %u due to network activity", currentTG);
@ -347,7 +359,7 @@ void CP25Gateway::run()
srcId = (buffer[1U] << 16) & 0xFF0000U;
srcId |= (buffer[2U] << 8) & 0x00FF00U;
srcId |= (buffer[3U] << 0) & 0x0000FFU;
if (dstTG != currentTG) {
if (currentAddrLen > 0U) {
std::string callsign = lookup->find(srcId);
@ -449,7 +461,7 @@ void CP25Gateway::run()
if (res > 0) {
buffer[res] = '\0';
if (::memcmp(buffer + 0U, "TalkGroup", 9U) == 0) {
unsigned int tg = (unsigned int)::atoi((char*)(buffer + 9U));
unsigned int tg = ((strlen((char*)buffer + 0U) > 10) ? (unsigned int)::atoi((char*)(buffer + 10U)) : 9999);
if (tg != currentTG) {
if (currentAddrLen > 0U) {
@ -514,6 +526,21 @@ void CP25Gateway::run()
voice->linkedTo(currentTG);
}
}
} else if (::memcmp(buffer + 0U, "status", 6U) == 0) {
std::string state = std::string("p25:") + ((currentAddrLen > 0) ? "conn" : "disc");
remoteSocket->write((unsigned char*)state.c_str(), (unsigned int)state.length(), addr, addrLen);
} else if (::memcmp(buffer + 0U, "host", 4U) == 0) {
std::string ref;
if (currentAddrLen > 0) {
char buffer[INET6_ADDRSTRLEN];
if (getnameinfo((struct sockaddr*)&currentAddr, currentAddrLen, buffer, sizeof(buffer), 0, 0, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
ref = std::string(buffer);
}
}
std::string host = std::string("p25:\"") + ((ref.length() == 0) ? "NONE" : ref) + "\"";
remoteSocket->write((unsigned char*)host.c_str(), (unsigned int)host.length(), addr, addrLen);
} else {
CUtils::dump("Invalid remote command received", buffer, res);
}

View File

@ -6,14 +6,29 @@
# 6 XLX045E P25 <-> DMR/DSTAR/YSF/NXDN
6 70.44.20.24 41000
# 38 Thailand P25 Link XLX Nexus
38 p2538.freeddns.org 41002
# XLX137 Module A Link to YSF79655
137 p25a.mywire.org 41000
# 138 P25 PKT THAILAND
138 p25138.freeddns.org 41001
# P25 Link XLX148 Modules X
148 p148.hs3tdi.com 41000
# 149 P25 Link To XLX Nexus Module X
149 p25.pwk.ac.th 41000
# 164 K4FSG Reflector
164 reflector.k4fsg.net 41000
# 202 HELLAS Zone P25
202 hellaszone.com 41000
# 204 Technology First
204 w8ufo.hamshack.info 41000
# 204 W8UFO P25 Reflector
204 41611.asnode.org 41000
# 214 SPAIN P25 Reflector
214 214p25.xreflector.es 41000
@ -21,21 +36,48 @@
# 226 Romania YO P25 Network
226 p25.dstar-yo.ro 41000
# 228 Switzerland - https://project25.ch
228 project25.ch 41000
# 235 DVSPH UK Wide
235 p25.dvsph.net 41000
# 260 HBLink Poland P25
260 p25.hblink.pl 41000
# 304 W8ARA P25
304 ara.selfip.net 41000
# 357 VARG http://www.varg.club
357 3.215.215.169 41010
# 419 Toledo Amateur Digital Association
419 tada-p25.ddns.net 41000
# 420 Super Freq
420 hb.superfreqdigital.com 41000
420 p25.superfreqdigital.com 41000
# 445 SuperMag Australia
445 p25.Supermag.fishersaudio.com.au 41000
# 456 Apco25 Ruhrgebiet/NRW Germany
456 456.ham-p25.de 41000
# 530 NZ
530 zldigitalreflectors.hopto.org 41000
# 555 Georgia 900 P25
555 georgia900p25.us 41000
# 556 ARFCOM AR15.com
556 reflector.site 41000
# 621 HRCC LINK
621 urf.hrcc.link 41000
# 666 Brazil PY1IP P25 Reflector - http://tg666.p25.py1ip.com
666 p25.py1ip.com 41000
# 707 Rural Minnesota - Bridge to TGIF707, YSF US RuralMN-707
707 707p25.kd0ioe.com 41000
@ -45,35 +87,71 @@
# 730 Chile P25 Reflector to BM TG 730
730 sdradio.cl 41000
# 762 W4PFT Multimode Linked to BM TG 312486-Franklin County, GA
762 p25.w4pft.com 41000
# 822 TH-ASL-5508
822 p25.xlx822.com 41000
822 p25.xlx822.com 41000
# 841 Team Wave
841 mx0wvv.ddns.net 41000
# 847 Chandler Hams
847 xlx847.kk7mnz.com 41000
# 848 Chandler Hams
848 xlx848.kk7mnz.com 41000
# 858 San Diego, CA
858 nz6d.dx40.com 41000
# 865 K1LNX Multimode Server - Knoxville, TN
865 knoxp25.k1lnx.net 41000
865 knoxp25.k1lnx.net 41000
# 891 WNY DMR Network
891 p25.wnydmr.network 41000
# 891 Western New York Digital Multimode Network - http://wny-digital.network - Buffalo, NY
891 p25.wny-digital.network 41000
# 910 Washington,DC - Virginia - Maryland
910 p25.freeddns.org 41000
# 925 MotoChat
925 p25.motochat.eu 41009
# 926 HamFurs/LoFAR MultiMode Bridge
926 urf.kf3rry.org 41000
# 927 Southern California
927 927.org 41000
# 946 FlagTorchSociety
946 xlx.flagandtorchsociety.com 41000
# 994 The Online Radio Club (Bridged to XLX994)
994 misc.openreflector.com 41000
# 1007 The Harley-Hangout "TGIF TG-1007 Multi-Function Bridge"
1007 43773.kb5rir.com 41000
1007 43773.kb5rir.com 41003
# 1402 DuckFar Repeater Group, Chicago
1402 duckfarw9bmk.gotdns.com 43000
# 1701 Sector 001
1701 hamsomniac.mooo.com 41001
# 1928 Motorola Nerd Network
1928 216.128.134.7 41000
# 2044 P25 The Netherlands Main Reflector
2044 51.83.46.75 41000
# 2050 KM4NNO AllStarLink DIU 3000 (Bridged to the P25Link Network).
2050 reflector.p25.link 41009
# 2140 P25 Reflector BM DMR+ Multi
2140 164.132.96.157 41000
2140 andalucia.xreflector.es 41002
# 2147 P25 Reflector ANDALUCIA
2147 andalucia.xreflector.es 41001
# 2221 IT PIEDMONT GDO
2221 iz1zpj.duckdns.org 41000
@ -87,6 +165,15 @@
# 2265 Baia Mare YO5 P25 Network
2265 p25.dstar-yo.ro 41005
# 2284 Basel Switzerland - https://p25.network
2284 p25.network 41000
# 2345 CQ-North UK
2345 p25.cqnorth.org.uk 41000
# 2350 UK ChatterBOX
2350 p252350.freestar.network 41001
# RU DMR TG2503
2503 p25.r1ik.ru 41000
@ -97,11 +184,23 @@
3023 ontxlink.hopto.org 41000
# 3026 Alberta
3026 3026.hamshack.info 41000
3026 reflector.p25alberta.ca 41000
# 3120 LKDVM P25
3120 lkdvm.xreflector.es 41000
# 3142 Pennsylvania
3142 3.215.215.169 41002
# 3147 Tennessee
3147 p25tn.w4kdg.org 41000
# 3149 Utah
3149 p25.aarthek.net 41000
# 3160 K6JWN Multimode
3160 p25-3160.k6jwn.org 41000
# 3300 PRadise
3300 3300p25.from-pr.com 41000
@ -111,32 +210,83 @@
# 3345 Mexico Multimode (Bridged to the P25Link Network).
3345 reflector.p25.link 41008
# 3400 3400 Digital Group (NJ Multimode Reflector)
3400 3400.ddns.net 41000
# 4095 KM4NNO Wave (Bridged to the P25Link Network).
4095 reflector.p25.link 41010
# 4487 448.700 UHF Repeater in Aurora, CO
4487 N0oba1.asuscomm.cn 41000
# 5000 ALL THE COMMS
5000 p25.p25stuff.com 41000
# 5057 VK7 TAS (hosted by VK7HSE)
5057 45.248.50.37 41000
# 6935 Indiana Digital Ham Radio P25 Reflector
# 5205 CCARCNSW P25 Bridge
5205 5205.p25dvm.com 41000
# 5658 DuckFar Repeater Group, Chicago
5658 duckfarw9bmk.gotdns.com 41000
# 6395 Indiana Digital Ham Radio P25 Reflector
6395 p25ref.nf9k.net 41000
# 6969 JTF_HV Ham P25
6969 69.118.62.100 41000
# 7144 Chiriqui Link Panama
7144 p25-hp3.ddns.net 41000
# 7160 Peru Digital
7160 p25.dmr-peru.pe 41000
# 7225 MULTIPROTOCOLO ARGENTINA
7225 ysfarg.ddns.net 41000
# 7240 MASTER-SUL Brasil
7240 p25.freedmr-brasil.qsl.br 41000
# 7245 BRASIL Multiprotocolo P25
7245 pu4ron.dynv6.net 41000
# Uruguay Link
7487 23.234.230.152 41000
# 7573 Docksea P25
7573 p25.docksea.com 41000
# 7941 WHITE MOUNTAIN REPEATER ASSOCIATION
7941 wmra.mooo.com 41000
# 8200 Mountain Lakes Regional Amateur Radio Society
8200 n2yqt.tourge.net 41000
# 8207 Houston Area XLX Reflector
8207 p25.kd5dfb.net 41000
# 8208 China P25 Network bridge to P25NX
8208 47.105.33.47 41000
# 8210 Ohio Valley
8210 reflector.p25.in 41000
# 9050 East Coast Reflector
9050 45.77.198.235 41000
# 9480 ICQPODCAST
9480 xlx.icqpodcast.com 41001
9480 46.101.36.246 41000
# 9517 M17 Project - M17-M17 C Reflector bridge
9517 112.213.34.65 41002
# 9846 P25 Portal to WW8GM YSF network www.gmarc.org
9846 p25.dudetronics.com 41001
# 10100 World Wide http://www.george-smart.co.uk/p25/
10100 m1geo.com 41000
# 10100 World Wide http://dvgateway.m1geo.com/
10100 dvgateway.m1geo.com 41000
# 10101 World Wide TAC 1 (Bridged to the P25Link Network).
10101 reflector.p25.link 41000
@ -150,6 +300,9 @@
# 10120 CQ-UK
10120 81.150.10.62 41000
# 10169 Dipspit International - N0DIP
10169 p25.dipspit.net 41000
# 10200 North America
10200 dvswitch.org 41000
@ -162,17 +315,26 @@
# 10203 North America TAC 3 (Bridged to the P25Link Network).
10203 reflector.p25.link 41004
# P25 France
10208 m55.evxonline.net 41000
# 10207 Arizona 900 P25
10207 n6ex.ddns.net 41001
# P25 Fun Machine WE0FUN Bridge to C4FM, DMR, DStar, NXDN and AllStarLink (Analog) http://www.we0fun.com
# 10208 P25 France
10208 p25.f5dan.fr 41000
# 10209 P25 Fun Machine WE0FUN Bridge to C4FM, DMR, DStar, NXDN and AllStarLink (Analog) http://www.we0fun.com
10209 p25.we0fun.com 41000
# 10216 Northeast Ohio
10216 xlx216.km8v.com 41000
# 10255 Southern Ontario
10255 ve3rd.hopto.org 41000
# 10260 Poland
10260 80.211.249.221 41000
10260 185.174.14.75 41000
# 10294 SkyHub https://skyhublink.com/connections
10294 hub.skyhublink.com 41000
# 10300 Europe https://p25-eu.n18.de/
10300 176.9.1.168 41000
@ -217,7 +379,7 @@
10402 47.104.177.248 41000
# 10403 Pacific TAC 3 http://ysf.sz790.com:8082/
10403 ysf.sz790.com 41000
10403 ysf46073.sz790.com 41000
# 10404 Pacific TAC 4
10404 p25tw338.ddns.net 41000
@ -231,11 +393,11 @@
# 10407 Shanghai City, China,bridged to DMR TG 46021
10407 p25021.dyndns.org 41000
# 10421 DL-Nordwest (dl-nordwest.com) by 9V1LH/DG1BGS and DK5BS
10421 9v1lh.spdns.org 41000
# 10409 Beijing City, China,Miyun-HAM-Club P25 Repeater bridged to DMR TG 46001
10409 101.43.186.84 41000
# 10444 VK64 P25 Group
10444 vk64.chiffers.com 41000
# 10421 DL-Nordwest (dl-nordwest.com) by 9V1LH/DG1BGS and DK5BS
10421 dl-nordwest.com 41000
# 10472 Shenzhen City, China,bridged to DMR TG 46072
10472 14.116.159.221 41000
@ -243,18 +405,42 @@
# 10473 LinAn, China, Fireside Chat Reflector
10473 p25.hamdao.com 41000
# 10512 Shanghai, China, SHLK Reflector
10512 bolelk.vicp.net 41000
# 10666 F5KFF P25 Net in Paris
10666 f5kff.hd.free.fr 41000
# 10700 Australia NSW Bridge to AU NSW YSF
10700 p25nsw.gustotech.net 41000
# 10750 Australian Secondary P25 Reflector
10750 clasn-p25.cloudasn.com 41000
# 10888 Texas
10888 29520.asnode.org 41000
# 10901 P25 Group Culpeper VA
10901 Randin.Org 41000
# 10945 Deutschland DL1BH
10945 dl1bh.ddns.net 41000
# 11069 KK6RQs reflector
# 11069 KK6RQ DMR-310551
11069 area52.zapto.org 41000
# 17603 URFM17 Universal Reflector
17603 urf.m17.link 41000
# 20281 GR-KERKYRA-DV
20281 greece.freedmr.online 41000
# 20222 HELLAS-FRN
20222 greece-frn.ddns.net 41000
# 21909 PRIDE - LGBTQIA+ Hams
21909 ham.kimberlychase.com 41000
# 22200 IT HBLINK REFLECTOR
22200 p25.hblink.it 41000
@ -267,35 +453,83 @@
# 22221 HBLINK IT-DMR REGIONALE LOMBARDIA
22221 dagobah.hblink.it 41000
# 22222 North Carolina NCC-1701
22222 NCC-1701-P25.ddns.net 41001
# 22252 IT MULTIPROTOCOL NETWORK
22252 46.226.178.80 41000
# 22258 D2ALP HBLink Italia
22258 94.177.173.53 41000
# 22487 IT - Italy Centro
22487 famiuse.ddns.net 41000
# 23225 Austria
23225 94.199.173.123 41000
23225 service.oe9hamnet.at 41000
# 23426 FreeSTAR UK
23426 p25.freestar.network 41000
# 23456 SHARC Multi Mode System Sherman, ME
23456 kc1noc.duckdns.org 41000
# 23511 LEFARS Multi-Reflector
23511 xlxlef.gb7hh.co.uk 41000
# 23522 GB-PrestonARS-P25
23522 23522p25ref.dyndns.org 41000
# 23551 P25 Scotland
23551 p25scotland.ddns.net 41000
# 23556 DVSPH Multimode
23556 xlx600.dvsph.net 41000
# 23595 OZ-DMR
23595 reflector.oz-dmr.uk 41000
23595 p25.oz-dmr.network 41000
# 24033 2 Meter Crew Anti-Net
24033 wg5eek.com 41000
# 25605 Russia Ekaterinburg
25605 ysf.386i.ru 41000
# 25617 Russia Kavkaz
25617 kavkaz.qrz.ru 41000
# 26078 Poland HBLink Network
26078 p25.hblink.kutno.pl 41000
# 25641 Russia P25 Net
25641 194.182.85.217 41000
# 26078 Poland HBLink Network
26078 p25.hblink.kutno.pl 41000
# 26230 German Hannover-XLink
26230 p25.hannover-x.link 41000
# 26285 German Oberbayern Region
26285 xlx850.bm262.de 41008
# 26444 German Inselfreunde Net
26444 xlx850.bm262.de 41004
# 26538 DE-NDS-Ost
26538 116.203.223.233 41000
# 27565 KN4KNG Network
27565 139.144.61.167 41000
# 27566 KN4KNG Network TAC1
27566 139.144.61.167 41001
# 27567 KN4KNG Network TAC2
27567 139.144.61.167 41002
# 27568 KN4KNG Network TAC3
27568 139.144.61.167 41003
# 28299 America-Ragchew
28299 65.101.7.51 41000
28299 arcp25.duckdns.org 41000
# 29252 Oklahoma Hamsomniacs
29252 hamsomniac.mooo.com 41000
@ -306,9 +540,15 @@
# 31010 Alabama Link
31010 alabamalink.radiotechnology.xyz 41000
# 31044 WNY-DIGITAL
31044 p25.wny-digital.network 41002
# 31057 AF5XP Sulphur,Louisiana
31057 af5xp.ddns.net 41000
# 31059 Vidalia Net P25
31059 vidalianet.cbridge.net 41000
# 31062 Mountain West
31062 p25.mw-dmr.net 41000
@ -324,29 +564,41 @@
# 31079 ALERT Radio / Multimode P25/DMR
31079 927.org 41001
# 31088 Colorado HD
31088 54.191.50.212 41000
# 31138 kingsland Ga
31138 kingsland.cbridge.net 41000
# 31092 Connecticut Chat
31092 p25.alecwasserman.com 41000
# 31177 WESDIG P25 Reflector
31177 p25.wesdig.com 41000
# 31121 First Coast FL
31121 dvse.dmrnet.net 41000
# 31123 Florida Treasure Coast
31123 45.152.209.147 41000
31123 p25.kg4orq.com 41000
# 31161 Virginia
31161 24.49.15.69 41000
# 31171 Illinois Link
31171 illink.radiotechnology.xyz 41000
31171 illink.radiotechnology.xyz 41000
# 31188 Southern Indiana
31188 w9windigital.org 41000
# 31226 Worldwide Dx Link System
31226 192.99.70.1 41000
# 31207 Sunflower Net
31207 155.138.244.192 41000
# 31217 Central Illinois Skywarn - Linked to Brandmeister TG 311899
31217 tg31217.kd9koo.com 41000
# 31220 Lucas County Ohio ARES
31220 w8mal-dvbridge.hopto.org 41000
# 31226 Worldwide Chat
31226 74.208.163.225 41000
# 31238 Foxhole Radio Bridged Network
31238 p25.foxhole.radio 41000
# 31257 NEARC
31257 p25.w0jay.com 41000
@ -354,9 +606,27 @@
# 31264 XLX625 The BROniverse www.wa8bro.com
31264 p25.dudetronics.com 41000
# 31267 W8LRK Blue Zone - Livingston County Amateur Radio Klub
31267 w8lrkp25.dyndns.org 41001
# 31291 Southwest Missouri (P25/DMR)
31291 p25.ddns.me 41001
# 31297 Southwest Missouri Skywarn (P25/DMR)
31297 p25.ddns.me 41003
# 31313 America's Kansas City Wide (P25/DMR/YSF)
31313 p25.ddns.me 41002
# 31337 SWLA <-> DMR TG 311995 <-> XLX337
31337 bridge.kc5jmj.com 41000
# 31395 Cleveland Skywarn Backbone
31395 backbone.ad8g.net 41000
# 31399 OhioLink Network Crossmode. http://olnradio.digital
31399 xlx.kd8grn.net 41000
# 31340 Central New Jersey
31340 cnjham.msmts.com 41000
@ -369,23 +639,35 @@
# XLX045A P25 <-> DMR/DSTAR/YSF/NXDN <-> BM TG31425 PA Wide Cross Mode
31425 70.44.20.24 41001
# 31424 SVARC-Shenango Valley Amateur Radio Club- K3WRB
31424 p25.n1tvi.net 41000
# PA Cross Mode (alt), 31426
31426 3.215.215.169 41001
# 31444 RI DIGITAL LINK TG#31444
31444 149.28.54.153 41000
# 31490 Link to DMR TG 314900
31490 utah00.utahdrn.org 41000
# 31497 LifeFlight, UT Statewide - Link to DMR TG 31497
31497 45.79.110.170 41000
# 31555 SE Wisconsin Regional Linked to WiDMR 31555
31555 mmdvm-p25.v24bridge.net 41000
# 31581 KD2UQK Long Island, NY - P25 Reflector
# 31581 KD2UQK Long Island, NY - P25 Talkaround
31581 kd2uqk.ham-radio-op.net 41000
# 31582 KO4UYJ & KD2UQK East Coast Reflector P25 Bridge to 9050/27339
31582 lnr.ko4uyj.com 41000
# 31620 Kings of Digital
31620 wb5ekup25.duckdns.org 41000
# 31655 Ham Radio Venture Overland
31655 149.248.8.155 41000
31655 149.248.8.155 41000
# 31665 TGIF Network, http://tgif.network
31665 tgif.network 41000
@ -405,29 +687,74 @@
# 31888 KG4JPL North-Central Florida
31888 p25.kg4jpl.com 41000
# 31947 K0MGS Western Missouri/KC Metro
31947 p25.ddns.me 41000
# 31983 K8JTK Hub Multimode ILS/DVMIS (K8JTK.org)
31983 P25Reflector31983.K8JTK.org 41000
# 32103 CW-Ops Academy
32103 cwops.dyndns.org 41000
# 33015 KP4CA Digital Network
33015 kp4ca-p25.ddns.net 41000
# 33581 OMISS Group
33581 omiss.dyndns.org 41000
# 37030 RED SKYNET
37030 skynet.xreflector.es 41000
# 37225 Haiti Digital Communications League (HDCL) P25
37225 3.215.215.169 41011
# 37500 Belarus MultiMode Digital Voice Network
37500 xlx375.bfrr.by 41000
# 40721 Fusion Canada Fr
40721 38.110.97.161 41000
# 41120 LONE STAR LINK SYSTEM
41120 216.128.136.176 41000
# 43389 SouthEast Link US
43389 p25.lmarc.net 41000
# 43715 Kazakhstan P25
43715 un7bww.svx03.kz 41000
# 44000 Japan Main P25
44000 p25-2.f5.si 41000
# 44120 Japan P25
44120 p25.f5.si 41000
# 45000 Korea
45000 p25.dvham.com 41000
# 45001 P25-DS5QDR Korea
45001 ds5qdr-mst.duckdns.org 41000
# 46001 P25 Link TG46001, China
46001 46001.bh1nyr.net 41000
# 46010 P25 Link TG46010, Beijing, China
46010 46010.bh1nyr.net 41002
# 46023 P25 Link TG46023 bridge to BM TG46023, Chongqing, China
46023 119.3.248.195 41000
# 46516 P25 Link TG46516, Xuzhou, China
46516 46516.bh1nyr.net 41004
# 46551 China ADEC
46551 60.173.209.129 41000
# 49562 Boredom Breaker
49562 146.71.77.238 41000
# 50210 Bridge to BM TG50210/XLX/YSF/WiresX Malaysia-Net
50210 edone.now.im 41000
50210 edone.no-ip.com 41000
# 50525 Bridge to YSF, NXDN and DMR
50525 50525.p25dvm.com 41000
@ -435,18 +762,39 @@
# 50535 VK Multimode Link
50535 p25tg50535.vkradio.com 41000
# 50536 FreeSTAR VK
50536 p25tg50536.vkradio.com 41001
# 51502 DX1ACE
51502 p25-dx1ace.hopto.org 41000
# 51503 US Philippines P25 network
51503 149.28.201.109 4569
51503 45.79.76.10 41000
# 51526 Omega Communications
51526 omega25.ddns.net 41000
# 51547 KAPIHAN Network
51547 p25.kapihan.net 41000
# 51575 PH-Dumaguete Link (Multimode)
51575 140.82.14.24 41000
# 52072 Phuket
52072 xlx727phuketdstar.ddns.net 41000
# 52032 P25 Link XLX149 Modules C
52032 p52032.pwk.ac.th 41009
# 52072 Phuket P25 <> FreeDMR <> Echolink
52072 203.170.129.69 41000
# 52138 P25 Link Thailand
52138 p2552138.freeddns.org 41000
# 52149 P25 Link To XLX149 Modules D
52149 p52149.pwk.ac.th 41005
# 52910 XLX Nexus
52910 p25x.mywire.org 41000
# 53099 New Zealand bridge to D-Star, DMR and NXDN
53099 203.86.206.49 41000
@ -454,7 +802,20 @@
54100 hs1qcj.ddns.net 41000
# 55100 (WWRARN) World Wide Ragchew Amateur Radio Net
55100 140.82.3.34 41000
55100 45.63.6.57 41000
# 60100 K8SDR SignalsEverywhere Experimenters Club
60100 p25.signalseverywhere.com 41000
60100 p25.signalseverywhere.com 41000
# 60777 Who Cares ARG (URF239 A) https://whocaresradio.com/reflector
60777 urf239.whocaresradio.com 41000
# 63600 Latvian Digital Voice network
63600 xlx.ham.lv 41000
# 65100 P25 2007DXgroup
65100 89.46.75.115 41000
# 65101 KM4HJJ repeater Pompano, Florida
65101 km4hjj-p25.dyndns-server.com 41000

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2014,2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2014,2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,8 +26,8 @@
CP25Network::CP25Network(unsigned short port, const std::string& callsign, bool debug) :
m_callsign(callsign),
m_socket(),
m_port(port),
m_socket4(port),
m_socket6(port),
m_debug(debug)
{
assert(port > 0U);
@ -43,16 +43,17 @@ bool CP25Network::open()
{
LogInfo("Opening P25 network connection");
unsigned int index = 0U;
sockaddr_storage addr4;
addr4.ss_family = AF_INET;
bool ret1 = m_socket.open(index, PF_INET, "", m_port);
if (ret1)
index++;
bool ret = m_socket4.open(addr4);
if (!ret)
return false;
bool ret2 = m_socket.open(index, PF_INET6, "", m_port);
sockaddr_storage addr6;
addr6.ss_family = AF_INET6;
// We're OK as long as we have either IPv4 or IPv6 or both.
return ret1 || ret2;
return m_socket6.open(addr6);
}
bool CP25Network::write(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen)
@ -63,7 +64,15 @@ bool CP25Network::write(const unsigned char* data, unsigned int length, const so
if (m_debug)
CUtils::dump(1U, "P25 Network Data Sent", data, length);
return m_socket.write(data, length, addr, addrLen);
switch (addr.ss_family) {
case AF_INET:
return m_socket4.write(data, length, addr, addrLen);
case AF_INET6:
return m_socket6.write(data, length, addr, addrLen);
default:
LogError("Unknown socket address family - %u", addr.ss_family);
return false;
}
}
bool CP25Network::poll(const sockaddr_storage& addr, unsigned int addrLen)
@ -78,7 +87,15 @@ bool CP25Network::poll(const sockaddr_storage& addr, unsigned int addrLen)
if (m_debug)
CUtils::dump(1U, "P25 Network Poll Sent", data, 11U);
return m_socket.write(data, 11U, addr, addrLen);
switch (addr.ss_family) {
case AF_INET:
return m_socket4.write(data, 11U, addr, addrLen);
case AF_INET6:
return m_socket6.write(data, 11U, addr, addrLen);
default:
LogError("Unknown socket address family - %u", addr.ss_family);
return false;
}
}
bool CP25Network::unlink(const sockaddr_storage& addr, unsigned int addrLen)
@ -93,7 +110,15 @@ bool CP25Network::unlink(const sockaddr_storage& addr, unsigned int addrLen)
if (m_debug)
CUtils::dump(1U, "P25 Network Unlink Sent", data, 11U);
return m_socket.write(data, 11U, addr, addrLen);
switch (addr.ss_family) {
case AF_INET:
return m_socket4.write(data, 11U, addr, addrLen);
case AF_INET6:
return m_socket6.write(data, 11U, addr, addrLen);
default:
LogError("Unknown socket address family - %u", addr.ss_family);
return false;
}
}
unsigned int CP25Network::read(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen)
@ -101,7 +126,9 @@ unsigned int CP25Network::read(unsigned char* data, unsigned int length, sockadd
assert(data != NULL);
assert(length > 0U);
int len = m_socket.read(data, length, addr, addrLen);
int len = m_socket4.read(data, length, addr, addrLen);
if (len <= 0)
len = m_socket6.read(data, length, addr, addrLen);
if (len <= 0)
return 0U;
@ -113,7 +140,8 @@ unsigned int CP25Network::read(unsigned char* data, unsigned int length, sockadd
void CP25Network::close()
{
m_socket.close();
m_socket4.close();
m_socket6.close();
LogInfo("Closing P25 network connection");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2014,2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2014,2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -42,10 +42,10 @@ public:
void close();
private:
std::string m_callsign;
CUDPSocket m_socket;
unsigned short m_port;
bool m_debug;
std::string m_callsign;
CUDPSocket m_socket4;
CUDPSocket m_socket6;
bool m_debug;
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2006-2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -34,29 +34,19 @@
#endif
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
m_address_save(address),
m_port_save(port),
m_counter(0U)
m_localAddress(address),
m_localPort(port),
m_fd(-1),
m_af(AF_UNSPEC)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::CUDPSocket(unsigned short port) :
m_address_save(),
m_port_save(port),
m_counter(0U)
m_localAddress(),
m_localPort(port),
m_fd(-1),
m_af(AF_UNSPEC)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::~CUDPSocket()
@ -93,10 +83,10 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
std::string portstr = std::to_string(port);
struct addrinfo *res;
/* port is always digits, no needs to lookup service */
/* Port is always digits, no needs to lookup service */
hints.ai_flags |= AI_NUMERICSERV;
int err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res);
int err = ::getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res);
if (err != 0) {
sockaddr_in* paddr = (sockaddr_in*)&addr;
::memset(paddr, 0x00U, address_length = sizeof(sockaddr_in));
@ -109,7 +99,7 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
freeaddrinfo(res);
::freeaddrinfo(res);
return 0;
}
@ -121,33 +111,33 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
if (type == IMT_ADDRESS_AND_PORT) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
}
} else if (type == IMT_ADDRESS_ONLY) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
}
} else {
return false;
@ -163,35 +153,34 @@ bool CUDPSocket::isNone(const sockaddr_storage& addr)
bool CUDPSocket::open(const sockaddr_storage& address)
{
return open(address.ss_family);
m_af = address.ss_family;
return open();
}
bool CUDPSocket::open(unsigned int af)
bool CUDPSocket::open()
{
return open(0, af, m_address_save, m_port_save);
}
assert(m_fd == -1);
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
{
sockaddr_storage addr;
unsigned int addrlen;
struct addrinfo hints;
::memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = af;
hints.ai_family = m_af;
/* to determine protocol family, call lookup() first. */
int err = lookup(address, port, addr, addrlen, hints);
// To determine protocol family, call lookup() on the local address first.
int err = lookup(m_localAddress, m_localPort, addr, addrlen, hints);
if (err != 0) {
LogError("The local address is invalid - %s", address.c_str());
LogError("The local address is invalid - %s", m_localAddress.c_str());
return false;
}
close(index);
m_af = addr.ss_family;
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
if (fd < 0) {
m_fd = ::socket(m_af, SOCK_DGRAM, 0);
if (m_fd < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
#else
@ -200,62 +189,51 @@ bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std
return false;
}
m_address[index] = address;
m_port[index] = port;
m_af[index] = addr.ss_family;
m_fd[index] = fd;
if (port > 0U) {
if (m_localPort > 0U) {
int reuse = 1;
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError());
#else
LogError("Cannot set the UDP socket option, err: %d", errno);
#endif
close();
return false;
}
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
if (::bind(m_fd, (sockaddr*)&addr, addrlen) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot bind the UDP address, err: %lu", ::GetLastError());
#else
LogError("Cannot bind the UDP address, err: %d", errno);
#endif
close();
return false;
}
LogInfo("Opening UDP port on %hu", port);
LogInfo("Opening UDP port on %hu", m_localPort);
}
return true;
}
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength)
{
assert(buffer != NULL);
assert(length > 0U);
assert(m_fd >= 0);
// Check that the readfrom() won't block
int i, n;
struct pollfd pfd[UDP_SOCKET_MAX];
for (i = n = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] >= 0) {
pfd[n].fd = m_fd[i];
pfd[n].events = POLLIN;
n++;
}
}
// no socket descriptor to receive
if (n == 0)
return 0;
struct pollfd pfd;
pfd.fd = m_fd;
pfd.events = POLLIN;
pfd.revents = 0;
// Return immediately
#if defined(_WIN32) || defined(_WIN64)
int ret = WSAPoll(pfd, n, 0);
int ret = WSAPoll(&pfd, 1, 0);
#else
int ret = ::poll(pfd, n, 0);
int ret = ::poll(&pfd, 1, 0);
#endif
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
@ -266,14 +244,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
return -1;
}
int index;
for (i = 0; i < n; i++) {
// round robin
index = (i + m_counter) % n;
if (pfd[index].revents & POLLIN)
break;
}
if (i == n)
if ((pfd.revents & POLLIN) == 0)
return 0;
#if defined(_WIN32) || defined(_WIN64)
@ -283,9 +254,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
#endif
#if defined(_WIN32) || defined(_WIN64)
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#else
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#endif
if (len <= 0) {
#if defined(_WIN32) || defined(_WIN64)
@ -294,7 +265,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
LogError("Error returned from recvfrom, err: %d", errno);
if (len == -1 && errno == ENOTSOCK) {
LogMessage("Re-opening UDP port on %hu", m_port[index]);
LogMessage("Re-opening UDP port on %hu", m_localPort);
close();
open();
}
@ -302,43 +273,39 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
return -1;
}
m_counter++;
address_length = size;
addressLength = size;
return len;
}
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength)
{
assert(buffer != NULL);
assert(length > 0U);
assert(m_fd >= 0);
bool result = false;
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] < 0 || m_af[i] != address.ss_family)
continue;
#if defined(_WIN32) || defined(_WIN64)
int ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
#else
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
#endif
if (ret < 0) {
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Error returned from sendto, err: %lu", ::GetLastError());
LogError("Error returned from sendto, err: %lu", ::GetLastError());
#else
LogError("Error returned from sendto, err: %d", errno);
LogError("Error returned from sendto, err: %d", errno);
#endif
} else {
} else {
#if defined(_WIN32) || defined(_WIN64)
if (ret == int(length))
result = true;
if (ret == int(length))
result = true;
#else
if (ret == ssize_t(length))
result = true;
if (ret == ssize_t(length))
result = true;
#endif
}
}
return result;
@ -346,18 +313,13 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s
void CUDPSocket::close()
{
for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++)
close(i);
}
void CUDPSocket::close(const unsigned int index)
{
if ((index < UDP_SOCKET_MAX) && (m_fd[index] >= 0)) {
if (m_fd >= 0) {
#if defined(_WIN32) || defined(_WIN64)
::closesocket(m_fd[index]);
::closesocket(m_fd);
#else
::close(m_fd[index]);
::close(m_fd);
#endif
m_fd[index] = -1;
m_fd = -1;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,10 +35,6 @@
#include <ws2tcpip.h>
#endif
#if !defined(UDP_SOCKET_MAX)
#define UDP_SOCKET_MAX 1
#endif
enum IPMATCHTYPE {
IMT_ADDRESS_AND_PORT,
IMT_ADDRESS_ONLY
@ -50,34 +46,33 @@ public:
CUDPSocket(unsigned short port = 0U);
~CUDPSocket();
bool open(unsigned int af = AF_UNSPEC);
bool open();
bool open(const sockaddr_storage& address);
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port);
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length);
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length);
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength);
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength);
void close();
void close(const unsigned int index);
static void startup();
static void shutdown();
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
static bool isNone(const sockaddr_storage& addr);
private:
std::string m_address_save;
unsigned short m_port_save;
std::string m_address[UDP_SOCKET_MAX];
unsigned short m_port[UDP_SOCKET_MAX];
unsigned int m_af[UDP_SOCKET_MAX];
int m_fd[UDP_SOCKET_MAX];
unsigned int m_counter;
std::string m_localAddress;
unsigned short m_localPort;
#if defined(_WIN32) || defined(_WIN64)
SOCKET m_fd;
#else
int m_fd;
#endif
sa_family_t m_af;
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
* Copyright (C) 2015-2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20201105";
const char* VERSION = "20240129";
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2006-2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -34,29 +34,19 @@
#endif
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
m_address_save(address),
m_port_save(port),
m_counter(0U)
m_localAddress(address),
m_localPort(port),
m_fd(-1),
m_af(AF_UNSPEC)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::CUDPSocket(unsigned short port) :
m_address_save(),
m_port_save(port),
m_counter(0U)
m_localAddress(),
m_localPort(port),
m_fd(-1),
m_af(AF_UNSPEC)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::~CUDPSocket()
@ -93,10 +83,10 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
std::string portstr = std::to_string(port);
struct addrinfo *res;
/* port is always digits, no needs to lookup service */
/* Port is always digits, no needs to lookup service */
hints.ai_flags |= AI_NUMERICSERV;
int err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res);
int err = ::getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res);
if (err != 0) {
sockaddr_in* paddr = (sockaddr_in*)&addr;
::memset(paddr, 0x00U, address_length = sizeof(sockaddr_in));
@ -109,7 +99,7 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockadd
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
freeaddrinfo(res);
::freeaddrinfo(res);
return 0;
}
@ -121,33 +111,33 @@ bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& ad
if (type == IMT_ADDRESS_AND_PORT) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
}
} else if (type == IMT_ADDRESS_ONLY) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
}
} else {
return false;
@ -163,35 +153,34 @@ bool CUDPSocket::isNone(const sockaddr_storage& addr)
bool CUDPSocket::open(const sockaddr_storage& address)
{
return open(address.ss_family);
m_af = address.ss_family;
return open();
}
bool CUDPSocket::open(unsigned int af)
bool CUDPSocket::open()
{
return open(0, af, m_address_save, m_port_save);
}
assert(m_fd == -1);
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
{
sockaddr_storage addr;
unsigned int addrlen;
struct addrinfo hints;
::memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = af;
hints.ai_family = m_af;
/* to determine protocol family, call lookup() first. */
int err = lookup(address, port, addr, addrlen, hints);
// To determine protocol family, call lookup() on the local address first.
int err = lookup(m_localAddress, m_localPort, addr, addrlen, hints);
if (err != 0) {
LogError("The local address is invalid - %s", address.c_str());
LogError("The local address is invalid - %s", m_localAddress.c_str());
return false;
}
close(index);
m_af = addr.ss_family;
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
if (fd < 0) {
m_fd = ::socket(m_af, SOCK_DGRAM, 0);
if (m_fd < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
#else
@ -200,62 +189,51 @@ bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std
return false;
}
m_address[index] = address;
m_port[index] = port;
m_af[index] = addr.ss_family;
m_fd[index] = fd;
if (port > 0U) {
if (m_localPort > 0U) {
int reuse = 1;
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError());
#else
LogError("Cannot set the UDP socket option, err: %d", errno);
#endif
close();
return false;
}
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
if (::bind(m_fd, (sockaddr*)&addr, addrlen) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot bind the UDP address, err: %lu", ::GetLastError());
#else
LogError("Cannot bind the UDP address, err: %d", errno);
#endif
close();
return false;
}
LogInfo("Opening UDP port on %hu", port);
LogInfo("Opening UDP port on %hu", m_localPort);
}
return true;
}
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength)
{
assert(buffer != NULL);
assert(length > 0U);
assert(m_fd >= 0);
// Check that the readfrom() won't block
int i, n;
struct pollfd pfd[UDP_SOCKET_MAX];
for (i = n = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] >= 0) {
pfd[n].fd = m_fd[i];
pfd[n].events = POLLIN;
n++;
}
}
// no socket descriptor to receive
if (n == 0)
return 0;
struct pollfd pfd;
pfd.fd = m_fd;
pfd.events = POLLIN;
pfd.revents = 0;
// Return immediately
#if defined(_WIN32) || defined(_WIN64)
int ret = WSAPoll(pfd, n, 0);
int ret = WSAPoll(&pfd, 1, 0);
#else
int ret = ::poll(pfd, n, 0);
int ret = ::poll(&pfd, 1, 0);
#endif
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
@ -266,14 +244,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
return -1;
}
int index;
for (i = 0; i < n; i++) {
// round robin
index = (i + m_counter) % n;
if (pfd[index].revents & POLLIN)
break;
}
if (i == n)
if ((pfd.revents & POLLIN) == 0)
return 0;
#if defined(_WIN32) || defined(_WIN64)
@ -283,9 +254,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
#endif
#if defined(_WIN32) || defined(_WIN64)
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#else
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#endif
if (len <= 0) {
#if defined(_WIN32) || defined(_WIN64)
@ -294,7 +265,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
LogError("Error returned from recvfrom, err: %d", errno);
if (len == -1 && errno == ENOTSOCK) {
LogMessage("Re-opening UDP port on %hu", m_port[index]);
LogMessage("Re-opening UDP port on %hu", m_localPort);
close();
open();
}
@ -302,43 +273,39 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag
return -1;
}
m_counter++;
address_length = size;
addressLength = size;
return len;
}
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength)
{
assert(buffer != NULL);
assert(length > 0U);
assert(m_fd >= 0);
bool result = false;
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] < 0 || m_af[i] != address.ss_family)
continue;
#if defined(_WIN32) || defined(_WIN64)
int ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
#else
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, addressLength);
#endif
if (ret < 0) {
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Error returned from sendto, err: %lu", ::GetLastError());
LogError("Error returned from sendto, err: %lu", ::GetLastError());
#else
LogError("Error returned from sendto, err: %d", errno);
LogError("Error returned from sendto, err: %d", errno);
#endif
} else {
} else {
#if defined(_WIN32) || defined(_WIN64)
if (ret == int(length))
result = true;
if (ret == int(length))
result = true;
#else
if (ret == ssize_t(length))
result = true;
if (ret == ssize_t(length))
result = true;
#endif
}
}
return result;
@ -346,18 +313,13 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s
void CUDPSocket::close()
{
for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++)
close(i);
}
void CUDPSocket::close(const unsigned int index)
{
if ((index < UDP_SOCKET_MAX) && (m_fd[index] >= 0)) {
if (m_fd >= 0) {
#if defined(_WIN32) || defined(_WIN64)
::closesocket(m_fd[index]);
::closesocket(m_fd);
#else
::close(m_fd[index]);
::close(m_fd);
#endif
m_fd[index] = -1;
m_fd = -1;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2011,2013,2015,2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,10 +35,6 @@
#include <ws2tcpip.h>
#endif
#if !defined(UDP_SOCKET_MAX)
#define UDP_SOCKET_MAX 1
#endif
enum IPMATCHTYPE {
IMT_ADDRESS_AND_PORT,
IMT_ADDRESS_ONLY
@ -50,34 +46,33 @@ public:
CUDPSocket(unsigned short port = 0U);
~CUDPSocket();
bool open(unsigned int af = AF_UNSPEC);
bool open();
bool open(const sockaddr_storage& address);
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port);
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length);
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length);
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &addressLength);
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int addressLength);
void close();
void close(const unsigned int index);
static void startup();
static void shutdown();
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& addressLength, struct addrinfo& hints);
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
static bool isNone(const sockaddr_storage& addr);
private:
std::string m_address_save;
unsigned short m_port_save;
std::string m_address[UDP_SOCKET_MAX];
unsigned short m_port[UDP_SOCKET_MAX];
unsigned int m_af[UDP_SOCKET_MAX];
int m_fd[UDP_SOCKET_MAX];
unsigned int m_counter;
std::string m_localAddress;
unsigned short m_localPort;
#if defined(_WIN32) || defined(_WIN64)
SOCKET m_fd;
#else
int m_fd;
#endif
sa_family_t m_af;
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2020,2024 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20201101";
const char* VERSION = "20240129";
#endif

View File

@ -1,191 +0,0 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Conf.h"
#include "Log.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
const int BUFFER_SIZE = 500;
enum SECTION {
SECTION_NONE,
SECTION_GENERAL,
SECTION_ID_LOOKUP,
SECTION_LOG,
SECTION_NETWORK
};
CConf::CConf(const std::string& file) :
m_file(file),
m_daemon(false),
m_lookupName(),
m_lookupTime(0U),
m_logDisplayLevel(0U),
m_logFileLevel(0U),
m_logFilePath(),
m_logFileRoot(),
m_logFileRotate(true),
m_networkPort(0U),
m_networkDebug(false)
{
}
CConf::~CConf()
{
}
bool CConf::read()
{
FILE* fp = ::fopen(m_file.c_str(), "rt");
if (fp == NULL) {
::fprintf(stderr, "Couldn't open the .ini file - %s\n", m_file.c_str());
return false;
}
SECTION section = SECTION_NONE;
char buffer[BUFFER_SIZE];
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
if (buffer[0U] == '#')
continue;
if (buffer[0U] == '[') {
if (::strncmp(buffer, "[General]", 9U) == 0)
section = SECTION_GENERAL;
else if (::strncmp(buffer, "[Id Lookup]", 11U) == 0)
section = SECTION_ID_LOOKUP;
else if (::strncmp(buffer, "[Log]", 5U) == 0)
section = SECTION_LOG;
else if (::strncmp(buffer, "[Network]", 9U) == 0)
section = SECTION_NETWORK;
else
section = SECTION_NONE;
continue;
}
char* key = ::strtok(buffer, " \t=\r\n");
if (key == NULL)
continue;
char* value = ::strtok(NULL, "\r\n");
if (value == NULL)
continue;
// Remove quotes from the value
size_t len = ::strlen(value);
if (len > 1U && *value == '"' && value[len - 1U] == '"') {
value[len - 1U] = '\0';
value++;
} else {
char *p;
// if value is not quoted, remove after # (to make comment)
if ((p = strchr(value, '#')) != NULL)
*p = '\0';
// remove trailing tab/space
for (p = value + strlen(value) - 1U; p >= value && (*p == '\t' || *p == ' '); p--)
*p = '\0';
}
if (section == SECTION_GENERAL) {
if (::strcmp(key, "Daemon") == 0)
m_daemon = ::atoi(value) == 1;
} else if (section == SECTION_ID_LOOKUP) {
if (::strcmp(key, "Name") == 0)
m_lookupName = value;
else if (::strcmp(key, "Time") == 0)
m_lookupTime = (unsigned int)::atoi(value);
} else if (section == SECTION_LOG) {
if (::strcmp(key, "FilePath") == 0)
m_logFilePath = value;
else if (::strcmp(key, "FileRoot") == 0)
m_logFileRoot = value;
else if (::strcmp(key, "FileLevel") == 0)
m_logFileLevel = (unsigned int)::atoi(value);
else if (::strcmp(key, "DisplayLevel") == 0)
m_logDisplayLevel = (unsigned int)::atoi(value);
else if (::strcmp(key, "FileRotate") == 0)
m_logFileRotate = ::atoi(value) == 1;
} else if (section == SECTION_NETWORK) {
if (::strcmp(key, "Port") == 0)
m_networkPort = (unsigned short)::atoi(value);
else if (::strcmp(key, "Debug") == 0)
m_networkDebug = ::atoi(value) == 1;
}
}
::fclose(fp);
return true;
}
bool CConf::getDaemon() const
{
return m_daemon;
}
std::string CConf::getLookupName() const
{
return m_lookupName;
}
unsigned int CConf::getLookupTime() const
{
return m_lookupTime;
}
unsigned int CConf::getLogDisplayLevel() const
{
return m_logDisplayLevel;
}
unsigned int CConf::getLogFileLevel() const
{
return m_logFileLevel;
}
std::string CConf::getLogFilePath() const
{
return m_logFilePath;
}
std::string CConf::getLogFileRoot() const
{
return m_logFileRoot;
}
bool CConf::getLogFileRotate() const
{
return m_logFileRotate;
}
unsigned short CConf::getNetworkPort() const
{
return m_networkPort;
}
bool CConf::getNetworkDebug() const
{
return m_networkDebug;
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(CONF_H)
#define CONF_H
#include <string>
#include <vector>
class CConf
{
public:
CConf(const std::string& file);
~CConf();
bool read();
// The General section
bool getDaemon() const;
// The Id Lookup section
std::string getLookupName() const;
unsigned int getLookupTime() const;
// The Log section
unsigned int getLogDisplayLevel() const;
unsigned int getLogFileLevel() const;
std::string getLogFilePath() const;
std::string getLogFileRoot() const;
bool getLogFileRotate() const;
// The Network section
unsigned short getNetworkPort() const;
bool getNetworkDebug() const;
private:
std::string m_file;
bool m_daemon;
std::string m_lookupName;
unsigned int m_lookupTime;
unsigned int m_logDisplayLevel;
unsigned int m_logFileLevel;
std::string m_logFilePath;
std::string m_logFileRoot;
bool m_logFileRotate;
unsigned short m_networkPort;
bool m_networkDebug;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
/*
* Copyright (C) 2016 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "DMRLookup.h"
#include "Timer.h"
#include "Log.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
CDMRLookup::CDMRLookup(const std::string& filename, unsigned int reloadTime) :
CThread(),
m_filename(filename),
m_reloadTime(reloadTime),
m_table(),
m_mutex(),
m_stop(false)
{
}
CDMRLookup::~CDMRLookup()
{
}
bool CDMRLookup::read()
{
bool ret = load();
if (m_reloadTime > 0U)
run();
return ret;
}
void CDMRLookup::entry()
{
LogInfo("Started the DMR Id lookup reload thread");
CTimer timer(1U, 3600U * m_reloadTime);
timer.start();
while (!m_stop) {
sleep(1000U);
timer.clock();
if (timer.hasExpired()) {
load();
timer.start();
}
}
LogInfo("Stopped the DMR Id lookup reload thread");
}
void CDMRLookup::stop()
{
if (m_reloadTime == 0U) {
delete this;
return;
}
m_stop = true;
wait();
}
std::string CDMRLookup::find(unsigned int id)
{
std::string callsign;
if (id == 0xFFFFFFU)
return std::string("ALL");
m_mutex.lock();
try {
callsign = m_table.at(id);
} catch (...) {
char text[10U];
::sprintf(text, "%u", id);
callsign = std::string(text);
}
m_mutex.unlock();
return callsign;
}
bool CDMRLookup::load()
{
FILE* fp = ::fopen(m_filename.c_str(), "rt");
if (fp == NULL) {
LogWarning("Cannot open the Id lookup file - %s", m_filename.c_str());
return false;
}
m_mutex.lock();
// Remove the old entries
m_table.clear();
char buffer[100U];
while (::fgets(buffer, 100U, fp) != NULL) {
if (buffer[0U] == '#')
continue;
char* p1 = ::strtok(buffer, " \t\r\n");
char* p2 = ::strtok(NULL, " \t\r\n");
if (p1 != NULL && p2 != NULL) {
unsigned int id = (unsigned int)::atoi(p1);
for (char* p = p2; *p != 0x00U; p++)
*p = ::toupper(*p);
m_table[id] = std::string(p2);
}
}
m_mutex.unlock();
::fclose(fp);
size_t size = m_table.size();
if (size == 0U)
return false;
LogInfo("Loaded %u Ids to the callsign lookup table", size);
return true;
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2016 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef DMRLookup_H
#define DMRLookup_H
#include "Thread.h"
#include "Mutex.h"
#include <string>
#include <unordered_map>
class CDMRLookup : public CThread {
public:
CDMRLookup(const std::string& filename, unsigned int reloadTime);
virtual ~CDMRLookup();
bool read();
virtual void entry();
std::string find(unsigned int id);
void stop();
private:
std::string m_filename;
unsigned int m_reloadTime;
std::unordered_map<unsigned int, std::string> m_table;
CMutex m_mutex;
bool m_stop;
bool load();
};
#endif

View File

@ -1,192 +0,0 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Log.h"
#if defined(_WIN32) || defined(_WIN64)
#include <Windows.h>
#else
#include <sys/time.h>
#include <unistd.h>
#endif
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <ctime>
#include <cassert>
#include <cstring>
static unsigned int m_fileLevel = 2U;
static std::string m_filePath;
static std::string m_fileRoot;
static bool m_fileRotate = true;
static FILE* m_fpLog = NULL;
static bool m_daemon = false;
static unsigned int m_displayLevel = 2U;
static struct tm m_tm;
static char LEVELS[] = " DMIWEF";
static bool logOpenRotate()
{
bool status = false;
if (m_fileLevel == 0U)
return true;
time_t now;
::time(&now);
struct tm* tm = ::gmtime(&now);
if (tm->tm_mday == m_tm.tm_mday && tm->tm_mon == m_tm.tm_mon && tm->tm_year == m_tm.tm_year) {
if (m_fpLog != NULL)
return true;
} else {
if (m_fpLog != NULL)
::fclose(m_fpLog);
}
char filename[200U];
#if defined(_WIN32) || defined(_WIN64)
::sprintf(filename, "%s\\%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
#else
::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
#endif
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
status = true;
#if !defined(_WIN32) && !defined(_WIN64)
if (m_daemon)
dup2(fileno(m_fpLog), fileno(stderr));
#endif
}
m_tm = *tm;
return status;
}
static bool logOpenNoRotate()
{
bool status = false;
if (m_fileLevel == 0U)
return true;
if (m_fpLog != NULL)
return true;
char filename[200U];
#if defined(_WIN32) || defined(_WIN64)
::sprintf(filename, "%s\\%s.log", m_filePath.c_str(), m_fileRoot.c_str());
#else
::sprintf(filename, "%s/%s.log", m_filePath.c_str(), m_fileRoot.c_str());
#endif
if ((m_fpLog = ::fopen(filename, "a+t")) != NULL) {
status = true;
#if !defined(_WIN32) && !defined(_WIN64)
if (m_daemon)
dup2(fileno(m_fpLog), fileno(stderr));
#endif
}
return status;
}
bool LogOpen()
{
if (m_fileRotate)
return logOpenRotate();
else
return logOpenNoRotate();
}
bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate)
{
m_filePath = filePath;
m_fileRoot = fileRoot;
m_fileLevel = fileLevel;
m_displayLevel = displayLevel;
m_daemon = daemon;
m_fileRotate = rotate;
if (m_daemon)
m_displayLevel = 0U;
return ::LogOpen();
}
void LogFinalise()
{
if (m_fpLog != NULL)
::fclose(m_fpLog);
}
void Log(unsigned int level, const char* fmt, ...)
{
assert(fmt != NULL);
char buffer[501U];
#if defined(_WIN32) || defined(_WIN64)
SYSTEMTIME st;
::GetSystemTime(&st);
::sprintf(buffer, "%c: %04u-%02u-%02u %02u:%02u:%02u.%03u ", LEVELS[level], st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
#else
struct timeval now;
::gettimeofday(&now, NULL);
struct tm* tm = ::gmtime(&now.tv_sec);
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03ld ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000L);
#endif
va_list vl;
va_start(vl, fmt);
::vsnprintf(buffer + ::strlen(buffer), 500, fmt, vl);
va_end(vl);
if (level >= m_fileLevel && m_fileLevel != 0U) {
bool ret = ::LogOpen();
if (!ret)
return;
::fprintf(m_fpLog, "%s\n", buffer);
::fflush(m_fpLog);
}
if (level >= m_displayLevel && m_displayLevel != 0U) {
::fprintf(stdout, "%s\n", buffer);
::fflush(stdout);
}
if (level == 6U) { // Fatal
::fclose(m_fpLog);
exit(1);
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(LOG_H)
#define LOG_H
#include <string>
#define LogDebug(fmt, ...) Log(1U, fmt, ##__VA_ARGS__)
#define LogMessage(fmt, ...) Log(2U, fmt, ##__VA_ARGS__)
#define LogInfo(fmt, ...) Log(3U, fmt, ##__VA_ARGS__)
#define LogWarning(fmt, ...) Log(4U, fmt, ##__VA_ARGS__)
#define LogError(fmt, ...) Log(5U, fmt, ##__VA_ARGS__)
#define LogFatal(fmt, ...) Log(6U, fmt, ##__VA_ARGS__)
extern void Log(unsigned int level, const char* fmt, ...);
extern bool LogInitialise(bool daemon, const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel, bool rotate);
extern void LogFinalise();
#endif

View File

@ -1,22 +0,0 @@
CC = cc
CXX = c++
CFLAGS = -g -O3 -Wall -DHAVE_LOG_H -DUDP_SOCKET_MAX=2 -std=c++0x -pthread
LIBS = -lpthread
LDFLAGS = -g
OBJECTS = Conf.o DMRLookup.o Log.o Mutex.o Network.o P25Reflector.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o
all: P25Reflector
P25Reflector: $(OBJECTS)
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o P25Reflector
%.o: %.cpp
$(CXX) $(CFLAGS) -c -o $@ $<
install:
install -m 755 P25Reflector /usr/local/bin/
clean:
$(RM) P25Reflector *.o *.d *.bak *~

View File

@ -1,65 +0,0 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Mutex.h"
#if defined(_WIN32) || defined(_WIN64)
CMutex::CMutex() :
m_handle()
{
m_handle = ::CreateMutex(NULL, FALSE, NULL);
}
CMutex::~CMutex()
{
::CloseHandle(m_handle);
}
void CMutex::lock()
{
::WaitForSingleObject(m_handle, INFINITE);
}
void CMutex::unlock()
{
::ReleaseMutex(m_handle);
}
#else
CMutex::CMutex() :
m_mutex(PTHREAD_MUTEX_INITIALIZER)
{
}
CMutex::~CMutex()
{
}
void CMutex::lock()
{
::pthread_mutex_lock(&m_mutex);
}
void CMutex::unlock()
{
::pthread_mutex_unlock(&m_mutex);
}
#endif

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(MUTEX_H)
#define MUTEX_H
#if defined(_WIN32) || defined(_WIN64)
#include <WS2tcpip.h>
#include <windows.h>
#else
#include <pthread.h>
#endif
class CMutex
{
public:
CMutex();
~CMutex();
void lock();
void unlock();
private:
#if defined(_WIN32) || defined(_WIN64)
HANDLE m_handle;
#else
pthread_mutex_t m_mutex;
#endif
};
#endif

View File

@ -1,75 +0,0 @@
/*
* Copyright (C) 2009-2014,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Network.h"
#include "Utils.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
#include <cstring>
CNetwork::CNetwork(unsigned short port, bool debug) :
m_socket(port),
m_debug(debug)
{
}
CNetwork::~CNetwork()
{
}
bool CNetwork::open()
{
LogInfo("Opening P25 network connection");
return m_socket.open();
}
bool CNetwork::writeData(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen)
{
assert(data != NULL);
assert(length > 0U);
if (m_debug)
CUtils::dump(1U, "P25 Network Data Sent", data, length);
return m_socket.write(data, length, addr, addrLen);
}
unsigned int CNetwork::readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen)
{
assert(data != NULL);
assert(length > 0U);
int len = m_socket.read(data, length, addr, addrLen);
if (len <= 0)
return 0U;
if (m_debug)
CUtils::dump(1U, "P25 Network Data Received", data, len);
return len;
}
void CNetwork::close()
{
m_socket.close();
LogInfo("Closing P25 network connection");
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2009-2014,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef Network_H
#define Network_H
#include "UDPSocket.h"
#include <cstdint>
#include <string>
class CNetwork {
public:
CNetwork(unsigned short port, bool debug);
~CNetwork();
bool open();
bool writeData(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen);
unsigned int readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen);
void close();
private:
CUDPSocket m_socket;
bool m_debug;
};
#endif

View File

@ -1,363 +0,0 @@
/*
* Copyright (C) 2016,2018,2020,2021 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "P25Reflector.h"
#include "StopWatch.h"
#include "DMRLookup.h"
#include "Network.h"
#include "Version.h"
#include "Thread.h"
#include "Utils.h"
#include "Log.h"
#if defined(_WIN32) || defined(_WIN64)
#include <WS2tcpip.h>
#include <Windows.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <pwd.h>
#endif
#if defined(_WIN32) || defined(_WIN64)
const char* DEFAULT_INI_FILE = "P25Reflector.ini";
#else
const char* DEFAULT_INI_FILE = "/etc/P25Reflector.ini";
#endif
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <ctime>
#include <cstring>
#include <algorithm>
int main(int argc, char** argv)
{
const char* iniFile = DEFAULT_INI_FILE;
if (argc > 1) {
for (int currentArg = 1; currentArg < argc; ++currentArg) {
std::string arg = argv[currentArg];
if ((arg == "-v") || (arg == "--version")) {
::fprintf(stdout, "P25Reflector version %s\n", VERSION);
return 0;
} else if (arg.substr(0, 1) == "-") {
::fprintf(stderr, "Usage: P25Reflector [-v|--version] [filename]\n");
return 1;
} else {
iniFile = argv[currentArg];
}
}
}
CP25Reflector* reflector = new CP25Reflector(std::string(iniFile));
reflector->run();
delete reflector;
return 0;
}
CP25Reflector::CP25Reflector(const std::string& file) :
m_conf(file),
m_repeaters()
{
CUDPSocket::startup();
}
CP25Reflector::~CP25Reflector()
{
CUDPSocket::shutdown();
}
void CP25Reflector::run()
{
bool ret = m_conf.read();
if (!ret) {
::fprintf(stderr, "P25Reflector: cannot read the .ini file\n");
return;
}
#if !defined(_WIN32) && !defined(_WIN64)
bool m_daemon = m_conf.getDaemon();
if (m_daemon) {
// Create new process
pid_t pid = ::fork();
if (pid == -1) {
::fprintf(stderr, "Couldn't fork() , exiting\n");
return;
} else if (pid != 0) {
exit(EXIT_SUCCESS);
}
// Create new session and process group
if (::setsid() == -1) {
::fprintf(stderr, "Couldn't setsid(), exiting\n");
return;
}
// Set the working directory to the root directory
if (::chdir("/") == -1) {
::fprintf(stderr, "Couldn't cd /, exiting\n");
return;
}
// If we are currently root...
if (getuid() == 0) {
struct passwd* user = ::getpwnam("mmdvm");
if (user == NULL) {
::fprintf(stderr, "Could not get the mmdvm user, exiting\n");
return;
}
uid_t mmdvm_uid = user->pw_uid;
gid_t mmdvm_gid = user->pw_gid;
// Set user and group ID's to mmdvm:mmdvm
if (setgid(mmdvm_gid) != 0) {
::fprintf(stderr, "Could not set mmdvm GID, exiting\n");
return;
}
if (setuid(mmdvm_uid) != 0) {
::fprintf(stderr, "Could not set mmdvm UID, exiting\n");
return;
}
// Double check it worked (AKA Paranoia)
if (setuid(0) != -1) {
::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n");
return;
}
}
}
#endif
#if !defined(_WIN32) && !defined(_WIN64)
ret = ::LogInitialise(m_daemon, m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel(), m_conf.getLogFileRotate());
#else
ret = ::LogInitialise(false, m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel(), m_conf.getLogFileRotate());
#endif
if (!ret) {
::fprintf(stderr, "P25Gateway: unable to open the log file\n");
return;
}
#if !defined(_WIN32) && !defined(_WIN64)
if (m_daemon) {
::close(STDIN_FILENO);
::close(STDOUT_FILENO);
::close(STDERR_FILENO);
}
#endif
CNetwork network(m_conf.getNetworkPort(), m_conf.getNetworkDebug());
ret = network.open();
if (!ret) {
::LogFinalise();
return;
}
CDMRLookup* lookup = new CDMRLookup(m_conf.getLookupName(), m_conf.getLookupTime());
lookup->read();
CStopWatch stopWatch;
stopWatch.start();
CTimer dumpTimer(1000U, 120U);
dumpTimer.start();
LogMessage("Starting P25Reflector-%s", VERSION);
CP25Repeater* current = NULL;
bool displayed = false;
bool seen64 = false;
bool seen65 = false;
CTimer watchdogTimer(1000U, 0U, 1500U);
unsigned char lcf = 0U;
unsigned int srcId = 0U;
unsigned int dstId = 0U;
for (;;) {
unsigned char buffer[200U];
sockaddr_storage addr;
unsigned int addrLen;
unsigned int len = network.readData(buffer, 200U, addr, addrLen);
if (len > 0U) {
CP25Repeater* rpt = findRepeater(addr);
if (buffer[0U] == 0xF0U) {
if (rpt == NULL) {
rpt = new CP25Repeater;
rpt->m_timer.start();
::memcpy(&rpt->m_addr, &addr, sizeof(struct sockaddr_storage));
rpt->m_addrLen = addrLen;
rpt->m_callsign = std::string((char*)(buffer + 1U), 10U);
m_repeaters.push_back(rpt);
char buff[80U];
LogMessage("Adding %s (%s)", rpt->m_callsign.c_str(), CUDPSocket::display(addr, buff, 80U));
} else {
rpt->m_timer.start();
}
// Return the poll
network.writeData(buffer, len, addr, addrLen);
} else if (buffer[0U] == 0xF1U && rpt != NULL) {
char buff[80U];
LogMessage("Removing %s (%s) unlinked", rpt->m_callsign.c_str(), CUDPSocket::display(addr, buff, 80U));
for (std::vector<CP25Repeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
if (CUDPSocket::match((*it)->m_addr, rpt->m_addr)) {
delete *it;
m_repeaters.erase(it);
break;
}
}
} else if (rpt != NULL) {
rpt->m_timer.start();
if (current == NULL) {
current = rpt;
displayed = false;
seen64 = false;
seen65 = false;
LogMessage("Transmission started from %s", current->m_callsign.c_str());
}
if (current == rpt) {
watchdogTimer.start();
if (buffer[0U] == 0x64U && !seen64) {
lcf = buffer[1U];
seen64 = true;
}
if (buffer[0U] == 0x65U && !seen65) {
dstId = (buffer[1U] << 16) & 0xFF0000U;
dstId |= (buffer[2U] << 8) & 0x00FF00U;
dstId |= (buffer[3U] << 0) & 0x0000FFU;
seen65 = true;
}
if (buffer[0U] == 0x66U && seen64 && seen65 && !displayed) {
srcId = (buffer[1U] << 16) & 0xFF0000U;
srcId |= (buffer[2U] << 8) & 0x00FF00U;
srcId |= (buffer[3U] << 0) & 0x0000FFU;
displayed = true;
std::string callsign = lookup->find(srcId);
LogMessage("Transmission from %s at %s to %s%u", callsign.c_str(), current->m_callsign.c_str(), lcf == 0x00U ? "TG " : "", dstId);
}
for (std::vector<CP25Repeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
if (!CUDPSocket::match(addr, (*it)->m_addr))
network.writeData(buffer, len, (*it)->m_addr, (*it)->m_addrLen);
}
if (buffer[0U] == 0x80U) {
LogMessage("Received end of transmission");
watchdogTimer.stop();
current = NULL;
}
}
} else {
LogMessage("Data received from an unknown source");
CUtils::dump(2U, "Data", buffer, len);
}
}
unsigned int ms = stopWatch.elapsed();
stopWatch.start();
// Remove any repeaters that haven't reported for a while
for (std::vector<CP25Repeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
(*it)->m_timer.clock(ms);
for (std::vector<CP25Repeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
if ((*it)->m_timer.hasExpired()) {
char buff[80U];
LogMessage("Removing %s (%s) disappeared", (*it)->m_callsign.c_str(),
CUDPSocket::display((*it)->m_addr, buff, 80U));
delete *it;
m_repeaters.erase(it);
break;
}
}
watchdogTimer.clock(ms);
if (watchdogTimer.isRunning() && watchdogTimer.hasExpired()) {
LogMessage("Network watchdog has expired");
watchdogTimer.stop();
current = NULL;
}
dumpTimer.clock(ms);
if (dumpTimer.hasExpired()) {
dumpRepeaters();
dumpTimer.start();
}
if (ms < 5U)
CThread::sleep(5U);
}
network.close();
lookup->stop();
::LogFinalise();
}
CP25Repeater* CP25Reflector::findRepeater(const sockaddr_storage& addr) const
{
for (std::vector<CP25Repeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
if (CUDPSocket::match(addr, (*it)->m_addr))
return *it;
}
return NULL;
}
void CP25Reflector::dumpRepeaters() const
{
if (m_repeaters.size() == 0U) {
LogMessage("No repeaters linked");
return;
}
LogMessage("Currently linked repeaters:");
for (std::vector<CP25Repeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
char buffer[80U];
LogMessage(" %s: %s %u/%u", (*it)->m_callsign.c_str(),
CUDPSocket::display((*it)->m_addr, buffer, 80U),
(*it)->m_timer.getTimer(),
(*it)->m_timer.getTimeout());
}
}

View File

@ -1,73 +0,0 @@
/*
* Copyright (C) 2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(P25Reflector_H)
#define P25Reflector_H
#include "Timer.h"
#include "Conf.h"
#include <cstdio>
#include <string>
#include <vector>
#if !defined(_WIN32) && !defined(_WIN64)
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#else
#include <WS2tcpip.h>
#endif
class CP25Repeater {
public:
CP25Repeater() :
m_addr(),
m_addrLen(0U),
m_callsign(),
m_timer(1000U, 120U)
{
}
sockaddr_storage m_addr;
unsigned int m_addrLen;
std::string m_callsign;
CTimer m_timer;
};
class CP25Reflector
{
public:
CP25Reflector(const std::string& file);
~CP25Reflector();
void run();
private:
CConf m_conf;
std::vector<CP25Repeater*> m_repeaters;
CP25Repeater* findRepeater(const sockaddr_storage& addr) const;
void dumpRepeaters() const;
};
#endif

View File

@ -1,18 +0,0 @@
[General]
Daemon=1
[Id Lookup]
Name=DMRIds.dat
Time=24
[Log]
# Logging levels, 0=No logging
DisplayLevel=1
FileLevel=1
FilePath=.
FileRoot=P25Reflector
FileRotate=1
[Network]
Port=41000
Debug=0

View File

@ -1,76 +0,0 @@
#!/bin/bash
### BEGIN INIT INFO
#
# Provides: P25Reflector
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Example startscript P25Reflector
#
### END INIT INFO
## Fill in name of program here.
PROG="P25Reflector"
PROG_PATH="/usr/local/bin/"
PROG_ARGS="/etc/P25Reflector.ini"
PIDFILE="/var/run/P25Reflector.pid"
USER="root"
start() {
if [ -e $PIDFILE ]; then
## Program is running, exit with error.
echo "Error! $PROG is currently running!" 1>&2
exit 1
else
cd $PROG_PATH
./$PROG $PROG_ARGS
echo "$PROG started"
touch $PIDFILE
fi
}
stop() {
if [ -e $PIDFILE ]; then
## Program is running, so stop it
echo "$PROG is running"
rm -f $PIDFILE
killall $PROG
echo "$PROG stopped"
else
## Program is not running, exit with error.
echo "Error! $PROG not started!" 1>&2
exit 1
fi
}
## Check to see if we are running as root first.
## Found at
## http://www.cyberciti.biz/tips/shell-root-user-check-script.html
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
case "$1" in
start)
start
exit 0
;;
stop)
stop
exit 0
;;
reload|restart|force-reload)
stop
sleep 5
start
exit 0
;;
**)
echo "Usage: $0 {start|stop|reload}" 1>&2
exit 1
;;
esac
exit 0
### END

View File

@ -1,183 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Conf.h" />
<ClInclude Include="DMRLookup.h" />
<ClInclude Include="Log.h" />
<ClInclude Include="Mutex.h" />
<ClInclude Include="Network.h" />
<ClInclude Include="P25Reflector.h" />
<ClInclude Include="StopWatch.h" />
<ClInclude Include="Thread.h" />
<ClInclude Include="Timer.h" />
<ClInclude Include="UDPSocket.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="Version.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Conf.cpp" />
<ClCompile Include="DMRLookup.cpp" />
<ClCompile Include="Log.cpp" />
<ClCompile Include="Mutex.cpp" />
<ClCompile Include="Network.cpp" />
<ClCompile Include="P25Reflector.cpp" />
<ClCompile Include="StopWatch.cpp" />
<ClCompile Include="Thread.cpp" />
<ClCompile Include="Timer.cpp" />
<ClCompile Include="UDPSocket.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>P25Reflector</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>HAVE_LOG_H;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>HAVE_LOG_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Conf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DMRLookup.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Log.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mutex.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Network.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="P25Reflector.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="StopWatch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Thread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UDPSocket.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Version.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Conf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DMRLookup.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Mutex.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="P25Reflector.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StopWatch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Thread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UDPSocket.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,105 +0,0 @@
/*
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "StopWatch.h"
#if defined(_WIN32) || defined(_WIN64)
CStopWatch::CStopWatch() :
m_frequencyS(),
m_frequencyMS(),
m_start()
{
::QueryPerformanceFrequency(&m_frequencyS);
m_frequencyMS.QuadPart = m_frequencyS.QuadPart / 1000ULL;
}
CStopWatch::~CStopWatch()
{
}
unsigned long long CStopWatch::time() const
{
LARGE_INTEGER now;
::QueryPerformanceCounter(&now);
return (unsigned long long)(now.QuadPart / m_frequencyMS.QuadPart);
}
unsigned long long CStopWatch::start()
{
::QueryPerformanceCounter(&m_start);
return (unsigned long long)(m_start.QuadPart / m_frequencyS.QuadPart);
}
unsigned int CStopWatch::elapsed()
{
LARGE_INTEGER now;
::QueryPerformanceCounter(&now);
LARGE_INTEGER temp;
temp.QuadPart = (now.QuadPart - m_start.QuadPart) * 1000;
return (unsigned int)(temp.QuadPart / m_frequencyS.QuadPart);
}
#else
#include <cstdio>
#include <ctime>
CStopWatch::CStopWatch() :
m_startMS(0ULL)
{
}
CStopWatch::~CStopWatch()
{
}
unsigned long long CStopWatch::time() const
{
struct timeval now;
::gettimeofday(&now, NULL);
return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL;
}
unsigned long long CStopWatch::start()
{
struct timespec now;
::clock_gettime(CLOCK_MONOTONIC, &now);
m_startMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL;
return m_startMS;
}
unsigned int CStopWatch::elapsed()
{
struct timespec now;
::clock_gettime(CLOCK_MONOTONIC, &now);
unsigned long long nowMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL;
return nowMS - m_startMS;
}
#endif

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(STOPWATCH_H)
#define STOPWATCH_H
#if defined(_WIN32) || defined(_WIN64)
#include <WS2tcpip.h>
#include <windows.h>
#else
#include <sys/time.h>
#endif
class CStopWatch
{
public:
CStopWatch();
~CStopWatch();
unsigned long long time() const;
unsigned long long start();
unsigned int elapsed();
private:
#if defined(_WIN32) || defined(_WIN64)
LARGE_INTEGER m_frequencyS;
LARGE_INTEGER m_frequencyMS;
LARGE_INTEGER m_start;
#else
unsigned long long m_startMS;
#endif
};
#endif

View File

@ -1,107 +0,0 @@
/*
* Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Thread.h"
#if defined(_WIN32) || defined(_WIN64)
CThread::CThread() :
m_handle()
{
}
CThread::~CThread()
{
}
bool CThread::run()
{
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
return m_handle != NULL;
}
void CThread::wait()
{
::WaitForSingleObject(m_handle, INFINITE);
::CloseHandle(m_handle);
}
DWORD CThread::helper(LPVOID arg)
{
CThread* p = (CThread*)arg;
p->entry();
return 0UL;
}
void CThread::sleep(unsigned int ms)
{
::Sleep(ms);
}
#else
#include <unistd.h>
CThread::CThread() :
m_thread()
{
}
CThread::~CThread()
{
}
bool CThread::run()
{
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
}
void CThread::wait()
{
::pthread_join(m_thread, NULL);
}
void* CThread::helper(void* arg)
{
CThread* p = (CThread*)arg;
p->entry();
return NULL;
}
void CThread::sleep(unsigned int ms)
{
struct timespec ts;
ts.tv_sec = ms / 1000U;
ts.tv_nsec = (ms % 1000U) * 1000000U;
::nanosleep(&ts, NULL);
}
#endif

View File

@ -1,57 +0,0 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(THREAD_H)
#define THREAD_H
#if defined(_WIN32) || defined(_WIN64)
#include <WS2tcpip.h>
#include <windows.h>
#else
#include <pthread.h>
#endif
class CThread
{
public:
CThread();
virtual ~CThread();
virtual bool run();
virtual void entry() = 0;
virtual void wait();
static void sleep(unsigned int ms);
private:
#if defined(_WIN32) || defined(_WIN64)
HANDLE m_handle;
#else
pthread_t m_thread;
#endif
#if defined(_WIN32) || defined(_WIN64)
static DWORD __stdcall helper(LPVOID arg);
#else
static void* helper(void* arg);
#endif
};
#endif

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2009,2010,2015 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Timer.h"
#include <cstdio>
#include <cassert>
CTimer::CTimer(unsigned int ticksPerSec, unsigned int secs, unsigned int msecs) :
m_ticksPerSec(ticksPerSec),
m_timeout(0U),
m_timer(0U)
{
assert(ticksPerSec > 0U);
if (secs > 0U || msecs > 0U) {
// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
}
}
CTimer::~CTimer()
{
}
void CTimer::setTimeout(unsigned int secs, unsigned int msecs)
{
if (secs > 0U || msecs > 0U) {
// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
} else {
m_timeout = 0U;
m_timer = 0U;
}
}
unsigned int CTimer::getTimeout() const
{
if (m_timeout == 0U)
return 0U;
return (m_timeout - 1U) / m_ticksPerSec;
}
unsigned int CTimer::getTimer() const
{
if (m_timer == 0U)
return 0U;
return (m_timer - 1U) / m_ticksPerSec;
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) 2009,2010,2011,2014 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef Timer_H
#define Timer_H
class CTimer {
public:
CTimer(unsigned int ticksPerSec, unsigned int secs = 0U, unsigned int msecs = 0U);
~CTimer();
void setTimeout(unsigned int secs, unsigned int msecs = 0U);
unsigned int getTimeout() const;
unsigned int getTimer() const;
unsigned int getRemaining()
{
if (m_timeout == 0U || m_timer == 0U)
return 0U;
if (m_timer >= m_timeout)
return 0U;
return (m_timeout - m_timer) / m_ticksPerSec;
}
bool isRunning()
{
return m_timer > 0U;
}
void start(unsigned int secs, unsigned int msecs = 0U)
{
setTimeout(secs, msecs);
start();
}
void start()
{
if (m_timeout > 0U)
m_timer = 1U;
}
void stop()
{
m_timer = 0U;
}
bool hasExpired()
{
if (m_timeout == 0U || m_timer == 0U)
return false;
if (m_timer >= m_timeout)
return true;
return false;
}
void clock(unsigned int ticks = 1U)
{
if (m_timer > 0U && m_timeout > 0U)
m_timer += ticks;
}
private:
unsigned int m_ticksPerSec;
unsigned int m_timeout;
unsigned int m_timer;
};
#endif

View File

@ -1,391 +0,0 @@
/*
* Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "UDPSocket.h"
#include <cassert>
#if !defined(_WIN32) && !defined(_WIN64)
#include <cerrno>
#include <cstring>
#endif
#if defined(HAVE_LOG_H)
#include "Log.h"
#else
#define LogMessage(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__)
#define LogError(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__)
#define LogInfo(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__)
#endif
CUDPSocket::CUDPSocket(const std::string& address, unsigned short port) :
m_address_save(address),
m_port_save(port),
m_counter(0U)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::CUDPSocket(unsigned short port) :
m_address_save(),
m_port_save(port),
m_counter(0U)
{
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
m_address[i] = "";
m_port[i] = 0U;
m_af[i] = 0U;
m_fd[i] = -1;
}
}
CUDPSocket::~CUDPSocket()
{
}
void CUDPSocket::startup()
{
#if defined(_WIN32) || defined(_WIN64)
WSAData data;
int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data);
if (wsaRet != 0)
LogError("Error from WSAStartup");
#endif
}
void CUDPSocket::shutdown()
{
#if defined(_WIN32) || defined(_WIN64)
::WSACleanup();
#endif
}
int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockaddr_storage& addr, unsigned int& address_length)
{
struct addrinfo hints;
::memset(&hints, 0, sizeof(hints));
return lookup(hostname, port, addr, address_length, hints);
}
int CUDPSocket::lookup(const std::string& hostname, unsigned short port, sockaddr_storage& addr, unsigned int& address_length, struct addrinfo& hints)
{
std::string portstr = std::to_string(port);
struct addrinfo *res;
/* port is always digits, no needs to lookup service */
hints.ai_flags |= AI_NUMERICSERV;
int err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res);
if (err != 0) {
sockaddr_in* paddr = (sockaddr_in*)&addr;
::memset(paddr, 0x00U, address_length = sizeof(sockaddr_in));
paddr->sin_family = AF_INET;
paddr->sin_port = htons(port);
paddr->sin_addr.s_addr = htonl(INADDR_NONE);
LogError("Cannot find address for host %s", hostname.c_str());
return err;
}
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
freeaddrinfo(res);
return 0;
}
bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type)
{
if (addr1.ss_family != addr2.ss_family)
return false;
if (type == IMT_ADDRESS_AND_PORT) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
}
} else if (type == IMT_ADDRESS_ONLY) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
}
} else {
return false;
}
}
bool CUDPSocket::isNone(const sockaddr_storage& addr)
{
struct sockaddr_in *in = (struct sockaddr_in *)&addr;
return ((addr.ss_family == AF_INET) && (in->sin_addr.s_addr == htonl(INADDR_NONE)));
}
char* CUDPSocket::display(const sockaddr_storage& addr, char* buffer, unsigned int length)
{
assert(buffer != NULL);
assert(length > INET6_ADDRSTRLEN);
switch (addr.ss_family) {
case AF_INET: {
struct sockaddr_in* in4 = (struct sockaddr_in*)&addr;
::inet_ntop(AF_INET, &in4->sin_addr, buffer, length);
::sprintf(buffer + ::strlen(buffer), ":%u", in4->sin_port);
}
break;
case AF_INET6: {
struct sockaddr_in6* in6 = (struct sockaddr_in6*)&addr;
::inet_ntop(AF_INET6, &in6->sin6_addr, buffer, length);
::sprintf(buffer + ::strlen(buffer), ":%u", in6->sin6_port);
}
break;
default:
::strcpy(buffer, "Unknown");
break;
}
return buffer;
}
bool CUDPSocket::open(const sockaddr_storage& address)
{
return open(address.ss_family);
}
bool CUDPSocket::open(unsigned int af)
{
return open(0, af, m_address_save, m_port_save);
}
bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port)
{
sockaddr_storage addr;
unsigned int addrlen;
struct addrinfo hints;
::memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = af;
/* to determine protocol family, call lookup() first. */
int err = lookup(address, port, addr, addrlen, hints);
if (err != 0) {
LogError("The local address is invalid - %s", address.c_str());
return false;
}
close(index);
int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0);
if (fd < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
#else
LogError("Cannot create the UDP socket, err: %d", errno);
#endif
return false;
}
m_address[index] = address;
m_port[index] = port;
m_af[index] = addr.ss_family;
m_fd[index] = fd;
if (port > 0U) {
int reuse = 1;
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError());
#else
LogError("Cannot set the UDP socket option, err: %d", errno);
#endif
return false;
}
if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Cannot bind the UDP address, err: %lu", ::GetLastError());
#else
LogError("Cannot bind the UDP address, err: %d", errno);
#endif
return false;
}
LogInfo("Opening UDP port on %hu", port);
}
return true;
}
int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length)
{
assert(buffer != NULL);
assert(length > 0U);
// Check that the readfrom() won't block
int i, n;
struct pollfd pfd[UDP_SOCKET_MAX];
for (i = n = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] >= 0) {
pfd[n].fd = m_fd[i];
pfd[n].events = POLLIN;
n++;
}
}
// no socket descriptor to receive
if (n == 0)
return 0;
// Return immediately
#if defined(_WIN32) || defined(_WIN64)
int ret = WSAPoll(pfd, n, 0);
#else
int ret = ::poll(pfd, n, 0);
#endif
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Error returned from UDP poll, err: %lu", ::GetLastError());
#else
LogError("Error returned from UDP poll, err: %d", errno);
#endif
return -1;
}
int index;
for (i = 0; i < n; i++) {
// round robin
index = (i + m_counter) % n;
if (pfd[index].revents & POLLIN)
break;
}
if (i == n)
return 0;
#if defined(_WIN32) || defined(_WIN64)
int size = sizeof(sockaddr_storage);
#else
socklen_t size = sizeof(sockaddr_storage);
#endif
#if defined(_WIN32) || defined(_WIN64)
int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#else
ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size);
#endif
if (len <= 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Error returned from recvfrom, err: %lu", ::GetLastError());
#else
LogError("Error returned from recvfrom, err: %d", errno);
if (len == -1 && errno == ENOTSOCK) {
LogMessage("Re-opening UDP port on %hu", m_port[index]);
close();
open();
}
#endif
return -1;
}
m_counter++;
address_length = size;
return len;
}
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length)
{
assert(buffer != NULL);
assert(length > 0U);
bool result = false;
for (int i = 0; i < UDP_SOCKET_MAX; i++) {
if (m_fd[i] < 0 || m_af[i] != address.ss_family)
continue;
#if defined(_WIN32) || defined(_WIN64)
int ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
#else
ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length);
#endif
if (ret < 0) {
#if defined(_WIN32) || defined(_WIN64)
LogError("Error returned from sendto, err: %lu", ::GetLastError());
#else
LogError("Error returned from sendto, err: %d", errno);
#endif
} else {
#if defined(_WIN32) || defined(_WIN64)
if (ret == int(length))
result = true;
#else
if (ret == ssize_t(length))
result = true;
#endif
}
}
return result;
}
void CUDPSocket::close()
{
for (unsigned int i = 0; i < UDP_SOCKET_MAX; i++)
close(i);
}
void CUDPSocket::close(const unsigned int index)
{
if ((index < UDP_SOCKET_MAX) && (m_fd[index] >= 0)) {
#if defined(_WIN32) || defined(_WIN64)
::closesocket(m_fd[index]);
#else
::close(m_fd[index]);
#endif
m_fd[index] = -1;
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef UDPSocket_H
#define UDPSocket_H
#include <string>
#if !defined(_WIN32) && !defined(_WIN64)
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#else
#include <ws2tcpip.h>
#endif
#if !defined(UDP_SOCKET_MAX)
#define UDP_SOCKET_MAX 1
#endif
enum IPMATCHTYPE {
IMT_ADDRESS_AND_PORT,
IMT_ADDRESS_ONLY
};
class CUDPSocket {
public:
CUDPSocket(const std::string& address, unsigned short port = 0U);
CUDPSocket(unsigned short port = 0U);
~CUDPSocket();
bool open(unsigned int af = AF_UNSPEC);
bool open(const sockaddr_storage& address);
bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned short port);
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length);
bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length);
void close();
void close(const unsigned int index);
static void startup();
static void shutdown();
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length);
static int lookup(const std::string& hostName, unsigned short port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
static bool isNone(const sockaddr_storage& addr);
static char* display(const sockaddr_storage& address, char* buffer, unsigned int length);
private:
std::string m_address_save;
unsigned short m_port_save;
std::string m_address[UDP_SOCKET_MAX];
unsigned short m_port[UDP_SOCKET_MAX];
unsigned int m_af[UDP_SOCKET_MAX];
int m_fd[UDP_SOCKET_MAX];
unsigned int m_counter;
};
#endif

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include "Utils.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
{
assert(data != NULL);
dump(2U, title, data, length);
}
void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length)
{
assert(data != NULL);
::Log(level, "%s", title.c_str());
unsigned int offset = 0U;
while (length > 0U) {
std::string output;
unsigned int bytes = (length > 16U) ? 16U : length;
for (unsigned i = 0U; i < bytes; i++) {
char temp[10U];
::sprintf(temp, "%02X ", data[offset + i]);
output += temp;
}
for (unsigned int i = bytes; i < 16U; i++)
output += " ";
output += " *";
for (unsigned i = 0U; i < bytes; i++) {
unsigned char c = data[offset + i];
if (::isprint(c))
output += c;
else
output += '.';
}
output += '*';
::Log(level, "%04X: %s", offset, output.c_str());
offset += 16U;
if (length >= 16U)
length -= 16U;
else
length = 0U;
}
}
void CUtils::dump(const std::string& title, const bool* bits, unsigned int length)
{
assert(bits != NULL);
dump(2U, title, bits, length);
}
void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length)
{
assert(bits != NULL);
unsigned char bytes[100U];
unsigned int nBytes = 0U;
for (unsigned int n = 0U; n < length; n += 8U, nBytes++)
bitsToByteBE(bits + n, bytes[nBytes]);
dump(level, title, bytes, nBytes);
}
void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
{
assert(bits != NULL);
bits[0U] = (byte & 0x80U) == 0x80U;
bits[1U] = (byte & 0x40U) == 0x40U;
bits[2U] = (byte & 0x20U) == 0x20U;
bits[3U] = (byte & 0x10U) == 0x10U;
bits[4U] = (byte & 0x08U) == 0x08U;
bits[5U] = (byte & 0x04U) == 0x04U;
bits[6U] = (byte & 0x02U) == 0x02U;
bits[7U] = (byte & 0x01U) == 0x01U;
}
void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
{
assert(bits != NULL);
bits[0U] = (byte & 0x01U) == 0x01U;
bits[1U] = (byte & 0x02U) == 0x02U;
bits[2U] = (byte & 0x04U) == 0x04U;
bits[3U] = (byte & 0x08U) == 0x08U;
bits[4U] = (byte & 0x10U) == 0x10U;
bits[5U] = (byte & 0x20U) == 0x20U;
bits[6U] = (byte & 0x40U) == 0x40U;
bits[7U] = (byte & 0x80U) == 0x80U;
}
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
{
assert(bits != NULL);
byte = bits[0U] ? 0x80U : 0x00U;
byte |= bits[1U] ? 0x40U : 0x00U;
byte |= bits[2U] ? 0x20U : 0x00U;
byte |= bits[3U] ? 0x10U : 0x00U;
byte |= bits[4U] ? 0x08U : 0x00U;
byte |= bits[5U] ? 0x04U : 0x00U;
byte |= bits[6U] ? 0x02U : 0x00U;
byte |= bits[7U] ? 0x01U : 0x00U;
}
void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
{
assert(bits != NULL);
byte = bits[0U] ? 0x01U : 0x00U;
byte |= bits[1U] ? 0x02U : 0x00U;
byte |= bits[2U] ? 0x04U : 0x00U;
byte |= bits[3U] ? 0x08U : 0x00U;
byte |= bits[4U] ? 0x10U : 0x00U;
byte |= bits[5U] ? 0x20U : 0x00U;
byte |= bits[6U] ? 0x40U : 0x00U;
byte |= bits[7U] ? 0x80U : 0x00U;
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2009,2014,2015 by Jonathan Naylor, G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#ifndef Utils_H
#define Utils_H
#include <string>
class CUtils {
public:
static void dump(const std::string& title, const unsigned char* data, unsigned int length);
static void dump(int level, const std::string& title, const unsigned char* data, unsigned int length);
static void dump(const std::string& title, const bool* bits, unsigned int length);
static void dump(int level, const std::string& title, const bool* bits, unsigned int length);
static void byteToBitsBE(unsigned char byte, bool* bits);
static void byteToBitsLE(unsigned char byte, bool* bits);
static void bitsToByteBE(const bool* bits, unsigned char& byte);
static void bitsToByteLE(const bool* bits, unsigned char& byte);
private:
};
#endif

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2015,2016,2020,2021 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20210912";
#endif

View File

@ -10,4 +10,4 @@ The MMDVM .ini file should have the IP address and port number of the client in
They build on 32-bit and 64-bit Linux as well as on Windows using Visual Studio 2017 on x86 and x64.
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
This software is licenced under the GPL v2 and is primarily intended for amateur and educational use.