bintec-capi-isdnlogin/il_tty.c

161 lines
3.9 KiB
C
Raw Normal View History

2011-04-30 15:09:33 +00:00
#include "isdnlogin.h"
extern global_t global;
int tty_event(int fd)
{
size_t len;
call_t *ptrCall = global.calls;
static unsigned short usDataHandle;
char out[REG_CAPI_DATA_BLK_SIZE+1];
char *c = &out[1];
len = read(fd, c, sizeof(out));
/* check for read errors */
if (len <=0) {
switch(errno) {
case EBADF:
printf("read: bad filedescriptor!\n");
return 0;
case EFAULT:
printf("read: Buf points outside the allocated address space.\n");
return 0;
case EIO:
printf("read: An I/O error occurred while reading from the file system.\n");
return 0;
case EINTR:
printf("read: interrupted!\n");
return 0;
case EINVAL:
printf("read: The pointer associated with d was negative.\n");
return 0;
case EAGAIN:
printf("read: no data to read.\n");
return 0;
default:
printf("got read error = %d\n", len);
return 0;
break;
}
}
if (TTYS_ESCAPE_RECV == global.tty_state) {
switch (*c) {
case TERMINATE_CHAR:
global.endloop = E_LocalTerminate;
break;
#if WITH_UNFINISHED_XMODEM
case SENDFILE_CHAR:
/* this feature is not really working now, the first shot
* showed that it's much too slow for ISDN connections. So
* maybe i will never implement this. Also the prompt()
* feature breaks keepalive feature. readbyte() in xmodem.c
* won't work on other messages than DATAB3_IND, so a
* disconnect while in transfer will be ignored. Feel free to
* integrate this feature */
if (ptrCall) {
/* send first data now */
/* TODO: to be implemented here using prompt() function */
char buf[256];
prompt("Local file name? ", buf, sizeof(buf));
printf("buf=%s\n", buf);
ptrCall->xmodem = xmodem_open( ptrCall, 115200, 1, ptrCall->error_msg,
buf);
while ( SendXmodemData(ptrCall) );
if (ptrCall->error_msg) printf("XMODEM error: %s\n", ptrCall->error_msg);
}
break;
#endif
default:
/* nothing */
len++;
out[0] = ESCAPE_CHAR;
c = &out[0];
break;
}
global.tty_state = TTYS_ESCAPE_WAITFOR;
} else if (ESCAPE_CHAR == *c) {
/* eat the tilde */
global.tty_state = TTYS_ESCAPE_RECV;
return 0;
}
/* send data if in right state */
if ((ptrCall) && ptrCall->state == Connected) {
ptrCall->NotAcknowledged++; /* count pending confirms */
usDataHandle++;
capi2_datab3_req( ptrCall->capi_fd,
ptrCall->ident,
c,
len,
0,
usDataHandle);
}
return 0;
}
/* copied from /usr/src/lib/libc/gen/termios.c of FreeBSD because this
* is no POSIX compatible function and not available on any OS such as
* HP-UX or Solaris */
/*
* Make a pre-existing termios structure into "raw" mode: character-at-a-time
* mode with no characters interpreted, 8-bit data path.
*/
void mymakeraw(struct termios *t)
{
t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR);
t->c_iflag |= IGNBRK;
t->c_oflag &= ~OPOST;
t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN);
t->c_cflag &= ~(CSIZE|PARENB);
t->c_cflag |= CS8|CREAD;
t->c_cc[VMIN] = 1;
t->c_cc[VTIME] = 0;
}
void reset_terminal(void) {
/* restore old terminal opts */
tcsetattr(0,TCSANOW, &(global.oldtermopts));
}
void set_raw_terminal(void) {
struct termios scheisse;
/* set terminal to raw mode */
memcpy(&scheisse, &(global.oldtermopts), sizeof(scheisse));
mymakeraw(&scheisse);
tcsetattr(0,TCSANOW, &scheisse);
}
void prompt(char *promptmsg, char *inputbuf, size_t buf_len)
{
char *bufptr = inputbuf;
reset_terminal();
mypolldel(STDIN);
printf("%s", promptmsg);
while ((*bufptr = getchar())) {
if (*bufptr == '\n') break;
if (buf_len-- <= 0) break;
//printf("bufptr=%c buf_len=%d\n", *bufptr, buf_len);
bufptr++;
}
*bufptr = '\0';
//printf("end of conversation\n");
pollset( STDIN, POLLIN, tty_event);
set_raw_terminal();
}