<*+M2EXTENSIONS *> <* IF __GEN_C__ THEN *> <*+COMMENT*> <*+GENCTYPES*> <* END *> (* (C)OE5DXL 1993-2015, GPL3 *) DEFINITION MODULE l2; FROM SYSTEM IMPORT CARD32, CARD16, ADDRESS; TYPE SET16=SET OF [0..15]; SET8=SET OF [0..7]; CONST UA = SET16{0,1,5,6}; DM = SET16{0,1,2,3}; SABM=SET16{0,1,2,3,5}; DISC=SET16{0,1,6}; FRMR=SET16{0,1,2,7}; UI = SET16{0,1}; RR = SET16{0}; REJ= SET16{0,3}; RNR= SET16{0,2}; PORTS=15; (* portset is SET16 *) MYCALLS=16; TYPE CALLTYP=ARRAY[0..6] OF CHAR; pSTRING=POINTER TO ARRAY[0..65535] OF CHAR; pDATA=POINTER TO DFIELD; DFIELD=RECORD next:pDATA; len: CARD16; info:ARRAY[0..256] OF CHAR; (*incl PID*) END; pLINK; AFIELD=ARRAY[0..70] OF CHAR; EVENT=(eCONNECTED, eDISCONNECTED, eBUSY, eTXFREE, eRXDATA, eMONITOR, eLISTEN, eIDLE, eCONNREQ, eFLEXDATA); VAR L2Lock : BOOLEAN; (*disable interrupt starting L2*) LostINT: CARD16; dbuf : pDATA; (*must be new allocated after use*) adress : AFIELD; (*static adress field*) asize : CARD16; (*length of static adress*) l2verb : BOOLEAN; dupchk : CARDINAL; udp2buf:ARRAY[0..99] OF CHAR; (* axudp2 header after Getframe *) PortSt:ARRAY[0..PORTS] OF RECORD Links, (*statistics: links, including inactives*) MaxLinks:CARD16; Flows:ARRAY[0..12] OF RECORD Isent, (*I-frames sent, without I.P*) Iack, (*therefrom ackowledged*) Igot:CARD16; (*I-frames got and accepted*) Bytesent, (*all frames + FCS + 1 flag*) Bytegot:CARD32; (*all frames + FCS + 1 flag*) END; END; Parms:ARRAY[1..PORTS] OF RECORD (* (*c*) = rangecheck necessary*) CASE : BOOLEAN OF TRUE: card:ARRAY[0..16] OF CARD16 |FALSE: SendPort, (*c*) (*associated send port to that uplinkport*) Diversity, (*c*) (*accept frames to existing links from ports with same numbers*) DCDlevel, TXwait, (*wait after sending before sending again*) TXtail, (*for fullduplex*) TXdel, (*txdelay*) DCDwait, (*wait after dcd before sending*) BaudSwBytes, (*c*) (*number of flags sent after baud-switch*) txDelByte, (*bit pattern sent for sync*) MaxFrames, (*c*) (*send windowsize*) T1, T3, IPoll, (*max info length for I.Poll*) Retries, MhTime, (*0 = mh off*) DCDIGNOR:CARD16; (*ignore dcd longer than this time/dama slave off*) END; monitor, passall, DamaMaster, HalfDuplex, Digipeat, Echo:BOOLEAN; SendBauds:ARRAY[0..MYCALLS] OF CHAR; (*relation mycall <-> baud*) END; TYPE CMD=CARD16; CONNTYP=(cNORMAL, cCONNAK, cFLEXback, cFLEXbusy, cTEST); pCONNECT=POINTER TO CONNECT; CONNECT=RECORD (* cmd:CARD16;*) handle:CARD16; port, (*the port number of uplink port*) baud, (*baud is the index of sendbaud-table*) cpid:CARD16; (*PID*) l2adr, (*0-terminated unshifted raw ax.25 adress*) l3adr:pSTRING; (*0-terminated SABM-with-info text for routing unused if points to NIL*) typ:CONNTYP; (*TEST returns an existing link with same adress*) END; pSENDUI=POINTER TO SENDUI; SENDUI=RECORD cmd:CHAR; (* frame cmd *) port, baud:CARD16; path:pSTRING; (*0-terminated, raw, unshifted ax.25 adress-field*) datalen:CARD16[0..256]; data:pSTRING; (* PID is part of data *) END; pGETADRESS=POINTER TO GETADRESS; GETADRESS=RECORD cmd:CARD16; port, (*number of uplink port*) my, (*number of mycall*) cpid:CARD16; (*65535 if not known*) adress:ARRAY[0..71] OF CHAR; (*0-terminated, raw ax.25 adress*) END; pGETSTAT=POINTER TO GETSTAT; GETSTAT=RECORD cmd:CARD16; l:pLINK; n, st, port, my, txbu, ret:CARD16; bsy, remb:BOOLEAN; nudl:pLINK; adress:ARRAY[0..71] OF CHAR; sent, ack, rcvd, since:CARD32; END; SUMMS=ARRAY[0..6] OF CARD32; pPORTSTAT=POINTER TO PORTSTAT; PORTSTAT=RECORD cmd:CARD16; port, minits5 : CARD16; sums : SUMMS; mem : CARD16; time : CARD32; END; pPARMS=POINTER TO PARMS; PARMS=RECORD cmd:CARD16; port, parm : CARD16; test : BOOLEAN; (* get instead of set parm *) val : CARDINAL; (* for numeric values *) str : pSTRING; (* for string values *) END; CALLBACKPROC=PROCEDURE(VAR ADDRESS, pLINK, EVENT); PROCEDURE Connect(mp:ADDRESS; p:pCONNECT):pLINK; (* NIL if no link *) (*mp: adress that is enclosed in all messages from L2 to the host and may point to host-task-context*) PROCEDURE Disconnect(VAR l:pLINK; dealloc:BOOLEAN); (*if dealloc, the owner of the link will be l2, else owner stays the host and it must send a disconnect with dealloc later to release memory and timers*) PROCEDURE Circuit(VAR l1,l2:pLINK; reconn1, reconn2:BOOLEAN; exitchar:CARD16); (*links streams of l1 and l2, if not reconn, then the link will then belong to L2 again reconn: if the other link disconnects, this links datastream will be switched back to host exitchar: if first char in l1-input-stream equals exitchar the stream of l1 will be switched to host*) PROCEDURE GetAdress(l:pLINK; p:pGETADRESS); PROCEDURE Getudp2info(l:pLINK; VAR s:ARRAY OF CHAR); PROCEDURE GetChar(l:pLINK; delete:BOOLEAN; VAR char:CHAR):BOOLEAN; (*returns false if buffer is empty delete: delete char from buffer after get*) PROCEDURE GetStr(l:pLINK; size:CARD16; buf:pSTRING):CARD16; (*return is length of data *) PROCEDURE SendStr(l:pLINK; size:CARD16; buf:pSTRING):BOOLEAN; (* max 256 byte, false if data not sent (sendbuffer full) *) PROCEDURE SendRaw(p:pSENDUI); (* pid >255 send no pid *) PROCEDURE GetStat(p:pGETSTAT); PROCEDURE PortStat(p:pPORTSTAT):BOOLEAN; (* true if port is enabled *) PROCEDURE Parm(p:pPARMS); PROCEDURE GetMon():pLINK; PROCEDURE Layer2; (*started by 10ms interrupt-ticker if not L2Lock*) PROCEDURE L2Init(bufs:CARD16; portset:SET16; callback:CALLBACKPROC); END l2.