This section of the document describes how an application
interfaces to the µH Router using the UDP interface. If you
are only interested in using the router, please go directly
to the Set Up page.
UDP Interface
The UDP interface uses the bidirectional
User Datagram Protocol to
communicate.
Once µH Router is
launched, it opens a number of UDP
ports that the client can use to communicate with each
of the keyer's function.
When the client has finished using the router, it can
terminate the router, or just leave µH
Router running.
Launching the µH
Router
There
are multiple ways to launch µH Router. With Cocoa, you
can send a
-launchApplication: message to the
AppKit's
NSWorkspace class. With Carbon, you
can launch an application by calling
LSOpenApplication in
Launch Services. Finally, you can
use AppleScript to launch the router from an
AppleScript Studio program or a Carbon or Cocoa
application.
Master UDP Ports on the µH Router
The µH Router opens
four UDP ports when it is launched. The master port is at
60744. The other ports are used by up to three keyers
(microKeyer, CW Keyer and digiKeyer) and have the next
three consecutive port numbers.
Although they are not dynamically created, you won't
directly use the three ports that are associated with the
keyers. You request those port numbers from the master
port. They are mentioned here in case you need to open a
network Firewall for the UDP packets to pass through.
The master port corresponds to the number
( ( 0x8000
|
' mH'
)
& 0xffff
).
The following are single byte datagrams that you can send
to the router's master port:
#define
ROUTERFUNCTION 0x80
#define
OPENMICROKEYER ( ROUTERFUNCTION + 0x01 )
// get a port to the microKEYER router
#define OPENCWKEYER ( ROUTERFUNCTION +
0x02 ) // get a port to the CW KEYER router
#define OPENDIGIKEYER ( ROUTERFUNCTION + 0x03
) // get a port to the DIGI KEYER router
#define QUITIFNOKEYER ( ROUTERFUNCTION + 0x1f
) // quit if there are no keyers
#define QUITIFNOTINUSE ( ROUTERFUNCTION + 0x1e )
// quit if not connected
#define QUITALWAYS (
ROUTERFUNCTION + 0x1d ) // quit
#define WATCHDOG
( 0x08 )
(Notice that, except for the additional WATCHDOG item,
these have the same values as the commands sent to the
FIFO's master port that is described in the
Interface section. The watchdog
function is described later
here.)
Obtaining UDP Ports to a
Keyer
To obtain a port for communicating with a keyer, you send a
single byte datagram with
OPENMICROKEYER or
the
OPENDIGIKEYER or
the
OPENCWKEYER byte
to the master port. The µH Router will send back a three
byte datagram. The following is an example of obtaining the
UDP port of the microKeyer.
unsigned
char buffer[4] ;
buffer[0]
= OPENMICROKEYER
;
sendto(
mySocket,
command, 1, 0, (struct
sockaddr*)udpServerAddress,
sizeof(
struct
sockaddr ) ) ;
int
port = 0 ;
if
( recv( mySocket,
buffer, 4, 0 ) == 3 ) && (
buffer[0] & 0xff ) == OPENMICROKEYER
) {
port
= buffer[1]*256 + buffer[2] ;
}
The first byte of the reply datagram contains
OPENMICROKEYER or
OPENDIGIKEYER or
OPENCWKEYER. The
next two bytes contain the big endian port number for the
keyer's UDP port. The two bytes will be zero if µH Router
could not find an attached (hardware) keyer.
There is no need to "close" a connection. The router will
remove any UDP client that has been inactive for more than
60 seconds. A client stays connected by sending keyer
commands, and it can ask to stay connected by periodically
sending a watchdog datagram. A watchdog packet can be
considered to be a
no-op operation that only
updates timers in the router. The watchdog packet is
described in greater detail
here.
Note: µH Router should return port 60745 for the microKeyer
if it exists, 60746 for the CW Keyer if it exists, and port
60746 for the digiKeyer if it exists. However, you should
use the number that is returned in the datagram in case
there is a change in the future.
Communicating with Keyer
Functions
Each
microHAM keyer has multiple functions, and each of
these functions can be accessed by prefixing a
datagram with a PREFIX byte:
#define
RADIO_PREFIX ( KEYERFUNCTION + 0x02 ) // RADIO
function
#define CONTROL_PREFIX ( KEYERFUNCTION + 0x03 ) // CONTROL
function
#define PTT_PREFIX ( KEYERFUNCTION +
0x04 ) // PTT flag bit
#define CW_PREFIX ( KEYERFUNCTION
+ 0x05 ) // serial CW flag bit
#define RTS_PREFIX ( KEYERFUNCTION +
0x06 ) // RTS flag bit
#define FSK_PREFIX ( KEYERFUNCTION +
0x07 ) // FSK serial port
#define WINKEY_PREFIX ( KEYERFUNCTION + 0x08 ) //
WinKey port
#define FLAGS_PREFIX ( KEYERFUNCTION + 0x09 ) //
FLAG bits
#define WINDOW_PREFIX ( KEYERFUNCTION + 0x0b ) //
response window
Whenever µH Router gets a response from a function (e.g.,
FSK) in the keyer, it checks all connected UDP clients to
see if the client has sent a command to that function
within a
response time. A UDP client is
"connected" if it has used one of the OPEN operations
described
above. If a client has sent a
command, µH Router will pass the keyer's response to
the client.
Please note that a UDP client can still receive a response
that it did not initiate; for example when a different
client has sent a keyer command to the same function within
the same response window. However, this mechanism should
reduce the number of datagrams that the client has to
discard.
There are two exceptions to this.
The first exception is that in addition to responding to
FLAGS requests, a FLAGS response will also be returned to
clients that have made PTT, CW, RTS or FSK requests within
the response window. This is because PTT, CW, RTS ad FSK
can all cause a FLAGS response. E.g., the FSK buffer empty
state is sent back from a microHAM keyer through the FLAGS
channel, not the FSK channel.
The second exception is when the WRITEONLY flag is merged
with the PREFIX byte (e.g., PTT _PREFIX | WRITEONLY ). In
this case, a response window will not be opened.
RADIO Port
Datagrams that are
sent to a keyer's RADIO port should have a RADIO_PREFIX
byte prepended to the control data.
Datagrams that are sent back through the UDP keyer port
will also begin with a RADIO_PREFIX byte. As in the FIFO
case, µH Router aggregates single byte responses from the
keyer's RADIO port into a buffer. An entire buffer is sent
to the client only when an "aggregate timeout" has
exceeded. The client should be prepared to see multiple
byte RADIO datagrams.
Please note that you do not use ioctl to set the serial
port parameters (bits, parity, baud rate) of the radio
port. Instead, you set the radio's serial parameter by
using SET RADIO CHANNEL command the
Control Port. Please refer to the
microHAM Keyer Protocol document for the details.
CONTROL Port
Datagrams that are sent to a keyer's CONTROL port should
have a CONTROL_PREFIX byte prepended to the RADIO data.
Datagrams that are sent back through the UDP keyer port
will start witjh a RADIO_PREFIX byte.
In addition to the 8 bit data bytes in a CONTROL stream,
the microHAM keyers require that the first and the last
byte of a control command string be specially tagged.
The way the
µH Router handles this is to require that you send each
complete command string using a single UDP sendto()
call. The router will then tag the first and the
last byte of that string properly. These tagged bytes are
the ones that are shown in bold in the microHAM Keyer
Protocol document.
A response from a keyer's CONTROL port will likewise be
buffered so that all the bytes of a CONTROL stream are sent
in a single datagram back to the client.
The Control port of a microHAM keyer is used to set
parameters in the keyer. This includes setting the serial
port parameters (number of data and stop bits, parity and
baud rate) of the RADIO and FSK channels, settings various
parameters such as FSK polarity, setting up the WinKey
memory, obtaining version number of the keyer, setting up
the bootloader for downloading new firmware, etc.
PTT Port
If you send a
non-zero byte that is not an ASCII '0' to this port, the
keyer will engage the PTT of the attached receiver (as long
as the keyer is set up to connect this command to the
physical PTT line - see STORE SETTINGS command in the
microHAM Keyer Protocol document).
Whenever the PTT state changes, the PTT changes are
reported back as a bit within the FLAGS channel of the
keyer. µH Router will send the FLAGS bytes back to the
client.
Please be prepared to ignore any FLAGS state changes that
you did not initiate since they can be caused by other
applications or even other physical sources (e.g., from a
foot switch).
Data is sent from UDP to the PTT port if the datagram
starts with the PTT_PREFIX byte. Responses from the keyer
are sent to the client as datagrams whose initial byte
contains the FLAGS_PREFIX.
Serial CW Port
Like the PTT port, this port asserts or
deasserts a "serial CW" keying line. If the keyer is set up
to obey the signal, writing a non-zero character to this
port will assert the keying line from the keyer to the
radio. With the current firmware from microHAM, the Keyer
Mode has to be set to CW for serial CW and WinKey to
function.
Data is sent from UDP to the serial CW port if the datagram
starts with the CW_PREFIX byte. Responses from the keyer
are sent to the client as datagrams whose initial byte
contains the FLAGS_PREFIX.
RTS Port
This is yet another
port that controls a flag bit on the Keyer and appears on
the RTS pin of the serial port from the keyer to the radio.
Data is sent from UDP to the RTS port if the datagram
starts with the RTS_PREFIX byte. Responses from the keyer
are sent to the client as datagrams whose initial byte
contains the FLAGS_PREFIX.
WinKey Port
This is the port that
is connected to the WinKey chip on a microKEYER and a CW
KEYER (note: the DIGI KEYER lacks this chip).
The data that you send to this port is documented in K1EL's
WinKey document. You can command
the WinKey chip to send Morse characters, change
dash/dot weighting, CW speed, join two characters into
a Prosign, etc.
Data is sent from UDP to the WinKey port if the datagram
starts with the WINKEY_PREFIX byte. Responses from the
keyer are sent to the client as datagrams whose initial
byte contains the WINKEY_PREFIX.
FSK Port
This port allows you
to send Baudot data to an FSK buffer in the keyer, to be
sent out as an FSK keying line. The baud rate and other
parameters are set up by sending the SET FSK CHANNEL
command to the CONTROL port. Characters sent to the FSK
Port will key the FSK line of the radio.
(NOTE: the
FSK ports in the microHAM devices do not work at the
nominal Amateur RTTY data rate of 45.45 baud -- you will
have to configure it to use 45.0 baud. While this is not
ideal with demodulators that are tuned for 22 msec bit
periods, there should be no noticeable difference in
performance except when the SNR is very poor.)
Data is sent from UDP to the FSK port if the datagram
starts with the FSK_PREFIX byte. Changes in the empty state
of the FSK buffer in the keyer is reported back as a bit in
the FLAGS channel. Because of that, µH Router will send
FLAGS changes to a client that is actively using the FSK
port as datagrams whose initial byte contains FLAGS_PREFIX.
Currently, the microHAM keyers do not send any response
back in the FSK port.
Write-only
Datagrams
The keyer functions (PTT, WinKey, FSK, etc) can be sent in
Write-only mode if you are not interested in responses from
the keyer. To send a command and not receive a response,
merge the WRITEONLY flag to the PREFIX byte (e.g.,
PTT_PREFIX|WRITEONLY).
The WRITEONLY flag is defined as:
#define WRITEONLY
0x80
Timeouts and response
windows
The router will stop communicating with a client if it does
not see any datagrams from the client in 60 seconds.
To keep the router alive when there is no new data to send
to the keyer, the client can send a single byte WATCHDOG
datagram to either the router's master UDP port, or one of
the keyer's UDP port.
#define WATCHDOG
( 0x08 )
If the WATCHDOG packet is sent to the master UDP port, the
router will update all the keyers which the client is
using. If it is sent to a keyer's UDP port, it only extend
the timeout for the client's connection to the keyer.
The router has a mechanism to keep responses from the keyer
that are not initiated by a client down to a minimum. This
is done by establishing a
response window for each
keyer function. If a keyer response arrives outside of a
window after a keyer command was sent by the client, the
router will assume that the response belongs to a different
client. The default window is 1 second.
For example, if a response to a CONTROL command arrives
from the keyer later than 1 second after a CONTROL command
arrives from the client, the response will not be passed
back to the client.
The client can change the response window from the default
1 second by issuing a datagram that has the WINDOW_PREFIX
as the first byte.
#define
WINDOW_PREFIX ( KEYERFUNCTION + 0x0b ) // response
window
A
response window datagram consists of 3 bytes,
starting with the WINDOW_PREFIX byte. It is followed by a
byte that specifies the function, such as
RADIO_PREFIX.
The third byte encodes the response window duration.
If the duration (last) byte contains 0, the response window
will be set to the default (1 second) value. If it contains
255, the response time will be consider indefinite
(actually hundreds of days). For any other value, the
response time is set to n/16 of a second, where n is
between 1 and 254.
The FLAGS, PTT, serial CW and RTS "ports" share the same
response window parameter.
Terminating the µH
Router
There are three different ways that you can use to
terminate the µH Routerby sending a single byte datagram to
the µH Router's master port.
#define
QUITALWAYS ( ROUTERFUNCTION +
0x1d ) // quit
#define
QUITIFNOKEYER ( ROUTERFUNCTION + 0x1f )
// quit if there are no keyers
#define QUITIFNOTINUSE ( ROUTERFUNCTION + 0x1e )
// quit if not connected
The first way is the unconditional
quit
message that you can send to the router's master port. It
is not advisable to use this command if the router can
potentially be shared and be in use by another
application., for example:
command[0]
= QUITALWAYS ;
sendto(
mySocket, command, 1, 0, (struct
sockaddr*)udpServerAddress,
sizeof(
struct
sockaddr ) ) ;
When the µH Router receives the
QUITALWAYS command, it waits one
second and then quits.
The µH Router also supports a
quitIfNoKeyer command. When the µH Router
wakes up, it looks to find any serial port that is
associated with a microHAM device. It it does not find any
keyer and if it receives a subsequent quitIfNoKeyer
command, the µH Router will terminate itself.
command[0]
= QUITIFNOKEYER ;
sendto(
mySocket, command, 1, 0, (struct
sockaddr*)udpServerAddress,
sizeof(
struct
sockaddr ) ) ;
Instead of launching the µH Router and then asking it to
quit, the application can also check to see if any microHAM
devices exist before launching the router. microHAM devices
have serial ports with names that start with "
usbserial-MK"(microKEYER),
"
usbserial-DK"(DIGI
KEYER) or "
usbserial-CK"(CW
KEYER).
Another conditional termination script is the
quitIfNotInUse command. This command will
cause the µH Router to terminate if there are no
connections made to it from an application. You can safely
send the quitIfNotInUse command to the µH Router just
before your application terminates. This will remove the
router from the dock if no other application is using the
router. E.g.,
command[0]
= QUITIFNOTINUSE ;
sendto(
mySocket, command, 1, 0, (struct
sockaddr*)udpServerAddress,
sizeof(
struct
sockaddr ) ) ;