home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / COMIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  9.4 KB  |  355 lines

  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. }
  355.