|
|
1.1 ! root 1: #line 1 "COMIO.C" ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: /***********************************/ ! 6: /* COM port and modem i/o routines */ ! 7: /***********************************/ ! 8: ! 9: #include "sbbs.h" ! 10: ! 11: #ifndef __FLAT__ ! 12: extern mswtyp; ! 13: #endif ! 14: ! 15: extern char term_ret; ! 16: extern uint addrio; ! 17: ! 18: /****************************************************************************/ ! 19: /* Outputs a NULL terminated string to the COM port verbatim */ ! 20: /* Called from functions putmsg, getstr and color */ ! 21: /****************************************************************************/ ! 22: void putcom(char *str) ! 23: { ! 24: ulong l=0; ! 25: ! 26: while(str[l]) ! 27: putcomch(str[l++]); ! 28: } ! 29: ! 30: /****************************************************************************/ ! 31: /* Outputs a single character to the COM port */ ! 32: /****************************************************************************/ ! 33: void putcomch(char ch) ! 34: { ! 35: char lch; ! 36: int i=0; ! 37: ! 38: if(!com_port) ! 39: return; ! 40: while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */ ! 41: if(lkbrd(1)) { ! 42: lch=lkbrd(0); /* ctrl-c */ ! 43: if(lch==3) { ! 44: lputs("local abort (putcomch)\r\n"); ! 45: i=1440; ! 46: break; } ! 47: ungetkey(lch); } ! 48: if(!DCDHIGH) ! 49: break; ! 50: i++; ! 51: if(sys_status&SS_SYSPAGE) ! 52: beep(i,80); ! 53: else ! 54: mswait(80); } ! 55: if(i==1440) { /* timeout - beep flush outbuf */ ! 56: i=rioctl(TXBC); ! 57: lprintf("timeout(putcomch) %04X %04X\r\n",i,rioctl(IOFO)); ! 58: outcom(7); ! 59: lputc(7); ! 60: rioctl(IOCS|PAUSE); } ! 61: } ! 62: ! 63: /****************************************************************************/ ! 64: /* Sends string of characters to COM port. Interprets ^M and ~ (pause) */ ! 65: /* Called from functions waitforcall and offhook */ ! 66: /****************************************************************************/ ! 67: void mdmcmd(char *str) ! 68: { ! 69: int i=0; ! 70: uint lch; ! 71: ! 72: if(mdm_misc&MDM_DUMB) ! 73: return; ! 74: if(sys_status&SS_MDMDEBUG) ! 75: lputs("\r\nModem command : "); ! 76: while(str[i]) { ! 77: if(str[i]=='~') ! 78: mswait(DELAY_MDMTLD); ! 79: else { ! 80: if(i && str[i-1]=='^' && str[i]!='^') /* control character */ ! 81: putcomch(toupper(str[i])-64); ! 82: else if(str[i]!='^' || (i && str[i-1]=='^')) ! 83: putcomch(str[i]); ! 84: if(sys_status&SS_MDMDEBUG) ! 85: lputc(str[i]); } ! 86: i++; } ! 87: putcomch(CR); ! 88: i=0; ! 89: while(rioctl(TXSYNC|(1<<8)) && i<10) { /* wait for modem to receive all chars */ ! 90: if(lkbrd(1)) { ! 91: lch=lkbrd(0); /* ctrl-c */ ! 92: if(lch==0x2e03) { ! 93: lputs("local abort (mdmcmd)\r\n"); ! 94: break; } ! 95: if(lch==0xff00) ! 96: bail(1); ! 97: ungetkey(lch); } ! 98: i++; } ! 99: if(i==10) { ! 100: i=rioctl(TXBC); ! 101: lprintf("\r\ntimeout(mdmcmd) %04X %04X\r\n",i,rioctl(IOFO)); } ! 102: if(sys_status&SS_MDMDEBUG) ! 103: lputs(crlf); ! 104: } ! 105: ! 106: /****************************************************************************/ ! 107: /* Returns CR terminated string from the COM port. */ ! 108: /* Called from function waitforcall */ ! 109: /****************************************************************************/ ! 110: char getmdmstr(char *str, int sec) ! 111: { ! 112: uchar j=0,ch; ! 113: uint lch; ! 114: time_t start; ! 115: ! 116: if(sys_status&SS_MDMDEBUG) ! 117: lputs("Modem response : "); ! 118: start=time(NULL); ! 119: while(time(NULL)-start<sec && j<81) { ! 120: if(lkbrd(1)) { ! 121: lch=lkbrd(0); /* ctrl-c */ ! 122: if(lch==0x2e03 || lch==3) { ! 123: lputs("local abort (getmdmstr)\r\n"); ! 124: break; } ! 125: if(lch==0xff00) ! 126: bail(1); ! 127: ungetkey(lch); } ! 128: if((ch=incom())==CR && j) { ! 129: if(mdm_misc&MDM_VERBAL) ! 130: incom(); /* LF */ ! 131: break; } ! 132: if(ch && (ch<0x20 || ch>0x7f)) { /* ignore ctrl characters and ex-ascii */ ! 133: if(sys_status&SS_MDMDEBUG) ! 134: lprintf("[%02X]",ch); ! 135: continue; } ! 136: if(ch) { ! 137: str[j++]=ch; ! 138: if(sys_status&SS_MDMDEBUG) ! 139: lputc(ch); } ! 140: else mswait(0); } ! 141: mswait(500); ! 142: str[j]=0; ! 143: if(sys_status&SS_MDMDEBUG) ! 144: lputs(crlf); ! 145: return(j); ! 146: } ! 147: ! 148: /****************************************************************************/ ! 149: /* Drops DTR (if COM port used), clears KEY and COM Buffers and other vars */ ! 150: /* Called from functions checkline, getkey, inkey, main, waitforcall, */ ! 151: /* main_sec, xfer_sec, gettimeleft and newuser */ ! 152: /****************************************************************************/ ! 153: void hangup() ! 154: { ! 155: char str1[256],str2[256],c; ! 156: uint i; ! 157: ! 158: rioctl(MSR); ! 159: if(!term_ret && com_port && (rioctl(IOSTATE)&DCD)) { /* if carrier detect */ ! 160: riosync(0); ! 161: mswait(DELAY_HANGUP); /* wait for modem buffer to clear */ ! 162: if(mdm_misc&MDM_NODTR) ! 163: mdmcmd(mdm_hang); ! 164: else { ! 165: lputs("\r\nDropping DTR..."); ! 166: if(dtr(15)) { /* drop dtr, wait 15 seconds for dcd to drop */ ! 167: lputs("\rDropping DTR Failed"); ! 168: logline("@!","Dropping DTR Failed"); ! 169: mdmcmd(mdm_hang); } } ! 170: mswait(110); ! 171: rioctl(MSR); ! 172: if(rioctl(IOSTATE)&DCD) { ! 173: mswait(5000); ! 174: rioctl(MSR); ! 175: if(rioctl(IOSTATE)&DCD) { ! 176: lputs("\r\nDCD high after hang up"); ! 177: logline("@!","DCD high after hang up"); ! 178: mswait(5000); } } } ! 179: if(sys_status&SS_CAP) { /* Close capture if open */ ! 180: fclose(capfile); ! 181: #ifdef __MSDOS__ ! 182: freedosmem=farcoreleft(); /* fnopen allocates memory and fclose frees */ ! 183: #endif ! 184: sys_status^=SS_CAP; } ! 185: if(sys_status&SS_FINPUT) { /* Close file input if open */ ! 186: close(inputfile); ! 187: sys_status^=SS_FINPUT; } ! 188: ! 189: keybufbot=keybuftop=online=console=0; ! 190: sys_status&=~(SS_TMPSYSOP|SS_LCHAT|SS_SYSPAGE|SS_ABORT); ! 191: nosound(); ! 192: if(com_port) ! 193: dtr(1); ! 194: } ! 195: ! 196: /****************************************************************************/ ! 197: /* Sends 'off-hook' string to modem to pick up phone (if COM port used) */ ! 198: /* Called from function waitforcall */ ! 199: /****************************************************************************/ ! 200: void offhook() ! 201: { ! 202: if(com_port && !(mdm_misc&MDM_DUMB)) { ! 203: mdmcmd(mdm_offh); ! 204: rioctl(TXSYNC|(2<<8)); /* wait up 2 seconds for modem to receive */ ! 205: } ! 206: } ! 207: ! 208: /****************************************************************************/ ! 209: /* Checks to see if remote user has hung up. */ ! 210: /* Called from function getkey */ ! 211: /****************************************************************************/ ! 212: void checkline() ! 213: { ! 214: if(online!=ON_REMOTE) return; ! 215: if(!DCDHIGH) { ! 216: lprintf("\r\nHung up"); ! 217: logline(nulstr,"Hung up"); ! 218: hangup(); } ! 219: } ! 220: ! 221: /****************************************************************************/ ! 222: /* Syncronizes the remote and local machines before command prompts */ ! 223: /****************************************************************************/ ! 224: void riosync(char abortable) ! 225: { ! 226: int i=0; ! 227: ! 228: if(useron.misc&(RIP|WIP)) /* don't allow abort with RIP or WIP */ ! 229: abortable=0; /* mainly because of ANSI cursor posistion response */ ! 230: if(sys_status&SS_ABORT) /* no need to sync if already aborting */ ! 231: return; ! 232: if(online==ON_REMOTE && console&CON_R_ECHO) { ! 233: while(rioctl(TXSYNC|(1<<8)) && i<180) { /* three minutes till tx buf empty */ ! 234: if(sys_status&SS_SYSPAGE) ! 235: beep(i,10); ! 236: if(lkbrd(1)) ! 237: break; ! 238: if(abortable && rioctl(RXBC)) { /* incoming characer */ ! 239: rioctl(IOFO); /* flush output */ ! 240: sys_status|=SS_ABORT; /* set abort flag so no pause */ ! 241: break; } /* abort sync */ ! 242: if(!DCDHIGH) ! 243: break; ! 244: mswait(0); ! 245: i++; } ! 246: if(i==180) { ! 247: i=rioctl(TXBC); ! 248: lprintf("timeout(sync) %04X %04X\r\n",i,rioctl(IOFO)); ! 249: outcom(7); ! 250: lputc(7); ! 251: rioctl(IOCS|PAUSE); } ! 252: if(rioctl(IOSTATE)&ABORT) ! 253: sys_status|=SS_ABORT; ! 254: rioctl(IOCS|ABORT); } ! 255: } ! 256: ! 257: /*****************************************************************************/ ! 258: /* Initializes com i/o routines and sets baud rate */ ! 259: /*****************************************************************************/ ! 260: void comini() ! 261: { ! 262: int i; ! 263: #ifndef __FLAT__ ! 264: uint base=0xffff; ! 265: #endif ! 266: ! 267: if(sys_status&SS_COMISR) /* Already installed */ ! 268: return; ! 269: lprintf("\r\nInitializing COM port %u: ",com_port); ! 270: #ifndef __FLAT__ ! 271: switch(com_base) { ! 272: case 0xb: ! 273: lputs("PC BIOS"); ! 274: break; ! 275: case 0xd: ! 276: lputs("DigiBoard"); ! 277: break; ! 278: case 0xe: ! 279: lputs("PS/2 BIOS"); ! 280: break; ! 281: case 0xf: ! 282: lputs("FOSSIL"); ! 283: break; ! 284: case 0: ! 285: base=com_port; ! 286: lputs("UART I/O (BIOS), "); ! 287: if(com_irq) ! 288: lprintf("IRQ %d",com_irq); ! 289: else lputs("default IRQ"); ! 290: break; ! 291: default: ! 292: base=com_base; ! 293: lprintf("UART I/O %Xh, ",com_base); ! 294: if(com_irq) ! 295: lprintf("IRQ %d",com_irq); ! 296: else lputs("default IRQ"); ! 297: break; } ! 298: ! 299: if(base==0xffff) ! 300: lprintf(" channel %u",com_irq); ! 301: i=rioini(base,com_irq); ! 302: #else ! 303: #ifdef __OS2__ ! 304: if(rio_handle!=-1) // Already opened, prolly passed to SBBS4OS2 via cmd line ! 305: lprintf("handle %d",rio_handle); ! 306: #endif ! 307: i=rioini(com_port,0); ! 308: #endif ! 309: if(i) { ! 310: lprintf(" - Failed! (%d)\r\n",i); ! 311: bail(1); } ! 312: i=0; ! 313: if(mdm_misc&MDM_CTS) ! 314: i=CTSCK; ! 315: if(mdm_misc&MDM_RTS) ! 316: i|=RTSCK; ! 317: if(i) ! 318: rioctl(IOSM|i); /* set cts checking if hardware flow control */ ! 319: ! 320: #ifndef __FLAT__ ! 321: rioctl(TSTYPE|mswtyp); /* set time-slice API type */ ! 322: #endif ! 323: ! 324: rioctl(CPTON); /* ctrl-p translation */ ! 325: ! 326: if(addrio) { ! 327: lprintf("\r\nAdditional rioctl: %04Xh",addrio); ! 328: rioctl(addrio); } ! 329: ! 330: sys_status|=SS_COMISR; ! 331: } ! 332: ! 333: /****************************************************************************/ ! 334: /* Sets the current baud rate to either the current connect rate or the */ ! 335: /* DTE rate */ ! 336: /****************************************************************************/ ! 337: void setrate() ! 338: { ! 339: int i; ! 340: ! 341: if(online==ON_REMOTE && !(mdm_misc&MDM_STAYHIGH)) ! 342: dte_rate=cur_rate; ! 343: else ! 344: dte_rate=com_rate; ! 345: lprintf("\r\nSetting DTE rate: %lu baud",dte_rate); ! 346: #ifdef __FLAT__ ! 347: if((i=setbaud(dte_rate))!=0) { ! 348: #else ! 349: if((i=setbaud((uint)(dte_rate&0xffffL)))!=0) { ! 350: #endif ! 351: lprintf(" - Failed! (%d)\r\n",i); ! 352: bail(1); } ! 353: lputs(crlf); ! 354: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.