!********************** !* LMEOTS/LMEOTY * !* DATE: 17.SEP.80 * !********************* %CONSTSTRING (7) VSN = "VSN001B" !! STACK = 300, STREAMS = 1 %CONTROL K'100001' %RECORDFORMAT XF(%BYTEINTEGER UNIT,FSYS,%BYTEINTEGERARRAY FNAME(0:5)) %CONSTRECORD (XF) %NAME NULL = 0 %SYSTEMROUTINESPEC ALARM(%INTEGER TICKS) %BEGIN %%RECORDFORMAT ITPF(%BYTEINTEGER CNSL,HB1,HB2,LEN, %C %BYTEINTEGERARRAY DATA(0:127)) %RECORDFORMAT RJEF(%BYTEINTEGERARRAY DATA(0:239)) %RECORDFORMAT NSI1F(%BYTEINTEGER FN,SUFL,ST,SS,FLAG,UFLAG, %C %RECORD(ITPF) ITP) %RECORDFORMAT NSI2F(%BYTEINTEGER FN,SUFL,ST,SS,%C FLAG, UFL, %C %BYTEINTEGERARRAY A(0:239)) %RECORDFORMAT MEF(%RECORD(MEF)%NAME LINK,%BYTEINTEGER LEN,TYPE, %C %RECORD(NSI1F) NSL) %RECORDFORMAT ME2F(%RECORD(ME2F)%NAME LINK,%BYTEINTEGER LEN,TYPE, %C %RECORD(NSI2F) NSL) %RECORDFORMAT PF(%BYTEINTEGER SERVICE,REPLY,FN,PORT, %C %RECORD(MEF)%NAME MES,%BYTEINTEGER LEN,S1) %RECORDFORMAT P2F(%BYTEINTEGER SERVICE,REPLY,FN,PORT,%RECORD(ME2F)%NAME MES, %C %BYTEINTEGER LEN,S1) %RECORDFORMAT P3F(%BYTEINTEGER SERVICE,REPLY,FN,PORT,FACILITY,FLAG,NODE,TERM) %RECORD(PF) P %RECORDFORMAT QF(%RECORD (MEF) %NAME E) %RECORDFORMAT TCPF(%INTEGER STATE, CON STATE IND, %C HELD, H IND, H NO, %BYTEINTEGER PORT, OSTATE, TCPN, TERM, %C SIZE, MAX, %RECORD (QF) OUTQ) %OWNRECORD (TCPF) TCP ! %CONSTINTEGER NOT ALLOCATED = 0 %CONSTINTEGER CONNECTED = 1 %CONSTINTEGER TCP DISCONNECTING = 2 !****** TCP_OSTATE STATES (PERMISSION TO SEND) ***** %CONSTINTEGER IDLE = 0 %CONSTINTEGER BUSY = 1 !*********************************************************** %RECORDFORMAT CONSF(%INTEGER CNSL, STATE) %OWNRECORD (CONSF) %ARRAY CONA(0:48) %OWNRECORD (CONSF) %NAME CON %CONSTBYTEINTEGERNAME ID = K'160030' %CONSTBYTEINTEGERNAME INT = K'160060' %CONSTINTEGER TT SER=1, GATE SER=16, BUFFER MANAGER=17 %CONSTINTEGER RD=0, ECHO OFF=10 %CONSTINTEGER REQUEST BUFFER=0, RELEASE BUFFER=1 %CONSTINTEGER ENABLE FACILITY=1, DISABLE FACILITY=2, CALL REPLY=3 %CONSTINTEGER ENABLE INPUT=4, PUT OUTPUT=5, CLOSE CALL=6 %CONSTINTEGER ABORT CALL=7, OPEN CALL=8, OPEN MESSAGE=9 %CONSTINTEGER OPEN CALL REPLY=1, INCOMING CALL=2, INPUT RECD=3 %CONSTINTEGER OUTPUT TRANSMITTED=4, CALL CLOSED=5, CALL ABORTED=6 %CONSTINTEGER OPEN REPLY A=7, OPEN REPLY B=8, MESSAGE IN=9, MESSAGE REPLY=10 %INTEGER I, NODE, TERM, STRM, K, FLAG %OWNINTEGER INITF %OWNINTEGER USERS, STA, CPU, PKTS, SBR, BYT, RJEI, TIM, RJEO %OWNINTEGER CONN OK, G PORT, POWER, KILL IT %ROUTINE GET BUFFER(%INTEGER REASON) P_SERVICE=BUFFER MANAGER; P_REPLY=ID P_FN=REQUEST BUFFER; P_LEN=0; P_S1=REASON PON(P) %END %ROUTINE FREE BUFFER(%RECORD(MEF)%NAME MES) P_SERVICE=BUFFER MANAGER; P_REPLY=ID P_FN=RELEASE BUFFER; P_MES==MES PON(P) %END %ROUTINE TO GATE(%INTEGER FN, %RECORD (MEF) %NAME MES, %C %INTEGER FLAG) %IF FN = PUT OUTPUT %START; ! QUEUE THESE AS NECESSARY %IF TCP_STATE # CONNECTED %START; ! THROW AWAY FREE BUFFER(MES); %RETURN %FINISH %IF TCP_OSTATE # IDLE %START PUSH(TCP_OUTQ, MES) TCP_SIZE = TCP_SIZE+1 TCP_MAX = TCP_SIZE %IF TCP_SIZE>TCP_MAX %RETURN %FINISH TCP_OSTATE = BUSY ! %IF MON # 0 %START ! SELECT OUTPUT(1) ! PRINTSTRING("IO ");! MON MES(MES) ! %FINISH %FINISH P_SERVICE = GATE SER; P_REPLY = ID P_FN = FN; P_PORT = TCP_PORT; P_MES == MES; P_S1 = FLAG PON(P) %END %ROUTINE DO CONNECT(%INTEGER TYPE) %RECORDFORMAT P3F(%BYTEINTEGER SER, REPLY, %C FN, PORT, FACILITY, FLAG, NODE, TERM) %RECORD (P3F) %NAME P3 P3 == P P3_SER = GATE SER; P3_REPLY = ID P3_FN = OPEN CALL; P3_PORT = TYPE P3_NODE = NODE; P3_TERM = TERM P3_FLAG = POWER P3_FACILITY = STRM PON(P) %END %ROUTINE BLOCK(%RECORD (MEF) %NAME MES, %INTEGER CNSL) %INTEGER I %RECORD (NSI2F) %NAME NSI %RECORDFORMAT ITP2F(%BYTEINTEGER CNSL, HB1, HB2, %STRING (128) S) %RECORD (ITP2F) %NAME ITP %SWITCH SW(0:5) %OWNSTRING (7) NAME = "EYRH01" %CONSTSTRING (5) PASS = "PASS" NSI == MES_NSL ITP == NSI_ITP CON == CONA(CNSL) ITP_CNSL = CNSL -> SW(CON_STATE) SW(0): ! SEND HELLO ITP_HB1 = 8 MES_LEN = 6+4 -> COMM SW(1): ! SEND NAME ITP_S = NAME ITP_HB1 = 0; ITP_HB2 = 2 MES_LEN = 6+4+6 -> COMM SW(2): ! SEND PASS ITP_S = PASS ITP_HB1 = 0; ITP_HB2 = 2 MES_LEN = 6+4+4 -> COMM SW(3): ! SEND EOT ITP_HB1 = 4; ITP_HB2 = 0 MES_LEN = 6+4 COMM: TO GATE(PUT OUTPUT, MES, 0) CON_STATE = CON_STATE+1 %IF CON_STATE = 4 %THEN CON_STATE = 0 %END PKTS = PKTS+1 TO GATE(PUT OUTPUT, MES, 0) %END %ROUTINE ANALYSE ITP INPUT(%RECORD (MEF) %NAME MES) %RECORD (ITPF) %NAME ITP %INTEGER I, J, K ITP == MES_ITP K = ITP_CNSL CON == CONA(K) %IF CON_STATE < 3 %START; ! LOOK FOR PROMPT %IF ITP_HB1&1 = 0 %START; ! TEXT %IF ITP_HB2&4 # 0 %START; ! PROMPT GET BUFFER(K); ! DO THE NEXT THING %FINISH %FINISH %ELSE; ! READY TO SEND EOT GET BUFFER(K) %FINISH FREE BUFFER(MES) %END MAP VIRT(BUFFER MANAGER,4, 3) MAP VIRT(BUFFER MANAGER, 5, 4) MAP VIRT(BUFFER MANAGER, 6, 5) PROMPT("NODE?"); READ(NODE) PROMPT("TERM?"); READ(TERM) PROMPT("STRM?"); READ(STRM) PROMPT("SEND AHEAD?") SKIPSYMBOL READSYMBOL(I); READSYMBOL(K) I = I-'0'; K=K-'0' %IF 0<=K<=7 %THEN POWER=I<<4+K<<1 %ELSE POWER=I<<4 STA = 1 DO CONNECT(0) ALARM(4*50) %CYCLE P_SERVICE = 0; POFF(P) %IF P_REPLY = 0 %START; ! CLOCK %IF INT = 'A' %START KILL IT = -1 PRINTSTRING("KILLING IT ") TO GATE(CALL ABORTED, NULL, 0) %IF CONN OK # 0 INT = 0 %CONTINUE %FINISH ALARM(5); ! 30 SECS %IF INT='?' %START WRITE(FLAG, 1) WRITE(PKTS, 4); NEWLINE INT = 0 %FINISH %IF TCP_OSTATE = CONNECTED %START I = INITF INITF = INITF+1; INITF = 0 %IF INITF = 49 %CYCLE CON == CONA(I) %IF CON_STATE = 0 %START; ! READY TO GO GET BUFFER(I) %EXIT %FINISH %EXIT %IF I = INITF I = I+1; I = 0 %IF I = 49 %REPEAT %CONTINUE %FINISH %IF P_REPLY = BUFFER MANAGER %START %IF KILL IT < 0 %THEN FREE BUFFER(P_MES) %AND %CONTINUE BLOCK(P_MES, P_S1) %CONTINUE %FINISH %IF P_REPLY = GATE SER %START %IF P_FN = OPEN REPLY A %START; ! 1ST REPLY I = P_PORT; ! MY PORT NUMBER K = P_S1; ! GATE PORT NUMBER %IF K = 0 %START PRINTSTRING("MCON: GATE REFUSED ") %STOP %FINISH %CONTINUE; ! WAIT FOR REPLY B %FINISH %IF P_FN = OPEN REPLY B %START; ! 2ND REPLY %STOP %IF KILL IT < 0 I = P_PORT; ! GATE PORT NUMBER !! G PORT = I FLAG = P_S1 %IF P_S1 # 0 %START; ! FAILED %IF TIM = 0 %START PRINTSTRING("FAILED"); WRITE(P_S1, 1); NEWLINE %FINISH TIM = TIM+1 DO CONNECT(0); ! TRY AGAIN %CONTINUE %FINISH PRINTSTRING("CALL ACCEPTED ") CONN OK = 1 GET BUFFER(0) %CONTINUE %FINISH %IF P_FN=CALL ABORTED %OR P_FN=CALL CLOSED %START; ! MY END I HOPE PRINTSTRING("CALL GONE ") %STOP %FINISH %IF P_FN = OUTPUT TRANSMITTED %START TCP_OSTATE = IDLE %UNLESS TCP_OUTQ_E == NULL %START TCP_SIZE = TCP_SIZE-1 TO GATE(PUT OUTPUT, POP(TCP_OUTQ), 0) %FINISH %CONTINUE %FINISH %IF P_FN = INPUT RECD %START PKTS = PKTS+1 ANALYSE ITP INPUT(MES) %CONTINUE %FINISH PRINTSTRING("FUNNY FN"); WRITE(P_FN, 1); NEWLINE %CONTINUE %FINISH %REPEAT %ENDOFPROGRAM ") FLAG = P_S1