Annotation of os2sdk/demos/apps/terminal/modem.c, revision 1.1

1.1     ! root        1: /***   modem.c
        !             2:  *
        !             3:  * TITLE 
        !             4:  *
        !             5:  *     modem.c
        !             6:  *     Copyright (C) Microsoft Corporation 1987
        !             7:  *     March 1987
        !             8:  *
        !             9:  * DESCRIPTION
        !            10:  *
        !            11:  *     This module contains routines that support Hayes compatible modem. 
        !            12:  *
        !            13:  ***/
        !            14: 
        !            15: #include       <stdio.h>       
        !            16: #include       <doscalls.h>
        !            17: #include       <subcalls.h>
        !            18: #include       <malloc.h>
        !            19: #include       <string.h>
        !            20: #include       <memory.h>
        !            21: #include       <conio.h>
        !            22: #include       "term.h"
        !            23: 
        !            24: #define min(a,b) (((a)<(b)) ? (a):(b)) /* This is pulled out of the old */
        !            25:                                        /* v2tov3.h (c v2.0) header file */
        !            26: 
        !            27: extern char    *ErrMsg[]; 
        !            28: extern unsigned FileHndl;
        !            29: 
        !            30: make_dial_cmd(char *, int);
        !            31: void flush_ques(int);
        !            32: void clr_com_error(void);
        !            33: void com_clr_flush(void);
        !            34: 
        !            35: static char Init[]    = {'A', 'T', 'V', '0', 0x0d};
        !            36: static char Attn[]    = {'A', 'T', 0x0d};
        !            37: static char Esc[]     = {'+', '+', '+'};
        !            38: static char OnHook[]  = {'A', 'T', 'H', '0', 0X0d};
        !            39: static char OffHook[] = {'A', 'T', 'H', '1', 0x0d};
        !            40: static char Reset[]   = {'A', 'T', 'Z', 0x0d};
        !            41: 
        !            42: struct s_Cmd{
        !            43:         char *pCmd;
        !            44:         int   CmdLen;
        !            45: } Cmds[] = {
        !            46:     {Init, sizeof(Init)},              /* Initialize modem */
        !            47:     {Attn, sizeof(Attn)},              /* Attention cmd */
        !            48:     {Esc, sizeof(Esc)},                /* Modem escape sequence*/
        !            49:     {OnHook, sizeof(OnHook)},          /* Put phone on hook */
        !            50:     {OffHook, sizeof(OffHook)},        /* Take phone off hook */
        !            51:     {Reset, sizeof(Reset)}             /* Reset command */
        !            52:   };
        !            53: 
        !            54: 
        !            55: 
        !            56: /***   make_modem_conn - make modem connection
        !            57:  *
        !            58:  *     This routine tries to setup the modem connection, retrying if 
        !            59:  *     appropriate.
        !            60:  *
        !            61:  *     make_modem_conn()
        !            62:  *
        !            63:  *     ENTRY
        !            64:  *
        !            65:  *     EXIT
        !            66:  *             TRUE if modem connection was made 
        !            67:  *             FALSE if modem connection did not go through
        !            68:  *
        !            69:  *     WARNING
        !            70:  *
        !            71:  *     EFFECTS
        !            72:  *
        !            73:  ***/
        !            74: 
        !            75: make_modem_conn()
        !            76: {
        !            77:        unsigned        NumBytes,       /* number of bytes to be written    */
        !            78:                        RetCode,        /* return code from system calls    */
        !            79:                        Result = FALSE; /* to be returned by this routine */
        !            80:        char            OutBuffer,
        !            81:                        ModemRetry = TRUE,   /* retry for modem connection   */
        !            82:                        NumRetries = 0;      /* no. times connection retried */
        !            83: 
        !            84:        printf("trying modem connection...\n");
        !            85: 
        !            86:        while (ModemRetry)
        !            87:           switch (setup_modem_conn()) {
        !            88:            case MS_CONNECT    :
        !            89:            case MS_CONNECT1200: 
        !            90:              Result = TRUE;
        !            91:              ModemRetry = FALSE;
        !            92:              OutBuffer = '\r';
        !            93:              if ((RetCode = DOSWRITE(FileHndl, &OutBuffer, 1, 
        !            94:                                       &NumBytes)) != 0)
        !            95:                error(ERR_DOSWRITE, RetCode);
        !            96:               break;
        !            97:            case MS_NOCARRIER  :
        !            98:            case MS_NODIALTONE :
        !            99:              if (++NumRetries > NUM_RETRY) {
        !           100:                printf("modem connection failed\n");
        !           101:                ModemRetry = FALSE;
        !           102:              }
        !           103:              else
        !           104:                printf("modem connection failed; retrying...\n");
        !           105:              break;
        !           106:            case MS_NOREPLY    :
        !           107:             case MS_ERROR      : 
        !           108:            case OT_FAILURE    :                /* OTher failure */
        !           109:             case MS_BUSY       : 
        !           110:            default            : 
        !           111:              ModemRetry = FALSE;
        !           112:               printf("modem connection failed\n");
        !           113:               break;
        !           114:          }             /* switch (setup_modem_conn()) */
        !           115: 
        !           116:        return(Result);
        !           117: 
        !           118: }
        !           119: 
        !           120: 
        !           121: 
        !           122: 
        !           123: /***   setup_modem_conn - setup modem connection
        !           124:  *
        !           125:  *     This is the helper routine for the make_modem_conn(). It initialises
        !           126:  *     the modem connection and sends out the dial command to the modem.
        !           127:  *
        !           128:  *     setup_modem_conn()
        !           129:  *
        !           130:  *     ENTRY
        !           131:  *
        !           132:  *     EXIT
        !           133:  *             returns one of the following: MS_CONNECT MS_CONNECT1200 
        !           134:  *             MS_NOCARRIER MS_NODIALTONE MS_NOREPLY MS_ERROR MS_BUSY 
        !           135:  *             OT_FAILURE
        !           136:  *
        !           137:  *     WARNING
        !           138:  *
        !           139:  *     EFFECTS
        !           140:  *
        !           141:  ***/
        !           142: 
        !           143: int    setup_modem_conn()
        !           144: {
        !           145:        int             Result = OT_FAILURE;
        !           146: 
        !           147:        /* initialise modem connection */
        !           148:        if (!(send_modem_cmd(MC_INIT)))
        !           149:          return(Result);
        !           150:        if (get_modem_reply() != MS_OK)
        !           151:          return(Result);
        !           152:        DOSSLEEP((long) 100);
        !           153: 
        !           154:        /* write AT string to the modem. This will cause the modem to
        !           155:         * determine the communications rate of the terminal as well
        !           156:         * as its parity setting.
        !           157:         */
        !           158:        if (!(send_modem_cmd(MC_ATTN)))
        !           159:          return(Result);
        !           160:        if (get_modem_reply() != MS_OK)
        !           161:          return(Result);
        !           162:        DOSSLEEP((long) 100);
        !           163: 
        !           164:        /* send DIAL command to the modem */
        !           165:        if (!(send_modem_cmd(MC_DIAL)))
        !           166:          return(Result);
        !           167: 
        !           168:        return(get_modem_reply());
        !           169: };
        !           170: 
        !           171: 
        !           172: 
        !           173: 
        !           174: /***   send_modem_cmd - send a command to modem
        !           175:  *
        !           176:  *     This routine sends a command to the modem and ensures that the echo 
        !           177:  *     from the modem matches the input command.
        !           178:  *
        !           179:  *     send_modem_cmd(CmdType)
        !           180:  *
        !           181:  *     ENTRY
        !           182:  *             CmdType - type of modem command: MC_INIT MC_ATTN MC_ESC 
        !           183:  *                             MC_ONHOOK MC_OFFHOOK MC_RESET MC_DIAL
        !           184:  *
        !           185:  *     EXIT
        !           186:  *             TRUE if command was sent succesfully
        !           187:  *             FALSE if command failed
        !           188:  *
        !           189:  *     WARNING
        !           190:  *
        !           191:  *     EFFECTS
        !           192:  *
        !           193:  ***/
        !           194: 
        !           195: send_modem_cmd(CmdType)
        !           196: int    CmdType;                /* The command to send */
        !           197: {
        !           198:        int             Result = TRUE,
        !           199:                        ReadCnt,
        !           200:                        WriteCnt,
        !           201:                        CmdLen,
        !           202:                        RetCode;
        !           203:        char            Buf[80],
        !           204:                        Cmd[80],
        !           205:                        *pDst,
        !           206:                        *pCmd;
        !           207:        
        !           208: 
        !           209:        /* clear COM error and flush transmit/receive queues */
        !           210:        com_clr_flush();
        !           211: 
        !           212:         if (CmdType == MC_INIT) {
        !           213:          send_modem_cmd(MC_RESET);     /* modem command: ATZ */
        !           214:          /* clear COM error and flush transmit/receive queues */
        !           215:          com_clr_flush();
        !           216:        };
        !           217: 
        !           218:        /* set pCmd -> command string; CmdLen = length of command string */
        !           219:        if (CmdType == MC_DIAL) {
        !           220:           CmdLen = make_dial_cmd(Cmd, sizeof(Cmd));
        !           221:           pCmd = Cmd;
        !           222:         }
        !           223:        else {
        !           224:           pCmd = Cmds[CmdType].pCmd;
        !           225:           CmdLen = Cmds[CmdType].CmdLen;
        !           226:         };
        !           227: 
        !           228:        /* write the command out to the modem */
        !           229:        if (((RetCode = DOSWRITE(FileHndl, pCmd, CmdLen, &WriteCnt)) != 0)
        !           230:            || (WriteCnt != CmdLen))
        !           231:          return(FALSE);
        !           232: 
        !           233:         /* wait for the echo & wait for the command to clear */
        !           234:         DOSSLEEP((long) 250); 
        !           235:         if (CmdType == MC_DIAL || CmdType == MC_RESET)
        !           236:           DOSSLEEP((long) 750); 
        !           237: 
        !           238:        /* read back the echo from the modem & check if it matches the input */
        !           239:        RetCode = 
        !           240:           DOSREAD(FileHndl, Buf, min(WriteCnt, sizeof(Buf)), &ReadCnt);
        !           241:        if ((RetCode != 0) || (ReadCnt != WriteCnt))
        !           242:          Result = FALSE;
        !           243:         else {
        !           244:           pDst = Buf;
        !           245:           while (--ReadCnt >= 0) {
        !           246:             if (*pDst++ != *pCmd++) {
        !           247:              printf("send_modem_cmd: error in echo of modem input\n");
        !           248:               Result = FALSE;
        !           249:               break;
        !           250:             }
        !           251:           } /* while (--ReadCnt >= 0) */
        !           252:         } 
        !           253: 
        !           254:        return(Result);
        !           255: }
        !           256: 
        !           257: 
        !           258: 
        !           259: 
        !           260: /***   make_dial_cmd - create a modem command for dialing 
        !           261:  *
        !           262:  *     builds the dial command string and returns its length in bytes
        !           263:  *
        !           264:  *     make_dial_cmd(pBuf, BufLen)
        !           265:  *
        !           266:  *     ENTRY
        !           267:  *             pBuf - ptr to buffer
        !           268:  *             BufLen - length of buffer in bytes
        !           269:  *
        !           270:  *     EXIT
        !           271:  *             pBuf -> dial command string
        !           272:  *             make_dial_cmd = length of dial command string in bytes 
        !           273:  *
        !           274:  *     WARNING
        !           275:  *
        !           276:  *     EFFECTS
        !           277:  *
        !           278:  ***/
        !           279: 
        !           280: make_dial_cmd(pBuf, BufLen)
        !           281: char   *pBuf;
        !           282: int    BufLen;
        !           283: {
        !           284:        char            *pSrc,
        !           285:                        *pDst,
        !           286:                        Ch,
        !           287:                        Cmd[80],        /* allocate a huge command buffer */
        !           288:                        *bin_to_dec();
        !           289:        int             Len;
        !           290:        structModemOptions sModemOptions;               /* modem options */
        !           291: 
        !           292:        get_modem_options(&sModemOptions);
        !           293:        pDst = Cmd;
        !           294:        *pDst++ = 'A';          /* get Modem's attention */
        !           295:        *pDst++ = 'T';
        !           296:        *pDst++ = 'S';          /* set R6 for wait for dial tone */
        !           297:        *pDst++ = '6';
        !           298:        *pDst++ = '=';
        !           299:        pDst = bin_to_dec(pDst, sModemOptions.iWaitTone);
        !           300:        *pDst++ = B_PAUSE;
        !           301:        *pDst++ = 'S';          /* set R7 for wait for carrier time */
        !           302:        *pDst++ = '7';
        !           303:        *pDst++ = '=';
        !           304:        pDst = bin_to_dec(pDst, sModemOptions.iWaitCarrier); 
        !           305:        *pDst++ = B_PAUSE;
        !           306:        *pDst++ = 'D';
        !           307:        *pDst++ = (sModemOptions.chDialType == PULSE) ? 'P' : 'T';
        !           308:        pSrc = sModemOptions.pPhoneNumber;
        !           309:        while (Ch = *pSrc++) 
        !           310:           if ((Ch >= '0' && Ch <= '9') || (Ch == ','))
        !           311:             *pDst++ = Ch;
        !           312:        *pDst++ = 0x0d;
        !           313:        *pDst = 0;
        !           314: 
        !           315:        /* copy the command string into caller's buffer */
        !           316:        pSrc = Cmd;
        !           317:        pDst = pBuf;
        !           318:        for (Len = 0; Len <= BufLen; ++Len)
        !           319:           if (*pSrc==0)
        !           320:             break;
        !           321:           else
        !           322:             *pDst++ = *pSrc++;
        !           323:        return(Len);
        !           324: }
        !           325: 
        !           326: 
        !           327: 
        !           328: 
        !           329: /***   bin_to_dec - convert a binary number to ASCII decimal 
        !           330:  *
        !           331:  *     bin_to_dec(pDst, i)
        !           332:  *
        !           333:  *     ENTRY
        !           334:  *             pDst -> buffer to place the ASCII decimal
        !           335:  *             i = integer to be converted to ASCII decimal
        !           336:  *
        !           337:  *     EXIT
        !           338:  *             ASCII decimal placed in the buffer pointed by pDst
        !           339:  *             bin_to_dec -> byte next to ASCII decimal in the buffer
        !           340:  *
        !           341:  *     WARNING
        !           342:  *
        !           343:  *     EFFECTS
        !           344:  *
        !           345:  ***/
        !           346: 
        !           347: char *bin_to_dec(pDst, i)
        !           348: char   *pDst;
        !           349: int    i;
        !           350: {
        !           351:        if (i > 10)
        !           352:           pDst = bin_to_dec (pDst, i/10);
        !           353:        *pDst++ = '0' + (i % 10);
        !           354:        return(pDst);
        !           355: }
        !           356: 
        !           357: 
        !           358: 
        !           359: 
        !           360: /***   get_modem_reply - get reply from modem
        !           361:  *
        !           362:  *     get_modem_reply()
        !           363:  *
        !           364:  *     ENTRY
        !           365:  *
        !           366:  *     EXIT
        !           367:  *             get_modem_reply = MS_CONNECT MS_CONNECT1200 MS_NOCARRIER 
        !           368:  *                               MS_NODIALTONE MS_NOREPLY MS_ERROR MS_BUSY
        !           369:  *
        !           370:  *     WARNING
        !           371:  *
        !           372:  *     EFFECTS
        !           373:  *
        !           374:  ***/
        !           375: 
        !           376: int get_modem_reply()
        !           377: {
        !           378:        char            Ch;
        !           379:        int             Cnt,
        !           380:                        Result,
        !           381:                        RetCode;
        !           382: 
        !           383:        do              /* skip CR, LF and get resultcode */
        !           384:          if ((RetCode = DOSREAD(FileHndl, &Ch, 1, &Cnt)) != 0) 
        !           385:             Error(ERR_DOSREAD, RetCode);
        !           386:         while ((Cnt == 1) && ((Ch == 0x0d) || (Ch == 0x0a)));
        !           387: 
        !           388:        switch(Cnt) {
        !           389:           case 0:  Result = MS_NOREPLY;
        !           390:                   break;
        !           391:           case 1:  if ((Ch >= '0') && (Ch <= '7'))
        !           392:                      Result = Ch - '0';
        !           393:                    else
        !           394:                      Result = MS_ERROR;
        !           395:                    break;
        !           396:           default: Result = MS_ERROR;
        !           397:                    break;
        !           398:         }
        !           399: 
        !           400:        return(Result);
        !           401: }
        !           402: 
        !           403: 
        !           404: 
        !           405: 
        !           406: /***   discon_modem - disconnect the modem 
        !           407:  *
        !           408:  *     discon_modem()
        !           409:  *
        !           410:  *     ENTRY
        !           411:  *
        !           412:  *     EXIT
        !           413:  *             modem disconnected
        !           414:  *
        !           415:  *     WARNING
        !           416:  *
        !           417:  *     EFFECTS
        !           418:  *
        !           419:  ***/
        !           420: 
        !           421: void discon_modem()
        !           422: {
        !           423:        /* Wait for the last command to clear, then be quiet for 1.5 seconds */
        !           424:        DOSSLEEP((long) 1000);          /* wait 1. second */
        !           425:        flush_ques(FLUSHOUTPUT);        /* flush the transmit que */
        !           426:        DOSSLEEP((long) 1500);          /* wait 1.5 seconds */
        !           427: 
        !           428:        send_modem_cmd(MC_ESC);         /* put modem in command mode */
        !           429:        DOSSLEEP((long) 2000);          /* wait 2 seconds */
        !           430: 
        !           431:        send_modem_cmd(MC_ONHOOK);      /* place phone back on hook */
        !           432:        DOSSLEEP((long) 200);           /* wait for command to clear*/
        !           433: }
        !           434: 
        !           435: 
        !           436: 
        !           437: 
        !           438: /***   com_clr_flush - clear COM error and flush transmit/receive queues
        !           439:  *
        !           440:  *     com_clr_flush()
        !           441:  *
        !           442:  *     ENTRY
        !           443:  *
        !           444:  *     EXIT
        !           445:  *             com error cleared
        !           446:  *             transmit and receive queues of com port flushed out
        !           447:  *
        !           448:  *     WARNING
        !           449:  *
        !           450:  *     EFFECTS
        !           451:  *
        !           452:  ***/
        !           453: 
        !           454: void com_clr_flush()
        !           455: {
        !           456:        /* retrieve and clear the com error information */
        !           457:        clr_com_error();
        !           458:        /* flush transmit and receive queues */
        !           459:        flush_ques(FLUSHINPUT);
        !           460:        flush_ques(FLUSHOUTPUT);
        !           461: }
        !           462: 
        !           463: 
        !           464: 
        !           465: 
        !           466: /***   flush_ques - flush COM transmit/receive queue 
        !           467:  *
        !           468:  *     flush_ques(FuncId)
        !           469:  *
        !           470:  *     ENTRY
        !           471:  *             FuncId - set to one of: FLUSHINPUT FLUSHOUTPUT
        !           472:  *
        !           473:  *     EXIT
        !           474:  *             transmit or receive queue of com port flushed
        !           475:  *
        !           476:  *     WARNING
        !           477:  *
        !           478:  *     EFFECTS
        !           479:  *
        !           480:  ***/
        !           481: 
        !           482: void flush_ques(FuncId)
        !           483: int    FuncId;                 
        !           484: {      
        !           485:        char    FlushData,      /* data returned by flush IOCTL function */
        !           486:                FlushParm = FLUSH_CMDINFO; /* param to flush IOCTL function */
        !           487:        int     RetCode;
        !           488:        
        !           489:        /* flush transmit/receive queue */
        !           490:        if ((RetCode = DOSDEVIOCTL(&FlushData, &FlushParm, 
        !           491:                                   FuncId, GENERIC, FileHndl)) != 0) 
        !           492:          Error(ERR_IOCTLFLUSHQUE, RetCode);
        !           493: }
        !           494: 
        !           495: 
        !           496: 
        !           497: 
        !           498: /***   clr_com_error - retrieve and clear COM error information
        !           499:  *
        !           500:  *     clr_com_error()
        !           501:  *
        !           502:  *     ENTRY
        !           503:  *
        !           504:  *     EXIT
        !           505:  *             com error cleared
        !           506:  *
        !           507:  *     WARNING
        !           508:  *
        !           509:  *     EFFECTS
        !           510:  *
        !           511:  ***/
        !           512: 
        !           513: void clr_com_error()
        !           514: 
        !           515: {
        !           516:        int     ComError,
        !           517:                RetCode;
        !           518: 
        !           519:        if ((RetCode = DOSDEVIOCTL((char *) &ComError, 0L, GETCOMERROR, 
        !           520:                                    SERIAL, FileHndl)) != 0)
        !           521:          Error(ERR_IOCTLGETCOMERROR, RetCode);
        !           522: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.