/* * SERNET.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. * * NetWork device interface. */ #include "dnet.h" IOSER *NetAbortRead(); void NetWaitWrite(); void SaveState(); void RestoreState(); void NetSerialOff(); void NetSerialOn(); static IOSER Iosw; static ubyte IoswIP; static ubyte LastWasWrite; static ubyte IosrIP; static ubyte RBuf[MAXPACKET*2]; /* Recv Buf. */ static IOSER *CNet; /* control-req (synchro) */ static IOSER *RNet; /* read-request */ static ubyte SerialIsOpen; /* serial device is open */ static ubyte RecvEnabled = 1; static char *DevName; static long UnitNum; void NetOpen(iosink, devname, unitnum, pbaud) PORT *iosink; char *devname; long *pbaud; { IOSER ios; long baud = *pbaud; DevName = devname; UnitNum = unitnum; printf("netopen %s %d\n", devname, unitnum); BZero(&ios, sizeof(ios)); ios.io_CtlChar = 0x11130102; ios.io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE; if (OpenDevice(devname, unitnum, (IOR *)&ios, 0)) dneterror(devname); ios.IOSer.io_Message.mn_ReplyPort = iosink; SerialIsOpen = 1; RNet = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC); CNet = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC); *RNet = ios; *CNet = ios; { IOSER *ioc = CNet; ioc->IOSer.io_Command = SDCMD_QUERY; DoIO((IOR *)ioc); if (Getty == 0) { ioc->IOSer.io_Command = SDCMD_SETPARAMS; ioc->io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE; ioc->io_ExtFlags = 0; ioc->io_ReadLen = ioc->io_WriteLen = 8; ioc->io_CtlChar = 0x01020304; if (baud) ioc->io_Baud = baud; switch(Protocol) { case 0: break; case 1: /* xon-xoff */ Mode7 = 1; ioc->io_SerFlags &= ~SERF_XDISABLED; break; case 2: ioc->io_SerFlags |= SERF_7WIRE; break; } *pbaud = Baud = ioc->io_Baud; if (DoIO((IOR *)ioc) != 0) dneterror("Unable to set serial parameters"); } } RNet->IOSer.io_Command = CMD_READ; RNet->IOSer.io_Message.mn_Node.ln_Name = (char *)RNET_REQ; CNet->IOSer.io_Command = CMD_WRITE; CNet->IOSer.io_Message.mn_Node.ln_Name = (char *)WNET_REQ; Iosw = *CNet; CNet->IOSer.io_Message.mn_Node.ln_Name = (char *)CNET_REQ; puts("net open"); } /* * Closedown the network. */ void NetClose() { NetAbortRead(); NetWaitWrite(); if (SerialIsOpen) CloseDevice((IOR *)RNet); if (RNet) FreeMem(RNet, sizeof(IOSER)); if (CNet) FreeMem(CNet, sizeof(IOSER)); SerialIsOpen = 0; RNet = CNet = NULL; } /* * NETCLWRITE() * * Clear write request which was GetMsg()'d in DNET.C instead of * WaitIO()'d here. */ void NetClWrite(ior) IOSER *ior; { if (ior == &Iosw) IoswIP = 0; } void NetWrite(buf, bytes) ubyte *buf; int bytes; { if (PDebug) { short i; LastWasWrite = 1; printf("WRITE %03x Bytes:", bytes); for (i = 0; i < bytes; ++i) printf(" %02x", buf[i]); printf("\n"); } if (!SerialIsOpen) return; if (IoswIP) { WaitIO((IOR *)&Iosw); IoswIP = 0; } if (bytes) { Iosw.IOSer.io_Message.mn_Node.ln_Name = (char *)WNET_REQ; Iosw.IOSer.io_Data = (APTR)buf; Iosw.IOSer.io_Length = bytes; SendIO((IOR *)&Iosw); IoswIP = 1; } fixsignal(Iosw.IOSer.io_Message.mn_ReplyPort); } void NetBreak() { if (SerialIsOpen) { CNet->IOSer.io_Command = SDCMD_BREAK; DoIO((IOR *)CNet); fixsignal(Iosw.IOSer.io_Message.mn_ReplyPort); } } /* * NETREADY() * * Using the specified inactive request, return the # bytes ready and * the carrier status. */ NetReady() { long n = 0; if (SerialIsOpen && RecvEnabled) { CNet->IOSer.io_Command = SDCMD_QUERY; if (DoIO((IOR *)CNet) == 0) n = CNet->IOSer.io_Actual; Cd = !(CNet->io_Status & (1 << 5)); } return(n); } /* * SetBaudRate() */ SetBaudRate(baud) long baud; { long result; if (Getty) return(0); if (TOBaud == 0) SetTimeouts(baud); if (CNet) CNet->io_Baud = baud; if (!SerialIsOpen) return(1); SaveState(); CNet->IOSer.io_Command = SDCMD_SETPARAMS; result = DoIO((IOR *)CNet); RestoreState(); if (result) printf("Unable to set baud rate to %d\n", baud); if (!result && PDebug) printf("Baud rate set to %d\n", baud); return(0); /* don't abort whether we can or not */ } /* * Assumes CNet holds current settings */ void DropDTR() { if (SerialIsOpen) { /* only if serial.device currently open */ NetSerialOff(); Delay(50*4); NetSerialOn(); } } IOSER * NetAbortRead() { if (IosrIP) { if (SerialIsOpen && RecvEnabled) { AbortIO((IOR *)RNet); WaitIO((IOR *)RNet); } IosrIP = 0; } return(RNet); } /* * NetStartRead(bytes) */ static long SaveLen; void NetStartRead(len) long len; { if (len > sizeof(RBuf)) len = sizeof(RBuf); if (SerialIsOpen && RecvEnabled) { if (IosrIP) NetAbortRead(); RNet->IOSer.io_Data = (APTR)RBuf; SaveLen = RNet->IOSer.io_Length = len; SendIO((IOR *)RNet); } else { SaveLen = len; RNet->IOSer.io_Actual = 0; } IosrIP = 1; } IOSER * NetReadReady() { return((IOSER *)CheckIO((IOR *)RNet)); } NetReadReturned(pptr) ubyte **pptr; { long bytes = 0; IosrIP = 0; bytes = RNet->IOSer.io_Actual; *pptr = RBuf; if (PDebug) { short i = 0; if (LastWasWrite) { LastWasWrite = 0; printf("READ: "); } for (i = 0; i < bytes; ++i) printf("%02x ", RBuf[i]); fflush(stdout); } return(bytes); } void NetWaitWrite() { if (IoswIP) { WaitIO((IOR *)&Iosw); IoswIP = 0; fixsignal(Iosw.IOSer.io_Message.mn_ReplyPort); } } static char SaveIosrIP; void SaveState() { if (SaveIosrIP = IosrIP) NetAbortRead(); NetWaitWrite(); } void RestoreState() { if (SaveIosrIP) NetStartRead(SaveLen); } void NetRecvOff() { if (RecvEnabled) { SaveState(); RecvEnabled = 0; } } void NetRecvOn() { if (!RecvEnabled) { RecvEnabled = 1; RestoreState(); } } void NetSerialOff() { if (SerialIsOpen) { SaveState(); /* make sure no requests pending */ CloseDevice((IOR *)RNet); /* close the device */ SerialIsOpen = 0; } } void NetSerialOn() { if (!SerialIsOpen) { if (OpenDevice(DevName, UnitNum, (IOR *)RNet, 0)) /* OH HELL! */ return; /* * Fix the Device / Unit fields and restore the previous * modes. */ SerialIsOpen = 1; Iosw.IOSer.io_Device = RNet->IOSer.io_Device; Iosw.IOSer.io_Unit = RNet->IOSer.io_Unit; CNet->IOSer.io_Device = RNet->IOSer.io_Device; CNet->IOSer.io_Unit = RNet->IOSer.io_Unit; RNet->IOSer.io_Command = CMD_READ; /* restore params */ CNet->IOSer.io_Command = SDCMD_SETPARAMS; CNet->io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE; DoIO((IOR *)CNet); RestoreState(); /* restore pending read req. */ } return; }