G8BPQ
Host Mode
From
Version 4.00, a new application interface to the switch is provided.
This
replaces the existing interfaces (TNC2, PK Host and KISS). New
software
should if possible use the new interface - interface routines
supporting
the old modes, and WA8DED Host mode, will be provided as TSRs
to
support existing application software.
The
interface is normally called using INT 7Fh. From version 4.03 the interrupt
number
may be changed - The value is specified in BPQCFG.TXT as INTERRUPT=nnn,
where
nnn is in decimal. The function required is in AH, and the stream in AL.
The
system supports 64 streams, or sessions, numbered from 1 - 64.
Changes
in Version 4.05.
1. Additional option on funtion 6 - allows
connects using BBS Call, even
if APPLMASK is not set (say to prevent
connects).
2. Additional info returned by function 8.
3. Format of frame returned by function 11
added to documentation.
4. Function 15 added. Simplifies access to
timing info.
5. Broadcast option added. If function 2 is
called with AL=0, the
data will be sent as a UI frame to all
ports which have an UNPROTO
address set.
6. Function 12 added to update Beacon text.
Changes
in Version 4.07b
1. Function 0 added to check if loaded, and
get version number. This
is because the old method of checking
(looking at the bytes before
the interrupt routine) isn't compatible
with some versions of
DesqView, or the Windows version of the
switch (coming soon!)
2. Function 12 extended to allow application
to request a NODES
broadcast.
3. Function 13 added to allow application to
request a free stream and
to free a stream after use. This will
simplify configuration when
several applications are used.
Note
that in all cases where a string is returned, ES:DI must point to
a
buffer supplied by the user, and the switch will copy the data to
this
buffer. The code does NOT return pointers to its own data.
AH = 0 Get
node/switch version number and description.
On return
AH='B',AL='P',BH='Q',BL='
'
DH
= major version number and DL = minor version number
AH = 1 Set
application mask to value in DL.
Set
application flags to value in CL.
If top bit of CL is set, monitored frames will be available.
Use function 11 to receive them.
AH = 2 Send
frame in ES:SI (length CX)
AH = 3 Receive
frame into buffer at ES:DI, length of frame returned
in
CX. BX returns the number of
outstanding frames still to
be
received (ie. after this one) or zero if no more frames
(ie.
this is last one).
Note
that CX is NOT an input param - the supplied buffer
must
be big enough to receive a full AX.25 frame, including
up
to 8 digi callsigns. 340 should be enough.
AH = 4 Get
stream status. Returns:
CX
= 0 if stream disconnected or CX = 1 if stream connected
DX
= 0 if no change of state, or DX = 1 if
the connected/disconnected state has changed.
AH = 5 ACK
stream status change. Must be called to allow another
status
change to be reported.
AH = 6 Session
control.
CX
= 0 Connect to Node. Session uses BBS callsign if bottom
bit of DL=1, otherwise uses Node Call .
CX
= 1 Connect to Node. Session uses BBS Call if APPLMASK=1,
otherwise Node Call.
CX
= 2 Disconnect
CX
= 3 Return user to node
AH = 7 Get
buffer counts for stream. Returns:
BX
= number of frames queued for receive
CX
= number of un-acked frames to be sent
DX
= number of buffers left in node
AH = 8 Port
control/information. Called with a
stream number
in
AL returns:
ES:DI
= CALLSIGN (10 bytes space padded)
The
following are now supported (4.05 onwards)
AL
= Radio port on which channel is connected (if level 2)
AH
= Session Type (If Connected). Session type bits are:
L2LINK EQU 1
SESSION EQU 10B
UPLINK EQU 100B
DOWNLINK EQU 1000B
BPQHOST EQU 100000B
BX
= L2 paclen for the session
CX
= Maxframe. Taken from PORT maxframe if L2 session,
Switch maxframe if L4.
DX
= L4 window size (if L4 circuit, or zero)
AH = 10 RAW
(KISS) transmit frame. Data pointed to
by ES:SI, of
length
CX, is transmitted as a HDLC frame on the radio
port
(not stream) in AL.
AH = 11 Get Trace (RAW Data) Frame into
ES:DI, Length to CX. Data
is
as received off air (ie with calls in AX.25 format, etc)
See
note on CX under function 3.
The
returned buffer includes a 5 byte header:
Bytes 0-1 - Internal control
info (ignore)
Byte 2 - Port number. Top bit set if transmitted frame.
Bytes 3-4 - Frame length
(including this header)
AH = 12 Update Switch Info. This will be
used for a number of
operations.
At the moment the only ones implemented are to
update
the Beacon Text field, and initiate a NODES broadcast.
DX
= Function Number.
DX = 1 Update Beacon Text.
ES:SI
Data to send in Beacons
CX Length of Data
DX = 2 Initiate NODES broadcast
AH = 13 Allocate/deallocate stream
If
AL=0, return first free stream in AL. If AL=255 on
return, there are no free streams
If
AL>0, CL=1, Allocate stream. If aleady allocated,
return CX nonzero, else allocate, and return CX=0
If
AL>0, CL=2, Release stream
Note that for compatiblity with old software, certain other
functions also set the allocated bit (Functions 1,2,6). So
an application has a reasonable chance of getting an unused
stream, even if some applications dont use the allocate function.
AH
= 15 Get time marker in AX. Value is number of timer interrupts
since
switch was loaded, modulo 65536. Timer interrupts
normally
occur at approx 18.2 per second.
PACLEN.
Frames
are transmitted as received from the application, so the application
is
responsible for the transmitted PACLEN. Function 8 will return the
recommended
value for the current session. I think the value is always OK,
but I
suggest you treat a value of zero as 'undefined', and use your own
default.
The value may change during a session, if for instance, you connect
to the
switch, and then out on a port with a different PACLEN. Also at
some
time in the future I hope to adjust PACLEN to suit conditions on the
channel.
So I recommend that the value is re-read from time to time during
a
session.
The
following sample of code shows how to find the Interrupt Number to use
to call
the switch, and check that the switch is loaded.
NOTBPQERROR DB 'Switch
not found$'
VERSERROR DB 'Version
not compatible with Node Software$'
BADCONFIGMSG DB 'Configuration
file read error',0DH,0AH,'$'
CONFIGFILENAME DB 'BPQCFG.BIN',0
NOCONFIGMSG DB 'Configuration
file BPQCFG.BIN not found',0DH,0AH,'$'
;
; BPQCFG FIRST 128 BYTES
;
CONFIGTABLE LABEL BYTE
;
; CONFIGURATION DATA STRUCTURE
;
; DEFINES LAYOUT OF CONFIG RECORD PRODUCED
BY CONFIGURATION PROG
;
; LAYOUT MUST MATCH THAT IN CONFIG.C SOURCE
;
C_NODECALL DB 10
DUP (0) ; OFFSET = 0
C_NODEALIAS DB 10
DUP (0) ; OFFSET = 10
C_BBSCALL DB 10
DUP (0) ; OFFSET = 20
C_BBSALIAS DB 10
DUP (0) ; OFFSET = 30
;
C_OBSINIT DW 0
; OFFSET = 40
C_OBSMIN DW 0
; OFFSET = 42
C_NODESINTERVAL DW 0
; OFFSET = 44
C_L3TIMETOLIVE DW 0
; OFFSET = 46
C_L4RETRIES DW 0
; OFFSET = 48
C_L4TIMEOUT DW 0
; OFFSET = 50
C_BUFFERS DW 0
; OFFSET = 52
C_PACLEN DW 0
; OFFSET = 54
C_TRANSDELAY DW 0
; OFFSET = 56
C_T3 DW 0 ; OFFSET = 58
DW 0
; OFFSET = 60
DW 0 ; OFFSET = 62
C_IDLETIME DW 0
; OFFSET = 64
C_EMSFLAG DB 0
; OFFSET = 66
DB 0
C_BBS DB 0 ; OFFSET = 68
C_NODE DB 0 ; OFFSET = 69
C_HOSTINTERRUPT DB 0
; OFFSET = 70
C_DESQVIEW DB 0
; OFFSET = 71
C_MAXLINKS DW 0
; OFFSET = 72
C_MAXDESTS DW 0
C_MAXNEIGHBOURS DW 0
C_MAXCIRCUITS DW 0 ;
78
C_TNCPORTLISTO DB 16
DUP (0) ; OFFSET = 80
C_IDINTERVAL DW 0 ;
96
C_XXXXXXXX DW 0 ;
98 ; SPARE (WAS DIGIFLAG)
C_MINQUAL DW 0 ;
100
C_HIDENODES DB 0 ;
102
C_L4DELAY DW 0 ;
103
C_L4WINDOW DW 0 ;
105
C_BTINTERVAL DW 0 ;
106
X_UNPROTO DB 9
DUP (0) ; 108 ; NOW SPARE
C_BBSQUAL DW 0 ;
117
DB (CONFIGTABLE+128-$) DUP (0)
CONFIGHANDLE DW 0
NODE:
INT 7FH
RET
INIT:
;
; GET NODE INTERRUPT NUMBER FROM CONFIG FILE
;
MOV DX,OFFSET
CONFIGFILENAME
MOV AH,3DH
MOV AL,0 ; READ ONLY
INT 21H ; OPEN IT
JC NOCONFIGFILE
MOV CONFIGHANDLE,AX
MOV BX,AX
MOV DX,OFFSET
CONFIGTABLE
MOV CX,128
MOV AH,3FH
INT 21H ; READ
CMP AX,CX
JNE SHORTCONFIG
JMP SHORT PROCESSCONFIG
NOCONFIGFILE:
MOV DX,OFFSET
NOCONFIGMSG
JMP SHORT CONFIGERR
SHORTCONFIG:
MOV DX,OFFSET
BADCONFIGMSG
CONFIGERR:
MOV AH,9
INT 21H
MOV AX,4C01H
INT 21H ; EXIT
PROCESSCONFIG:
MOV BX,CONFIGHANDLE
MOV AH,3EH
INT 21H ; CLOSE IT
MOV AL,C_HOSTINTERRUPT ; INTERRUPT
MOV BYTE
PTR NODE+1,AL ; PATCH NODE CALL
INSTRUCTION
;
; GET NODE VERSION
;
PUSH DS
MOV AH,0
ADD AX,AX ; VECTORS ARE 4 BYTES LONG
ADD AX,AX
MOV SI,AX
XOR AX,AX
MOV DS,AX
;
; DS:SI POINTS OUR VECTOR
;
; FIRST SEE IF VECTOR POINTS TO CODE -
CALLING AN UNINITIALISED
; INTERRUPT WILL CRASH THE SYSTEM
;
CMP WORD
PTR DS:2[SI],0 ; INTERRUPT ROUTINE
SEGMENT ADDRT
POP DS
JNE SWITCHOK ;
ROUTINE PRESENT
NOSWITCH:
MOV DX,OFFSET
NOTBPQERROR
MOV AH,9
INT 21H
JMP SHORT EXIT
SWITCHOK:
MOV AH,0
CALL NODE ; SET INSTALLED FLAGS AND VERSION
CMP AX,'PB' ;
AX,BX SHOULD BE 'BPQ '
JNE NOSWITCH
CMP BX,'
Q'
JNE NOSWITCH
CMP DH,MAJORVERSION
JNE BADVERSION
CMP DL,MINORVERSION
JE VERSIONOK
BADVERSION:
POP DS
MOV DX,OFFSET
VERSERROR
MOV AH,9
INT 21H
EXIT:
MOV AX,4C00H
INT 21H
VERSIONOK:
POP DS
;
..........
The
release disk also contains a demonstration terminal program, TERM4,
written
by G8IMB (in PASCAL) to demonstate the use of the new interface from
a high
level language. Note, however, that it was written for version 4.02,
and
therefore only works with the Host Mode interrupt configured at 7Fh
John
Wiseman, G8BPQ @ GB7BAD
20/12/91
Revised
5/9/92 and 26/3/94