mirror of
https://github.com/TheCommsChannel/TC2-APRS-BBS.git
synced 2025-06-28 15:57:15 -04:00
Merge f797b5909a
into 3fea62db14
This commit is contained in:
commit
37bbf38ee4
3 changed files with 66 additions and 41 deletions
80
README.md
80
README.md
|
@ -19,7 +19,7 @@ coming soon. This software is experimental and could have bugs. Bug reports and
|
||||||
- `aprs3`
|
- `aprs3`
|
||||||
|
|
||||||
### Update and Install Git
|
### Update and Install Git
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt upgrade
|
sudo apt upgrade
|
||||||
|
@ -29,27 +29,27 @@ coming soon. This software is experimental and could have bugs. Bug reports and
|
||||||
### Installation (Linux)
|
### Installation (Linux)
|
||||||
|
|
||||||
1. Clone the repository:
|
1. Clone the repository:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd ~
|
cd ~
|
||||||
git clone https://github.com/TheCommsChannel/TC2-APRS-BBS.git
|
git clone https://github.com/TheCommsChannel/TC2-APRS-BBS.git
|
||||||
cd TC2-APRS-BBS
|
cd TC2-APRS-BBS
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Set up a Python virtual environment:
|
2. Set up a Python virtual environment:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Activate the virtual environment:
|
3. Activate the virtual environment:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Install the required packages:
|
4. Install the required packages:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
@ -57,32 +57,32 @@ coming soon. This software is experimental and could have bugs. Bug reports and
|
||||||
5. Rename `example_config.ini`:
|
5. Rename `example_config.ini`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mv example_config.ini config.ini
|
cp example_config.ini config.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Set up the configuration in `config.ini`:
|
6. Set up the configuration in `config.ini`:
|
||||||
|
|
||||||
You'll need to open up the config.ini file in a text editor and make your changes following the instructions below
|
You'll need to open up the config.ini file in a text editor and make your changes following the instructions below
|
||||||
|
|
||||||
**[TACTICAL_CALL]**
|
**[TACTICAL_CALL]**
|
||||||
This is where you enter the callsign of your BBS. This can be your FCC callsign if you don't plan on using a tactical call or a tactical callsign like BBS, CAMP1, or whatever makes the most sense for you.
|
This is where you enter the callsign of your BBS. This can be your FCC callsign if you don't plan on using a tactical call or a tactical callsign like BBS, CAMP1, or whatever makes the most sense for you.
|
||||||
|
|
||||||
**[STANDARD_CALL]**
|
**[STANDARD_CALL]**
|
||||||
If using a Tactical Call in the TACTICAL_CALL field, be sure to enter in your ham radio callsign here to ensure your callsign is in the packets to comply with FCC regulations. If you're using your ham radio callsign in the TACTICAL_CALL field, you can just leave this as TC2BBS.
|
If using a Tactical Call in the TACTICAL_CALL field, be sure to enter in your ham radio callsign here to ensure your callsign is in the packets to comply with FCC regulations. If you're using your ham radio callsign in the TACTICAL_CALL field, you can just leave this as TC2BBS.
|
||||||
|
|
||||||
**[KISS_HOST & KISS PORT]**
|
**[KISS_HOST & KISS PORT]**
|
||||||
IP Address and Port of the host running direwolf (127.0.0.1 if the BBS is running on the same system)
|
IP Address and Port of the host running direwolf (127.0.0.1 if the BBS is running on the same system)
|
||||||
|
|
||||||
**[BULLETIN_EXPIRATION_DAYS]**
|
|
||||||
Number of days to have bulletins expire
|
|
||||||
|
|
||||||
**[APRS_PATH]**
|
**[BULLETIN_EXPIRATION_DAYS]**
|
||||||
The WIDEN-n path for digipeater hops
|
Number of days to have bulletins expire
|
||||||
|
|
||||||
**[RAW_PACKET_DISPLAY]**
|
|
||||||
Display RAW packet data on the terminal - "True" to display or "False" to not display
|
|
||||||
|
|
||||||
### [OPTIONAL] Steps for Bluetooth TNC Radio Users
|
**[APRS_PATH]**
|
||||||
|
The WIDEN-n path for digipeater hops
|
||||||
|
|
||||||
|
**[RAW_PACKET_DISPLAY]**
|
||||||
|
Display RAW packet data on the terminal - "True" to display or "False" to not display
|
||||||
|
|
||||||
|
### [OPTIONAL] Steps for Bluetooth TNC Radio Users
|
||||||
|
|
||||||
1. Run the following command to make the necessary scripts executable.
|
1. Run the following command to make the necessary scripts executable.
|
||||||
```sh
|
```sh
|
||||||
|
@ -94,13 +94,13 @@ coming soon. This software is experimental and could have bugs. Bug reports and
|
||||||
sudo apt install expect
|
sudo apt install expect
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Pairing radio:
|
3. Pairing radio:
|
||||||
The first time you connect your radio, it will need to be paired and trusted. The bt_pair.exp makes this process easy. It will search for currently known Bluetooth TNC capable radios ("VR-N76" "UV-PRO" "GA-5WB" "TH-D75" "TH-D74" "VR-N7500") If one is found, it will pair, trust, and save the info in a file for the binding script in the next step. This step only needs to be performed once when you're first setting things up, or wanting to use a different radio.
|
The first time you connect your radio, it will need to be paired and trusted. The bt_pair.exp makes this process easy. It will search for currently known Bluetooth TNC capable radios ("VR-N76" "UV-PRO" "GA-5WB" "TH-D75" "TH-D74" "VR-N7500") If one is found, it will pair, trust, and save the info in a file for the binding script in the next step. This step only needs to be performed once when you're first setting things up, or wanting to use a different radio.
|
||||||
|
|
||||||
Put your radio in pairing mode and run the follwing command to go through the pairing process:
|
Put your radio in pairing mode and run the follwing command to go through the pairing process:
|
||||||
```sh
|
```sh
|
||||||
./bt_pair.exp
|
./bt_pair.exp
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Binding the radio to a serial port:
|
4. Binding the radio to a serial port:
|
||||||
This will need to be run before you start the server (not every time; likely only after a reboot). If you're not sure, you can run the `rfcomm` command and if you see something listed, you probably don't need to run this script. If you get nothing from the `rfcomm` command then you need to run this script to bind your radio to the serial port. After running this command, you can continue on to the "Running the Server" section
|
This will need to be run before you start the server (not every time; likely only after a reboot). If you're not sure, you can run the `rfcomm` command and if you see something listed, you probably don't need to run this script. If you get nothing from the `rfcomm` command then you need to run this script to bind your radio to the serial port. After running this command, you can continue on to the "Running the Server" section
|
||||||
|
@ -126,28 +126,28 @@ You should see (venv) at the beginning of the command prompt
|
||||||
To interact with the BBS, send a message to the callsign of the BBS (whatever has been put into the MYCALL part of the config)
|
To interact with the BBS, send a message to the callsign of the BBS (whatever has been put into the MYCALL part of the config)
|
||||||
If the message that's sent isn't a command, the BBS will respond with a welcome message and list of the below commands:
|
If the message that's sent isn't a command, the BBS will respond with a welcome message and list of the below commands:
|
||||||
|
|
||||||
**(L)IST**
|
**(L)IST**
|
||||||
Sending a message with `L` will respond with a list of current bulletins
|
Sending a message with `L` will respond with a list of current bulletins
|
||||||
|
|
||||||
**(M)SG**
|
**(M)SG**
|
||||||
Sending a message with `M` will respond with a list of messages that were sent to the callsign of the user requesting the list of messages.
|
Sending a message with `M` will respond with a list of messages that were sent to the callsign of the user requesting the list of messages.
|
||||||
|
|
||||||
**(S)END**
|
**(S)END**
|
||||||
This command leaves a message for a specific user via their callsign and needs to be sent in the following format:
|
This command leaves a message for a specific user via their callsign and needs to be sent in the following format:
|
||||||
```S <callsign> <text>```
|
```S <callsign> <text>```
|
||||||
Example: ```S N0CALL-1 Meet at the Trailhead at 15:00```
|
Example: ```S N0CALL-1 Meet at the Trailhead at 15:00```
|
||||||
|
|
||||||
The BBS will send a notification to the callsign letting them know they have a message waiting.
|
The BBS will send a notification to the callsign letting them know they have a message waiting.
|
||||||
|
|
||||||
**(P)OST**
|
**(P)OST**
|
||||||
This command posts a bulletin and needs to be sent in the following format:
|
This command posts a bulletin and needs to be sent in the following format:
|
||||||
```P <text>```
|
```P <text>```
|
||||||
Example: ```P Checkpoint 3 operational. Volunteers needed.```
|
Example: ```P Checkpoint 3 operational. Volunteers needed.```
|
||||||
|
|
||||||
**(P)OST (U)RGENT**
|
**(P)OST (U)RGENT**
|
||||||
This command will post an urgent bulletin which will have the BBS send out a bulletin packet which will be seen by all
|
This command will post an urgent bulletin which will have the BBS send out a bulletin packet which will be seen by all
|
||||||
supported devices. It needs to be sent in the following format:
|
supported devices. It needs to be sent in the following format:
|
||||||
```PU <text>```
|
```PU <text>```
|
||||||
Example: ```PU Highway 12 closed. Use alternate routes.```
|
Example: ```PU Highway 12 closed. Use alternate routes.```
|
||||||
|
|
||||||
## Automatically run at boot
|
## Automatically run at boot
|
||||||
|
|
14
aprs_comm.py
14
aprs_comm.py
|
@ -22,9 +22,17 @@ unack_lock = Lock()
|
||||||
message_counter = 1
|
message_counter = 1
|
||||||
message_lock = threading.Lock()
|
message_lock = threading.Lock()
|
||||||
|
|
||||||
|
# Global flag to indicate shutdown
|
||||||
|
shutdown_event = threading.Event()
|
||||||
|
|
||||||
|
|
||||||
JSON_URL = "https://aprs-deviceid.aprsfoundation.org/tocalls.pretty.json"
|
JSON_URL = "https://aprs-deviceid.aprsfoundation.org/tocalls.pretty.json"
|
||||||
|
|
||||||
|
def shutdown():
|
||||||
|
"""Signal the APRS loop to shut down."""
|
||||||
|
print("Shutdown signal received. Stopping APRS communications...")
|
||||||
|
shutdown_event.set()
|
||||||
|
|
||||||
def fetch_device_data():
|
def fetch_device_data():
|
||||||
local_file = "tocalls_cache.json"
|
local_file = "tocalls_cache.json"
|
||||||
|
|
||||||
|
@ -148,7 +156,11 @@ def start():
|
||||||
print(f"BBS Callsign: {my_callsign}")
|
print(f"BBS Callsign: {my_callsign}")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for frame in ki.read(min_frames=1):
|
if shutdown_event.is_set():
|
||||||
|
print("Shutdown event set. Exiting APRS loop.")
|
||||||
|
ki.stop()
|
||||||
|
break
|
||||||
|
for frame in ki.read(min_frames=0):
|
||||||
try:
|
try:
|
||||||
if config.RAW_PACKET_DISPLAY:
|
if config.RAW_PACKET_DISPLAY:
|
||||||
print(f"{COLOR_RAW}RAW PACKET:{COLOR_RESET} {frame}")
|
print(f"{COLOR_RAW}RAW PACKET:{COLOR_RESET} {frame}")
|
||||||
|
|
13
main.py
13
main.py
|
@ -3,6 +3,9 @@ import aprs_comm
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def scheduled_cleanup():
|
def scheduled_cleanup():
|
||||||
"""Periodically run cleanup of expired bulletins."""
|
"""Periodically run cleanup of expired bulletins."""
|
||||||
|
@ -14,6 +17,11 @@ def scheduled_cleanup():
|
||||||
print(f"Error during cleanup: {e}")
|
print(f"Error during cleanup: {e}")
|
||||||
time.sleep(24 * 60 * 60) # Run cleanup every 24 hours
|
time.sleep(24 * 60 * 60) # Run cleanup every 24 hours
|
||||||
|
|
||||||
|
def signal_handler(signum, frame):
|
||||||
|
print(f"Received signal {signum}. Shutting down...")
|
||||||
|
aprs_comm.shutdown()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
banner = """
|
banner = """
|
||||||
\033[96m
|
\033[96m
|
||||||
|
@ -34,8 +42,13 @@ def main():
|
||||||
cleanup_thread = threading.Thread(target=scheduled_cleanup, daemon=True)
|
cleanup_thread = threading.Thread(target=scheduled_cleanup, daemon=True)
|
||||||
cleanup_thread.start()
|
cleanup_thread.start()
|
||||||
|
|
||||||
|
print("Setting up signal handlers...")
|
||||||
|
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler) # kill command
|
||||||
|
|
||||||
print("Starting APRS communications...")
|
print("Starting APRS communications...")
|
||||||
aprs_comm.start()
|
aprs_comm.start()
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue