-
-
Save M0LTE/37c02b17c61b9c3d517e022879c36101 to your computer and use it in GitHub Desktop.
| SIMPLE ; sets a lot of defaults | |
| NODECALL=GB7RDG ; Node callsign | |
| NODEALIAS=THURST ; Node alias (6 characters max) | |
| LOCATOR=IO91lk ; Maidenhead locator | |
| MAPCOMMENT=40m, 6m, 2m, 70cm | |
| PASSWORD=xxxxxxxx | |
| AUTOSAVE=1 | |
| EnableEvents=1 | |
| EnableM0LTEMap=1 | |
| NODESINTERVAL=60 | |
| MINQUAL=10 | |
| IDINTERVAL=15 | |
| IDMSG: | |
| GB7RDG - Reading - 40m, 6m, 2m, 70cm | |
| *** | |
| INFOMSG: | |
| See https://ukpacketradio.network/nodes:gb7rdg | |
| *** | |
| CTEXT: | |
| Welcome to GB7RDG. Sysop M0LTE. | |
| Type ? for Help | |
| *** | |
| BTINTERVAL=5 | |
| BTEXT: | |
| GB7RDG node IO91lk67SI - https://packet.oarc.uk | |
| *** | |
| ; https://www.cantab.net/users/john.wiseman/Documents/BPQCFGFile.html##Port | |
| PORT | |
| PORTNUM=1 | |
| ID=VHF | |
| TYPE=ASYNC | |
| PROTOCOL=KISS | |
| KISSOPTIONS=ACKMODE | |
| COMPORT=/dev/serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0 | |
| SPEED=57600 | |
| TXDELAY=100 | |
| FRACK=4000 | |
| PACLEN=150 | |
| DIGIFLAG=1 | |
| QUALITY=191 | |
| MINQUAL=100 | |
| ENDPORT | |
| PORT | |
| PORTNUM=2 | |
| ID=UHF | |
| TYPE=ASYNC | |
| PROTOCOL=KISS | |
| KISSOPTIONS=ACKMODE | |
| COMPORT=/dev/serial/by-path/platform-3f980000.usb-usb-0:1.3:1.0 | |
| SPEED=57600 | |
| QUALITY=192 | |
| MINQUAL=20 | |
| DIGIFLAG=1 | |
| TXDELAY=30 | |
| PACLEN=236 | |
| FRACK=1000 | |
| MAXFRAME=4 | |
| RESPTIME=200 | |
| ENDPORT | |
| PORT | |
| PORTNUM=3 | |
| ID=7052.75kHz IL2P+CRC QPSK600 | |
| TYPE=ASYNC | |
| PROTOCOL=KISS | |
| KISSOPTIONS=ACKMODE | |
| COMPORT=/dev/serial/by-path/platform-3f980000.usb-usb-0:1.5:1.0 | |
| SPEED=57600 | |
| FRACK=7000 | |
| PACLEN=80 | |
| NODESPACLEN=60 | |
| DIGIFLAG=0 | |
| MAXFRAME=1 | |
| RETRIES=10 | |
| QUALITY=190 | |
| MINQUAL=193 | |
| TXDELAY=100 | |
| TXTAIL=300 | |
| RESPTIME=100 | |
| T3=300 | |
| ENDPORT | |
| PORT | |
| PORTNUM=4 | |
| ID=50.650MHz IL2P+CRC BPSK300 | |
| TYPE=ASYNC | |
| PROTOCOL=KISS | |
| KISSOPTIONS=ACKMODE | |
| COMPORT=/dev/serial/by-path/platform-3f980000.usb-usb-0:1.4:1.0 | |
| SPEED=57600 | |
| FRACK=7000 | |
| PACLEN=80 | |
| NODESPACLEN=60 | |
| DIGIFLAG=0 | |
| MAXFRAME=1 | |
| RETRIES=10 | |
| QUALITY=190 | |
| MINQUAL=193 | |
| TXDELAY=100 | |
| TXTAIL=300 | |
| RESPTIME=100 | |
| T3=300 | |
| ENDPORT | |
| PORT | |
| PORTNUM=7 | |
| ID=Telnet | |
| DRIVER=Telnet | |
| CONFIG | |
| SECURETELNET=1 ; otherwise there's a gaping security hole | |
| LOGGING=1 | |
| CMS=1 | |
| DisconnectOnClose=0 ; 1 = closes window when you bye | |
| TCPPORT=8010 | |
| FBBPORT=8011 | |
| HTTPPORT=8008 | |
| LOGINPROMPT=user: | |
| PASSWORDPROMPT=password: | |
| MAXSESSIONS=10 | |
| RELAYAPPL=BBS ; RMS | |
| CTEXT=Welcome to GB7RDG Telnet Server\n Enter ? for list of commands\n\n | |
| USER=tf,xxxxxxxx,m0lte,,SYSOP | |
| USER=2e1epq,xxxxxxxx,2e1epq | |
| ; https://www.cantab.net/users/john.wiseman/Documents/LinBPQ%20Applications%20Interface.html | |
| CMDPORT 63000 63987 | |
| ENDPORT | |
| ; https://www.cantab.net/users/john.wiseman/Documents/BPQAXIP.htm | |
| PORT | |
| PORTNUM=8 | |
| ID=OARC-AXIP | |
| DRIVER=BPQAXIP | |
| QUALITY=50 | |
| MINQUAL=20 | |
| MAXFRAME=7 | |
| FRACK=7000 | |
| RESPTIME=1000 | |
| RETRIES=10 | |
| UNPROTO=ID | |
| CONFIG | |
| UDP 10094 | |
| MHEARD ON | |
| BROADCAST NODES | |
| NODESINTERVAL 1 | |
| BROADCAST ID | |
| MAP GB7OUK 10.66.66.3 UDP 10094 B | |
| MAP MB7NPW 10.66.66.17 UDP 10094 B | |
| MAP MB7NGP 10.66.66.12 UDP 10094 B | |
| ENDPORT | |
| PORT | |
| PORTNUM=9 | |
| ID=GB7CIP-AXIP | |
| DRIVER=BPQAXIP ; Uses BPQAXIP.DLL | |
| QUALITY=9 ; Quality factor applied to node broadcasts heard on | |
| ; this port, unless overridden by a locked route | |
| ; entry. Setting to 0 stops node broadcasts. Was 200 | |
| MINQUAL=0 ; Entries in the nodes table with qualities greater or | |
| ; equal to MINQUAL will be sent on this port. A value | |
| ; of 0 sends everything. | |
| MAXFRAME=7 ; Max outstanding frames (1 thru 7) | |
| FRACK=7000 ; Level 2 timout in milliseconds | |
| RESPTIME=1000 ; Level 2 delayed ack timer in milliseconds | |
| RETRIES=10 ; Level 2 maximum retry value | |
| UNPROTO=ID ; BTEXT broadcast addrs format: DEST[,digi1[,digi2]] | |
| ;BCALL=NOCALL ; BTEXT call. unstated defaults to APPL1CALL | |
| CONFIG | |
| UDP 10093 ;Listens for UDP packets on this UDP port number | |
| MHEARD ON | |
| ; AUTOADDMAP | |
| BROADCAST NODES | |
| BROADCAST ID | |
| ; MAP CALL IP-ADDRESS UDP 10093 B | |
| MAP GB7CIP-5 82.70.39.222 UDP 10093 B | |
| MAP GB7NXT 79.77.173.61 UDP 10093 B | |
| ENDPORT | |
| LINMAIL | |
| LINCHAT | |
| ;APPLICATION n,CMD,New Command,Call,Alias,Quality,L2Alias | |
| ; | |
| ;n Application Number. You can define up to 32. | |
| ;CMD The command the user types | |
| ;New Command (optional) The Node command to be run | |
| ;Call (optional) The call which directly invokes CMD | |
| ;Alias,Quality (optional) If specified, causes an entry for Call and Alias to be added to your NODES table with the specified Quality | |
| ;L2Alias (optional)is an additional Alias for direct (L2) connects to the Node. | |
| APPLICATION 1,BBS,,GB7RDG-2,RDGBBS,255 | |
| APPLICATION 2,CHAT,,GB7RDG-1,RDGCHT,255 | |
| ; https://www.cantab.net/users/john.wiseman/Documents/LinBPQ%20Applications%20Interface.html | |
| ; APPLICATION 3,LINUX,C 2 HOST 0 S | |
| ;APPLICATION 3,TEST,C 2 HOST 0 S | |
| APPLICATION 3,TELSTAR,ATTACH 7 GLASSTTY.COM 6502,GB7RDG-5,TSTARV,0 | |
| APPLICATION 4,WALL,C 7 HOST 1 K S |
M0LTE
commented
Jan 9, 2025
via email
Can anyone help me out here please? I hav a Linbpq up and running and try to add ZORK to the Application via a Startscript. This won't work, and I dont know where is my Problem? APPLICATION 3,ZORK,/usr/local/bin/ZORK.Start.sh It doesent matter what I do in the Script, bbq won't even try to start it. ZORK appears in the manue of possible Application if i connect via Telnet. If I try to start ZORK, I get the Error Invalid command - Enter ? for command list have anyone a clue where is my problem and how to solve it please? 73 Tom
It's actually simple once you understand how to do it.
in bpq32.cfg, look at your telnet server section (here's mine):
PORT
PORTNUM=1
ID=Telnet Server
DRIVER=Telnet
CONFIG
LOGGING=1
CMS=1
HTTPPORT=8080
TCPPORT=23
FBBPORT=8010
USER=M0ODZ,PASSWORD,M0ODZ,,SYSOP
DISCONNECTONCLOSE=1
CMDPORT 63000 63001
CTEXT=Welcome to GB7ODZ Telnet Server\n Enter ? for list of commands\n\n
ENDPORT
In the APPLICATIONS section:
APPLICATION 4,HELLO,C 1 HOST 0 K S,YOURNODECALL-4,YOURAPPSHORTNAME,255
replacing YOURNODECALL with your node call eg. M0QRZ and YOURAPPSHORTNAME with a snappier version of the appname a remote user can connect directly to eg. QRZHLO, so a remote user can connect directly to QRZHLO and they will be served with the app. For Example:
APPLICATION 4,HELLO,C 1 HOST 0 K S,M0QRZ-4,QRZHLO,255
Do you see the CMDPORT line? That is where the magic happens. The number that follows is a port number on the BPQ32 computer that an app listens to.
install node and npm:
sudo apt install nodejs npm
write a .js file to create a server on one of the ports listed in CMDLINE eg 63000.
/**
* Simple Packet Radio "Hello World" Server
* Runs on Port 63000
*/
const net = require('net');
const SERVERADDRESS='127.0.0.1';
const PORT = 63000;
const MESSAGE = "Hello packet radio world!\r\n";
const server = net.createServer((socket) => {
// Log connection to the screen
console.log(`Connection received from: ${socket.remoteAddress}`);
// Send the message
socket.write(MESSAGE);
// Give it a tiny delay to ensure the packet is buffered
// through the LinBPQ stack before closing
setTimeout(() => {
socket.end();
}, 500);
});
server.on('error', (err) => {
console.error(`Server error: ${err.message}`);
});
server.listen(PORT, SERVERADDRESS, () => {
console.log(`Packet App listening on ${SERVERADDRESS}:${PORT}`);
});
Save this as sampleserver.js
run
node sampleserver.js
in a new window, type
telnet SERVERADDRESS PORT
eg.
telnet 127.0.0.1 63000
And you should see Hello packet radio world! displayed on your screen.
For your real world situation (playing Zork, much respect!):
PORT
PORTNUM=1
ID=Telnet Server
DRIVER=Telnet
CONFIG
LOGGING=1
CMS=1
HTTPPORT=8080
TCPPORT=23
FBBPORT=8010
USER=M0ODZ,PASSWORD,M0ODZ,,SYSOP
DISCONNECTONCLOSE=1
CMDPORT 63000 63001
CTEXT=Welcome to GB7ODZ Telnet Server\n Enter ? for list of commands\n\n
ENDPORT
APPLICATION 4,ZORK1,C 1 HOST 0 K S,M0QRZ-4,QRZZ1,255 ; CMDPORT first number (starting counting at 0) 63000
APPLICATION 5,ZORK2,C 1 HOST 1 K S,M0QRZ-4,QRZZ2,255 ; CMDPORT second number 63001
If you look carefully you will notice C 1 HOST 0 K S and C 1 HOST 1 K S. 0 is the first number in the CMDPORT list, 1 is the second and so on.
Here is a real world script to run Zork:
/**
* Zork1.z5 Packet Radio Wrapper
* * This script:
* 1. Listens on Port 63000
* 2. Asks for a Callsign (if not automatically provided by BPQ)
* 3. Creates a unique directory for that Callsign
* 4. Launches 'frotz' inside that directory
*/
const net = require('net');
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const PORT = 63000;
const GAMES_DIR = path.join(__dirname, 'player_data');
// Ensure the base games directory exists
if (!fs.existsSync(GAMES_DIR)) {
fs.mkdirSync(GAMES_DIR);
}
const server = net.createServer((socket) => {
socket.write("--- Welcome to the Zork 1 Packet Portal ---\r\n");
socket.write("Please enter your Callsign: ");
let callsign = "";
socket.on('data', (data) => {
// If we haven't got the callsign yet, treat the first input as the ID
if (!callsign) {
callsign = data.toString().trim().toUpperCase().replace(/[^A-Z0-9-]/g, '');
if (callsign.length < 3) {
socket.write("\r\nInvalid Callsign. Please try again: ");
callsign = "";
return;
}
socket.write(`\r\nWelcome ${callsign}\r\n\r\n`);
setupGame(socket, callsign);
}
});
});
function setupGame(socket, userCall) {
const userDir = path.join(GAMES_DIR, `SAVEDIR_${userCall}`);
// Create user-specific directory for save files
if (fs.existsSync(userDir)) {
socket.write(`\r\nWelcome back, ${userCall}!\r\n`);
}
else
{
fs.mkdirSync(userDir);
socket.write(`\r\nWelcome, ${userCall}!\r\n\r\n`);
}
socket.write("Loading Zork 1...\r\n\r\n");
// Start frotz
// -p: plain text mode (better for packet/telnet)
const frotz = spawn('frotz', ['-p', '/usr/share/games/zork1.z5'], {
cwd: userDir
});
// Pipe socket to frotz stdin
socket.pipe(frotz.stdin);
// Pipe frotz stdout back to socket
frotz.stdout.on('data', (data) => {
// Replace Unix newlines with Telnet/Packet friendly CRLF
socket.write(data.toString().replace(/\n/g, '\r\n'));
});
frotz.stderr.on('data', (data) => {
console.error(`Frotz Error: ${data}`);
});
frotz.on('close', (code) => {
socket.write("\r\n[Zork Session Closed - I blame the Grue!]\r\n");
socket.end();
});
socket.on('close', () => {
frotz.kill();
});
}
server.listen(PORT, '0.0.0.0', () => {
console.log(`Zork 1 Server listening on port ${PORT}`);
});
Save this as zork1server.js
run
node zork1server.js
To make it permanent:
sudo npm install -g pm2
# Start your script
pm2 start zork1server.js --name "zork-node"
# Make it start on boot
pm2 startup
pm2 save
Pretty soon, you'll outgrow 1 app, 1 port and make a menu script so all the apps run on the same port.
de M0ODZ Greg