Setting up an Auto-Beacon System
What software components do you need to begin? You
need Perl and a very basic understanding of how to edit code. You need to
have the "at" facility in JNOS enabled and the ID, or beaconing system,
active which in 99.9% of the distributions, is already there. You need to
have cron running on your Linux machine as well, again this is usually there
right out of the box. That's it! (If you are a programmer, you can use
any language you like that is adept at text/string handling. My examples
will be in Perl, but they should be straighforward enough so that you
can translate them into your favorite code if you want...)
Here is my synchronous strategy for the solution to the auto-beacon
problem. Use a Perl script to read a file which has the plain text part
of the broadcast message, and update or swap-in any dynamic components if
required. Use a Perl script to build and format a JNOS type script, which
resides in /jnos/scripts/, named do_beacon, so named here for purposes
of illustration. (You could call it anything you like...)
Use the AT facility in JNOS to run do_beacon at regular intervals.
So, for example, cron could be scheduled to run at perhaps a few minutes
after the top of the hour. The JNOS AT script could run a few minutes later,
and finally the BEACON/ID would be broadcast a few minutes later still,
at perhaps 20 after the hour.
|
COMMENTARY
: It should be noted that this approach is a highly synchronous one,
and that other, less "strict," more asynchronous approaches to this class
of problem could be applied. There is room for both
synchronous and asynchronous
types of information broadcasts on the net. Each has its own
application niche. I chose the "road less travelled" since I wanted to show
the potential system "links" between JNOS and Linux, and the areas that
might show developmental promise. You may choose more straightforward
methods which will work just as well...
|
Continuing on, if there were no change to the above text message, then the
do_beacon script would simply be "re-freshed" and re-broadcast as
usual. If new data were inserted into the message then that is what
would be sent out. If a special message were created manually by you,
and sent out between the regular intervals, then after its transmission,
the normal broadcast could be restored to its orginal format and sent
as usual via cron, do_beacon, and the "at" command. A very flexible
system that is remarkably reliable since it is built on system
components that are proven and stable!
- The Most Simple Case
-
Let's begin with the easiest "model" to follow
first. Suppose we don't want to change our beacon, but we just want to
put into place the foundation which potentially could change it. We need
to take two steps.
- Build the do_beacon file
- Set a time(s) for the AT facility in JNOS
In the directory /jnos/scripts, create a JNOS script that loads the
configuration buffer for the target device with the actual message to be
broadcast, which needs to be in quotes and optionally end with the "\r"
carriage return character. Recall too, this is a JNOS script, not a shell
script, so it doesn't need to be chmod'ed with the +x switch. (It is just
a regular flat text file.) JNOS knows to activate it because it resides
in the directory /jnos/scripts.
|
Sample Beacon Script: /jnos/scripts/do_beacon
|
# JNOS script
# do_beacon
# 07-25-04
# KA1FSB/kbn
# -------------------------------------------------------------
# Loads device beacon text buffer via ifconfig command
# Possible beacon kick at this time ...
# This is for device/iface hf
# -------------------------------------------------------------
#
ifc hf ax25 bctext "JNOS/Linux 1.11f * Network 105 * 14.105<>145.090
[Wellelesy, MA]\r"
#
# Optional beacon kick here...
# ax25 bc hf
#
#----- End of do_beacon
|
For easier viewing, I have placed the station location on a new line (\n).
In the real file, this would all be one massive line, sometimes extending
"far" to the right even off the screen! If we had multiple lines, each one
would be terminated with the "\r" only, and would be representated as one
continuous string in the file! Also, the first command, ifc, is not commented
out and so will be applied; the second, ax25 bc hf, is commented out and
so will not be applied, but could be if uncommented...
The second step is to tell JNOS when you want to run this script. For that,
you may use the AT command. AT is a timer facility that runs JNOS
functions or scripts, which may contain multiple commands as in the above
example, at a specified time or times. A typical command issued form the
console/admin session looks like this:
- at 05 "source /jnos/scripts/do_beacon+"
The plus sign "+" at the end of the command line means do this again in
the time interval shown, i.e., 5 minutes after each hour. Entering
"at" from the admin console will display the entry in the
JNOS AT event table:
|
A Typical AT Command Table Entry
|
At: Mon Aug 2 09:05:08 2004 - ID: 1 - Command: source /jnos/scripts/do_beacon+
|
And, there is no reason why you can't run the same script at several
pre-set intervals:
- at 15 "source /jnos/scripts/do_beacon+"
- at 30 "source /jnos/scripts/do_beacon+"
- at 45 "source /jnos/scripts/do_beacon+"
- at 59 "source /jnos/scripts/do_beacon+"
This will run the script at 15, 30, 45, and 59 minutes after every
hour! (You could run do_beacon even more often if the situation required.
More likely, you would not need to do so under normal conditions...)
Also, you could choose not to use the traditional beacon timer and use
this instead, but this script, as written, only updates the beacon area.
It does not actually do a beacon TX, although it could. (Perhaps, best to
let the global beacon timer handle the actual transmissions at this point.)
- Auto-Building the do_beacon JNOS Script
-
We are now ready to take this process to the next "level,"
a place where it gets "interesting," but is still fun! To build the
do_beacon script, we need a template file and a Perl script.
Here is what the template file looks like:
|
Sample Beacon Template file: /jnos/scripts/do_beacon.tmplt
|
# JNOS script
# do_beacon
# 07-25-04
# KA1FSB/kbn
# -----------------------------------------------------------------
# Generated on: MYDATE by build_beacon
# JNOS script to load the device configuration buffer for bc text
# -----------------------------------------------------------------
#
ifc DEVICE ax25 bctext "BODY"
#
# ax25 bc DEVICE
#
#----- End of do_beacon
|
Notice the three (3) upper case, bolded, names: MYDATE, DEVICE, and BODY.
The Perl script will replace these names with real data! MYDATE will become
today's real date; DEVICE will become, in this case, hf; and BODY will
become the entire message string for the broadcast text. This template file,
do_beacon.tmplt is read by the Perl script, and is then "transformed" into
a new copy of the do_beacon JNOS script ready to be executed.
Here is what that Perl script looks like:
|
Perl Script: build_beacon
|
#! /usr/bin/perl -w
# build_beacon
# 07-25-04, 07-26-04
# KA1FSB/kbn
#
# --------------------------------------------------------------------
# Script to insert various idents and data lines,
# so that it may be automated and run in background, using "at"
# and cron together... cron would run this one, and "at" would at
# intervals run "source /jnos/scripts/do_beacon"
#
# To get the \r, you need to use \\r, so that the backslash shows up.
#
# Usage: build_beacon <device_type> <beacon_form_type>
#
# NOTE: This will build a beacon kicker for any device; just make sure
# that it exists!
# --------------------------------------------------------------------
#----- Inits...
$buffer = "";
$line = "";
$date = "";
$buffer = "";
#----- Defaults...
$beacon = "shortform";
$device = "hf";
#----- Data Inits...
$eol = "\\r";
$myPath = "/jnos/scripts";
# ----------------------------------------------------------------
# Main process
# ----------------------------------------------------------------
#----- First look for command line args...
$device = $ARGV[0] if $ARGV[0];
$beacon = $ARGV[1] if $ARGV[1];
#----- Clear the previous file "buffer" ...
system("> $myPath/do_beacon");
#----- Get date for today
chomp($date = `/bin/date`);
#----- File I/O ops
open(FI, "< $myPath/do_beacon.tmplt");
open(FO, ">> $myPath/do_beacon");
open(BEACON, "< $myPath/beacons/$beacon");
#----- Read in the lines... create one big line
while (defined($buffer = <BEACON>))
{
chomp($buffer);
$line .= $buffer . $eol;
}
close(BEACON);
#----- Now make subs in the template file with real data swapped in...
$buffer = "";
while (defined($buffer = <FI>))
{
chomp($buffer);
#----- Make replacements...
$buffer =~ s/MYDATE/$date/;
$buffer =~ s/BODY/$line/;
$buffer =~ s/DEVICE/$device/g;
print FO "$buffer\n";
}
#----- Close all opens...
close(FO);
close(FI);
#----- End of build_beacon
|
This is a fairly straightforward piece of code. It accepts and requires
two (2) command line arguments: the device, hf, and the input beacon
text file, here named shortform. The script also captures today's
date. It opens the template file and makes the swaps. And, it's done! The
output is the updated do_beacon file.
Where does it get the shortform file? Well, there is a directory called
beacons, which you create, under the /jnos/scripts direcory. This
is where you can keep any and all forms that you wish to use as bctext
files. Here is what the shortform file looks like:
|
Sample shortform file: /jnos/scripts/beacons/shortform
|
JNOS/Linux 1.11f * Network 105 * 14.105<>145.090 [Wellesley, MA]
|
and here is the final output as generated by build_beacon:
|
Auto-Generated do_beacon JNOS script
|
# JNOS Script
# do_beacon
# 07-25-04
# KA1FSB/kbn
# ------------------------------------------------------------------
# Generated on: Mon Jul 26 10:37:24 EDT 2004 by build_beacon
# JNOS script to load the device configuration buffer for bc text
# ------------------------------------------------------------------
#
ifc hf ax25 bctext "JNOS/Linux 1.11f * Network 105 * 14.105<>145.090
[Wellelesy, MA]\r"
#
# ax25 bc hf
#
#----- End of do_beacon
|
To run build_beacon manually, issue this command:
- build_beacon hf shortform
Where hf is the device name and shortform is the beacon text file. At this
point, we have what could be described as a semi-automated system. Depending
on how often the AT function has been set to run do_beacon, we only need to
run this build_beacon script just prior and with the parameters that we need
to have set into the broadcast. For example, you might wish to run another
bctext file named longform. This is a slightly more detailed version of the
shortform. It is also a plain text file. (You enter it exactly as you wish
to see it displayed in the broadcast, "what you see is what you get.")
|
Sample longform file: /jnos/scripts/beacons/longform
|
JNOS/Linux 1.11f * Network 105 * 14.105<>145.090 - Karl
KA1FSB-7/N (WELLS) - TCP/IP 44.56.26.11
FN42jh [Wellesley, MA]
|
Invoking the command build_beacon hf longform, would produce a
do_beacon JNOS script as follows:
|
Auto-Generated do_beacon JNOS script for longform
|
# JNOS Script
# do_beacon
# 07-25-04
# KA1FSB/kbn
# ------------------------------------------------------------------
# Generated on: Mon Jul 27 10:37:37 EDT 2004 by build_beacon
# JNOS script to load the device configuration buffer for bc text
# ------------------------------------------------------------------
#
ifc hf ax25 "JNOS/Linux 1.11f * Network 105 * 14.105<>145.090 - Karl\r
KA1FSB-7/N (WELLS) - TCP/IP 44.56.26.11\r
FN42jh [Wellesley, MA]\r"
#
# ax25 bc hf
#
#----- End of do_beacon
|
Again, I have placed "\n" in the file for readabillity here. In the
actual do_beacon file, the ifc line would be "off the screen," seen as
one very long string. The build_beacon script essentially replaces all
'\n' characters in the original text file with '\r' characters in the
do_beacon JNOS script, and it surrounds the text body with quotations to
satisfy the ifc command syntax.
So, what do we have so far? We have set-up a feeder system using a JNOS
script named do_beacon, a template for that script named do_beacon.tmplt,
and a Perl script to convert various input flat text broadcast message
files into the correct command syntax for the JNOS script facility. And,
perhaps we have scheduled AT into action to always run the do_beacon
refresher at pre-determined intervals. We can create, on-the-fly, any
message file we wish in the beacon directory, and by running build_beacon,
we can "merge" that file into do_beacon, which in turn will prepare
the device's beacon area for its next scheduled broadcast.
- Using Cron to Automate the Linux Side
-
Can we automate this process even more, and of
course, the answer is yes! We can set up a schedule line in cron to
run just before our AT do_beacon run. This cron command will run
build_beacon on a "fixed" port/device but with a file named anyform.
So all we need to do is copy our beacon message, which could pre-exist or
be created on-the-fly, into the "feeder" file, anyform. Here is the
sequence of commands to set this into "motion:"
From the JNOS console enter:
- at 15 "source /jnos/scripts/do_beacon+"
which will set up the AT to run at 15 minutes past every hour.
From crontab -e enter:
- 10 */1 * * * /bin/bash /jnos/scripts/build_beacon hf anyform 1>/dev/null 2>/dev/null
which will set cron to run this script at 10 minutes past every hour.
So, as can be seen, we must synchronize these operations to get the
sequencing right. The cron utility runs the build_beacon script at 10
minutes after each hour and the JNOS AT runs do_beacon at 15 minutes
past the hour. If we were scheduled to beacon at 20 minutes past every
hour, then "in theory" any changes to the do_beacon script would always
be updated properly. If we do nothing to the file anyform, located in
/jnos/scripts/beacons, then whatever was first copied into it, will be
what is broadcast. However, if we edit, change, or copy any other
pre-existing message into that file, then that is the one that will
beaconed after cron runs build_beacon and AT runs do_beacon at their
coordinated times...
And speaking of coordination and synchronization, we need to be absolutely
sure that the clocks on JNOS and on Linux are on the same "page" to within
a second. Place the following command near the end of your autoexec.nos
file:
- rdate server ka1fsb.ampr.org
(Replace my domain name above with your FQDN for the host machine that is
running the JNOS application, or use the IP number for your Linux host
machine... rdate will "copy" the time from the Linux host to JNOS.)
And, to synchronize the actual beaconing transmission, please see
"Synchronizing a Beacon in JNOS". for a detailed explanantion
of this setup.
Suppose we were set to beacon every 20 minutes and we wanted to be sure that
each beacon "event" was properly accounted for. We would have to set up an
AT schedule very similar to the single-time one shown above. Here is a
listing of those JNOS AT commands based on a 20 minute broadcast interval:
- at 15 "source /jnos/scripts/do_beacon+"
- at 35 "source /jnos/scripts/do_beacon+"
- at 55 "source /jnos/scripts/do_beacon+"
And here is the line for cron...
- 10,30,50 */1 * * * /bin/bash /jnos/scripts/build_beacon hf anyform 1>/dev/null 2>/dev/null
The cron line translates to: run this script each hour at 10, 30 and 50
minutes after each and every hour...
The general rule I am following is: run build_beacon five minutes before
do_beacon, and run do_beacon five minutes before actually beaconing. We are
beaconing at the top of the hour, 20 minutes after, and 40 minutes after.
The allocation of scripting "resources" must be properly sequenced to
anticipate any change in the beacon message. If you were to beacon every ten
(10) minutes, then the AT JNOS commands would need to be adjusted
accordingly, as well as the cron schedule line.
In sum, each beacon transmission is preceded by a call to do_beacon
which in turn is preceded by a call to build_beacon. If you were
automating position beacons for mobile units, then even more
frequent time divisions might be considered. Therefore, it might be a
good idea to place all these JNOS AT timers into a single JNOS script!
(You could name it something like do_bctimers, and it could also be subject
to auto-generation based on the timing differentials... just a thought :)
- Automating "the Automaters"
-
Can we take this one step farther still? And,
again, the answer is yes! We can create "forms" on-the-fly that can be
"filled in" dynamically from various sources: data from OS calls, such
as the time and date function; reading log or data collections files;
and even pulling streams from pipes or sockets connected to the internet.
To keep things simple though, the example that will be developed here will
present a strategy for managing dynamic data flows. My approach to this
problem is to use another Perl script, and use its "format"
data structure to create a real, "live" form. Then write the output to a
file named dataform in the usual place, /jnos/scripts/beacons, and then call
build_beacon with that file as one of its argument. Let's take a look at
the Perl script:
|
A Perl Script for Dynamic Form Building: dataform.plx
|
#! /usr/bin/perl -w
# dataform.plx
# 07-27-04, 07-31-04
# KA1FSB/kbn
# ---------------------------------------------------------------
# Sample script for generating a dynamically populated form.
#
# Time is the only trully dynamic datum used here, but other
# types like Lat/Lon, etc, could be gathered and built from here.
#
# The output form is named dataform in /jnos/scripts/beacons
# Although a bit hard-coded, takes advantage of Perl's "format"
# data structure builder.
# ---------------------------------------------------------------
#----- Data Inits...
$wxdesc = "Sunny w/ some clouds";
$wxtemp = "70";
$myPath = "/jnos/scripts/beacons";
$loctime = "";
$utctime = "";
#----- The format as defined by Perl
format DATAFORM =
KA1FSB-7/N (WELLS) * Network 105 * FN42jh [Wellesley, MA]
Local Time.:@>>>>>>>> UTC..:@>>>>>>>>
$loctime, $utctime
Local WX...: @<<<<<<<<<<<<<<<<<<<<< Temp.:@##
$wxdesc, $wxtemp
.
# -----------------------------------------------------------------
# Main
# -----------------------------------------------------------------
#----- Open the form for output...
open(DATAFORM, ">$myPath/dataform");
chomp($loctime = `/bin/date +%H:%M:%S`);
chomp($utctime = `/bin/date -u +%H:%M:%S`);
#----- Write the format block ...
write (DATAFORM);
#----- Close the file
close(DATAFORM);
#----- Now build the JNOS do_beacon script using dataform as the input
system("/jnos/scripts/build_beacon hf dataform");
#----- End of dataform.plx
|
This very simple snippet of Perl code builds a form dynamically and then
writes it to the beacon text area (config table) via build_beacon and
eventually do_beacon. Therefore this script needs to be called within
the framework of the beacon synchronizers that were decribed above,
that is, JNOS AT and Linux cron facilities. Here is the cron line that
will call this script and keep the data flows in synchrony:
- 10,30,50 */1 * * * /bin/bash /jnos/scripts/dataform.plx 1>/dev/null 2>/dev/null
When using this cron command line, the script dataform.plx is only called
at fixed, coordinated time intervals, thus keeping the timing issues under
control. However, there might be other programs actually collecting
"live" data. If this were the case, then dataform.plx would need to take
a "snapshot" of these streams, collect and filter that data, and then
present the most updated information, probably via a logfile read to
Perl's format structure, generating the latest copy of the output
file, dataform.
Here is what finally resides in the JNOS script do_beacon which will be
sent out on the next transmission:
|
Dynamically Built Output Form: dataform, merged into do_beacon
|
# Beacon script
# 07-25-04
# KA1FSB/kbn
# --------------------------------------------------------------
# Generated on: Sat Jul 31 08:04:59 EDT 2004 by build_beacon
# Testing: A revised ID (beacon) text template
# --------------------------------------------------------------
#
ifc hf ax25 bctext "KA1FSB-7/N (WELLS) * Network 105 * FN42jh [Wellesley, MA]\r
Local Time.: 08:04:58 UTC..: 12:04:58\r
Local WX...: Sunny w/ some clouds Temp.: 70\r"
#
# ax25 bc hf
#
#----- End of do_beacon
|
Again, this is a very simple form. There could be several more updateable,
dynamically refreshed, fields; latitude and longitude come to mind. (And, I
have made it readable by including '\n' characters here which would normaly
not be included in this file.)
The code dataform.plx has embedded the format data structure into the
script itself. This should help in the understanding of how to use such a
code feature. For a more versatile approach, please see the article on
Setting up a Beacon Server which shows how to keep both formats and
data outside the program, making a simple script into a very capable
on-demand server.
- EOT ...
-
In sum, managing your beacon events can expand way
beyond the typical "signature" beacons in the world of *NOS! If used with
care and judiciously, beacons can convey timely information that may prove
to have great utility for the operators on the net. I encourage you to
experiment with these pieces of code given here. There is still room for
development and advancement in the field of Amateur Radio! We have just
shifted a bit from the hardware to the software.
And, a final observation, the code presented here is really to be taken
as an exemplification of a general approach to solving a few network
broadcasting problems. If you like Python, Java, or C++, these concepts could certainly
be re-developed within any language framework. Think about the potential
"connections," many of which nearly almost already exist!
(Courtesy KBNorton Computer Services)
|