30 #include <sys/types.h>
32 #include <sys/ioctl.h>
77 Modem::Modem( KandyPrefs *kprefs, TQObject *parent,
const char *name ) :
78 TQObject(parent, name)
84 timer =
new TQTimer(
this,
"modemtimer" );
86 connect( timer, TQT_SIGNAL( timeout() ), TQT_SLOT( timerDone() ) );
99 void Modem::setSpeed(
int speed )
137 fprintf(stderr,
"Modem: setSpeed(): fallback to default speed.\n");
144 void Modem::setData(
int data )
164 void Modem::setParity(
char parity )
166 cflag &= ~( PARENB | PARODD );
170 else if ( parity ==
'O' )
171 cflag |= PARENB | PARODD;
175 void Modem::setStop(
int stop )
194 TQCString dev = TQFile::encodeName( (*prefs).serialDevice() );
195 const char *fdev = dev.data();
196 if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) {
197 emit errorMessage( i18n(
"Unable to open device '%1'. "
198 "Please check that you have sufficient permissions." )
203 tcflush( fd, TCIOFLUSH );
204 if ( tcgetattr( fd, &init_tty ) == -1 ) {
205 int errnumber = errno;
206 emit errorMessage( i18n(
"Communication setup failed (tcgetattr code: %1)" )
207 .arg(strerror(errnumber)) );
213 memset( &tty, 0,
sizeof( tty ) );
214 tty.c_iflag = IGNBRK | IGNPAR;
218 cfsetospeed( &tty, cspeed );
219 cfsetispeed( &tty, cspeed );
222 if ( tcsetattr( fd, TCSANOW, &tty ) == -1 ) {
223 emit errorMessage( i18n(
"tcsetattr() failed." ) );
229 sn =
new TQSocketNotifier( fd, TQSocketNotifier::Read,
this,
230 "modemsocketnotifier" );
232 connect( sn, TQT_SIGNAL( activated(
int ) ), TQT_SLOT( readChar(
int ) ) );
248 tcflush( fd, TCIOFLUSH );
249 tcsetattr( fd, TCSANOW, &init_tty );
265 tcflush( fd, TCIOFLUSH );
274 bool Modem::lockDevice()
280 is_locked = !dev_lock( (*prefs).serialDevice().local8Bit() );
282 emit errorMessage( i18n(
"Unable to lock device '%1'." ).arg(
283 (*prefs).serialDevice() ));
290 TQStringList pathList;
291 TQString fileName, content;
293 pathList = TQStringList::split(
"/", (*prefs).serialDevice() );
294 fileName = (*prefs).lockDirectory() +
"/LCK.." + pathList.last();
296 if ( !access( TQFile::encodeName( fileName ).data(), F_OK ) ) {
300 if ( ( lfd = ::open( TQFile::encodeName( fileName ), O_RDONLY ) ) < 0 ) {
301 emit errorMessage( i18n(
"Unable to open lock file '%1'.")
306 count = read( lfd, buf, 79 );
309 emit errorMessage( i18n(
"Unable to read lock file '%1'.")
317 count = sscanf( buf,
"%d", &pid );
318 if ( ( count != 1 ) || ( pid <= 0 ) ) {
319 emit errorMessage( i18n(
"Unable to get PID from file '%1'.")
324 if ( !kill( (pid_t) pid, 0 ) ) {
325 emit errorMessage( i18n(
"Process with PID %1, which is locking the device, is still running.")
330 if ( errno != ESRCH ) {
331 emit errorMessage( i18n(
"Unable to emit signal to PID of existing lock file.") );
336 if ( ( lfd = creat( TQFile::encodeName( fileName ).data(), 0644 ) ) == -1 ) {
337 emit errorMessage( i18n(
"Unable to create lock file '%1'. "
338 "Please check that you have sufficient permissions.")
343 pid = (int) getpid();
344 pw = getpwuid( getuid() );
345 content.sprintf(
"%08d %s %s", pid,
"kandy", pw->pw_name );
346 write( lfd, TQFile::encodeName( content ).data(), content.length() );
356 void Modem::unlockDevice()
359 dev_unlock( (*prefs).serialDevice().local8Bit(), getpid() );
362 TQStringList pathList = TQStringList::split(
"/", (*prefs).serialDevice() );
364 TQFile::remove( (*prefs).lockDirectory() +
"/LCK.." + pathList.last() );
378 fprintf( stderr,
"Modem: dsrOn(): File not open.\n" );
383 if ( ioctl( fd, TIOCMGET, &flags ) == -1 ) {
385 fprintf( stderr,
"Modem: dsrOn(): ioctl() failed.\n" );
390 return ( flags & TIOCM_DSR ) != 0;
401 fprintf( stderr,
"Modem: ctsOn(): File not open.\n" );
406 if ( ioctl( fd, TIOCMGET, &flags ) == -1) {
408 fprintf( stderr,
"Modem: ctsOn(): ioctl() failed.\n" );
413 return ( flags & TIOCM_CTS ) != 0;
417 void Modem::writeChar(
const char c )
419 write( fd, (
const void *) &c, 1 );
423 void Modem::writeLine(
const char *line )
425 kdDebug() <<
"Modem::writeLine(): " << line << endl;
427 write( fd, (
const void *) line, strlen( line ) );
432 void Modem::timerStart(
int msec )
434 timer->start( msec,
true );
438 void Modem::receiveXModem(
bool crc )
440 disconnect( sn, 0,
this, 0 );
441 connect( sn, TQT_SIGNAL( activated(
int ) ), TQT_SLOT( readXChar(
int ) ) );
459 void Modem::abortXModem()
464 emit xmodemDone(
false );
468 void Modem::timerDone()
471 fprintf( stderr,
"Modem: timeout, xstate = %d.\n", xstate );
502 emit xmodemDone(
false );
513 void Modem::readChar(
int )
518 while ( read( fd, (
void *) &c, 1 ) == 1 ) {
520 buffer[ bufpos ] = 0;
522 emit gotLine( (
const char *) buffer );
525 if ( ( bufpos < 1000 ) && ( c !=
'\r' ) )
526 buffer[ bufpos++ ] = c;
531 void Modem::readXChar(
int )
534 static uchar crc_hi, block, cblock;
537 while ( read( fd, (
void *) &c, 1 ) == 1 ) {
563 emit xmodemDone(
true );
583 buffer[ bufpos++ ] = c;
584 if ( bufpos == xsize ) {
601 if ( (uchar) ( block ^ cblock ) != 0xff ) {
605 if ( block+1 == xblock ) {
609 if ( block != xblock ) {
613 emit xmodemDone(
false );
617 if ( ( (ushort) crc_hi << 8 | (ushort) c ) != calcCRC() ) {
622 if ( c != calcChecksum() ) {
629 emit gotXBlock( buffer, xsize );
649 cflag = CS8 | CREAD | CLOCAL;
666 disconnect( sn, 0,
this, 0 );
667 connect( sn, TQT_SIGNAL( activated(
int ) ), TQT_SLOT( readChar(
int ) ) );
672 uchar Modem::calcChecksum()
678 for ( i = 0; i < xsize; i++ )
685 ushort Modem::calcCRC()
691 for ( i = 0; i < xsize; i++ ) {
692 c ^= (ushort) buffer[ i ] << 8;
693 for ( j = 0; j < 8; j++ )