home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 239.lha / amiga / src / dnet / sernet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-02  |  6.7 KB  |  367 lines

  1.  
  2. /*
  3.  *  SERNET.C
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *  NetWork device interface.
  8.  */
  9.  
  10. #include "dnet.h"
  11.  
  12. #define WPEND    4            /*    must be at least 2        */
  13.  
  14. static IOSER Iowq[WPEND];
  15. static ubyte Iowact[WPEND];
  16.  
  17. static IOSER *CNet;            /*    control-req (synchro)        */
  18. static IOSER *RNet;            /*    read-request             */
  19. static ubyte RNetInProg;    /*    read request in progress     */
  20. static ubyte SerialIsOpen;  /*    serial device is open         */
  21. static ubyte RecvEnabled = 1;
  22. static char *DevName;
  23. static long UnitNum;
  24.  
  25. extern void *CheckIO();
  26.  
  27. NetOpen(iosink, devname, unitnum, pbaud)
  28. PORT *iosink;
  29. char *devname;
  30. long *pbaud;
  31. {
  32.     IOSER ios;
  33.     short i;
  34.     long baud = *pbaud;
  35.  
  36.     DevName = devname;
  37.     UnitNum = unitnum;
  38.  
  39.     bzero(&ios, sizeof(ios));
  40.     ios.io_CtlChar = 0x11130102;
  41.     ios.io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE;
  42.     if (OpenDevice(devname, unitnum, &ios, 0))
  43.     dneterror(devname);
  44.     ios.IOSer.io_Message.mn_ReplyPort = iosink;
  45.     SerialIsOpen = 1;
  46.  
  47.     RNet = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC);
  48.     CNet = (IOSER *)AllocMem(sizeof(IOSER), MEMF_PUBLIC);
  49.     *RNet = ios;
  50.     *CNet = ios;
  51.  
  52.     {
  53.     register IOSER *ioc = CNet;
  54.  
  55.     ioc->IOSer.io_Command = SDCMD_QUERY;
  56.     DoIO(ioc);
  57.     ioc->IOSer.io_Command = SDCMD_SETPARAMS;
  58.     ioc->io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE;
  59.     ioc->io_ExtFlags = 0;
  60.     ioc->io_ReadLen = ioc->io_WriteLen = 8;
  61.     ioc->io_CtlChar = 0x01020304;
  62.     if (baud)
  63.         ioc->io_Baud = baud;
  64.     *pbaud = Baud = ioc->io_Baud;
  65.     if (DoIO(ioc) != 0)
  66.         dneterror("Unable to set serial parameters");
  67.     }
  68.     RNet->IOSer.io_Command = CMD_READ;
  69.     RNet->IOSer.io_Message.mn_Node.ln_Name = (char *)RNET_REQ;
  70.     CNet->IOSer.io_Command = CMD_WRITE;
  71.     CNet->IOSer.io_Message.mn_Node.ln_Name = (char *)WNET_REQ;
  72.  
  73.     for (i = 0; i < WPEND; ++i)
  74.     Iowq[i] = *CNet;
  75.  
  76.     CNet->IOSer.io_Message.mn_Node.ln_Name = (char *)CNET_REQ;
  77. }
  78.  
  79. /*
  80.  *  Closedown the network.
  81.  */
  82.  
  83. NetClose()
  84. {
  85.     NetAbortRead();
  86.     NetWaitWrite();
  87.     if (SerialIsOpen)
  88.     CloseDevice(RNet);
  89.     if (RNet)
  90.     FreeMem(RNet, sizeof(IOSER));
  91.     if (CNet)
  92.     FreeMem(CNet, sizeof(IOSER));
  93.     SerialIsOpen = 0;
  94.     RNet = CNet = NULL;
  95. }
  96.  
  97. /*
  98.  *  NETCLWRITE()
  99.  *
  100.  *  Clear write request which was GetMsg()'d in DNET.C instead of
  101.  *  WaitIO()'d here.
  102.  */
  103.  
  104. NetClWrite(ior)
  105. IOSER *ior;
  106. {
  107.     short i = ior - &Iowq[0];
  108.     if (i < 0 || i >= WPEND) {
  109.     printf("NetClWrite: Software error %ld\n", i);
  110.     } else {
  111.     Iowact[i] = 0;
  112.     }
  113. }
  114.  
  115. /*
  116.  *  NETWRITE()
  117.  *
  118.  *  Write data to the network.    Only one standard request (for which we
  119.  *  expect a reply) is allowed queued at one time, while several (WPEND-1)
  120.  *  expect-no-reply requests may be queued.
  121.  */
  122.  
  123. void
  124. NetWrite(buf, bytes, expectreply)
  125. APTR buf;
  126. {
  127.     register short i;
  128.  
  129.     if (PDebug)
  130.     printf("SEND %02x %4ld bytes\n", ((ubyte *)buf)[1], bytes);
  131.  
  132.     if (!SerialIsOpen)
  133.     return;
  134.  
  135.     if (expectreply) {
  136.     if (Iowact[0]) {
  137.         WaitIO(&Iowq[0]);
  138.         Iowact[0] = 0;
  139.     }
  140.     i = 0;
  141.     } else {
  142.     for (i = 1; i < WPEND; ++i) {
  143.         if (!Iowact[i])
  144.         break;
  145.         if (CheckIO(&Iowq[i])) {
  146.         WaitIO(&Iowq[i]);
  147.         Iowact[i] = 0;
  148.         break;
  149.         }
  150.     }
  151.     if (i == WPEND) {
  152.         WaitIO(&Iowq[1]);
  153.         Iowact[1] = 0;
  154.         i = 1;
  155.     }
  156.     }
  157.  
  158.     if (bytes) {
  159.     register IOSER *iow = &Iowq[i];
  160.     iow->IOSer.io_Message.mn_Node.ln_Name = (char *)((expectreply) ? WNET_REQ : IGWNET_REQ);
  161.     iow->IOSer.io_Data = buf;
  162.     iow->IOSer.io_Length = bytes;
  163.     SendIO(iow);
  164.     Iowact[i] = 1;
  165.     }
  166.     fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort);
  167. }
  168.  
  169. NetBreak()
  170. {
  171.     if (SerialIsOpen) {
  172.     CNet->IOSer.io_Command = SDCMD_BREAK;
  173.     DoIO(CNet);
  174.     fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort);
  175.     }
  176. }
  177.  
  178. /*
  179.  *  NETREADY()
  180.  *
  181.  *  Using the specified inactive request, return the # bytes ready and
  182.  *  the carrier status.
  183.  */
  184.  
  185. NetReady()
  186. {
  187.     register long n = 0;
  188.  
  189.     if (SerialIsOpen && RecvEnabled) {
  190.     CNet->IOSer.io_Command = SDCMD_QUERY;
  191.     if (DoIO(CNet) == 0)
  192.         n = CNet->IOSer.io_Actual;
  193.     Cd = !(CNet->io_Status & (1 << 5));
  194.     }
  195.     return(n);
  196. }
  197.  
  198. /*
  199.  *  SetBaudRate()
  200.  */
  201.  
  202. SetBaudRate(baud)
  203. long baud;
  204. {
  205.     register long result;
  206.  
  207.     if (TOBaud == 0)
  208.     SetTimeouts(baud);
  209.     if (CNet)
  210.     CNet->io_Baud = baud;
  211.     if (!SerialIsOpen)
  212.     return(1);
  213.     SaveState();
  214.     CNet->IOSer.io_Command = SDCMD_SETPARAMS;
  215.     result = DoIO(CNet);
  216.     RestoreState();
  217.     return(result == 0);
  218. }
  219.  
  220. /*
  221.  *  Assumes CNet holds current settings
  222.  */
  223.  
  224. DropDTR()
  225. {
  226.     if (SerialIsOpen) {     /*  only if serial.device currently open    */
  227.     NetSerialOff();
  228.     Delay(50L);
  229.     NetSerialOn();
  230.     }
  231. }
  232.  
  233. IOSER *
  234. NetAbortRead()
  235. {
  236.     if (RNetInProg) {
  237.     if (SerialIsOpen && RecvEnabled) {
  238.         AbortIO(RNet);
  239.         WaitIO(RNet);
  240.     }
  241.     RNetInProg = 0;
  242.     }
  243.     return(RNet);
  244. }
  245.  
  246. static APTR  SaveBuf;
  247. static long  SaveLen;
  248.  
  249. NetStartRead(buf, len)
  250. APTR buf;
  251. long len;
  252. {
  253.     if (SerialIsOpen && RecvEnabled) {
  254.     if (RNetInProg)
  255.         NetAbortRead();
  256.     SaveBuf = RNet->IOSer.io_Data = buf;
  257.     SaveLen = RNet->IOSer.io_Length = len;
  258.     SendIO(RNet);
  259.     } else {
  260.     SaveBuf = buf;        /*  fake it */
  261.     SaveLen = len;
  262.     RNet->IOSer.io_Actual = 0;
  263.     }
  264.     RNetInProg = 1;
  265. }
  266.  
  267. IOSER *
  268. NetReadReady()
  269. {
  270.     return((IOSER *)CheckIO(RNet));
  271. }
  272.  
  273. NetReadReturned()
  274. {
  275.     RNetInProg = 0;
  276. }
  277.  
  278. NetWaitWrite()
  279. {
  280.     register short i;
  281.     register short flag = 0;
  282.     for (i = 0; i < WPEND; ++i) {
  283.     if (Iowact[i]) {
  284.         WaitIO(&Iowq[i]);
  285.         Iowact[i] = 0;
  286.         flag = 1;
  287.     }
  288.     }
  289.     if (flag)
  290.     fixsignal(Iowq[0].IOSer.io_Message.mn_ReplyPort);
  291. }
  292.  
  293. static char SvRInProg;
  294.  
  295. SaveState()
  296. {
  297.     if (SvRInProg = RNetInProg)
  298.     NetAbortRead();
  299.     NetWaitWrite();
  300. }
  301.  
  302. RestoreState()
  303. {
  304.     if (SvRInProg) {
  305.     register long n = RNet->IOSer.io_Actual;
  306.     if (n < 0)
  307.         n = 0;
  308.     NetStartRead((char *)SaveBuf + n, SaveLen - n);
  309.     }
  310. }
  311.  
  312. NetRecvOff()
  313. {
  314.     if (RecvEnabled) {
  315.     SaveState();
  316.     RecvEnabled = 0;
  317.     }
  318. }
  319.  
  320. NetRecvOn()
  321. {
  322.     if (!RecvEnabled) {
  323.     RecvEnabled = 1;
  324.     RestoreState();
  325.     }
  326. }
  327.  
  328. NetSerialOff()
  329. {
  330.     if (SerialIsOpen) {
  331.     SaveState();            /*  make sure no requests pending   */
  332.     CloseDevice(RNet);      /*  close the device                */
  333.     SerialIsOpen = 0;
  334.     }
  335. }
  336.  
  337. NetSerialOn()
  338. {
  339.     if (!SerialIsOpen) {
  340.     register short i;
  341.     if (OpenDevice(DevName, UnitNum, RNet, 0))      /* OH HELL! */
  342.         return(0);
  343.  
  344.     /*
  345.      *  Fix the Device / Unit fields and restore the previous
  346.      *  modes.
  347.      */
  348.  
  349.     SerialIsOpen = 1;
  350.     for (i = 0; i < WPEND; ++i) {
  351.         Iowq[i].IOSer.io_Device = RNet->IOSer.io_Device;
  352.         Iowq[i].IOSer.io_Unit   = RNet->IOSer.io_Unit;
  353.     }
  354.     CNet->IOSer.io_Device = RNet->IOSer.io_Device;
  355.     CNet->IOSer.io_Unit   = RNet->IOSer.io_Unit;
  356.  
  357.     RNet->IOSer.io_Command = CMD_READ;
  358.                 /*  restore params            */
  359.     CNet->IOSer.io_Command = SDCMD_SETPARAMS;
  360.     CNet->io_SerFlags = SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE;
  361.     DoIO(CNet);
  362.     RestoreState();         /*  restore pending read req.       */
  363.     }
  364.     return(1);
  365. }
  366.  
  367.