|
|
1.1 ! root 1: #ifndef NODIAL ! 2: char *dialv = "Dial Command, 5A(028) 23 Dec 91"; ! 3: ! 4: /* C K U D I A -- Dialing program for connection to remote system */ ! 5: ! 6: /* ! 7: Original author: Herm Fischer (HFISCHER@USC-ECLB). ! 8: Contributed to Columbia University for inclusion in C-Kermit. ! 9: Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436. ! 10: Permission is granted to any individual or institution to use, copy, or ! 11: redistribute this software so long as it is not sold for profit, provided ! 12: this copyright notice is retained. ! 13: ! 14: Os9/68k and Microcom modem support by Bob Larson ([email protected]) ! 15: Additional code by many others over the years. ! 16: ! 17: ------ ! 18: ! 19: This module should work under all versions of Unix. It calls externally ! 20: defined system-depended functions for i/o, but depends upon the existence ! 21: of various modem control functions. ! 22: ! 23: This module, and the supporting routines in the ckutio.c module, assume ! 24: that the computer and modem properly utilize the following data communi- ! 25: cations signals (that means one should prepare the modem to use, not ! 26: circumvent, these signals): ! 27: ! 28: Data Terminal Ready (DTR): This signal is asserted by the computer ! 29: when Kermit is about to ask the modem to dial a call, and is ! 30: removed when Kermit wishes to have the modem hang up a call. ! 31: The signal is asserted both while Kermit is asking the modem ! 32: to dial a specific number, and after connection, while Kermit ! 33: is in a data exchange mode. ! 34: ! 35: Carrier Detect (CD): This signal must be asserted by the modem when ! 36: a carrier is detected from a remote modem on a communications ! 37: circuit. It must be removed by the modem when the circuit ! 38: disconnects or is hung up. (Carrier Detect is ignored while ! 39: Kermit is asking the modem to dial the call, because there is ! 40: no consistant usage of this signal during the dialing phase ! 41: among different modem manufacturers.) ! 42: */ ! 43: ! 44: /* ! 45: * Modifications: ! 46: * ! 47: * 21-Jul-85 Fixed failure returns hanging on no carrier signal ! 48: * Requires tthang change too (ckutio.c revision) ! 49: * -- Herm Fischer ! 50: * ! 51: * 28-Jun-85 Fixed bug with defaulting the modem-failure message ! 52: * in lbuf. ! 53: * -- Dan Schullman ! 54: * ! 55: * 27-Jun-85 Merged in code from Joe Orost at Berkeley for ! 56: * supporting the US Robotics modem, which included ! 57: * changing the single characters in MDMINF into ! 58: * multi-character strings and modifying waitfor. ! 59: * -- Dan Schullman ! 60: * ! 61: * 26-Jun-85 Allow interrupts to be used to abort dialing, ! 62: * and ring the bell when a connection is made. ! 63: * Reorganized some of the failure paths to use the ! 64: * same code, and now close the line on failures. ! 65: * Allow use of stored numbers with the DF100 and ! 66: * DF200 modems. Handlers now declared after the ! 67: * call to setjmp. ! 68: * -- Dan Schullman ! 69: * ! 70: * 24-May-85 DF03, DF100-series, DF200-series, and "unknown" modem ! 71: * support added. Also restructured the various data ! 72: * tables, fixed some bugs related to missing data and ! 73: * missing case labels, and modified the failure message ! 74: * to display the "reason" given by the modem. ! 75: * -- Dan Schullman ! 76: * 16-Mar-87 Support for the ATT7300 UNIX PC internal modem was ! 77: * added. ! 78: * -- Richard E. Hill ! 79: * ! 80: * 21-Feb-88 Os9/68k and microcom modem support. ! 81: * -- Bob Larson ! 82: * ! 83: * 14-Mar-88 Rewrite code for ATT7300 (here and in ckutio.c) ! 84: * Avoids dial(3c) with it's LCK files, hangs up line ! 85: * correctly, enables user interrupts and timeouts, ! 86: * turns on/off the system getty() login procedure. ! 87: * Correct Hayes command sequence at little. ! 88: * Procedures: attdial, atthang, ongetty, offgetty. ! 89: * Parts adapted from work of Richard E. Hill and ! 90: * Kevin O'Gorman. ! 91: * -- Joe R. Doupnik ! 92: * ! 93: * 13-Jan-89 Added IBM/Siemens/Rolm CBX dialing support. ! 94: * - F. da Cruz ! 95: * ! 96: * 29-Aug-89 Added support for AT&T 2212C, 2224B, 2224CEO, and ! 97: * 2296A switched-network modems in AT&T mode, and ! 98: * for the AT&T Digital Terminal Data Module (DTDM). ! 99: * -- Eric F. Jones ! 100: * ! 101: * 4-Jun-90 Added delay on "ANSWERED" for AT&T DTDM ! 102: * 7-Jun-90 Added support for AT&T ISN Network ! 103: * - John L. Chmielewski, AT&T ! 104: * ! 105: * March 1991 Support for Telebit modems, Kermit spoofing. ! 106: * Warren Tucker, Larry Jacobs, Frank da Cruz. ! 107: */ ! 108: ! 109: /* ! 110: * To add support for another modem, do the following: ! 111: * ! 112: * Define a modem number symbol (n_XXX) for it, keeping the list ! 113: * in alphabetical and numerical order, and renumbering the values ! 114: * as necessary. Make sure the n_XXX symbol is unique within 7 chars. ! 115: * ! 116: * Create a MDMINF structure for it, again keeping the list alphabetical ! 117: * for sanity's sake. ! 118: * ! 119: * Add the address of the MDMINF structure to the ptrtab array, again ! 120: * in alphabetical and numerical order. ! 121: * ! 122: * Add the "user visible" modem name and corresponding modem number to ! 123: * the mdmtab array, again in alphabetical order. ! 124: * ! 125: * Read through the code and add modem-specific sections as necessary. ! 126: */ ! 127: ! 128: /* ! 129: * The intent of the "unknown" modem is hopefully to allow KERMIT to support ! 130: * unknown modems by having the user type the entire autodial sequence ! 131: * (possibly including control characters, etc.) as the "phone number". ! 132: * The only reason that the CONNECT command cannot be used to do this is ! 133: * that a remote line cannot normally be opened unless carrier is present. ! 134: * ! 135: * The protocol and other characteristics of this modem are unknown, with ! 136: * some "reasonable" values being chosen for some of them. The only way to ! 137: * detect if a connection is made is to look for carrier present. ! 138: */ ! 139: #include "ckcdeb.h" ! 140: #ifndef MAC ! 141: #include <signal.h> ! 142: #endif /* MAC */ ! 143: #include "ckcasc.h" ! 144: #include "ckcker.h" ! 145: #include "ckucmd.h" ! 146: ! 147: #ifndef ZILOG ! 148: #include <setjmp.h> /* Longjumps */ ! 149: #else ! 150: #include <setret.h> ! 151: #endif /* ZILOG */ ! 152: ! 153: #ifdef MAC ! 154: #define signal msignal ! 155: #define SIGTYP long ! 156: #define alarm malarm ! 157: #define SIG_IGN 0 ! 158: #define SIGALRM 1 ! 159: #define SIGINT 2 ! 160: SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int); ! 161: #endif /* MAC */ ! 162: ! 163: extern int flow, local, mdmtyp, quiet, parity, seslog, network, dialhng, ! 164: dialdpy, mdmspd, dialtmo, dialksp, dialmnp; ! 165: extern char *dialini; ! 166: extern CHAR stchr; ! 167: extern long speed; ! 168: extern char ttname[], sesfil[]; ! 169: ! 170: /* ! 171: * Failure reasons for use with the 'longjmp' exit. ! 172: */ ! 173: #define F_time 1 /* timeout */ ! 174: #define F_int 2 /* interrupt */ ! 175: #define F_modem 3 /* modem-detected failure */ ! 176: #define F_minit 4 /* cannot initialize modem */ ! 177: ! 178: static int mymdmtyp; /* Local copy of modem type. */ ! 179: static int n1 = F_time; ! 180: ! 181: #define MDMINF struct mdminf ! 182: ! 183: MDMINF /* structure for modem-specific information */ ! 184: { ! 185: int dial_time; /* time modem allows for dialing (secs) */ ! 186: char *pause_chars; /* character(s) to tell modem to pause */ ! 187: int pause_time; /* time associated with pause chars (secs) */ ! 188: char *wake_str; /* string to wakeup modem & put in cmd mode */ ! 189: int wake_rate; /* delay between wake_str characters (msecs) */ ! 190: char *wake_prompt; /* string prompt after wake_str */ ! 191: char *dmode_str; /* string to put modem in dialing mode */ ! 192: char *dmode_prompt; /* string prompt for dialing mode */ ! 193: char *dial_str; /* dialing string, with "%s" for number */ ! 194: int dial_rate; /* delay between dialing characters (msecs) */ ! 195: }; ! 196: ! 197: /* ! 198: * Define symbolic modem numbers. ! 199: * ! 200: * The numbers MUST correspond to the ordering of entries ! 201: * within the ptrtab array, and start at one (1). ! 202: * ! 203: * It is assumed that there are relatively few of these ! 204: * values, and that the high(er) bytes of the value may ! 205: * be used for modem-specific mode information. ! 206: * ! 207: * REMEMBER that only the first eight characters of these ! 208: * names are guaranteed to be unique. ! 209: */ ! 210: ! 211: #define n_ATTDTDM 1 ! 212: #define n_ATTISN 2 ! 213: #define n_ATTMODEM 3 ! 214: #define n_CERMETEK 4 ! 215: #define n_DF03 5 ! 216: #define n_DF100 6 ! 217: #define n_DF200 7 ! 218: #define n_GDC 8 ! 219: #define n_HAYES 9 ! 220: #define n_PENRIL 10 ! 221: #define n_RACAL 11 ! 222: #define n_UNKNOWN 12 ! 223: #define n_USROBOT 13 ! 224: #define n_VENTEL 14 ! 225: #define n_CONCORD 15 ! 226: #define n_ATTUPC 16 /* aka Unix PC and ATT7300 */ ! 227: #define n_ROLM 17 /* Rolm CBX DCM */ ! 228: #define n_MICROCOM 18 ! 229: #define n_HST 19 ! 230: #define n_TELEBIT 20 /* Telebit Trailblazer */ ! 231: #define MAX_MDM 20 ! 232: /* ! 233: * Declare modem "variant" numbers for any of the above for which it is ! 234: * necessary to note various operational modes, using the second byte ! 235: * of a modem number. ! 236: * ! 237: * It is assumed that such modem modes share the same modem-specific ! 238: * information (see MDMINF structure) but may differ in some of the actions ! 239: * that are performed. ! 240: */ ! 241: ! 242: /* Warning - this is starting to get kind of hokey... */ ! 243: ! 244: #define DIAL_NV 256 ! 245: #define DIAL_PEP 512 ! 246: #define DIAL_V32 1024 ! 247: #define DIAL_V42 2048 ! 248: #define DIAL_SLO 4096 ! 249: ! 250: #define n_HAYESNV ( n_HAYES | DIAL_NV ) ! 251: #define n_TBPEP ( n_TELEBIT | DIAL_PEP ) ! 252: #define n_TB3 ( n_TELEBIT | DIAL_V32 ) ! 253: #define n_TBNV ( n_TELEBIT | DIAL_NV ) ! 254: #define n_TBPNV ( n_TELEBIT | DIAL_NV | DIAL_PEP ) ! 255: #define n_TB3NV ( n_TELEBIT | DIAL_NV | DIAL_V32 ) ! 256: #define n_TB4 ( n_TELEBIT | DIAL_V42 ) ! 257: #define n_TBS ( n_TELEBIT | DIAL_SLO ) ! 258: #define n_TB4NV ( n_TELEBIT | DIAL_NV | DIAL_V42 ) ! 259: #define n_TBSNV ( n_TELEBIT | DIAL_NV | DIAL_SLO ) ! 260: ! 261: /* ! 262: * Declare structures containing modem-specific information. ! 263: * ! 264: * REMEMBER that only the first SEVEN characters of these ! 265: * names are guaranteed to be unique. ! 266: */ ! 267: ! 268: static ! 269: MDMINF ATTISN = /* AT&T ISN Network */ ! 270: { ! 271: 30, /* Dial time */ ! 272: "", /* Pause characters */ ! 273: 0, /* Pause time */ ! 274: "\015\015\015\015", /* Wake string */ ! 275: 900, /* Wake rate */ ! 276: "DIAL", /* Wake prompt */ ! 277: "", /* dmode_str */ ! 278: "", /* dmode_prompt */ ! 279: "%s\015", /* dial_str */ ! 280: 0 /* dial_rate */ ! 281: }; ! 282: ! 283: static ! 284: MDMINF ATTMODEM = /* information for AT&T switched-network modems */ ! 285: /* "Number" following "dial" can include: p's and ! 286: * t's to indicate pulse or tone (default) dialing, ! 287: * + for wait for dial tone, , for pause, r for ! 288: * last number dialed, and, except for 2224B, some ! 289: * comma-delimited options like o12=y, before number. ! 290: ! 291: * "Important" options for the modems: ! 292: * ! 293: * All: Except for 2224B, enable option 12 for "transparent ! 294: * data," o12=y. If a computer port used for both ! 295: * incoming and outgoing calls is connected to the ! 296: * modem, disable "enter interactive mode on carriage ! 297: * return," EICR. The Kermit "dial" command can ! 298: * function with EIA leads standard, EIAS. ! 299: * ! 300: * 2212C: Internal hardware switches at their default ! 301: * positions (four rockers down away from numbers) ! 302: * unless EICR is not wanted (rocker down at the 4). ! 303: * For EIAS, rocker down at the 1. ! 304: * ! 305: * 2224B: Front-panel switch position 1 must be up (at the 1, ! 306: * closed). Disable EICR with position 2 down. ! 307: * For EIAS, position 4 down. ! 308: * All switches on the back panel down. ! 309: * ! 310: * 2224CEO: All front-panel switches down except either 5 or 6. ! 311: * Enable interactive flow control with o16=y. ! 312: * Select normal asynchronous mode with o34=0 (zero). ! 313: * Disable EICR with position 3 up. For EIAS, 1 up. ! 314: * Reset the modem after changing switches. ! 315: * ! 316: * 2296A: If option 00 (zeros) is present, use o00=0. ! 317: * Enable interactive flow control with o16=y. ! 318: * Select normal asynchronous mode with o34=0 (zero). ! 319: * (available in Microcom Networking version, but ! 320: * not necessarily other models of the 2296A). ! 321: * Enable modem-port flow control (if available) with ! 322: * o42=y. Enable asynchronous operation with o50=y. ! 323: * Disable EICR with o69=n. For EIAS, o66=n, using ! 324: * front panel. ! 325: */ ! 326: { ! 327: 20, /* dial_time */ ! 328: ",", /* pause_chars */ ! 329: 2, /* pause_time */ ! 330: "+", /* wake_str */ ! 331: 0, /* wake_rate */ ! 332: "", /* wake_prompt */ ! 333: "", /* dmode_str */ ! 334: "", /* dmode_prompt */ ! 335: "at%s\015", /* dial_str */ ! 336: 0 /* dial_rate */ ! 337: }; ! 338: ! 339: static ! 340: MDMINF ATTDTDM = /* information for AT&T Digital Terminal Data Module ! 341: * For dialing: KYBD switch down, others usually up. */ ! 342: { ! 343: 20, /* dial_time */ ! 344: "", /* pause_chars */ ! 345: 0, /* pause_time */ ! 346: "", /* wake_str */ ! 347: 0, /* wake_rate */ ! 348: "", /* wake_prompt */ ! 349: "", /* dmode_str */ ! 350: "", /* dmode_prompt */ ! 351: "%s\015", /* dial_str */ /* not used */ ! 352: 0 /* dial_rate */ ! 353: }; ! 354: ! 355: static ! 356: MDMINF CERMETEK = /* information for "Cermetek Info-Mate 212 A" modem */ ! 357: { ! 358: 20, /* dial_time */ ! 359: "BbPpTt", /* pause_chars */ ! 360: 0, /* pause_time */ /** unknown -- DS **/ ! 361: " XY\016R\015", /* wake_str */ ! 362: 200, /* wake_rate */ ! 363: "", /* wake_prompt */ ! 364: "", /* dmode_str */ ! 365: NULL, /* dmode_prompt */ ! 366: "\016D '%s'\015", /* dial_str */ ! 367: 200 /* dial_rate */ ! 368: }; ! 369: ! 370: static ! 371: MDMINF DF03 = /* information for "DEC DF03-AC" modem */ ! 372: { ! 373: 27, /* dial_time */ ! 374: "=", /* pause_chars */ /* wait for second dial tone */ ! 375: 15, /* pause_time */ ! 376: "\001\002", /* wake_str */ ! 377: 0, /* wake_rate */ ! 378: "", /* wake_prompt */ ! 379: "", /* dmode_str */ ! 380: NULL, /* dmode_prompt */ ! 381: "%s", /* dial_str */ ! 382: 0 /* dial_rate */ ! 383: }; ! 384: ! 385: static ! 386: MDMINF DF100 = /* information for "DEC DF100-series" modem */ ! 387: /* ! 388: * The telephone "number" can include "P"s and/or "T"s ! 389: * within it to indicate that subsequent digits are ! 390: * to be dialed using pulse or tone dialing. The ! 391: * modem defaults to pulse dialing. You may modify ! 392: * the dial string below to explicitly default all ! 393: * dialing to pulse or tone, but doing so prevents ! 394: * the use of phone numbers that you may have stored ! 395: * in the modem's memory. ! 396: */ ! 397: { ! 398: 30, /* dial_time */ ! 399: "=", /* pause_chars */ /* wait for second dial tone */ ! 400: 15, /* pause_time */ ! 401: "\001", /* wake_str */ ! 402: 0, /* wake_rate */ ! 403: "", /* wake_prompt */ ! 404: "", /* dmode_str */ ! 405: NULL, /* dmode_prompt */ ! 406: "%s#", /* dial_str */ ! 407: 0 /* dial_rate */ ! 408: }; ! 409: ! 410: static ! 411: MDMINF DF200 = /* information for "DEC DF200-series" modem */ ! 412: /* ! 413: * The telephone "number" can include "P"s and/or "T"s ! 414: * within it to indicate that subsequent digits are ! 415: * to be dialed using pulse or tone dialing. The ! 416: * modem defaults to pulse dialing. You may modify ! 417: * the dial string below to explicitly default all ! 418: * dialing to pulse or tone, but doing so prevents ! 419: * the use of phone numbers that you may have stored ! 420: * in the modem's memory. ! 421: */ ! 422: { ! 423: 30, /* dial_time */ ! 424: "=W", /* pause_chars */ /* =: second tone; W: 5 secs */ ! 425: 15, /* pause_time */ /* worst case */ ! 426: "\002", /* wake_str */ /* allow stored number usage */ ! 427: 0, /* wake_rate */ ! 428: "", /* wake_prompt */ ! 429: "", /* dmode_str */ ! 430: NULL, /* dmode_prompt */ ! 431: "%s!", /* dial_str */ ! 432: 0 /* dial_rate */ ! 433: }; ! 434: ! 435: static ! 436: MDMINF GDC = /* information for "GeneralDataComm 212A/ED" modem */ ! 437: { ! 438: 32, /* dial_time */ ! 439: "%", /* pause_chars */ ! 440: 3, /* pause_time */ ! 441: "\015\015", /* wake_str */ ! 442: 500, /* wake_rate */ ! 443: "$", /* wake_prompt */ ! 444: "D\015", /* dmode_str */ ! 445: ":", /* dmode_prompt */ ! 446: "T%s\015", /* dial_str */ ! 447: 0 /* dial_rate */ ! 448: }; ! 449: ! 450: static ! 451: MDMINF HAYES = /* information for "Hayes" modem */ ! 452: { ! 453: 35, /* dial_time */ ! 454: ",", /* pause_chars */ ! 455: 2, /* pause_time */ ! 456: "AT\015", /* wake_str */ ! 457: /* ! 458: Note: Other wake_str's are possible here. For Hayes 2400 that is to ! 459: be used for both in and out calls, AT&F&D3 might be best. For out calls ! 460: only, maybe AT&F&D2. See Hayes 2400 manual. ! 461: */ ! 462: 0, /* wake_rate */ ! 463: "", /* wake_prompt */ ! 464: "", /* dmode_str */ ! 465: "", /* dmode_prompt */ ! 466: "ATD%s\015", /* dial_str, note: user can supply D or T */ ! 467: 0 /* dial_rate */ ! 468: }; ! 469: ! 470: static ! 471: MDMINF PENRIL = /* information for "Penril" modem */ ! 472: { ! 473: 50, /* dial_time */ ! 474: "", /* pause_chars */ /** unknown -- HF **/ ! 475: 0, /* pause_time */ ! 476: "\015\015", /* wake_str */ ! 477: 300, /* wake_rate */ ! 478: ">", /* wake_prompt */ ! 479: "k\015", /* dmode_str */ ! 480: ":", /* dmode_prompt */ ! 481: "%s\015", /* dial_str */ ! 482: 0 /* dial_rate */ ! 483: }; ! 484: ! 485: static ! 486: MDMINF RACAL = /* information for "Racal Vadic" modem */ ! 487: { ! 488: 35, /* dial_time */ ! 489: "Kk", /* pause_chars */ ! 490: 5, /* pause_time */ ! 491: "\005\015", /* wake_str */ ! 492: 50, /* wake_rate */ ! 493: "*", /* wake_prompt */ ! 494: "D\015", /* dmode_str */ ! 495: "?", /* dmode_prompt */ ! 496: "%s\015", /* dial_str */ ! 497: 0 /* dial_rate */ ! 498: }; ! 499: ! 500: static ! 501: MDMINF UNKNOWN = /* information for "Unknown" modem */ ! 502: { ! 503: 30, /* dial_time */ ! 504: "", /* pause_chars */ ! 505: 0, /* pause_time */ ! 506: "", /* wake_str */ ! 507: 0, /* wake_rate */ ! 508: "", /* wake_prompt */ ! 509: "", /* dmode_str */ ! 510: NULL, /* dmode_prompt */ ! 511: "%s\015", /* dial_str */ ! 512: 0 /* dial_rate */ ! 513: }; ! 514: ! 515: static ! 516: MDMINF USROBOT = /* information for "US Robotics 212A" modem */ ! 517: { ! 518: 30, /* dial_time */ ! 519: ",", /* pause_chars */ ! 520: 2, /* pause_time */ ! 521: "ATS2=01\015", /* wake_str */ ! 522: 0, /* wake_rate */ ! 523: "OK\015", /* wake_prompt */ ! 524: "", /* dmode_str */ ! 525: NULL, /* dmode_prompt */ ! 526: "ATTD%s\015", /* dial_str */ ! 527: 0 /* dial_rate */ ! 528: }; ! 529: #ifdef COMMENT ! 530: /* Reportedly this does not work at all. */ ! 531: static ! 532: MDMINF VENTEL = /* information for "Ventel" modem */ ! 533: { ! 534: 20, /* dial_time */ ! 535: "%", /* pause_chars */ ! 536: 5, /* pause_time */ ! 537: "\015\015\015", /* wake_str */ ! 538: 300, /* wake_rate */ ! 539: "$", /* wake_prompt */ ! 540: "", /* dmode_str */ ! 541: NULL, /* dmode_prompt */ ! 542: "<K\015%s\015>", /* dial_str (was "<K%s\r>") */ ! 543: 0 /* dial_rate */ ! 544: }; ! 545: #else ! 546: /* and this does. */ ! 547: static ! 548: MDMINF VENTEL = /* information for "Ventel" modem */ ! 549: { ! 550: 20, /* dial_time */ ! 551: "%", /* pause_chars */ ! 552: 5, /* pause_time */ ! 553: "\015\015\015", /* wake_str */ ! 554: 300, /* wake_rate */ ! 555: "$", /* wake_prompt */ ! 556: "K\015", /* dmode_str (was "") */ ! 557: "Number to call: ", /* dmode_prompt (was NULL) */ ! 558: "%s\015", /* dial_str (was "<K%s\r>") */ ! 559: 0 /* dial_rate */ ! 560: }; ! 561: #endif /* COMMENT */ ! 562: ! 563: static ! 564: MDMINF CONCORD = /* Info for Condor CDS 220 2400b modem */ ! 565: { ! 566: 35, /* dial_time */ ! 567: ",", /* pause_chars */ ! 568: 2, /* pause_time */ ! 569: "\015\015", /* wake_str */ ! 570: 20, /* wake_rate */ ! 571: "CDS >", /* wake_prompt */ ! 572: "", /* dmode_str */ ! 573: NULL, /* dmode_prompt */ ! 574: "<D M%s\015>", /* dial_str */ ! 575: 0 /* dial_rate */ ! 576: }; ! 577: ! 578: static ! 579: MDMINF ATTUPC = /* dummy information for "ATT7300/Unix PC" internal modem */ ! 580: { ! 581: 30, /* dial_time */ ! 582: "", /* pause_chars */ ! 583: 0, /* pause_time */ ! 584: "", /* wake_str */ ! 585: 0, /* wake_rate */ ! 586: "", /* wake_prompt */ ! 587: "", /* dmode_str */ ! 588: NULL, /* dmode_prompt */ ! 589: "%s\015", /* dial_str */ ! 590: 0 /* dial_rate */ ! 591: }; ! 592: ! 593: static ! 594: MDMINF ROLM = /* IBM / Siemens / Rolm 8000, 9000, 9751 CBX */ ! 595: { ! 596: 60, /* dial_time */ ! 597: "", /* pause_chars */ ! 598: 0, /* pause_time */ ! 599: "\015\015", /* wake_str */ ! 600: 5, /* wake_rate */ ! 601: "MODIFY?", /* wake_prompt */ ! 602: "", /* dmode_str */ ! 603: "", /* dmode_prompt */ ! 604: "CALL %s\015", /* dial_str */ ! 605: 0 /* dial_rate */ ! 606: }; ! 607: ! 608: static ! 609: MDMINF MICROCOM = /* information for "Microcom" modems in native mode */ ! 610: /* (long answer only) */ ! 611: { ! 612: 35, /* dial_time */ ! 613: ",!@", /* pause_chars (! and @ aren't pure pauses) */ ! 614: 3, /* pause_time */ ! 615: "\015", /* wake_str */ ! 616: 100, /* wake_rate */ ! 617: "!", /* wake_prompt */ ! 618: "", /* dmode_str */ ! 619: NULL, /* dmode_prompt */ ! 620: "d%s\015", /* dial_str */ ! 621: 0 /* dial_rate */ ! 622: }; ! 623: ! 624: static ! 625: MDMINF HST = /* information for Courier HST modem */ ! 626: { ! 627: 35, /* dial_time */ ! 628: ",", /* pause_chars */ ! 629: 2, /* pause_time */ ! 630: "ATE1Q0S2=43X7&B1&M4\015", /* wake_str */ ! 631: 0, /* wake_rate */ ! 632: "OK\015", /* wake_prompt */ ! 633: "", /* dmode_str */ ! 634: "", /* dmode_prompt */ ! 635: "ATD%s\015", /* dial_str */ ! 636: 0 /* dial_rate */ ! 637: }; ! 638: ! 639: static ! 640: MDMINF TELEBIT = /* information for Telebits */ ! 641: { ! 642: 60, /* dial_time */ ! 643: ",", /* pause_chars */ ! 644: 2, /* pause_time */ ! 645: "AAAAATF1M1Q4X3S2=43\015", /* wake_str */ ! 646: 10, /* wake_rate */ ! 647: "OK\015", /* wake_prompt */ ! 648: "", /* dmode_str */ ! 649: "", /* dmode_prompt */ ! 650: "ATD%s\015", /* dial_str */ ! 651: 80 /* dial_rate */ ! 652: }; ! 653: ! 654: /* ! 655: * Declare table for converting modem numbers to information pointers. ! 656: * ! 657: * The entries MUST be in ascending order by modem number, without any ! 658: * "gaps" in the numbers, and starting from one (1). ! 659: * ! 660: * This table should NOT include entries for the "variant" modem numbers, ! 661: * since it is assumed that they share the same information as the normal ! 662: * value. ! 663: */ ! 664: static ! 665: MDMINF *ptrtab[] = ! 666: { ! 667: &ATTDTDM, ! 668: &ATTISN, ! 669: &ATTMODEM, ! 670: &CERMETEK, ! 671: &DF03, ! 672: &DF100, ! 673: &DF200, ! 674: &GDC, ! 675: &HAYES, ! 676: &PENRIL, ! 677: &RACAL, ! 678: &UNKNOWN, ! 679: &USROBOT, ! 680: &VENTEL, ! 681: &CONCORD, ! 682: &ATTUPC, /* ATT7300 internal modem, jrd*/ ! 683: &ROLM, /* Rolm CBX, fdc */ ! 684: &MICROCOM, ! 685: &HST, ! 686: &TELEBIT ! 687: }; ! 688: ! 689: /* ! 690: * Declare modem names and associated numbers for command parsing, ! 691: * and also for doing number-to-name translation. ! 692: * ! 693: * The entries MUST be in alphabetical order by modem name. ! 694: */ ! 695: struct keytab mdmtab[] = ! 696: { ! 697: "attdtdm", n_ATTDTDM, 0, ! 698: "attisn", n_ATTISN, 0, ! 699: "attmodem", n_ATTMODEM, 0, ! 700: "att7300", n_ATTUPC, 0, ! 701: "cermetek", n_CERMETEK, 0, ! 702: "concord", n_CONCORD, 0, ! 703: "df03-ac", n_DF03, 0, ! 704: "df100-series", n_DF100, 0, ! 705: "df200-series", n_DF200, 0, ! 706: "direct", 0, 0, ! 707: "gendatacomm", n_GDC, 0, ! 708: "hayes", n_HAYES, 0, ! 709: "hst-courier", n_HST, 0, ! 710: "microcom", n_MICROCOM, 0, ! 711: "none", 0, 0, ! 712: "penril", n_PENRIL, 0, ! 713: "pep-telebit", n_TBPEP, 0, ! 714: "racalvadic", n_RACAL, 0, ! 715: "rolm", n_ROLM, 0, ! 716: "slow-telebit", n_TBS, 0, ! 717: "telebit", n_TELEBIT, 0, ! 718: "unknown", n_UNKNOWN, 0, ! 719: "usrobotics-212a", n_USROBOT, 0, ! 720: "v32-telebit", n_TB3, 0, ! 721: "v42-telebit", n_TB4, 0, ! 722: "ventel", n_VENTEL, 0 ! 723: }; ! 724: ! 725: int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)); /* number of modems */ ! 726: ! 727: _PROTOTYP (int dialhup, (void) ); ! 728: _PROTOTYP (int getok, (int) ); ! 729: _PROTOTYP (char * getdws, (int) ); ! 730: _PROTOTYP (static VOID ttslow, (char *s, int millisec) ); ! 731: _PROTOTYP (VOID xcpy, (char *to, char *from, unsigned len) ); ! 732: _PROTOTYP (static VOID waitfor, (char *s) ); ! 733: _PROTOTYP (static VOID dialoc, (char c) ); ! 734: _PROTOTYP (static int didweget, (char *s, char *r) ); ! 735: _PROTOTYP (static VOID spdchg, (long s) ); ! 736: ! 737: #define DIALING 4 /* for ttpkt parameter */ ! 738: #define CONNECT 5 ! 739: ! 740: #define CONNECTED 1 /* for completion status */ ! 741: #define FAILED 2 ! 742: ! 743: static ! 744: char *F_reason[5] = { /* failure reasons for message */ ! 745: "Unknown", "Timeout", "Interrupt", "Modem", "Initialize" }; ! 746: ! 747: static int tries = 0; ! 748: static int mdmecho = 0; /* assume modem does not echo */ ! 749: static int augmdmtyp; /* "augmented" modem type, to handle modem modes */ ! 750: ! 751: static char *p; /* For command strings & messages */ ! 752: ! 753: #define LBUFL 100 ! 754: #ifdef DYNAMIC ! 755: static char *lbuf; ! 756: #else ! 757: static char lbuf[LBUFL]; ! 758: #endif /* DYNAMIC */ ! 759: ! 760: static jmp_buf sjbuf; ! 761: ! 762: static SIGTYP (*savalrm)(); /* for saving alarm handler */ ! 763: static SIGTYP (*savint)(); /* for saving interrupt handler */ ! 764: ! 765: VOID ! 766: xcpy(to,from,len) /* Copy the given number of bytes */ ! 767: register char *to, *from; ! 768: register unsigned len; { ! 769: while (len--) *to++ = *from++; ! 770: } ! 771: ! 772: SIGTYP ! 773: dialtime(foo) int foo; { /* timer interrupt handler */ ! 774: n1 = F_time; ! 775: longjmp( sjbuf, F_time ); ! 776: } ! 777: ! 778: SIGTYP ! 779: dialint(foo) int foo; { /* user-interrupt handler */ ! 780: n1 = F_int; ! 781: longjmp( sjbuf, F_int ); ! 782: } ! 783: ! 784: static VOID ! 785: ttslow(s,millisec) char *s; int millisec; { /* output s-l-o-w-l-y */ ! 786: for (; *s; s++) { ! 787: ttoc(*s); ! 788: msleep(millisec); ! 789: } ! 790: } ! 791: ! 792: /* ! 793: * Wait for a string of characters. ! 794: * ! 795: * The characters are waited for individually, and other characters may ! 796: * be received "in between". This merely guarantees that the characters ! 797: * ARE received, and in the order specified. ! 798: */ ! 799: static VOID ! 800: waitfor(s) char *s; { ! 801: CHAR c, x; ! 802: while ( c = *s++ ) { /* while more characters remain... */ ! 803: do { /* wait for the character */ ! 804: x = ttinc(0) & 0177; ! 805: debug(F000,"dial waitfor got","",x); ! 806: if (dialdpy) { ! 807: if (x != LF) conoc(x); ! 808: if (x == CR) conoc(LF); ! 809: } ! 810: } while ( x != c); ! 811: } ! 812: } ! 813: ! 814: static int ! 815: didweget(s,r) char *s, *r; { /* Looks in string s for response r */ ! 816: int lr = (int)strlen(r); /* 0 means not found, 1 means found it */ ! 817: int i; ! 818: debug(F110,"didweget",r,0); ! 819: debug(F110," in",s,0); ! 820: for (i = (int)strlen(s)-lr; i >= 0; i--) ! 821: if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 ); ! 822: return( 0 ); ! 823: } ! 824: ! 825: ! 826: /* R E S E T -- Reset alarms, etc. on exit. */ ! 827: ! 828: static VOID ! 829: reset() { ! 830: alarm(0); ! 831: signal(SIGALRM,savalrm); /* restore alarm handler */ ! 832: signal(SIGINT,savint); /* restore interrupt handler */ ! 833: } ! 834: ! 835: /* ! 836: Call this routine when the modem reports that it has connected at a certain ! 837: speed, giving that speed as the argument. If the connection speed is not ! 838: the same as Kermit's current communication speed, AND the modem interface ! 839: speed is not locked (i.e. DIAL SPEED-MATCHING is not ON), then change the ! 840: device speed to the one given. ! 841: */ ! 842: static VOID ! 843: spdchg(s) long s; { ! 844: int s2; ! 845: if (!mdmspd) /* If modem interface speed locked, */ ! 846: return; /* don't do this. */ ! 847: if (speed != s) { /* Speeds differ? */ ! 848: s2 = s / 10L; /* Convert to cps expressed as int */ ! 849: if (ttsspd(s2) < 0) { /* Change speed. */ ! 850: printf(" Warning: speed change to %ld failed.\r\n",s); ! 851: } else { ! 852: printf(" Speed changed to %ld.\r\n",s); ! 853: speed = s; /* Update global speed variable */ ! 854: } ! 855: } ! 856: } ! 857: ! 858: /* ! 859: Display all characters received from modem dialer through this routine, ! 860: for consistent handling of carriage returns and linefeeds. ! 861: */ ! 862: ! 863: static VOID ! 864: #ifdef CK_ANSIC ! 865: dialoc(char c) ! 866: #else ! 867: dialoc(c) char c; ! 868: #endif /* CK_ANSIC */ ! 869: { /* dialoc */ /* Dial Output Character */ ! 870: if (dialdpy) { ! 871: if (c != LF) conoc(c); /* Don't echo LF */ ! 872: if (c == CR) conoc(LF); /* Echo CR as CRLF */ ! 873: } ! 874: } ! 875: ! 876: ! 877: /* C K D I A L -- Dial up the remote system */ ! 878: ! 879: /* Returns 1 if call completed, 0 otherwise */ ! 880: ! 881: int ! 882: ckdial(telnbr) char *telnbr; { ! 883: ! 884: char c, c2; ! 885: int waitct, status = 0; ! 886: char errmsg[50], *erp; ! 887: MDMINF *pmdminf; /* pointer to modem-specific info */ ! 888: int x, y, m, n; ! 889: char *s, *pc, *ws; ! 890: ! 891: long conspd; ! 892: char *cptr; ! 893: ! 894: mymdmtyp = mdmtyp; /* Make local copy of modem type */ ! 895: ! 896: if (network) { ! 897: printf("Sorry, 'dial' not available on network connection\n"); ! 898: return(0); ! 899: } ! 900: if (mymdmtyp < 1) { ! 901: printf("Sorry, you must 'set modem' first\n"); ! 902: return(0); ! 903: } ! 904: if (!local) { ! 905: printf("Sorry, you must 'set line' first\n"); ! 906: return(0); ! 907: } ! 908: if (speed < 0L) { ! 909: printf("Sorry, you must 'set speed' first\n"); ! 910: return(0); ! 911: } ! 912: debug(F110,"dial string",telnbr,0); ! 913: ! 914: /* Carrier no-wait can be invalidated by ckutio fun and games, jrd */ ! 915: if (ttopen(ttname,&local,mymdmtyp,0) < 0) { /* Open, no carrier wait */ ! 916: erp = errmsg; ! 917: sprintf(erp,"Sorry, can't open %s",ttname); ! 918: perror(errmsg); ! 919: return(0); ! 920: } ! 921: pmdminf = ptrtab[(mymdmtyp & 0xff) -1 ]; /* set pointer to modem info */ ! 922: augmdmtyp = mymdmtyp; /* initialize "augmented" modem type */ ! 923: mymdmtyp &= 0xff; /* major modem type */ ! 924: ! 925: /* interdigit waits for tone dial */ ! 926: ! 927: if (dialtmo < 1) { /* Automatic computation. */ ! 928: waitct = 1 * (int)strlen(telnbr) ; /* Compute worst case dial time */ ! 929: waitct += pmdminf->dial_time; /* dialtone + completion wait times */ ! 930: for (s = telnbr; *s; s++) { /* add in pause characters time */ ! 931: for (p=pmdminf->pause_chars; *p; p++) ! 932: if (*s == *p) { ! 933: waitct += pmdminf->pause_time; ! 934: break; ! 935: } ! 936: } ! 937: if (augmdmtyp == n_TBPEP || augmdmtyp == n_TBPNV) { ! 938: waitct += 30; /* Longer connect wait for PEP call */ ! 939: } ! 940: } else { /* User-specified timeout */ ! 941: waitct = dialtmo; ! 942: } ! 943: for (m = 0; m < nmdm; m++) { /* Look up modem type. */ ! 944: if (mdmtab[m].kwval == mymdmtyp) { ! 945: break; ! 946: } ! 947: } ! 948: printf(" Dialing %s\n",telnbr); ! 949: printf(" Device=%s, modem=%s, speed=%ld\n", ! 950: ttname, ! 951: (m >= nmdm ? "unk" : mdmtab[m].kwd), ! 952: speed); ! 953: ! 954: printf(" The timeout for completing the call is %d seconds.\n",waitct); ! 955: printf( ! 956: #ifdef MAC ! 957: " Type Command-. to cancel the dialing.\n"); ! 958: #else ! 959: " Type your interrupt character (normally ^C) to cancel the dialing.\n"); ! 960: #endif /* MAC */ ! 961: debug(F111,"ckdial",ttname,(int) (speed / 10L)); ! 962: debug(F101,"ckdial timeout","",waitct); ! 963: ! 964: /* Hang up the modem (in case it wasn't "on hook") */ ! 965: /* But only if SET DIAL HANGUP ON... */ ! 966: ! 967: if (dialhup() < 0) { ! 968: if (dialhng) { ! 969: ttclos(0); ! 970: if (ttopen(ttname,&local,mymdmtyp,0) < 0) { ! 971: printf("Sorry, Can't hang up tty line\n"); ! 972: printf("Try 'set line %s' again\n",ttname); ! 973: return(0); ! 974: } ! 975: } ! 976: } ! 977: if (augmdmtyp == n_ROLM) sleep(1); ! 978: ! 979: /* Condition console terminal and communication line */ ! 980: ! 981: /* Place line into "clocal" dialing state */ ! 982: ! 983: if (ttpkt(speed,DIALING,parity) < 0) { ! 984: dialhup(); /* If ttpkt fails do all this... */ ! 985: ttclos(0); ! 986: if (ttopen(ttname,&local,mymdmtyp,0) < 0) { ! 987: erp = errmsg; ! 988: sprintf(erp,"Sorry, can't reopen %s",ttname); ! 989: perror(errmsg); ! 990: return(0); ! 991: } /* And try again. */ ! 992: if (ttpkt(speed,DIALING,parity) < 0) { ! 993: printf("Sorry, Can't condition communication line\n"); ! 994: printf("Try 'set line %s' again\n",ttname); ! 995: return(0); ! 996: } ! 997: } ! 998: #ifdef DYNAMIC ! 999: if (!(lbuf = malloc(LBUFL+1))) { /* Allocate input line buffer */ ! 1000: printf("Sorry, memory buffer can't be allocated\n"); ! 1001: return(0); ! 1002: } ! 1003: #endif /* DYNAMIC */ ! 1004: sleep(2); /* Let it finish waking up. */ ! 1005: ! 1006: /* ! 1007: Establish jump vector, or handle "failure" jumps. ! 1008: longjmp() sets global failure reason, n1. ! 1009: */ ! 1010: if (setjmp(sjbuf)) { /* if a "failure jump" was taken... */ ! 1011: n = n1; ! 1012: alarm(0); /* disable timeouts */ ! 1013: if (setjmp(sjbuf)) { /* failure while handling failure */ ! 1014: printf ("%s failure while handling failure.\n", F_reason[n1]); ! 1015: } else { /* first (i.e., non-nested) failure */ ! 1016: signal(SIGALRM, dialtime); /* be sure to catch signals */ ! 1017: #ifdef MAC ! 1018: signal(SIGINT, dialint); ! 1019: #else /* MAC */ ! 1020: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 1021: signal(SIGINT, dialint); ! 1022: #endif /* MAC */ ! 1023: alarm(10); /* be sure to exit this section */ ! 1024: } ! 1025: switch (n) { /* type of failure */ ! 1026: case F_time: { /* timed out */ ! 1027: printf ("No connection made within the allotted time.\n"); ! 1028: if (mymdmtyp == n_HAYES || mymdmtyp == n_TELEBIT) ! 1029: ttoc('\015'); /* Send CR to interrupt dialing */ ! 1030: /* some hayes modems don't fail with BUSY on busy lines */ ! 1031: debug(F110,"dial","timeout",0); ! 1032: break; ! 1033: } ! 1034: case F_int: { /* dialing interrupted */ ! 1035: printf ("Dialing interrupted.\n"); ! 1036: debug(F110,"dial","interrupted",0); ! 1037: if (mymdmtyp == n_HAYES || mymdmtyp == n_TELEBIT) ! 1038: ttoc('\015'); /* Send CR to interrupt dialing */ ! 1039: break; ! 1040: } ! 1041: case F_modem: { /* modem detected a failure */ ! 1042: printf ("Failed (\""); ! 1043: for (pc = lbuf; *pc; pc++) ! 1044: if (isprint(*pc)) ! 1045: putchar(*pc); /* display printable reason */ ! 1046: printf ("\").\n"); ! 1047: debug(F110,"dial",lbuf,0); ! 1048: break; ! 1049: } ! 1050: case F_minit: { /* cannot initialize modem */ ! 1051: printf ("Can't initialize modem.\n"); ! 1052: debug(F110,"dial","modem init",0); ! 1053: break; ! 1054: } ! 1055: } ! 1056: reset(); /* reset alarms, etc. */ ! 1057: dialhup(); /* try to hang up phone. */ ! 1058: #ifdef DYNAMIC ! 1059: if (lbuf) free(lbuf); ! 1060: #endif /* DYNAMIC */ ! 1061: return(0); /* exit with failure code */ ! 1062: } ! 1063: ! 1064: /* Set timer and interrupt handlers. */ ! 1065: ! 1066: savalrm = signal(SIGALRM,dialtime); /* Set alarm handler */ ! 1067: #ifdef MAC ! 1068: savint = signal(SIGINT, dialint); ! 1069: #else /* MAC */ ! 1070: if ((savint = signal(SIGINT,SIG_IGN)) != SIG_IGN ) ! 1071: signal(SIGINT,dialint); /* Set int handler if not ignored */ ! 1072: #endif /* MAC */ ! 1073: #ifdef COMMENT ! 1074: x = 10; /* Give modem 10 seconds to wake up */ ! 1075: debug(F101,"ckdial wakeup timout","",x); ! 1076: x = alarm(x); ! 1077: debug(F101,"ckdial previous alarm","",x); ! 1078: #endif /* COMMENT */ ! 1079: ! 1080: /* Put modem in command mode. */ ! 1081: ! 1082: switch (augmdmtyp) { /* Send the wakeup string */ ! 1083: ! 1084: #ifdef ATT7300 ! 1085: case n_ATTUPC: { ! 1086: /* ! 1087: For ATT7300/Unix PC's with their special internal modem. Timeout ! 1088: and user interrupts are enabled during dialing. attdial() is in ! 1089: file ckutio.c. - jrd ! 1090: */ ! 1091: _PROTOTYP( int attdial, (char *, long, char *) ); ! 1092: alarm(waitct); /* do alarm properly */ ! 1093: if (attdial(ttname,speed,telnbr)) { /* dial internal modem */ ! 1094: reset(); /* reset alarms, etc. */ ! 1095: if (! quiet) printf(" Call did not complete."); ! 1096: dialhup(); /* Hangup the call */ ! 1097: #ifdef DYNAMIC ! 1098: if (lbuf) free(lbuf); ! 1099: #endif /* DYNAMIC */ ! 1100: return(0); /* return failure */ ! 1101: } ! 1102: reset(); /* reset alarms, etc. */ ! 1103: ttpkt(speed,CONNECT,parity); /* cancel dialing ioctl */ ! 1104: if (! quiet) { ! 1105: if (dialdpy) printf("\n"); ! 1106: printf(" Call completed.\07\r\n"); ! 1107: } ! 1108: #ifdef DYNAMIC ! 1109: if (lbuf) free(lbuf); ! 1110: #endif /* DYNAMIC */ ! 1111: return(1); /* no conversation with modem to complete dialing */ ! 1112: } ! 1113: #endif /* ATT7300 */ ! 1114: ! 1115: /* ! 1116: For Hayes modem command language, figure out if modem is giving verbose ! 1117: or digit result codes. ! 1118: */ ! 1119: case n_HAYES: ! 1120: case n_HAYESNV: ! 1121: ws = dialini ? dialini : HAYES.wake_str; ! 1122: for (tries = 4; tries > 0; tries--) { ! 1123: ttslow(ws,pmdminf->wake_rate); ! 1124: status = getok(4); ! 1125: if (status > 0) break; ! 1126: sleep(1); /* Wait before retrying */ ! 1127: } ! 1128: if (status > 0) break; /* Initialized OK. */ ! 1129: /* modem-initialization failure */ ! 1130: n1 = (status == 0) ? F_minit : F_modem; ! 1131: longjmp( sjbuf, n1 ); ! 1132: ! 1133: /* ! 1134: Telebit support: Trailblazer, T1000, T2500. ! 1135: C-Kermit global variables 'dialksp', 'flow', 'dialini', 'parity', ! 1136: and local variable 'augmdmtyp' modify our behavior: ! 1137: ! 1138: modulation- and confguration-independent initialization: ! 1139: S11 DTMF timing (left alone) ! 1140: S45 remote access (left alone) ! 1141: S48=1 all 8 bits are significant, 0 only 7 bits ! 1142: S51=255 set serial port baud rate automatically (no typeahead) ! 1143: S52=2 go on hook when DTR drops and reset to NV-RAM ! 1144: S53 DCD/DSR control (left alone) ! 1145: S54=2 pass BREAK signal to remote modem immediately ! 1146: S55=0 respond to command escape sequence <sec>+++<sec> ! 1147: depending upon the value of 'flow': ! 1148: ==FLO_NONE S58=0 DTE uses no flow control ! 1149: ==FLO_HARD S58=2 DTE uses hardware (CTS/RTS) flow control ! 1150: ==FLO_XONX S58=3 DTE uses XON/XOFF flow control ! 1151: S66 lock interface speed: depends on value of mdmspd variable: ! 1152: mdmspd == 0 sets S66=1 (lock speed, use flow control) ! 1153: mdmspd != 0 sets S66=0 (change speed, no flow control) ! 1154: S68=255 DCE uses whatever flow control DTE uses (specified in S58) ! 1155: S95=0 MNP: depends on value of dialmnp variable: ! 1156: dialmnp == 0 sets S95=0 (no MNP) ! 1157: dialmnp != 0 sets S95=2 (auto MNP) ! 1158: S110=1 use data compression if remote modem agrees ! 1159: ! 1160: SET MODEM TELEBIT ! 1161: "traditional" configuration (PEP, V.22, V.22bis, 212A, 103): ! 1162: S50=0 use automatic configuration to answering modem ! 1163: ! 1164: SET MODEM PEP-TELEBIT ! 1165: PEP mode with SET DIAL KERMIT-SPOOF ON ! 1166: S50=255 use PEP + lock DCE speed to DTE speed ! 1167: S111=10 Kermit with no parity ! 1168: S111=11 Kermit with odd parity ! 1169: S111=12 Kermit with even parity ! 1170: S111=13 Kermit with mark parity ! 1171: S111=14 Kermit with space parity ! 1172: S112=?? set to Kermit's start-of-packet character, stchr ! 1173: ! 1174: SET MODEM PEP-TELEBIT with SET DIAL KERMIT-SPOOF OFF ! 1175: S50=255 use PEP + lock DCE speed to DTE speed ! 1176: S111=0 use normal PEP inter-modem protocol ! 1177: ! 1178: SET MODEM V32-TELEBIT (doesn't work with Trailblazer or T1000) ! 1179: S50=6 use V.32 ! 1180: ! 1181: SET MODEM V42-TELEBIT ! 1182: S50=0 auto speed select ! 1183: S95=1 MNP reliable mode ! 1184: S96=1 enable MNP data compression ! 1185: S97=1 enable LAP-M ! 1186: S98=3 compression in both directions ! 1187: S106=1 V.42 detection enable ! 1188: ! 1189: SET MODEM SLOW-TELEBIT ! 1190: S94=1 connect to any speed up to maximum specified by S50 ! 1191: S50=3 connect to Bell 103/212a, V.21, V.22 and V.22bis ! 1192: */ ! 1193: case n_TELEBIT: /* Telebits... */ ! 1194: case n_TBNV: ! 1195: case n_TBPEP: ! 1196: case n_TB3: ! 1197: case n_TB4: ! 1198: case n_TBS: ! 1199: case n_TBPNV: ! 1200: case n_TB3NV: ! 1201: case n_TB4NV: ! 1202: case n_TBSNV: { ! 1203: int S58,S66,S95,S111,S112; /* Some Telebit register names */ ! 1204: char t25buf[64]; /* Modem command buffer */ ! 1205: /* ! 1206: If user defined a DIAL INIT-STRING, send that now, otherwise send built-in ! 1207: Telebit string. Try up to 4 times to get OK or 0 response from modem. ! 1208: */ ! 1209: ws = dialini ? dialini : TELEBIT.wake_str; ! 1210: debug(F110,"ckdial telebit init string",ws,0); ! 1211: for (tries = 4; tries > 0; tries--) { ! 1212: ttslow(ws,pmdminf->wake_rate); ! 1213: status = getok(5); ! 1214: if (status) break; ! 1215: dialhup(); /* Hang up */ ! 1216: ttflui(); /* Flush input buffer */ ! 1217: } ! 1218: if (status < 1) { ! 1219: n1 = F_minit; ! 1220: longjmp( sjbuf, F_minit ); /* Failed. */ ! 1221: } ! 1222: if (!dialini) { /* If using built-in init strings */ ! 1223: /* Step 2 */ ! 1224: sprintf(t25buf, ! 1225: "ATS48=%d S51=255 S52=2 S54=2\015", ! 1226: parity ? 0 : 1); ! 1227: s = t25buf; ! 1228: debug(F110,"ckdial Telebit init step 2",s,0); ! 1229: for (tries = 4; tries > 0; tries--) { ! 1230: ttslow(s,pmdminf->wake_rate); ! 1231: status = getok(5); ! 1232: if (status) break; ! 1233: msleep(500); ! 1234: ttflui(); ! 1235: } ! 1236: if (status < 1) { ! 1237: n1 = F_minit; ! 1238: longjmp( sjbuf, F_minit ); /* Failed. */ ! 1239: } ! 1240: switch (flow) { /* Flow control */ ! 1241: case FLO_HARD: S58 = 2; break; /* RTX/CTS (hardware) */ ! 1242: default: S58 = 0; break; /* NONE (or other) */ ! 1243: } ! 1244: if (dialmnp) { /* MNP negotiation */ ! 1245: S95 = 2; /* Enabled (auto) */ ! 1246: } else { ! 1247: S95 = 0; /* Disabled */ ! 1248: } ! 1249: S66 = mdmspd ? 0 : 1; /* Interface speed locked? */ ! 1250: msleep(500); ! 1251: sprintf(t25buf, ! 1252: "ATS58=%d S55=0 S66=%d S68=255 S95=%d\015",S58,S66,S95); ! 1253: s = t25buf; ! 1254: debug(F110,"ckdial Telebit init step 3",s,0); ! 1255: for (tries = 4; tries > 0; tries--) { ! 1256: ttslow(s,pmdminf->wake_rate); ! 1257: status = getok(5); ! 1258: if (status) break; ! 1259: msleep(500); ! 1260: ttflui(); ! 1261: } ! 1262: if (status < 1) { ! 1263: n1 = F_minit; ! 1264: longjmp( sjbuf, F_minit ); /* Failed. */ ! 1265: } ! 1266: p = ""; ! 1267: s = ""; ! 1268: switch (augmdmtyp) { /* we will auto-config */ ! 1269: case n_TELEBIT: /* 103,212,v22bis modulation */ ! 1270: case n_TBNV: ! 1271: p = "standard"; /* Automatic speed determination */ ! 1272: s = "ATS50=0 S110=0\015"; ! 1273: break; ! 1274: case n_TBPEP: /* PEP Protocol */ ! 1275: case n_TBPNV: ! 1276: if (dialksp) { /* SET DIAL KERMIT-SPOOF ON? */ ! 1277: switch (parity) { ! 1278: case 'e': S111 = 12; break; ! 1279: case 'm': S111 = 13; break; ! 1280: case 'o': S111 = 11; break; ! 1281: case 's': S111 = 14; break; ! 1282: default: ! 1283: case 0: S111 = 10; break; ! 1284: } ! 1285: S112 = stchr; /* Start-of-packet character */ ! 1286: sprintf(t25buf, ! 1287: "ATS50=255 S110=1 S111=%d S112=%d\015",S111,S112); ! 1288: p = "PEP/Kermit"; ! 1289: s = t25buf; ! 1290: } else { /* SET DIAL KERMIT-SPOOF OFF */ ! 1291: p = "PEP/No-Kermit"; ! 1292: s = "ATS50=255 S110=1\015"; /* Accept any protocol */ ! 1293: } ! 1294: debug(F101,"ckdial telebit pep waitct","",waitct); ! 1295: break; ! 1296: ! 1297: case n_TB3: /* Telebit V.32 */ ! 1298: case n_TB3NV: ! 1299: p = "V.32"; ! 1300: s = "ATS50=6\015"; ! 1301: break; ! 1302: ! 1303: case n_TB4: /* Telebit V.42 */ ! 1304: case n_TB4NV: ! 1305: p = "V.42"; ! 1306: s = "ATS50=0 S95=1 S96=1 S97=1 S98=3 S106=1\015"; ! 1307: break; ! 1308: ! 1309: case n_TBS: /* Telebit up to 2400 Baud */ ! 1310: case n_TBSNV: ! 1311: p = "300/1200/2400 Baud"; ! 1312: s = "ATS94=1 S50=3\015"; ! 1313: break; ! 1314: } ! 1315: debug(F111,"ckdial Telebit config",p,speed); ! 1316: debug(F110,"ckdial Telebit init step 4",s,0); ! 1317: if (*s) { ! 1318: for (tries = 4; tries > 0; tries--) { ! 1319: ttslow(s,pmdminf->wake_rate); ! 1320: status = getok(5); ! 1321: if (status) break; ! 1322: msleep(500); ! 1323: ttflui(); ! 1324: } ! 1325: debug(F101,"ckdial telebit init status","",status); ! 1326: if (status < 1) { ! 1327: n1 = F_minit; ! 1328: longjmp(sjbuf, F_minit); ! 1329: } ! 1330: } ! 1331: } ! 1332: /* Done with Telebit protocols, remove bits from modem type */ ! 1333: /* Except nonverbal bit */ ! 1334: augmdmtyp &= ~(DIAL_PEP|DIAL_V32|DIAL_V42|DIAL_SLO); ! 1335: debug(F101,"ckdial Telebit augmdmtyp","",augmdmtyp); ! 1336: break; ! 1337: } ! 1338: ! 1339: case n_MICROCOM: /* interdigit waits for tone dial */ ! 1340: { ! 1341: jmp_buf savejmp; ! 1342: alarm(0); ! 1343: xcpy((char *)savejmp, (char *)sjbuf, sizeof savejmp); ! 1344: if (setjmp(sjbuf)) { ! 1345: /* try the autobaud sequence */ ! 1346: xcpy((char *)sjbuf, (char *)savejmp, sizeof savejmp); ! 1347: alarm(5); ! 1348: ttslow("44445", MICROCOM.wake_rate); ! 1349: waitfor(MICROCOM.wake_str); ! 1350: } else { ! 1351: alarm(2); ! 1352: ws = dialini ? dialini : MICROCOM.wake_str; ! 1353: ttslow(ws, MICROCOM.wake_rate); ! 1354: ! 1355: waitfor(ws); ! 1356: alarm(0); ! 1357: xcpy((char *)sjbuf, (char *)savejmp, sizeof savejmp); ! 1358: } ! 1359: } ! 1360: break; ! 1361: case n_ATTDTDM: /* DTDM requires BREAK to wake up */ ! 1362: ttsndb(); /* Send BREAK */ ! 1363: break; /* ttsndb() defined in ckutio.c */ ! 1364: ! 1365: default: /* place modem into command mode */ ! 1366: ws = dialini ? dialini : pmdminf->wake_str; ! 1367: debug(F111,"ckdial default, wake string",ws, ! 1368: pmdminf->wake_rate); ! 1369: ttslow(ws, pmdminf->wake_rate); ! 1370: debug(F110,"ckdial default, waiting for wake_prompt", ! 1371: pmdminf->wake_prompt,0); ! 1372: savalrm = signal(SIGALRM,dialtime); ! 1373: alarm(10); ! 1374: waitfor(pmdminf->wake_prompt); ! 1375: break; ! 1376: } ! 1377: alarm(0); /* turn off alarm */ ! 1378: if (augmdmtyp != n_TELEBIT) ! 1379: debug(F100,"ckdial got wake prompt","",0); ! 1380: msleep(500); /* give things settling time */ ! 1381: ! 1382: /* Enable/disable MNP (Telebit already done above) */ ! 1383: ! 1384: switch (augmdmtyp) { ! 1385: case n_HST: ! 1386: if (dialmnp) ! 1387: ttslow("AT&K2\015",pmdminf->wake_rate); ! 1388: else ! 1389: ttslow("AT&K0\015",pmdminf->wake_rate); ! 1390: getok(5); /* Get response */ ! 1391: break; ! 1392: default: ! 1393: break; ! 1394: } ! 1395: ! 1396: /* Dial the number */ ! 1397: /* put modem into dialing mode */ ! 1398: ttslow(pmdminf->dmode_str, pmdminf->dial_rate); ! 1399: savalrm = signal(SIGALRM,dialtime); ! 1400: alarm(10); ! 1401: if (pmdminf->dmode_prompt) { /* wait for prompt, if any expected */ ! 1402: waitfor(pmdminf->dmode_prompt); ! 1403: msleep(300); ! 1404: } ! 1405: alarm(0); /* turn off alarm on dialing prompts */ ! 1406: ttflui(); /* clear out stuff from waking modem up */ ! 1407: ! 1408: sprintf(lbuf, pmdminf->dial_str, telnbr); /* form dialing string */ ! 1409: debug(F110,"dialing",lbuf,0); ! 1410: ttslow(lbuf,pmdminf->dial_rate); /* send dialing string */ ! 1411: ! 1412: savalrm = signal(SIGALRM,dialtime); /* Time to allow for connecting */ ! 1413: x = alarm(waitct); /* This much time... */ ! 1414: debug(F101,"ckdial old alarm","",x); ! 1415: debug(F101,"ckdial waitct","",waitct); ! 1416: ! 1417: switch (augmdmtyp) { ! 1418: case n_RACAL: /* acknowledge printout of dialing string */ ! 1419: sleep(3); ! 1420: ttflui(); ! 1421: ttoc('\015'); ! 1422: break; ! 1423: case n_VENTEL: ! 1424: waitfor("\012\012"); /* Ignore the first two strings */ ! 1425: break; ! 1426: default: ! 1427: break; ! 1428: } ! 1429: ! 1430: /* Check for connection */ ! 1431: ! 1432: /* ! 1433: * I believe we also need to look for carrier in order to determine if a ! 1434: * connection has been made. In fact, for many we may only want to look for ! 1435: * the "failure" responses in order to short-circuit the timeout, and let ! 1436: * carrier be the determination of whether a connection has been made. -- DS ! 1437: */ ! 1438: status = 0; ! 1439: strcpy(lbuf,"No Connection"); /* default failure reason */ ! 1440: debug(F101,"dial awaiting response, augmdmtyp","",augmdmtyp); ! 1441: while (status == 0) { ! 1442: switch (augmdmtyp) { ! 1443: default: ! 1444: for (n = 0; n < LBUFL-1; n++) { /* accumulate response */ ! 1445: lbuf[n] = c2 = (ttinc(0) & 0177); ! 1446: dialoc(c2); ! 1447: if ( lbuf[n] == CR || lbuf[n] == LF ) break; ! 1448: } ! 1449: lbuf[n] = '\0'; /* Terminate response from modem */ ! 1450: debug(F111,"dial modem response",lbuf,n); ! 1451: if (n) { /* If one or more characters present */ ! 1452: switch (augmdmtyp) { /* check for modem response message. */ ! 1453: case n_ATTMODEM: ! 1454: /* Careful - "Connected" / "Not Connected" */ ! 1455: if (didweget(lbuf,"Busy") || ! 1456: didweget(lbuf,"Not connected") || ! 1457: didweget(lbuf,"Not Connected") || ! 1458: didweget(lbuf,"No dial tone") || ! 1459: didweget(lbuf,"No Dial Tone") || ! 1460: didweget(lbuf,"No answer") || ! 1461: didweget(lbuf,"No Answer")) ! 1462: status = FAILED; ! 1463: else if (didweget(lbuf,"Answered") || ! 1464: didweget(lbuf,"Connected")) ! 1465: status = CONNECTED; ! 1466: break; ! 1467: ! 1468: case n_ATTISN: ! 1469: if (didweget(lbuf,"ANSWERED")) ! 1470: status = CONNECTED; ! 1471: else if (didweget(lbuf,"BUSY") || ! 1472: didweget(lbuf,"DISCONNECT") || ! 1473: didweget(lbuf,"NO ANSWER") || ! 1474: didweget(lbuf,"WRONG ADDRESS")) ! 1475: status = FAILED; ! 1476: break; ! 1477: ! 1478: case n_ATTDTDM: ! 1479: if (didweget(lbuf,"ANSWERED")) ! 1480: status = CONNECTED; ! 1481: else if (didweget(lbuf,"BUSY") || ! 1482: didweget(lbuf,"CHECK OPTIONS") || ! 1483: didweget(lbuf,"DISCONNECTED") || ! 1484: didweget(lbuf,"DENIED")) ! 1485: status = FAILED; ! 1486: #ifdef DEBUG ! 1487: #ifdef ATT6300 ! 1488: else if (deblog && didweget(lbuf,"~~")) ! 1489: status = CONNECTED; ! 1490: #endif /* ATT6300 */ ! 1491: #endif /* DEBUG */ ! 1492: break; ! 1493: ! 1494: case n_CERMETEK: ! 1495: if (didweget(lbuf,"\016A")) { ! 1496: status = CONNECTED; ! 1497: ttslow("\016U 1\015",200); /* make transparent*/ ! 1498: } ! 1499: break; ! 1500: ! 1501: case n_DF100: /* DF100 has short response codes */ ! 1502: if (strcmp(lbuf,"A") == 0) ! 1503: status = CONNECTED; /* Attached */ ! 1504: else if (strcmp(lbuf,"N") == 0 || /* No Ans or Dialtone */ ! 1505: strcmp(lbuf,"E") == 0 || /* Error */ ! 1506: strcmp(lbuf,"R") == 0) { /* Ready */ ! 1507: status = FAILED; ! 1508: break; ! 1509: } ! 1510: /* otherwise fall thru... */ ! 1511: ! 1512: case n_DF200: ! 1513: if (didweget(lbuf,"Attached")) ! 1514: status = CONNECTED; ! 1515: /* ! 1516: * The DF100 will respond with "Attached" even if DTR ! 1517: * and/or carrier are not present. Another reason to ! 1518: * (also) wait for carrier? ! 1519: */ ! 1520: else if (didweget(lbuf,"Busy") || ! 1521: didweget(lbuf,"Disconnected") || ! 1522: didweget(lbuf,"Error") || ! 1523: didweget(lbuf,"No answer") || ! 1524: didweget(lbuf,"No dial tone") || ! 1525: didweget(lbuf,"Speed:")) ! 1526: status = FAILED; ! 1527: /* ! 1528: * It appears that the "Speed:..." response comes after an ! 1529: * "Attached" response, so this is never seen. HOWEVER, ! 1530: * it would be very handy to detect this and temporarily ! 1531: * reset the speed, since it's a nuisance otherwise. ! 1532: * If we wait for some more input from the modem, how do ! 1533: * we know if it's from the remote host or the modem? ! 1534: * Carrier reportedly doesn't get set until after the ! 1535: * "Speed:..." response (if any) is sent. Another reason ! 1536: * to (also) wait for carrier. ! 1537: */ ! 1538: break; ! 1539: ! 1540: case n_GDC: ! 1541: if (didweget(lbuf,"ON LINE")) ! 1542: status = CONNECTED; ! 1543: else if (didweget(lbuf,"NO CONNECT")) ! 1544: status = FAILED; ! 1545: break; ! 1546: ! 1547: case n_HAYES: ! 1548: case n_USROBOT: ! 1549: case n_HST: ! 1550: case n_TELEBIT: ! 1551: if (mdmspd) { ! 1552: s = lbuf; ! 1553: while (*s != '\0' && *s != 'C') s++; ! 1554: cptr = (*s == 'C') ? s : NULL; ! 1555: conspd = 0L; ! 1556: if ((cptr != NULL) && !strncmp(cptr,"CONNECT ",8)) { ! 1557: if ((int)strlen(cptr) < 9) /* Just CONNECT, */ ! 1558: conspd = 300L; /* use 300 bps */ ! 1559: else if (isdigit(*(cptr+8))) /* not CONNECT FAST */ ! 1560: conspd = atol(cptr + 8); /* CONNECT nnnn */ ! 1561: if (conspd != speed) { ! 1562: if ((conspd / 10L) > 0) { ! 1563: if (ttsspd((int) (conspd / 10L)) < 0) { ! 1564: printf(" Can't change speed to %lu\r\n", ! 1565: conspd); ! 1566: } else { ! 1567: speed = conspd; ! 1568: status = CONNECTED; ! 1569: if ( !quiet ) ! 1570: printf(" Speed changed to %lu\r\n", ! 1571: conspd); ! 1572: } ! 1573: } ! 1574: } /* Expanded to handle any conceivable speed */ ! 1575: } ! 1576: } ! 1577: if (mymdmtyp == n_TELEBIT) { ! 1578: if (didweget(lbuf,"CONNECT FAST/KERM")) { ! 1579: status = CONNECTED; ! 1580: if (!quiet) printf("FAST/KERM "); ! 1581: break; ! 1582: } ! 1583: } ! 1584: if (didweget(lbuf,"RRING") || didweget(lbuf,"RINGING")) { ! 1585: status = 0; ! 1586: } else if (didweget(lbuf,"CONNECT")) { ! 1587: status = CONNECTED; ! 1588: } else if (didweget(lbuf,"NO CARRIER") || ! 1589: didweget(lbuf,"NO DIALTONE") || ! 1590: didweget(lbuf,"NO DIAL TONE") || ! 1591: didweget(lbuf,"BUSY") || ! 1592: didweget(lbuf,"NO ANSWER") || ! 1593: didweget(lbuf,"VOICE") || ! 1594: didweget(lbuf,"RING") || ! 1595: didweget(lbuf,"ERROR")) { ! 1596: status = FAILED; ! 1597: } ! 1598: break; ! 1599: case n_PENRIL: ! 1600: if (didweget(lbuf,"OK")) ! 1601: status = CONNECTED; ! 1602: else if (didweget(lbuf,"BUSY") || ! 1603: didweget(lbuf,"NO RING")) ! 1604: status = FAILED; ! 1605: break; ! 1606: case n_RACAL: ! 1607: if (didweget(lbuf,"ON LINE")) ! 1608: status = CONNECTED; ! 1609: else if (didweget(lbuf,"FAILED CALL")) ! 1610: status = FAILED; ! 1611: break; ! 1612: case n_ROLM: ! 1613: if (didweget(lbuf,"CALLING")) ! 1614: status = 0; ! 1615: else if (didweget(lbuf,"COMPLETE")) ! 1616: status = CONNECTED; ! 1617: else if (didweget(lbuf,"FAILED") || ! 1618: didweget(lbuf,"NOT AVAILABLE") || ! 1619: didweget(lbuf,"LACKS PERMISSION") || ! 1620: didweget(lbuf,"NOT A DATALINE") || ! 1621: didweget(lbuf,"BUSY") || ! 1622: didweget(lbuf,"ABANDONDED") || ! 1623: didweget(lbuf,"DOES NOT ANSWER")) ! 1624: status = FAILED; ! 1625: /* ! 1626: Early versions of the Rolm 9751 CBX software do not ! 1627: give a CALL COMPLETE indication when dialing an ! 1628: outpool number, but they do seem to return a long ! 1629: string of DELs at that point. (this doesn't really ! 1630: work...) ! 1631: else if (didweget(lbuf,"\177\177\177")) ! 1632: status = CONNECTED; ! 1633: */ ! 1634: break; ! 1635: case n_VENTEL: ! 1636: if (didweget(lbuf,"ONLINE!") || ! 1637: didweget(lbuf,"Online!")) ! 1638: status = CONNECTED; ! 1639: else if (didweget(lbuf,"BUSY") || ! 1640: didweget(lbuf,"DEAD PHONE") || ! 1641: didweget(lbuf,"Busy")) ! 1642: status = FAILED; ! 1643: break; ! 1644: case n_CONCORD: ! 1645: if (didweget(lbuf,"INITIATING")) ! 1646: status = CONNECTED; ! 1647: else if (didweget(lbuf,"BUSY") || ! 1648: didweget(lbuf,"CALL FAILED")) ! 1649: status = FAILED; ! 1650: break; ! 1651: case n_MICROCOM: ! 1652: /* "RINGBACK" means phone line ringing, continue */ ! 1653: if (didweget(lbuf,"NO CONNECT") || ! 1654: didweget(lbuf,"BUSY") || ! 1655: didweget(lbuf,"NO DIALTONE") || ! 1656: didweget(lbuf,"COMMAND ERROR") || ! 1657: didweget(lbuf,"IN USE")) ! 1658: status = FAILED; ! 1659: else if (didweget(lbuf,"CONNECT")) ! 1660: status = CONNECTED; ! 1661: /* trailing speed ignored */ ! 1662: break; ! 1663: } ! 1664: } ! 1665: break; ! 1666: ! 1667: case n_DF03: /* because response lacks CR or NL */ ! 1668: c = ttinc(0) & 0177; ! 1669: dialoc(c); ! 1670: debug(F000,"dial df03 got","",c); ! 1671: if ( c == 'A' ) status = CONNECTED; ! 1672: if ( c == 'B' ) status = FAILED; ! 1673: break; ! 1674: ! 1675: case n_HAYESNV: /* Hayeslike modems in digit */ ! 1676: case n_TBNV: /* response mode... */ ! 1677: case n_TB3NV: ! 1678: case n_TBPNV: ! 1679: case n_TB4NV: ! 1680: case n_TBSNV: ! 1681: /* ! 1682: The method for reading Hayes numeric result codes has been totally ! 1683: redone as of 5A(174) to account for all of the following. Not all have ! 1684: been tested, and others probably need to be added. ! 1685: ! 1686: Hayes numeric result codes (Hayes 1200 and higher): ! 1687: 0 = OK ! 1688: 1 = CONNECT at 300 bps (or 1200 bps on Hayes 1200 with basic code set) ! 1689: 2 = RING ! 1690: 3 = NO CARRIER ! 1691: 4 = ERROR (in command line) ! 1692: 5 = CONNECT 1200 (extended code set) ! 1693: Hayes 2400 and higher: ! 1694: 6 = NO DIALTONE ! 1695: 7 = BUSY ! 1696: 8 = NO ANSWER ! 1697: 9 = (there is no 9) ! 1698: 10 = CONNECT 2400 ! 1699: Reportedly, the codes for Hayes V.32 modems are: ! 1700: 1x = CONNECT <suffix> ! 1701: 5x = CONNECT 1200 <suffix> ! 1702: 9x = CONNECT 2400 <suffix> ! 1703: 11x = CONNECT 4800 <suffix> ! 1704: 12x = CONNECT 9600 <suffix> ! 1705: Where: ! 1706: x: suffix: ! 1707: R = RELIABLE ! 1708: RC = RELIABLE COMPRESSED ! 1709: L = LAPM ! 1710: LC = LAPM COMPRESSED ! 1711: And for Telebits: ! 1712: 50 = CONNECT FAST ! 1713: 52 = RRING ! 1714: What else? ! 1715: */ ! 1716: { /* Nonverbal response code handler */ ! 1717: char nbuf[8]; /* Response buffer */ ! 1718: int i, j; /* Buffer pointers */ ! 1719: if (mdmecho) { /* Sponge up dialing string echo. */ ! 1720: while ((c = (ttinc(0) & 0177)) != CR) ! 1721: dialoc(c); ! 1722: } ! 1723: while (status == 0) { /* Read response */ ! 1724: for (i = 0; i < 8; i++) /* Clear the buffer */ ! 1725: nbuf[i] = '\0'; ! 1726: i = 0; /* Reset the buffer pointer. */ ! 1727: c = ttinc(0) & 0177; /* Get first digit of response. */ ! 1728: /* using an untimed, blocking read. */ ! 1729: dialoc(c); /* Echo it if requested. */ ! 1730: if (!isdigit(c)) /* If not a digit, keep looking. */ ! 1731: continue; ! 1732: nbuf[i++] = c; /* Got a digit, save it. */ ! 1733: while (i < 8) { /* Keep reading till we time out */ ! 1734: y = alarm(0) - 1; /* Save current alarm */ ! 1735: x = ttinc(1); /* Read char with 1-sec timeout */ ! 1736: if (y > 0) alarm(y); /* Restore alarm */ ! 1737: if (x > 0) { /* If we didn't time out, */ ! 1738: c = (char) x; /* we got this character. */ ! 1739: if (c != CR) /* Save it, */ ! 1740: nbuf[i++] = c; /* if it's not a carriage return. */ ! 1741: dialoc(c); /* Echo it. */ ! 1742: } else break; /* Otherwise assume end of response. */ ! 1743: } ! 1744: nbuf[i] = '\0'; /* Terminate the buffer. */ ! 1745: debug(F111,"dial hayesnv lbuf",lbuf,n); ! 1746: debug(F111,"dial hayesnv got",nbuf,i); ! 1747: /* ! 1748: Separate any non-numeric suffix from the numeric result code ! 1749: with a null. ! 1750: */ ! 1751: for (j = i-1; (j > -1) && !isdigit(nbuf[j]); j--) ! 1752: nbuf[j+1] = nbuf[j]; ! 1753: j++; ! 1754: nbuf[j++] = '\0'; ! 1755: debug(F110,"dial hayesnv numeric",nbuf,0); ! 1756: debug(F111,"dial hayesnv suffix ",nbuf+j,j); ! 1757: if ((int)strlen(nbuf) > 3) /* Probably phone number echoing. */ ! 1758: continue; ! 1759: /* ! 1760: Now read and interpret the results... ! 1761: */ ! 1762: i = atoi(nbuf); /* Convert to integer */ ! 1763: switch (i) { ! 1764: case 1: /* CONNECT */ ! 1765: status = CONNECTED; /* Could be any speed */ ! 1766: break; ! 1767: case 2: /* RING */ ! 1768: if (dialdpy) printf("\r\n Local phone is ringing!\r\n"); ! 1769: status = FAILED; ! 1770: break; ! 1771: case 3: /* NO CARRIER */ ! 1772: if (dialdpy) printf("\r\n No Carrier.\r\n"); ! 1773: status = FAILED; ! 1774: break; ! 1775: case 4: /* ERROR */ ! 1776: if (dialdpy) printf("\r\n Modem Command Error.\r\n"); ! 1777: status = FAILED; ! 1778: break; ! 1779: case 5: /* CONNECT 1200 */ ! 1780: spdchg(1200L); /* Change speed if necessary. */ ! 1781: status = CONNECTED; ! 1782: break; ! 1783: case 6: /* NO DIALTONE */ ! 1784: if (dialdpy) printf("\r\n No Dialtone.\r\n"); ! 1785: status = FAILED; ! 1786: break; ! 1787: case 7: /* BUSY */ ! 1788: if (dialdpy) printf("\r\n Busy.\r\n"); ! 1789: status = FAILED; ! 1790: break; ! 1791: case 8: /* NO ANSWER */ ! 1792: if (dialdpy) printf("\r\n No Answer.\r\n"); ! 1793: status = FAILED; ! 1794: break; ! 1795: case 9: /* CONNECT 2400 */ ! 1796: case 10: ! 1797: spdchg(2400L); /* Change speed if necessary. */ ! 1798: status = CONNECTED; ! 1799: break; ! 1800: case 11: /* CONNECT 4800 */ ! 1801: spdchg(4800L); ! 1802: status = CONNECTED; ! 1803: break; ! 1804: case 12: /* CONNECT 9600 */ ! 1805: spdchg(9600L); ! 1806: status = CONNECTED; ! 1807: break; ! 1808: case 52: /* RRING */ ! 1809: debug(F101,"dial hayesnv 52 mymdmtyp","",mymdmtyp); ! 1810: debug(F101,"dial hayesnv 52 n_TELEBIT","",n_TELEBIT); ! 1811: if (mymdmtyp == n_TELEBIT) ! 1812: if (dialdpy) printf(" Ringing...\r\n"); ! 1813: break; ! 1814: case 50: /* CONNECT FAST */ ! 1815: if (mymdmtyp == n_TELEBIT) ! 1816: status = CONNECTED; /* CONNECT FAST */ ! 1817: break; ! 1818: default: ! 1819: break; ! 1820: } ! 1821: } ! 1822: if (status == CONNECTED && nbuf[j] != '\0') { ! 1823: if (dialdpy) { ! 1824: printf("\r\n"); ! 1825: if (nbuf[j] == 'R') printf("RELIABLE"); ! 1826: if (nbuf[j] == 'L') printf("LAPM"); ! 1827: if (nbuf[j+1] == 'C') printf(" COMPRESSED"); ! 1828: printf("\r\n"); ! 1829: } ! 1830: } ! 1831: } ! 1832: break; ! 1833: ! 1834: case n_UNKNOWN: { ! 1835: int x, y = waitct; ! 1836: while (y-- > -1) { ! 1837: x = ttchk(); ! 1838: if (x > 0) { ! 1839: if (x > LBUFL) x = LBUFL; ! 1840: x = ttxin(x,(CHAR *)lbuf); ! 1841: if ((x > 0) && dialdpy) conol(lbuf); ! 1842: } ! 1843: x = ttgmdm(); /* Try to read modem signals */ ! 1844: if (x < 0) break; /* Can't, pretend we suceeded */ ! 1845: if (x & BM_DCD) /* Got signals OK. Carrier present? */ ! 1846: break; /* Yes, done. */ ! 1847: sleep(1); ! 1848: } ! 1849: status = CONNECTED; ! 1850: break; ! 1851: } ! 1852: } /* switch (augmdmtyp) */ ! 1853: } /* while status == 0 */ ! 1854: x = alarm(0); /* turn off alarm on connecting */ ! 1855: debug(F101,"ckdial alarm off","",x); ! 1856: if ( status != CONNECTED ) { /* modem-detected failure */ ! 1857: n1 = F_modem; ! 1858: longjmp( sjbuf, F_modem ); /* exit (with reason in lbuf) */ ! 1859: } ! 1860: msleep(1000); /* in case DTR blinks */ ! 1861: alarm(3); /* precaution in case of trouble */ ! 1862: debug(F110,"dial","succeeded",0); ! 1863: if (augmdmtyp != n_ROLM) /* Rolm has wierd modem signaling */ ! 1864: ttpkt(speed,CONNECT,parity); /* cancel dialing state ioctl */ ! 1865: reset(); /* reset alarms, etc. */ ! 1866: if (!quiet) ! 1867: printf (" Call completed.\07\n"); ! 1868: #ifdef DYNAMIC ! 1869: if (lbuf) free(lbuf); ! 1870: #endif /* DYNAMIC */ ! 1871: return(1); /* return, and presumably connect */ ! 1872: } ! 1873: ! 1874: /* ! 1875: getok - wait up to n seconds for "OK<CRLF>" or "<CR>0" from modem. ! 1876: Use with Hayeslike modems for reading reply to a nondialing command. ! 1877: Does its own internal timeout handling, but resets alarms to 0. ! 1878: Returns 0 if it timed out, 1 if it succeeded, -1 on modem command error. ! 1879: */ ! 1880: static jmp_buf okbuf; /* Jump-buf for getok(). */ ! 1881: ! 1882: SIGTYP ! 1883: oktimo(foo) int foo; { /* Alarm handler for getok(). */ ! 1884: longjmp(okbuf,1); ! 1885: } ! 1886: ! 1887: int ! 1888: getok(n) int n; { ! 1889: CHAR c; ! 1890: int i, x, status; ! 1891: char rbuf[8]; /* response buffer */ ! 1892: SIGTYP (*saval)(); /* for saving alarm handler locally */ ! 1893: ! 1894: saval = signal(SIGALRM,oktimo); /* set timer */ ! 1895: alarm(n); ! 1896: if (setjmp(okbuf)) { /* handle timeout */ ! 1897: alarm(0); ! 1898: if (saval) signal(SIGALRM,saval); ! 1899: debug(F100,"getok timed out","",0); ! 1900: ttflui(); ! 1901: return(0); ! 1902: } else { /* not timed out... */ ! 1903: status = 0; ! 1904: rbuf[7] = '\0'; /* Terminate response buffer */ ! 1905: while (status == 0) { ! 1906: x = ttinc(0); /* Read a character */ ! 1907: if (x < 0) return(-1); /* i/o error */ ! 1908: debug(F101,"getok ttinc returns","",x); ! 1909: c = x & 0x7f; /* Get low order 7 bits */ ! 1910: debug(F101,"getok converts this to char","",c); ! 1911: if (dialdpy) conoc((char)c); /* Echo it if requested */ ! 1912: for (i = 0; i < 6; i++) /* Rotate buffer */ ! 1913: rbuf[i] = rbuf[i+1]; ! 1914: rbuf[6] = c; /* Deposit character */ ! 1915: debug(F000,"getok",rbuf,(int) c); /* Log it */ ! 1916: switch (c) { /* Interpret it. */ ! 1917: case CR: /* Got carriage return. */ ! 1918: if (augmdmtyp & DIAL_NV) /* If using digit result codes */ ! 1919: conoc(LF); /* echo a linefeed too. */ ! 1920: break; ! 1921: case LF: /* Got linefeed. */ ! 1922: /* ! 1923: Note use of explicit octal codes in the string for ! 1924: CR and LF. We want real CR and LF here, not whatever ! 1925: the compiler happens to define \r and \n as... ! 1926: */ ! 1927: if (!strcmp(rbuf+3,"OK\015\012")) ! 1928: status = 1; ! 1929: else if (!strcmp(rbuf,"ERROR\015\012")) ! 1930: status = -1; ! 1931: augmdmtyp &= ~(DIAL_NV); /* Turn off the nonverbal bit */ ! 1932: break; ! 1933: /* Check whether modem echoes its commands... */ ! 1934: case 't': /* Got little t */ ! 1935: if (!strcmp(rbuf+4,"\015at")) mdmecho = 1; ! 1936: break; ! 1937: case 'T': /* Got Big T */ ! 1938: if (!strcmp(rbuf+4,"\015AT")) mdmecho = 1; ! 1939: break; ! 1940: case '0': /* Got 0: Numeric result code? */ ! 1941: if (rbuf[5] == CR) { /* Yes if previous char was CR. */ ! 1942: augmdmtyp |= DIAL_NV; /* OR in the "nonverbal" bit. */ ! 1943: status = 1; ! 1944: } ! 1945: break; ! 1946: case '4': /* Command line error */ ! 1947: if (rbuf[5] == CR) /* if previous char was CR */ ! 1948: status = -1; ! 1949: break; ! 1950: default: /* Other characters, accumulate. */ ! 1951: status = 0; ! 1952: break; ! 1953: } ! 1954: } ! 1955: debug(F101,"getok returns","",status); ! 1956: alarm(0); ! 1957: if (saval) signal(SIGALRM,saval); ! 1958: ttflui(); ! 1959: return(status); ! 1960: } ! 1961: } ! 1962: ! 1963: /* Maybe hang up the phone, depending on various SET DIAL parameters. */ ! 1964: ! 1965: int ! 1966: dialhup() { ! 1967: int x = 0; ! 1968: if (dialhng) { /* DIAL HANGUP ON? */ ! 1969: x = tthang(); ! 1970: if (dialdpy) { /* DIAL DISPLAY ON? */ ! 1971: if (x > 0) /* Yes, tell results from tthang() */ ! 1972: printf(" Hangup ok\r\n"); ! 1973: else if (x == 0) ! 1974: printf(" Hangup skipped\r\n"); ! 1975: else ! 1976: perror(" Hangup error"); ! 1977: } ! 1978: } else if (dialdpy) printf(" No hangup\r\n"); /* DIAL HANGUP OFF */ ! 1979: return(x); ! 1980: } ! 1981: ! 1982: char * /* Let external routines ask */ ! 1983: getdws(mdmtyp) int mdmtyp; { /* about dial wake string. */ ! 1984: MDMINF * pmdminf; ! 1985: if (mdmtyp < 1 || mdmtyp > MAX_MDM) return(""); ! 1986: pmdminf = ptrtab[(mdmtyp & 0xff) -1 ]; ! 1987: return(dialini ? dialini : pmdminf->wake_str); ! 1988: } ! 1989: ! 1990: #else ! 1991: char *dialv = "Dial Command Disabled"; ! 1992: #endif /* NODIAL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.