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