; ; 13/9/99 ; ; Validate callsings in Nodes message PAGE 56,132 ; .386 ; ; SEGMENT definitions and order ; ;* 32 Bit code _TEXT SEGMENT DWORD USE32 PUBLIC 'CODE' _TEXT ENDS ;* Contains 32 Bit data _BPQDATA SEGMENT DWORD PUBLIC 'DATA' _BPQDATA ENDS ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:FLAT OFFSET32 EQU _BPQDATA SEGMENT INCLUDE STRUCS.INC TEMPFIELD DB 7 DUP (0) ; TEMP STORAGE FOR CALL NODEMSGLEN DW 0 ; LENGTH OF RECEIVED NODES MSG SAVEPTR DD 0 ; TEMP SAVE FIELD NODEQUAL DB 0 ; QUALITY OF ABOVE PORT ROUTEQUAL DB 0 ; QUALITY OF CURRENT ROUTE SAVENBOUR DD 0 ; POINTER TO NEIGHBOUR LIST WHEN ; PROCESSING NODES MSG L3TIMER DW 1 ; TIMER FOR 'NODES' MESSAGE IDTIMER DW 0 ; TIMER FOR ID MESSAGE BTTIMER DW 0 ; TIMER FOR BT MESSAGE NODECALL DB 9CH,9EH,88H,8AH,0A6H,40H,0E0H ; 'NODES' IN AX25 FORMAT SAVEBX DD 0 ; TEMP STORAGE DESTHEADER DD 0 ; HEAD OF SORTED NODES CHAIN ; ; FIELDS TO CONTROL INCREMENTAL NODERS BROADCASTS ; PUBLIC NODESINPROGRESS, CURRENTNODE NODESINPROGRESS DB 0 L3_10SECS DB 10 ; 1 SEC TO 10 SECS COUNTER CURRENTNODE DD 0 ; NEXT NODE TO SEND CURRENTPORT DD 0 ; PORT WE ARE SENDING NODES ON CURRENTPORTNO DB 0 ; NUMBER OF CURRENT PORT PORTSLEFT DB 0 ; PORTS STILL TO SEND ON D1093 DW 1093 ; TICKS TO MINS DIVIDER B100 DB 100 B10 DB 10 B21 DB 21 D86400 DD 86400 D3600 DD 3600 D60 DD 60 PUBLIC D86400,D3600,D60,ROUTEVECLEN ROUTEVECLEN DD 11 IDMSG_Q DD 0 ; ID/BEACONS WAITING TO BE SENT TXMINQUAL DB 0 ; MINIMUM TO SEND ON CURRENT PORT PUBLIC ROUTEQUAL,SAVENBOUR,NODECALL,BTTIMER,IDTIMER,L3TIMER PUBLIC DESTHEADER,IDMSG_Q,D1093 EXTRN _MYCALL:BYTE,APPLCALLTABLE:BYTE,AX25CALL:BYTE,NORMCALL:BYTE,QCOUNT:WORD EXTRN DECODEDNAME:BYTE,BUFFER:DWORD,SAVELINK:DWORD,SAVEPORT:BYTE EXTRN _STATSTIME:DWORD,IDINTERVAL:WORD EXTRN MINQUAL:WORD,L3INTERVAL:WORD,NEIGHBOURS:DWORD EXTRN MAXNEIGHBOURS:WORD,DESTS:DWORD,_MAXDESTS:WORD EXTRN OBSINIT:BYTE,PORTTABLE:DWORD,NUMBEROFPORTS:WORD EXTRN ENDDESTLIST:DWORD,OBSMIN:BYTE,NODE:BYTE,_NUMBEROFNODES:DWORD EXTRN NODEORDER:BYTE,_NETROMCALL:BYTE EXTRN TNCTABLE:DWORD,BTINTERVAL:WORD,LINKS:DWORD,MAXLINKS:WORD _BPQDATA ENDS _TEXT SEGMENT ; PUBLIC PROCESSNODEMESSAGE,L3SWAPADDRESSES,CHECKL3TABLES PUBLIC FINDDESTALIAS,_FINDDESTINATION,_FINDFREEDESTINATION,_FINDNEIGHBOUR PUBLIC L3CONNECTFAILED,L3LINKCLOSED,L3TIMERPROC,L3BG PUBLIC CHECKNEIGHBOUR,SENDNODESMSG,REFRESHROUTE PUBLIC L3FASTTIMER PUBLIC PROCROUTES EXTRN _Q_ADD:NEAR,GETBUFF:NEAR,RELBUFF:NEAR,COMPARECALLS:NEAR EXTRN _L2SETUPCROSSLINK:NEAR,GETPORTQUALITY:NEAR EXTRN CONVFROMAX25:NEAR,CONVTOAX25:NEAR,GETPORTTABLEENTRY:NEAR EXTRN Q_REM:NEAR,SENDIDMSG:NEAR,_COUNTNODES:NEAR,CLEAROUTLINK:NEAR EXTRN SENDBTMSG:NEAR,PUT_ON_PORT_Q:NEAR,COUNT_AT_L2:NEAR IF BLACKBITS EXTRN CHECKBLACKLIST:NEAR ENDIF extrn _time:near, _INP3TIMER:NEAR, _TellINP3LinkGone:NEAR, _TellINP3LinkSetupFailed:NEAR PUBLIC L3TIMERPROC L3TIMERPROC: ; ; CHECK FOR EXCESSIVE BUFFERS QUEUED AT LINK LEVEL ; CMP QCOUNT,100 JA SHORT COUNT_OK MOV ESI,LINKS MOVZX ECX,MAXLINKS PUBLIC CHKLINK00 CHKLINK00: CMP LINKTYPE[ESI],3 JNE SHORT CHKLINK10 ; NOT INTERNODE MOV EBX,ESI ; MOV AH,0 CALL COUNT_AT_L2 ; SEE HOW MANY QUEUED CMP AH,50 JB SHORT CHKLINK10 ; OK ; ; DESTROY THE SESSION ; MOV EBX,ESI CALL L3LINKCLOSED ; REPORT TO LEVEL 3 CALL CLEAROUTLINK JMP SHORT COUNT_OK ; CANT BE ANY MORE OVERLOADED LINKS PUBLIC CHKLINK10 CHKLINK10: ADD ESI,TYPE LINKTABLE LOOP CHKLINK00 ; PUBLIC COUNT_OK COUNT_OK: ADD _STATSTIME,1 CMP IDTIMER,0 JE SHORT NOIDMSG ; SUPPRESSED DEC IDTIMER JNZ SHORT NOIDMSG MOV AX,IDINTERVAL MOV IDTIMER,AX CALL SENDIDMSG PUBLIC NOIDMSG NOIDMSG: ; ; CHECK FOR BEACON ; CMP BTTIMER,0 JE SHORT NOBTMSG ; SUPPRESSED DEC BTTIMER JNZ SHORT NOBTMSG MOV AX,BTINTERVAL MOV BTTIMER,AX MOV EBX,TNCTABLE ; IN CASE SENDING MAIL BEACON CALL SENDBTMSG PUBLIC NOBTMSG NOBTMSG: ; ; CHECK FOR NODES BROADCAST ; CMP L3TIMER,0 JE SHORT L3TIMRET ; TIMER UPDATE AND BROADCAST SUPPRESSED DEC L3TIMER JNZ SHORT L3TIMRET ; ; UPDATE DEST LIST AND SEND 'NODES' MESSAGE ; MOV AX,L3INTERVAL MOV L3TIMER,AX CALL UPDATEDESTLIST CALL SENDNODESMSG ; ; TIDY ROUTES ; MOV ESI,NEIGHBOURS MOVZX ECX,MAXNEIGHBOURS PUBLIC CMDR10 CMDR10: PUSH ECX TEST NEIGHBOUR_FLAG[ESI],1 JNZ SHORT CMDR88 ; LOCKED CMP NEIGHBOUR_LINK[ESI],0 JNE SHORT CMDR88 ; HAS AN ACTIVE SESSION CALL _COUNTNODES ; NODES USING THIS DESTINATION ; ; IF NUMBER USING ROUTE IS ZERO, DELETE IT ; OR AX,AX JNZ SHORT CMDR88 PUSH EDI MOV EDI,ESI MOV ECX,TYPE NEIGHBOUR_LIST REP STOSB POP EDI PUBLIC CMDR88 CMDR88: POP ECX ADD ESI,TYPE NEIGHBOUR_LIST LOOP CMDR10 PUBLIC L3TIMRET L3TIMRET: RET PUBLIC L3FASTTIMER L3FASTTIMER: ; ; CALLED ONCE PER SECOND - USED ONLY TO SEND NEXT PART OF A NODES OR ; ID MESSAGE SEQUENCE ; CALL _INP3TIMER DEC L3_10SECS JNZ SHORT L3TIMRET MOV L3_10SECS,10 CMP IDMSG_Q,0 ; ID/BEACON TO SEND? JE SHORT L3FT00 ; NO MOV ESI,OFFSET32 IDMSG_Q CALL Q_REM JZ SHORT L3FT00 ; ?? MOV AL,MSGPORT[EDI] CALL GETPORTTABLEENTRY CMP TXPORT[EBX],0 JNE SHORT SKIPTX ; DONT SEND IF SHARED TX CALL PUT_ON_PORT_Q JMP L3TIMRET PUBLIC SKIPTX SKIPTX: CALL RELBUFF JMP L3TIMRET PUBLIC L3FT00 L3FT00: CMP NODESINPROGRESS,0 JE SHORT L3TIMRET CALL SENDNEXTNODESFRAGMENT RET PUBLIC L3BG L3BG: ; ; TRANSFER MESSAGES FROM DEST TO LINK ; MOV EBX,DESTS MOVZX ECX,_MAXDESTS PUBLIC L3BG60 L3BG60: CMP DEST_CALL[EBX],0 JE SHORT L3BG90 ; SPARE PUBLIC L3BG61 L3BG61: LEA ESI,DEST_Q[EBX] ; FRAMES TO SEND? CMP WORD PTR [ESI],0 JE SHORT L3BG90 ; NO PUSH EBX PUSH ECX ; MOVZX EAX,DEST_ROUTE[EBX] OR AL,AL JZ SHORT L3BG80 DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ROUTE ENTRY MOV EBX,ROUT1_NEIGHBOUR[EBX] ; GET NEIGHBOUR ENTRY OR EBX,EBX JZ SHORT L3BG80 ; NO NEIGHBOUR? MOV EAX,EBX ; SAVE NEIGHBOUR ADDR MOV EBX,NEIGHBOUR_LINK[EBX] ; GET LINK TABLE ENTRY OR EBX,EBX JZ SHORT L3BG80 ; ???? INACTIVE ???? CMP L2STATE[EBX],0 JA SHORT L3BG70 ; ; LINK ENTRY IS INVALID - IT PROBABLY HAS BEEN 'ZAPPED', SO CANCEL IT ; MOV EBX,EAX MOV NEIGHBOUR_LINK[EBX],0 JMP SHORT L3BG80 PUBLIC L3BG70 L3BG70: CMP L2STATE[EBX],5 ; LINK UP? JL SHORT L3BG85 ; NO, SO WAIT FOR IT PUSH EBX ; SAVE LINK MOV EBX,EAX ; NEIGHBOUR ; ; COUNT FRAMES TO NEIGHBOUR ; ADD NBOUR_IFRAMES[EBX],1 POP EBX CALL Q_REM ; GET THE FRAME LEA ESI,TX_Q[EBX] CALL _Q_ADD ; QUEUE ON LINK POP ECX POP EBX JMP L3BG61 ; SEE IF MORE PUBLIC L3BG80 L3BG80: POP ECX POP EBX ; RECOVER DEST TABLE ADDR PUSH EBX PUSH ECX CALL ACTIVATE_DEST PUBLIC L3BG85 L3BG85: POP ECX POP EBX PUBLIC L3BG90 L3BG90: ADD EBX,TYPE DEST_LIST LOOP L3BG60_J PUBLIC L3BG95 L3BG95: RET PUBLIC L3BG60_J L3BG60_J: JMP L3BG60 PUBLIC ACTIVATE_DEST ACTIVATE_DEST: PUSH EBX MOV AL,DEST_ROUTE[EBX] OR AL,AL JNZ SHORT DESTISOK ; ALREADY HAVE A SELECTED ROUTE ; MOV DEST_ROUTE[EBX],1 ; TRY TO ACTIVATE FIRST PUBLIC DESTISOK DESTISOK: MOVZX EAX,DEST_ROUTE[EBX] DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ROUTE ENTRY MOV EBX,ROUT1_NEIGHBOUR[EBX] ; GET NEIGHBOUR ENTRY OR EBX,EBX JNZ SHORT @F ; ; IF current route is 1, then we must have INP3 routes (or entry is corrupt) POP EBX PUSH EBX CMP DEST_ROUTE[EBX],1 JNE NOROUTETODEST CMP INPROUT1_NEIGHBOUR[EBX],0 JE NOROUTETODEST MOV DEST_ROUTE[EBX],4 MOV EBX, INPROUT1_NEIGHBOUR[EBX] @@: MOV EAX,NEIGHBOUR_LINK[EBX] ; GET LINK TABLE ENTRY OR EAX,EAX JZ SHORT ACTIVATENEIGHBOUR ; NEED TO SET UP L2 SESSION TO NEIGHBOUR POP EBX ; ? MUST BE WAITING FOR LINK TO COME UP RET PUBLIC ACTIVATENEIGHBOUR ACTIVATENEIGHBOUR: ; ; SET UP LINK TABLE ENTRY ; CALL _L2SETUPCROSSLINK ; START SESSION TO NODE IN [EBX] POP EBX RET PUBLIC NOROUTETODEST NOROUTETODEST: ; ; CURRENT NEIGHBOUR NOT DEFINED - RESET TO USE FIRST ; MOV DEST_ROUTE[EBX],0 POP EBX RET PUBLIC L3CONNECTFAILED L3CONNECTFAILED: ; ; L2 LINK SETUP HAS FAILED - SEE IF ANOTHER NEIGHBOUR CAN BE USED ; MOV ESI,NEIGHBOUR[EBX] ; TO NEIGHBOUR CMP ESI,0 JE SHORT L3CFRET ; NOTHING ??? PUSHAD PUSH ESI CALL _TellINP3LinkSetupFailed POP ESI POPAD MOV NEIGHBOUR_LINK[ESI],0 ; CLEAR IT PUSH EBX CALL L3TRYNEXTDEST ; RESET ASSOCIATED DEST ENTRIES POP EBX PUBLIC L3CFRET L3CFRET: RET PUBLIC L3TRYNEXTDEST L3TRYNEXTDEST: ; ; FIND ANY DESINATIONS WITH [ESI] AS ACTIVE NEIGHBOUR, AND ; SET NEXT BEST NEIGHBOUR (IF ANY) ACTIVE ; MOV EBX,DESTS MOVZX ECX,_MAXDESTS ; PUBLIC L3CFR010 L3CFR010: CMP DEST_ROUTE[EBX],0 JE SHORT L3CFR090 ; NO ACTIVE ROUTE ; PUSH EBX MOVZX EAX,DEST_ROUTE[EBX] DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ACTIVE ROUTE ENTRY CMP ROUT1_NEIGHBOUR[EBX],ESI ; GET NEIGHBOUR ENTRY JNE SHORT L3CFR080 ; NOT THIS DEST ; ; NEIGHBOUR HAS FAILED - DECREMENT OBSCOUNT ; AND TRY TO ACTIVATE ANOTHER (IF ANY) ; CMP ROUT1_OBSCOUNT[EBX],0 JE SHORT L3CFR020 ; ALREADY ZERO - WILL BE DELETED BY NEXT NODES UPDATE TEST ROUT1_OBSCOUNT[EBX],80H JNZ SHORT L3CFR020 ; LOCKED DEC ROUT1_OBSCOUNT[EBX] JNZ SHORT L3CFR020 ; STILL OK ; ; (ROUTE HAS EXPIRED - WE SHOULD CLEAR IT, AND MOVE OTHERS (IF ANY) UP) ; PUBLIC L3CFR020 L3CFR020: POP EBX ; ; REMOVE FIRST MESSAGE FROM DEST_Q. L4 WILL RETRY - IF IT IS LEFT HERE ; WE WILL TRY TO ACTIVATE THE DESTINATION FOR EVER ; PUSH ESI LEA ESI,DEST_Q[EBX] CALL Q_REM JZ SHORT L3CFR025 ; NONE?? CALL RELBUFF PUBLIC L3CFR025 L3CFR025: POP ESI INC DEST_ROUTE[EBX] ; TO NEXT CMP DEST_ROUTE[EBX],7 JNE SHORT L3CFR040 ; MOV DEST_ROUTE[EBX],1 ; TRY TO ACTIVATE FIRST PUBLIC L3CFR040 L3CFR040: JMP SHORT L3CFR090 PUBLIC L3CFR080 L3CFR080: POP EBX PUBLIC L3CFR090 L3CFR090: ADD EBX,TYPE DEST_LIST LOOP L3CFR010 RET PUBLIC CHECKNEIGHBOUR CHECKNEIGHBOUR: ; ; MESSAGE RECEIVED ON LINK WITH NO DESTINATION - SET ONE UP ; LEA ESI,LINKCALL[EBX] CALL _FINDNEIGHBOUR JZ SHORT L3CONN07 ; IN LIST - OK CMP EBX,0 JE SHORT L3CONN08 ; TABLE FULL?? ; ; FIRST MAKE SURE WE ARE ALLOWING NETWORK ACTIVITY ON THIS PORT ; MOV AL,SAVEPORT CALL GETPORTQUALITY CMP AL,0 JNE SHORT QUALOK ; ; NOT A NETWORKING PORT ; RET PUBLIC QUALOK QUALOK: MOV NEIGHBOUR_QUAL[EBX],AL ; QUALITY MOV ECX,7 MOV EDI,EBX REP MOVSB ; PUT IN CALL MOV AL,SAVEPORT MOV NEIGHBOUR_PORT[EBX],AL PUBLIC L3CONN07 L3CONN07: ; ; SET THIS AS ACTIVE LINK IF NONE PRESENT ; CMP NEIGHBOUR_LINK[EBX],0 JNE SHORT L3CONN08 MOV EAX,SAVELINK MOV NEIGHBOUR_LINK[EBX],EAX MOV AL,SAVEPORT MOV NEIGHBOUR_PORT[EBX],AL PUBLIC L3CONN08 L3CONN08: MOV EAX,EBX MOV EBX,SAVELINK MOV NEIGHBOUR[EBX],EAX ; SET LINK - NEIGHBOUR RET CHECKL3TABLES: ; ; CHECK THAT FAR NODE IS IN 'NODES'. ; BX POINTS TO L4 TABLE ENTRY ; RETURNS POINTER TO NEIGHBOUR ENTRY IN AX ; PUSH EBX MOV EBX,SAVELINK MOV EBX,NEIGHBOUR[EBX] ; NEIGHBOUR ENTRY MOV SAVENBOUR,EBX MOV ESI,BUFFER LEA ESI,L3SRCE[ESI] CALL _FINDDESTINATION JZ SHORT L3CONN09 ; OK ; CMP EBX,0 JNE SHORT CAN_ADD PUBLIC DONT_ADD DONT_ADD: MOV EAX,0 POP EBX RET ; TABLES FULL PUBLIC CAN_ADD CAN_ADD: ; ; ADD DESTINATION VIA NEIGHBOUR, UNLESS ON BLACK LIST ; IF BLACKBITS PUSH ESI CALL CHECKBLACKLIST POP ESI JZ SHORT DONT_ADD ; ENDIF MOV ECX,7 LEA EDI,DEST_CALL[EBX] REP MOVSB ; PUT IN CALL INC _NUMBEROFNODES PUBLIC L3CONN09 L3CONN09: ; ; MAKE SURE NEIGHBOUR IS DEFINED FOR DESTINATION ; ; IF NODE - NEIGHBOUR, THEN CAN USE NEIGHBOUR QUALITY, ; OTHERWISE WE DONT KNOW ROUTE, SO MUST SET QUAL TO 0 ; MOV ROUTEQUAL,0 ; DONT KNOW ROUTING, SO SET QUALITY TO ZERO MOV EAX,SAVENBOUR CALL PROCROUTES ; ADD NEIGHBOUR IF NOT PRESENT ; CMP DEST_ROUTE[EBX],0 ; IS THERE AN ACTIVE ROUTE? JNE SHORT L3CONN20 ; DEST IS ACTIVE ; ; MAKE CURRENT NEIGHBOUR ACTIVE ; MOV EAX,SAVENBOUR INC DEST_ROUTE[EBX] CMP ROUT1_NEIGHBOUR[EBX],EAX JE SHORT L3CONN20 ; FOUND REQUIRED ENTRY ; INC DEST_ROUTE[EBX] CMP ROUT2_NEIGHBOUR[EBX],EAX JE SHORT L3CONN20 ; FOUND REQUIRED ENTRY ; INC DEST_ROUTE[EBX] CMP ROUT3_NEIGHBOUR[EBX],EAX JE SHORT L3CONN20 ; FOUND REQUIRED ENTRY ; ; CURRENT NEIGHBOUR ISNT IN DEST LIST - SET TO USE BEST ; MOV DEST_ROUTE[EBX],1 PUBLIC L3CONN20 L3CONN20: ; ; REFRESH OBS COUNT ; PUSH EBX ; SAVE DEST TABLE ENTRY MOVZX EAX,DEST_ROUTE[EBX] OR AL,AL JZ SHORT REFROUTY ; NONE ACTIVE??? DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ROUTE ENTRY TEST ROUT1_OBSCOUNT[EBX],80H JNZ SHORT REFROUTY ; LOCKED MOV AL,OBSINIT MOV ROUT1_OBSCOUNT[EBX],AL ; SET OBSOLESCENCE COUNT PUBLIC REFROUTY REFROUTY: POP EAX ; DEST TABLE ENTRY POP EBX RET PUBLIC _PROCESSUZ7HONODEMESSAGE _PROCESSUZ7HONODEMESSAGE: MOV SAVEPORT,AL PROCESSNODEMESSAGE: ; ; PROCESS A NET/ROM 'NODES' MESSAGE ; ; UPDATE NEIGHBOURS LIST WITH ORIGINATING CALL, AND ; DESTINATION LIST WITH ANY PRACTICAL ROUTES ; ; ; INCOMING MESSAGE IS IN [EDI] ; ; MOV AL,SAVEPORT ; PORT MESSAGE CAME IN ON CALL GETPORTQUALITY OR AL,AL JZ SHORT PROCNODE02 ; PORT QUALITY=0, SO IGNORE MOV AX,MSGLENGTH[EDI] ; GET MESSAGE LENGTH MOV NODEMSGLEN,AX ; SAVE MOV AL,MSGPORT[EDI] MOV SAVEPORT,AL MOV SAVEPTR,EDI ; SAVE POINTER ; ; SEE IF OUR CALL - DONT WANT TO PUT IT IN LIST! ; LEA ESI,MSGORIGIN[EDI] ; SET TO ADDR OF ORIGINATING STATION MOV EDI,OFFSET32 _NETROMCALL PUSH ESI CALL COMPARECALLS POP ESI JZ SHORT PROCNODE02 MOV EDI,OFFSET32 APPLCALLTABLE LEA EDI,APPLCALL[EDI] CALL COMPARECALLS JNZ SHORT PROCNODE03 ; OK PUBLIC PROCNODE02 PROCNODE02: RET PUBLIC PROCNODE03 PROCNODE03: ; MOV EDI,SAVEPTR LEA ESI,MSGORIGIN[EDI] ; SET TO ADDR OF ORIGINATING STATION AND BYTE PTR 6[ESI],01EH ; MASK OFF LAST ADDR BIT ; ; SEE IF ORIGINATING CALL IS IN NEIGHBOUR LIST - IF NOT ADD IT ; CALL _FINDNEIGHBOUR ; RETURNS ZF AND BX ALIGNED TO ENTRY ; OR FIRST FREE ENTRY JZ SHORT PROCNODE10 ; ENTRY FOUND ; CMP EBX,0 JE TABLESFULL_JMP ; NO ROOM ; ; CREATE NEIGHBOUR RECORD ; PUSH ESI LEA EDI,NEIGHBOUR_CALL[EBX] MOV ECX,7 REP MOVSB AND BYTE PTR -1[EDI],01EH ; MASK END OF ADDR BIT MOV AL,SAVEPORT ; PORT MESSAGE CAME IN ON MOV NEIGHBOUR_PORT[EBX],AL ; SAVE CALL GETPORTQUALITY MOV NEIGHBOUR_QUAL[EBX],AL ; QUALITY MOV NEIGHBOUR_LINK[EBX],0 ; CANT HAVE A LINK IF NEW NODE MOVZX EAX,PortNoKeepAlive[EBP] ; EBP is Port MOV NoKeepAlive[EBX],EAX POP ESI PUBLIC PROCNODE10 PROCNODE10: MOV SAVENBOUR,EBX ; SAVE POINTER TO NEIGHBOUR FOR DEST ; LIST UPDATES ; IF not locked, update rute quality from port quality (may have changed config and not cleared SAVENODES TEST NEIGHBOUR_FLAG[EBX],1 ; LOCKED ROUTE JNZ @F MOV AL,SAVEPORT ; PORT MESSAGE CAME IN ON CALL GETPORTQUALITY MOV NEIGHBOUR_QUAL[EBX],AL ; QUALITY @@: ; ; GET TIME FROM BIOS DATA AREA OR RTC ; push 0 call _time add esp,4 MOV EDX,0 DIV DWORD PTR D86400 ; REMAINDER IS SECS IN DAY MOV EAX,EDX MOV EDX,0 DIV DWORD PTR D3600 ; GIVES HOURS, REM = SECS MOV BYTE PTR NEIGHBOUR_TIME+1[EBX],AL ; SAVE MOV EAX,EDX MOV EDX,0 DIV DWORD PTR D60 ; GIVES MINS, REM = SECS MOV BYTE PTR NEIGHBOUR_TIME[EBX],AL ; SAVE ; GET QUALITY ; MOV AL,NEIGHBOUR_QUAL[EBX] MOV ROUTEQUAL,AL ; FOR INITIAL ROUTE TABLE UPDATE MOV NODEQUAL,AL ; ; CHECK LINK IS IN DEST LIST ; CALL _FINDDESTINATION ; RETURNS ZF AND BX ALIGNED TO ENTRY ; OR FIRST FREE ENTRY JZ SHORT PROCNODE20 ; ENTRY FOUND ; CMP EBX,0 JNE SHORT PROCNODE11 ; OK PUBLIC TABLESFULL_JMP TABLESFULL_JMP: RET PUBLIC PROCNODE11 PROCNODE11: ; ; CREATE DESTINATION RECORD ; PUSH ESI MOV EDI,EBX MOV ECX,TYPE DEST_LIST MOV AL,0 REP STOSB ; CLEAR ENTRY LEA EDI,DEST_CALL[EBX] MOV ECX,7 REP MOVSB AND BYTE PTR -1[EDI],01EH ; MASK END OF ADDR BIT POP ESI INC _NUMBEROFNODES JMP SHORT PROCNODE21 PUBLIC PROCNODE20 PROCNODE20: ; ; ALWAYS UPDATE ALIAS IN CASE NOT PRESENT IN ORIGINAL TABLE ; PUBLIC PROCNODE21 PROCNODE21: PUSH ESI ADD ESI,10 ; SKIP CONTROL, PID AND SIG BYTES LEA EDI,DEST_ALIAS[EBX] ; If no alias in message, ignore cmp byte ptr[esi], 20h jbe NoAlias ; Validate Alias, mainly for DISABL KPC3 Problem MOV ECX,6 @@: lodsb CMP AL,7AH JA SHORT DuffAlias CMP AL,20H JAE SHORT AliasOK PUBLIC DuffAlias DuffAlias: mov al,20h PUBLIC AliasOK AliasOK: stosb loop @B POP ESI NoAlias: ; ; UPDATE QUALITY AND OBS COUNT ; MOV EAX,SAVENBOUR ; POINTER TO NEIGHBOUR CALL PROCROUTES ; SUB NODEMSGLEN,23 ; LEVEL 2 HEADER + NODE MNEMONIC ; ; PROCESS KNOWN DESTINATIONS ; ADD ESI,16 ; TO DESTINATIONS PUBLIC PROCNODE30 PROCNODE30: CMP NODEMSGLEN,21 JAE SHORT PROCNODE31 ; STILL AT LEAST 1 ENTRY LEFT RET PUBLIC PROCNODE31 PROCNODE31: ; ; SEE IF OUR CALL - DONT WANT TO PUT IT IN LIST! ; MOV EDI,OFFSET32 _MYCALL PUSH ESI CALL COMPARECALLS POP ESI JZ PROCNODE50 MOV EDI,OFFSET32 APPLCALLTABLE MOV ECX, 8 PUBLIC CHECK_APPL_ENTRIES CHECK_APPL_ENTRIES: PUSH EDI LEA EDI,APPLCALL[EDI] PUSH ESI push ecx CALL COMPARECALLS pop ecx POP ESI pop edi JZ PROCNODE50 ADD EDI,TYPE APPLCALLS loop CHECK_APPL_ENTRIES ; MAKE SURE ITS NOT CORRUPTED ; PUSH ESI MOV ECX,6 PUBLIC CALLLOOP CALLLOOP: CMP BYTE PTR [ESI],40H ; DUFF CALLSIGN? JB SHORT DUFFNODE INC ESI LOOP CALLLOOP MOV ECX,6 INC ESI ; TO ALIAS PUBLIC ALIASLOOP ALIASLOOP: LODSB CMP AL,7AH JA SHORT DUFFNODE CMP AL,20H JAE SHORT NODEOK CMP AL,0 JE SHORT NODEOK PUBLIC DUFFNODE DUFFNODE: POP ESI JMP SHORT PROCNODE50 PUBLIC NODEOK NODEOK: LOOP ALIASLOOP ; POP ESI ; ; CALCULATE ROUTE QUALITY ; MOV AL,NODEQUAL ; LINK QUALITY MUL BYTE PTR 20[ESI] ; REPORTED QUALITY ADD AX,128 MOV ROUTEQUAL,AH ; ; SEE IF BELOW MIN QUAL FOR AUTO UPDATES ; CMP AH,BYTE PTR MINQUAL JB SHORT TOO_POOR ; IGNORE IT ; ; CHECK LINK IS IN DEST LIST ; CALL _FINDDESTINATION ; RETURNS ZF AND BX ALIGNED TO ENTRY ; OR FIRST FREE ENTRY JZ SHORT PROCNODE33 ; ENTRY FOUND ; CMP EBX,0 JNE SHORT PROCNODE32 PUBLIC TOO_POOR TOO_POOR: JMP SHORT PROCNODE50 ; NO ROOM TO ADD - SHOULD WE DROP POORER DESTS?? PUBLIC PROCNODE32 PROCNODE32: ; ; CREATE DESTINATION RECORD ; PUSH ESI MOV EDI,EBX MOV ECX,TYPE DEST_LIST MOV AL,0 REP STOSB ; CLEAR ENTRY LEA EDI,DEST_CALL[EBX] MOV ECX,7 REP MOVSB POP ESI INC _NUMBEROFNODES PUBLIC PROCNODE33 PROCNODE33: ; ; UPDATE ALIAS ; PUSH ESI ADD ESI,7 LEA EDI,DEST_ALIAS[EBX] MOV ECX,6 REP MOVSB ; PUT IN ALIAS ; POP ESI ; ; PROCESS ROUTE QUALITY INFO ; PUSH ESI ADD ESI,13 ; TO BEST NEIGHBOUR ; ; NOW POINTING AT BEST NEIGHBOUR - IF THIS IS US, THEN ROUTE IS A LOOP ; MOV EDI,OFFSET32 _NETROMCALL CALL COMPARECALLS JNE SHORT PROCNODE35 ; NOT US MOV ROUTEQUAL,0 ; ZERO QUALITY PUBLIC PROCNODE35 PROCNODE35: POP ESI ; ; DEST IS NOW IN TABLE - ; 1. SEE IF THIS ROUTE IS IN TABLE - IF SO UPDATE QUALITY, ; IF NOT, ADD THIS ONE IF IT HAS HIGHER QUALITY THAN EXISTING ONES ; MOV EAX,SAVENBOUR ; POINTER TO NEIGHBOUR CALL PROCROUTES PUBLIC PROCNODE50 PROCNODE50: ADD ESI,21 SUB NODEMSGLEN,21 JMP PROCNODE30 PUBLIC PROCROUTES PROCROUTES: MOV SAVENBOUR,EAX ; IN CASE ENTRY FROM INIT ; ; ADD NEIGHBOUR ADDRESS IN EAX TO ROUTE TABLE IF BETTER QUALITY ; THAN THOSE PRESENT ; TEST DEST_STATE[EBX],80H ; BBS ENTRY JZ SHORT OKTOPROC ; NO RET ; LEAVE WELL ALONE! PUBLIC OKTOPROC OKTOPROC: PUSH EBX ; SAVE CMP ROUT1_NEIGHBOUR[EBX],EAX JE PROCNODE44 ; FOUND (ROUTE 1) ADD EBX,ROUTEVECLEN CMP ROUT1_NEIGHBOUR[EBX],EAX JE PROCNODE45 ; FOUND (ROUTE 2) ADD EBX,ROUTEVECLEN CMP ROUT1_NEIGHBOUR[EBX],EAX JE SHORT PROCNODE45 ; FOUND (ROUTE 3) ; ; NOT IN ANY ROUTE ; POP EBX PUSH EBX CMP ROUT1_NEIGHBOUR[EBX],0 JE SHORT PROCNODE45 ; SPARE ENTRY, SO USE IT MOV AL,ROUTEQUAL CMP AL,ROUT1_QUALITY[EBX] JB SHORT PROCNODE41 ; WORSE ; ; MOVE NEXT 2 ENTRIES DOWN 1 ; MOV AL,ROUT2_QUALITY[EBX] MOV ROUT3_QUALITY[EBX],AL MOV AL,ROUT2_OBSCOUNT[EBX] MOV ROUT3_OBSCOUNT[EBX],AL MOV EAX,ROUT2_NEIGHBOUR[EBX] MOV ROUT3_NEIGHBOUR[EBX],EAX ; MOV AL,ROUT1_QUALITY[EBX] MOV ROUT2_QUALITY[EBX],AL MOV AL,ROUT1_OBSCOUNT[EBX] MOV ROUT2_OBSCOUNT[EBX],AL MOV EAX,ROUT1_NEIGHBOUR[EBX] MOV ROUT2_NEIGHBOUR[EBX],EAX MOV DEST_ROUTE[EBX],0 ; CANCEL ACTIVE ROUTE, SO WILL USE NEW ONE JMP SHORT PROCNODE45 ; PUT IN NEW ENTRY PUBLIC PROCNODE41 PROCNODE41: ADD EBX,ROUTEVECLEN CMP ROUT1_NEIGHBOUR[EBX],0 JE SHORT PROCNODE45 ; SPARE ENTRY, SO USE IT CMP AL,ROUT1_QUALITY[EBX] JB SHORT PROCNODE42 ; WORSE MOV AL,ROUT1_QUALITY[EBX] ; REALLY MOVING 2 TO 3 - BX IS OFFSET BY 6 MOV ROUT2_QUALITY[EBX],AL MOV AL,ROUT1_OBSCOUNT[EBX] MOV ROUT2_OBSCOUNT[EBX],AL MOV EAX,ROUT1_NEIGHBOUR[EBX] MOV ROUT2_NEIGHBOUR[EBX],EAX JMP SHORT PROCNODE45 ; SPARE ENTRY, SO USE IT PUBLIC PROCNODE42 PROCNODE42: ADD EBX,ROUTEVECLEN CMP ROUT1_NEIGHBOUR[EBX],0 ; 3RD JE SHORT PROCNODE45 ; SPARE ENTRY, SO USE IT CMP AL,ROUT1_QUALITY[EBX] JA SHORT PROCNODE45 ; WE ARE BETTER THAN WORSE, SO OVERWRITE ; ; THIS ROUTE IS WORSE THAN ANY OF THE CURRENT 3 - IGNORE IT ; JMP SHORT PROCNODE49 PUBLIC PROCNODE44 PROCNODE44: ; ; THIS IS A REFRESH OF BEST - IF THIS ISNT ACTIVE ROUTE, MAKE IT ACTIVE ; CMP DEST_ROUTE[EBX],1 JBE SHORT PROCNODE45 ; LEAVE IT IF NOT SELECTED OR ALREADY USING BEST MOV DEST_ROUTE[EBX],1 ; PUBLIC PROCNODE45 PROCNODE45: MOV EAX,SAVENBOUR ; POINTER TO NEIGHBOUR MOV ROUT1_NEIGHBOUR[EBX],EAX ; ; I DONT KNOW WHY I DID THIS, BUT IT CAUSES REFLECTED ROUTES ; TO BE SET UP WITH OBS = 0. THIS MAY PREVENT A VALID ALTERNATE ; VIA THE SAME NODE TO FAIL TO BE FOUND. SO I'LL TAKE OUT THE ; TEST AND SEE IF ANYTHING NASTY HAPPENS ; IT DID - THIS IS ALSO CALLED BY CHECKL3TABLES. TRY RESETING ; OBS, BUT NOT QUALITY TEST ROUT1_OBSCOUNT[EBX],80H JNZ SHORT PROCNODE49X ; LOCKED MOV AL,OBSINIT MOV ROUT1_OBSCOUNT[EBX],AL ; SET OBSOLESCENCE COUNT PUBLIC PROCNODE49X PROCNODE49X: MOV AL,ROUTEQUAL CMP AL,0 JE SHORT PROCNODE49 ; IF ZERO, SKIP UPDATE MOV ROUT1_QUALITY[EBX],AL PUBLIC PROCNODE49 PROCNODE49: POP EBX ; ; IT IS POSSIBLE ROUTES ARE NOW OUT OF ORDER ; PUBLIC SORTROUTES SORTROUTES: MOV AL,ROUT1_QUALITY[EBX] CMP AL,ROUT2_QUALITY[EBX] JAE SHORT ROUT1_OK ; ; SWAP 1 AND 2 ; CALL SWAP1_2 MOV DEST_ROUTE[EBX],0 ; FORCE A RE-ASSESSMENT PUBLIC ROUT1_OK ROUT1_OK: MOV AL,ROUT2_QUALITY[EBX] CMP AL,ROUT3_QUALITY[EBX] JAE SHORT ROUTESOK ; ; SWAP 2 AND 3 ; ADD EBX,ROUTEVECLEN ; SO SWAP1_2 REALLY SWAPS 2-3 CALL SWAP1_2 SUB EBX,ROUTEVECLEN MOV DEST_ROUTE[EBX],0 ; FORCE A RE-ASSESSMENT JMP SORTROUTES ; 1 AND 2 MAY NOW BE WRONG! PUBLIC ROUTESOK ROUTESOK: RET PUBLIC SWAP1_2 SWAP1_2: MOV AL,ROUT1_QUALITY[EBX] MOV AH,ROUT2_QUALITY[EBX] MOV ROUT1_QUALITY[EBX],AH MOV ROUT2_QUALITY[EBX],AL MOV AL,ROUT1_OBSCOUNT[EBX] MOV AH,ROUT2_OBSCOUNT[EBX] MOV ROUT1_OBSCOUNT[EBX],AH MOV ROUT2_OBSCOUNT[EBX],AL PUSH ECX MOV EAX,ROUT1_NEIGHBOUR[EBX] MOV ECX,ROUT2_NEIGHBOUR[EBX] MOV ROUT1_NEIGHBOUR[EBX],ECX MOV ROUT2_NEIGHBOUR[EBX],EAX POP ECX RET PUBLIC _FINDNEIGHBOUR _FINDNEIGHBOUR: ; MOV EBX,0 MOV EDI,NEIGHBOURS MOVZX ECX,MAXNEIGHBOURS PUBLIC FINDNE00 FINDNE00: CMP BYTE PTR [EDI],0 JNE SHORT FINDNE05 ; NOT A SPARE ENTRY CMP EBX,0 JNE SHORT FINDNE10 ; ALREADY FOUND A SPARE MOV EBX,EDI ; POINTER TO FIRST FREE JMP SHORT FINDNE10 ; TRY NEXT ENTRY PUBLIC FINDNE05 FINDNE05: MOV AL,SAVEPORT CMP NEIGHBOUR_PORT[EDI],AL ; CORRECT PORT? JNE SHORT FINDNE10 ; NO PUSH ESI PUSH EDI PUSH ECX CALL COMPARECALLS ; CORRECT ENTRY? POP ECX POP EDI POP ESI JE SHORT FINDNE99 ; YES PUBLIC FINDNE10 FINDNE10: ADD EDI,TYPE NEIGHBOUR_LIST LOOP FINDNE00 ; ; ENTRY NOT FOUND - BX HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL ; OR AL,1 RET PUBLIC FINDNE99 FINDNE99: MOV EBX,EDI XOR AL,AL RET PUBLIC _FINDFREEDESTINATION _FINDFREEDESTINATION: MOV EBX,0 MOV EDI,DESTS MOVZX ECX,_MAXDESTS PUBLIC FINDFDE00 FINDFDE00: CMP DEST_CALL[EDI],0 JNE SHORT @F ; NOT A SPARE ENTRY MOV EBX,EDI XOR AL,AL RET @@: ADD EDI,TYPE DEST_LIST LOOP FINDFDE00 ; ; ENTRY NOT FOUND - BX HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL ; OR AL,1 RET _FINDDESTINATION: MOV EBX,0 MOV EDI,DESTS MOVZX ECX,_MAXDESTS PUBLIC FINDDE00 FINDDE00: CMP DEST_CALL[EDI],0 JNE SHORT FINDDE05 ; NOT A SPARE ENTRY CMP EBX,0 JNE SHORT FINDDE10 ; ALREADY FOUND A SPARE MOV EBX,EDI ; POINTER TO FIRST FREE JMP SHORT FINDDE10 ; TRY NEXT ENTRY PUBLIC FINDDE05 FINDDE05: PUSH ESI PUSH EDI PUSH ECX LEA EDI,DEST_CALL[EDI] CALL COMPARECALLS ; CORRECT ENTRY? POP ECX POP EDI POP ESI JE SHORT FINDDE99 ; YES PUBLIC FINDDE10 FINDDE10: ADD EDI,TYPE DEST_LIST LOOP FINDDE00 ; ; ENTRY NOT FOUND - BX HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL ; OR AL,1 RET PUBLIC FINDDE99 FINDDE99: MOV EBX,EDI XOR AL,AL RET ; PUBLIC FINDDESTALIAS FINDDESTALIAS: ; ; FIND DEST ENTRY USING ALIAS MOV EBX,DESTS MOVZX ECX,_MAXDESTS PUBLIC FINDDA00 FINDDA00: PUSH ESI PUSH EDI PUSH ECX LEA EDI,DEST_ALIAS[EBX] MOV ECX,6 REP CMPSB ; CORRECT ENTRY? POP ECX POP EDI POP ESI JE SHORT FINDDA99 ; YES ADD EBX,TYPE DEST_LIST LOOP FINDDA00 ; ; ENTRY NOT FOUND ; OR AL,1 RET PUBLIC FINDDA99 FINDDA99: XOR AL,AL RET PUBLIC L3SWAPADDRESSES L3SWAPADDRESSES: ; ; EXCHANGE ORIGIN AND DEST ; MOV EDI,BUFFER LEA ESI,L3SRCE[EDI] LEA EDI,TEMPFIELD MOV ECX,7 REP MOVSB ; SAVE ORIGIN MOV EDI,BUFFER LEA ESI,L3DEST[EDI] LEA EDI,L3SRCE[EDI] MOV ECX,7 REP MOVSB ; AND BYTE PTR -1[EDI],00011110B ; MASK SSID OR BYTE PTR -1[EDI],00000001B ; SET LAST CALL MOV EDI,BUFFER LEA ESI,TEMPFIELD LEA EDI,L3DEST[EDI] MOV ECX,7 REP MOVSB ; AND BYTE PTR -1[EDI],00011110B ; MASK SSID RET PUBLIC L3LINKCLOSED L3LINKCLOSED: ; ; L2 SESSION HAS SHUT DOWN (PROBABLY DUE TO INACTIVITY) ; CLEAR NEIGHBOUR ; MOV ESI,NEIGHBOUR[EBX] ; TO NEIGHBOUR CMP ESI,0 JE SHORT L3LCRET ; NOTHING ??? MOV NEIGHBOUR[EBX],0 MOV NEIGHBOUR_LINK[ESI],0 ; CLEAR IT PUSH EBX CALL CLEARACTIVEROUTE POP EBX ; CLEAR ASSOCIATED DEST ENTRIES PUBLIC L3LCRET L3LCRET: RET PUBLIC CLEARACTIVEROUTE CLEARACTIVEROUTE: ; ; FIND ANY DESINATIONS WITH [ESI] AS ACTIVE NEIGHBOUR, AND ; SET INACTIVE ; PUSHAD PUSH ESI CALL _TellINP3LinkGone POP ESI POPAD MOV EBX,DESTS MOVZX ECX,_MAXDESTS ; PUBLIC L3CAR010 L3CAR010: CMP DEST_ROUTE[EBX],0 JE SHORT L3CAR090 ; NO ACTIVE ROUTE ; PUSH EBX MOVZX EAX,DEST_ROUTE[EBX] DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ACTIVE ROUTE ENTRY CMP ROUT1_NEIGHBOUR[EBX],ESI ; GET NEIGHBOUR ENTRY POP EBX JNE SHORT L3CAR090 ; NOT THIS DEST ; MOV DEST_ROUTE[EBX],0 ; SET NO ACTIVE ROUTE PUBLIC L3CAR090 L3CAR090: ADD EBX,TYPE DEST_LIST LOOP L3CAR010 RET PUBLIC REFRESHROUTE REFRESHROUTE: ; ; RESET OBS COUNT ON CURRENT ROUTE TO DEST FOR SESSION IN [EBX] ; CALLED WHEN INFO ACK RECEIVED, INDICATING ROUTE IS STILL OK ; PUSH EBX MOV EBX,L4TARGET[EBX] ; DEST OR EBX,EBX JZ SHORT REFROUTX ; No Dest ??? MOVZX EAX,DEST_ROUTE[EBX] OR AL,AL JZ SHORT REFROUTX ; NONE ACTIVE??? DEC AL MUL BYTE PTR ROUTEVECLEN ADD EBX,EAX ; TO ROUTE ENTRY TEST ROUT1_OBSCOUNT[EBX],80H JNZ SHORT REFROUTX ; LOCKED MOV AL,OBSINIT MOV ROUT1_OBSCOUNT[EBX],AL ; SET OBSOLESCENCE COUNT PUBLIC REFROUTX REFROUTX: POP EBX RET UPDATEDESTLIST: ; ; DECREMENT OBS COUNTERS ON EACH ROUTE, AND REMOVE 'DEAD' ENTRIES ; MOV EBX,DESTS MOVZX ECX,_MAXDESTS ; PUBLIC UPDEST000 UPDEST000: CMP DEST_CALL[EBX],0 JE SHORT UPDEST050 ; SPARE ENTRY TEST DEST_STATE[EBX],80H JNZ SHORT UPDEST050 ; LOCKED DESTINATION CMP ROUT1_NEIGHBOUR[EBX],0 JE SHORT UPDEST060 ; NO DESTINATIONS - DELETE ENTRY CMP ROUT1_OBSCOUNT[EBX],0 JE SHORT UPDEST005 ; FAILED IN USE - DELETE TEST ROUT1_OBSCOUNT[EBX],80H JNZ SHORT UPDEST010 ; LOCKED DEC ROUT1_OBSCOUNT[EBX] JNZ SHORT UPDEST010 ; STILL OK ; ; REMOVE ENTRY ; PUBLIC UPDEST005 UPDEST005: CALL MOVEALL PUBLIC UPDEST000_J UPDEST000_J: JMP UPDEST000 ; LOOP BACK TO PROCESS MOVED ENTRIES PUBLIC UPDEST010 UPDEST010: CMP ROUT2_NEIGHBOUR[EBX],0 JE SHORT UPDEST050 ; NO MORE DESTINATIONS CMP ROUT2_OBSCOUNT[EBX],0 JE SHORT UPDEST015 ; FAILED IN USE - DELETE TEST ROUT2_OBSCOUNT[EBX],80H JNZ SHORT UPDEST020 ; LOCKED DEC ROUT2_OBSCOUNT[EBX] JNZ SHORT UPDEST020 ; STILL OK ; ; REMOVE ENTRY ; PUBLIC UPDEST015 UPDEST015: CALL MOVE3TO2 JMP UPDEST010 ; LOOP BACK PUBLIC UPDEST020 UPDEST020: CMP ROUT3_NEIGHBOUR[EBX],0 JE SHORT UPDEST050 ; NO MORE CMP ROUT3_OBSCOUNT[EBX],0 JE SHORT UPDEST025 ; FAILED IN USE - DELETE TEST ROUT3_OBSCOUNT[EBX],80H JNZ SHORT UPDEST050 ; LOCKED DEC ROUT3_OBSCOUNT[EBX] JNZ SHORT UPDEST050 ; STILL OK ; ; REMOVE ENTRY ; PUBLIC UPDEST025 UPDEST025: CALL CLEARTHIRD PUBLIC UPDEST050 UPDEST050: ADD EBX,TYPE DEST_LIST LOOP UPDEST000_J RET PUBLIC UPDEST060 UPDEST060: ; ; Any INP3 Routes? CMP INPROUT1_NEIGHBOUR[EBX],0 JNE SHORT UPDEST050 ; Got INP3 Route(s) ; NO ROUTES LEFT TO DEST - REMOVE IT ; PUSH ECX ; SAVE COUNT CALL _REMOVENODE ; Unchain, Clear queue and zap POP ECX JMP UPDEST050 ; LOOP BACK PUBLIC MOVEALL MOVEALL: MOV AL,ROUT2_QUALITY[EBX] MOV ROUT1_QUALITY[EBX],AL MOV AL,ROUT2_OBSCOUNT[EBX] MOV ROUT1_OBSCOUNT[EBX],AL MOV EAX,ROUT2_NEIGHBOUR[EBX] MOV ROUT1_NEIGHBOUR[EBX],EAX PUBLIC MOVE3TO2 MOVE3TO2: ; MOV AL,ROUT3_QUALITY[EBX] MOV ROUT2_QUALITY[EBX],AL MOV AL,ROUT3_OBSCOUNT[EBX] MOV ROUT2_OBSCOUNT[EBX],AL MOV EAX,ROUT3_NEIGHBOUR[EBX] MOV ROUT2_NEIGHBOUR[EBX],EAX PUBLIC CLEARTHIRD CLEARTHIRD: MOV ROUT3_QUALITY[EBX],0 MOV ROUT3_OBSCOUNT[EBX],0 MOV ROUT3_NEIGHBOUR[EBX],0 MOV DEST_ROUTE[EBX],0 ; CANCEL ACTIVE ROUTE, SO WILL RE-ASSESS BEST RET PUBLIC _REMOVENODE _REMOVENODE: ; Remove a node, either becuase routes have gone, or APPL API has invalidated it LEA ESI,DEST_Q[EBX] CALL Q_REM JZ SHORT @F ; NO BUFFERS QUEUED CALL RELBUFF JMP SHORT _REMOVENODE @@: ; ; MAY NEED TO CHECK FOR L4 CIRCUITS USING DEST, BUT PROBABLY NOT, ; AS THEY SHOULD HAVE TIMED OUT LONG AGO ; MOV ECX,TYPE DEST_LIST MOV EDI,EBX XOR AL,AL REP STOSB DEC _NUMBEROFNODES ret PUBLIC SENDNODESMSG SENDNODESMSG: CMP NODESINPROGRESS,0 ; STILL GOING? JE SHORT SENDNODE00 ; NO RET PUBLIC SENDNODE00 SENDNODE00: ; ; SEND NODES MESSAGES TO ALL PORTS ; MOV EBX,PORTTABLE MOV CURRENTPORT,EBX MOVZX ECX,NUMBEROFPORTS MOV PORTSLEFT,CL PUBLIC SENDNEXTNODESFRAGMENT SENDNEXTNODESFRAGMENT: ; ; SEND NEXT FRAGMENT OF A NODES BROADCAST ; ; FRAGMENTS ARE SENT AT 10 SECONDS INTERVALS - PARTLY TO REDUCE ; QRM, PARTLY TO REDUCE LOAD ON BUFFERS (AND TX POWER SUPPLIES!) ; ; ; SEND TO PORT IN CURRENTPORT, STARTING AT CURRENTNODE ; ; MOV EBX,CURRENTPORT MOV AL,PORTNUMBER[EBX] MOV CURRENTPORTNO,AL CMP CURRENTNODE,0 JNE SHORT NOTFIRST ; ; FIRST FRAGMENT TO A PORT ; CMP PORTQUALITY[EBX],0 JNE SHORT SENDNODE30 JMP SENDNODEXX ; NO NODES MSG IF QUAL = 0 PUBLIC SENDNODE30 SENDNODE30: MOV EAX,DESTS MOV CURRENTNODE,EAX ; START OF LIST PUBLIC NOTFIRST NOTFIRST: MOV AL,PORTMINQUAL[EBX] MOV TXMINQUAL,AL CALL GETBUFF JNZ SHORT SENDNODE32 JMP STILLMORE ; WAIT A BIT PUBLIC SENDNODE32 SENDNODE32: ; PUSH EBX PUSH EDI ; SAVE BUFFER CALL SETUPNODESMSG ; ; ADD DESTINATION INFO (UNLESS BBS ONLY) ; CMP NODE,0 JE SHORT SENDNODEAA ; BBS ONLY - DONT SEND FULL NODES LIST MOV AH,0 MOV AL,NODESPACLEN[EBX] OR AL,AL JNZ SHORT PAC_OK MOV AH,1 ; 0 = 256 PUBLIC PAC_OK PAC_OK: CMP AX,50 ; STUPIDLY SMALL? JA SHORT PAC_OK2 MOV AX,50 ; EVEN THIS IS RATHER SILLY! PUBLIC PAC_OK2 PAC_OK2: SUB AX,22 ; FIXED PART DIV B21 ; 21 BYTES PER ENTRY MOV AH,0 MOVZX ECX,AX ; MAX DESTS IN ONE MESSAGE MOV EBX,CURRENTNODE PUBLIC SENDNODE42 SENDNODE42: CMP EBX,ENDDESTLIST JNE SHORT SENDNODE43 ; ; END OF TABLE ; PUBLIC SENDNODEAA SENDNODEAA: MOV CURRENTNODE,0 JMP SHORT SENDNODE48 ; FINISHED PUBLIC SENDNODE43 SENDNODE43: MOV AL,ROUT1_QUALITY[EBX] CMP AL,0 JE SHORT IGNORENODE ; IGNORE IT ; CMP AL,TXMINQUAL JB SHORT IGNORENODE MOV AL,OBSMIN ; MINIMUM TO BROADCAST CMP ROUT1_OBSCOUNT[EBX],AL JAE SHORT SENDNODE44 ; SEND ; TEST DEST_STATE[EBX],80H ; JNZ SHORT SENDNODE44 ; LOCKED DESTINATION - INCLUDE IT PUBLIC IGNORENODE IGNORENODE: ; ; IGNORE IT ; ADD EBX,TYPE DEST_LIST PUBLIC SENDNODE42_J SENDNODE42_J: JMP SENDNODE42 PUBLIC SENDNODE44 SENDNODE44: LEA ESI,DEST_CALL[EBX] IF BLACKBITS CALL CHECKBLACKLIST ; RETURN Z IF NODE IS IN LIST JZ SHORT IGNORENODE ; DONT BROADCAST ENDIF PUSH ECX MOV ECX,13 REP MOVSB ; CALL AND ALIAS MOV ESI,ROUT1_NEIGHBOUR[EBX] CMP ESI,0 JNE SHORT SENDNODE45 ; VALID POINTER ; ; DUMMY POINTER IN BBS ENTRY - PUT IN OUR CALL ; MOV ESI,OFFSET32 _MYCALL PUBLIC SENDNODE45 SENDNODE45: MOV AH,NEIGHBOUR_PORT[ESI] ; GET PORT OF BEST NEIGHBOUR MOV ECX,7 REP MOVSB ; PUT IN CALL MOV AL,100 CMP AH,CURRENTPORTNO JNE SHORT NOTSAMEPORT ; ; BEST NEIGHBOUR IS ON CURRENT PORT - REDUCE QUALITY BY QUAL_ADJUST ; MOV ESI,CURRENTPORT SUB AL,QUAL_ADJUST[ESI] ; PERCENTAGE REDUCTION PUBLIC NOTSAMEPORT NOTSAMEPORT: MUL ROUT1_QUALITY[EBX] DIV B100 STOSB POP ECX ADD EBX,TYPE DEST_LIST LOOP SENDNODE42_J ; ; CURRENT MESSAGE FULL, SEND IT AND START ANOTHER ; MOV CURRENTNODE,EBX PUBLIC SENDNODE48 SENDNODE48: MOV ECX,EDI POP EDI SUB ECX,EDI MOV MSGLENGTH[EDI],CX POP EBX CMP TXPORT[EBX],0 JNE SHORT SKIPTX1 ; DONT SEND IF SHARED TX CALL PUT_ON_PORT_Q JMP SHORT SENDNODE48A PUBLIC SKIPTX1 SKIPTX1: CALL RELBUFF PUBLIC SENDNODE48A SENDNODE48A: ; ; SEE IF MORE TO GO ; CMP CURRENTNODE,0 JNE SHORT STILLMORE PUBLIC SENDNODEXX SENDNODEXX: ; ; FINISHED THIS PORT - SEE IF MORE ; DEC PORTSLEFT JNZ SHORT ANOTHERPORT ; MOV NODESINPROGRESS,0 ; FINISHED RET PUBLIC ANOTHERPORT ANOTHERPORT: MOV EBX,CURRENTPORT MOV EBX,PORTPOINTER[EBX] MOV CURRENTPORT,EBX PUBLIC STILLMORE STILLMORE: MOV NODESINPROGRESS,1 ; RESTART TIMER RET PUBLIC SETUPNODESMSG SETUPNODESMSG: MOV AL,PORTNUMBER[EBX] MOV MSGPORT[EDI],AL LEA EDI,MSGDEST[EDI] MOV ESI,OFFSET32 NODECALL MOV ECX,7 REP MOVSB MOV ESI,OFFSET32 _NETROMCALL MOV ECX,7 REP MOVSB OR BYTE PTR -1[EDI],01100001B ; SET CMD END AND RESERVED BITS MOV AL,UI STOSB ; CONTROL MOV AL,0CFH STOSB ; PID MOV AL,0FFH STOSB ; FLAG MOV ECX,6 MOV ESI,OFFSET32 _MYCALL+7 ; ALIAS FOLLOWS CALL REP MOVSB RET _TEXT ENDS END