From: MsgPost.v1.00@mtask.omahug.org (MsgPost v1.00)
Newsgroups: comp.sys.amiga.programmer
Subject: [2 of 2] A serial device example (LONG)
Date: 03 Sep 92 08:19:34 CST
Reply-To: msgpost.v1.00@mtask.omahug.org
Organization: Multitasking Systems, Kansas City
Followup-To: comp.sys.amiga.programmer

                mask = 1L <<
iorequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
                mask = Wait (mask | SIGBREAKF_CTRL_C);

                if (mask & SIGBREAKF_CTRL_C) {
                        AbortIO (iorequest);
                        WaitIO (iorequest);
                        NNTP_in_ip = 0;

                        // PutStr ("reads: terminated outstanding IO\n");
                        return -1;
                }
                WaitIO (iorequest);
                NNTP_in_ip = 0;
        }

        if (errno = iorequest->IOSer.io_Error) {
                PrintFault (errno, "reads IO error");
                return -1;
        }

        return iorequest->IOSer.io_Actual;
}

int writes (struct IOExtSer *iorequest, char *buf, int len)
{
        int errno;
        //
        //  writes: Output 'len' bytes in 'buf' to 'iorequest'.
        //
        //          Return an error if one occurs.
        //
        //          Much simpler than reads().
        //
        iorequest->IOSer.io_Command = CMD_WRITE;
        iorequest->IOSer.io_Data    = buf;
        iorequest->IOSer.io_Length  = len;
        NNTP_out_ip = 1;

        DoIO (iorequest);
        NNTP_out_ip = 0;

        if (errno = iorequest->IOSer.io_Error) {
                PrintFault (errno, "writes: IO error");
                return -1;
        }

        return iorequest->IOSer.io_Actual;
}

#ifdef DEBUG
void DebugIoRequest (struct IOExtSer * iorequest)
{
        int mask = iorequest->io_SerFlags;

        printf ("CtlChar    0x%lx \n", iorequest->io_CtlChar);
        printf ("RBufLen    %ld   \n", iorequest->io_RBufLen);
        printf ("ExtFlags   0x%lx \n", iorequest->io_ExtFlags);
        printf ("Baud       %ld   \n", iorequest->io_Baud);
        printf ("BrkTime    %ld   \n", iorequest->io_BrkTime);
        printf ("ReadLen    %ld   \n", iorequest->io_ReadLen);
        printf ("WriteLen   %ld   \n", iorequest->io_WriteLen);
        printf ("StopBits   %ld   \n", iorequest->io_StopBits);
        printf ("SerFlags   0x%lx \n", iorequest->io_SerFlags);
        if (mask) {
                printf ("           ");
                if (mask & SERF_XDISABLED)
                        printf ("XDISABLED ");
                if (mask & SERF_EOFMODE)
                        printf ("EOFMODE ");
                if (mask & SERF_SHARED)
                        printf ("SHARED ");
                if (mask & SERF_RAD_BOOGIE)
                        printf ("RAD_BOOGIE ");
                if (mask & SERF_QUEUEDBRK)
                        printf ("QUEUEDBRK ");
                if (mask & SERF_7WIRE)
                        printf ("7WIRE ");
                if (mask & SERF_PARTY_ODD)
                        printf ("PARTY_ODD ");
                if (mask & SERF_PARTY_ON)
                        printf ("PARTY_ON");
                printf ("\n");
        }
        printf ("Status     0x%lx \n", iorequest->io_Status);
        printf ("\n");

        return;
}
#endif

int done = 0;
int ih_done = 0;

__geta4 void InputHandler (void)
{
    int ih_len;
    char ih_inbuf [256];

    struct MsgPort *myport = (struct MsgPort *) CreatePort (NULL, 0);
    struct MsgPort *saveport = NULL;

    // NO ONE touch NNTP_in_io after I've been entered, until I'm done.
    // Under pain of GURU.

    if (!myport) {
            PutStr ("InputHandler: CreatePort() failure\n");

            ih_done = 1;
            done = 3;
            return;
    }

    saveport = NNTP_in_io->IOSer.io_Message.mn_ReplyPort;
    NNTP_in_io->IOSer.io_Message.mn_ReplyPort = myport;

    while (!done) {

            ih_len = reads (NNTP_in_io, ih_inbuf, 256);

            if (ih_len <= 0)
                    continue;

            ih_len = Write (Output (), ih_inbuf, ih_len);
            if (ih_len < 1)
                    PrintFault (IoErr (), "InputHandler Write error");
            Flush (Output ());
    }

    DeletePort (myport);
    NNTP_in_io->IOSer.io_Message.mn_ReplyPort = saveport;

    ih_done = 1;
    return;
}

int main (int argc, char **argv)
{
        char *device;
        int unit;
        unsigned long pid;
        char *cmd;
        char chr;
        char main_inbuf [128];
        char outbuf [128];
        int len;
        int in_command = 0;
        int last_was_newline = 0;

        if (argc <= 1) {
                device = "serial.device";
                unit = 0;
        }
        else
                if (argc != 3) {
                        PutStr ("GRn-Term <device> <unit>\n");
                        exit (20);
                }

        device = argv [1];
        unit = atoi (argv [2]);

        SetupSerialPort (0, device, unit);

        pid = CreateNewProcTags (
                NP_Entry,       InputHandler,
                NP_Input,       Input(),
                NP_Output,      Output(),
                NP_CloseInput,  DOSFALSE,
                NP_CloseOutput, DOSFALSE,
                NP_Name,        "InputHandler",
                TAG_DONE);

        if (!pid)
                KillSerialPort (0, "CreateNewProc() failed\n");

        PutStr ("\nGRn-Term Initialized\n\n");

        cmd = outbuf;
        while (!done) {

                len = Read (Input (), main_inbuf, 1);

                if (len < 0) {
                        PrintFault (IoErr (), "CONSOLE: input error");
                        continue;
                }
                if (len == 0) {
                        // EOF on input
                        done = 1;
                        Signal ((struct Task *) pid, SIGBREAKF_CTRL_C);
                        continue;
                }

                chr = main_inbuf [0];

                if (cmd == outbuf && chr == '\\')
                        in_command = 1;
                if (!in_command)
                        if (chr == '\n')
                                writes (NNTP_out_io, "\r", 1);
                        else
                                writes (NNTP_out_io, main_inbuf, 1);

                *cmd++ = main_inbuf [0];

                if (chr == '\n') {
                        last_was_newline = 1;
                        *cmd = '\0';
                        cmd = outbuf;

                        if (!in_command)
                                continue;

                        if (strnicmp (outbuf, "\\quit", 5) == 0) {
                                done = 2;
                                Signal ((struct Task *) pid, SIGBREAKF_CTRL_C);
                        }
                        else if (strncmp (outbuf, "\\dial ", 6) == 0) {
                                char *p = outbuf + 6;

                                writes (NNTP_out_io, "\rAT\r", 4);
                                Delay (50);
                                *(p + strlen (p) - 1) = '\r';
                                writes (NNTP_out_io, p, strlen (p));
                        }
                        else if (strncmp (outbuf, "\\hangup", 7) == 0) {
                                Delay (110);
                                writes (NNTP_out_io, "+", 1);
                                Delay (5);
                                writes (NNTP_out_io, "+", 1);
                                Delay (5);
                                writes (NNTP_out_io, "+", 1);
                                Delay (150);
                                writes (NNTP_out_io, "ATH0\r\n", 6);
                                Delay (110);
                        }
#if 0
                        // FIXME: get InputHandler() off the serial port
                        else if (strncmp (outbuf, "\\grn", 4) == 0) {
                                int rslt;

                                ShutDownSerialPort ();
                                rslt = SystemTagList (outbuf + 1, TAG_DONE);
                                if (rslt == -1)
                                        PutStr ("GRn failed\n");
                                else
                                        PutStr ("GRn complete\n");
                                SetupSerialPort (0, device, unit);
                        }
#endif
                        else {
                                PutStr ("Unknown control command '");
                                PutStr (outbuf);
                                PutStr ("'\n");
                        }
                        in_command = 0;
                }
                else
                        last_was_newline = 0;
                *cmd = '\0';
        }

        len = 0;
        while (!ih_done) {
                len++;
                if (len > 10) {
                        len = 0;
                        PutStr ("Waiting on InputHandler to terminate\n");
                }
                Delay (10);
        }

        ShutDownSerialPort ();

        PutStr ("\nGRn-Term closing down\n\n");
}
--
  //   Michael B. Smith
\X/    mbs@adastra.cvl.va.us  -or-  uunet.uu.net!virginia.edu!adastra!mbs