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

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

unix.superglobalmegacorp.com

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