30 #include <sys/types.h>
32 #include <sys/ioctl.h>
46 #include <tdelocale.h>
78 Modem::Modem( KandyPrefs *kprefs, TQObject *parent, const char *name ) :
79 TQObject(parent, name), fd(-1)
85 timer = new TQTimer( this, "modemtimer" );
86 TQ_CHECK_PTR( timer );
87 connect( timer, TQ_SIGNAL( timeout() ), TQ_SLOT( timerDone() ) );
100 void Modem::setSpeed( int speed )
138 fprintf(stderr, "Modem: setSpeed(): fallback to default speed.\n");
145 void Modem::setData( int data )
165 void Modem::setParity( char parity )
167 cflag &= ~( PARENB | PARODD );
171 else if ( parity == 'O' )
172 cflag |= PARENB | PARODD;
176 void Modem::setStop( int stop )
193 TQCString dev = TQFile::encodeName( (*prefs).serialDevice() );
194 const char *fdev = dev.data();
195 if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) {
196 emit errorMessage( i18n( "Unable to open device '%1'. "
197 "Please check that you have sufficient permissions." )
206 tcflush( fd, TCIOFLUSH );
207 if ( tcgetattr( fd, &init_tty ) == -1 ) {
208 int errnumber = errno;
209 emit errorMessage( i18n( "Communication setup failed (tcgetattr code: %1)" )
210 .arg(strerror(errnumber)) );
217 memset( &tty, 0, sizeof( tty ) );
218 tty.c_iflag = IGNBRK | IGNPAR;
222 cfsetospeed( &tty, cspeed );
223 cfsetispeed( &tty, cspeed );
226 if ( tcsetattr( fd, TCSANOW, &tty ) == -1 ) {
227 emit errorMessage( i18n( "tcsetattr() failed." ) );
234 sn = new TQSocketNotifier( fd, TQSocketNotifier::Read, this,
235 "modemsocketnotifier" );
237 connect( sn, TQ_SIGNAL( activated( int ) ), TQ_SLOT( readChar( int ) ) );
255 tcflush( fd, TCIOFLUSH );
256 tcsetattr( fd, TCSANOW, &init_tty );
270 tcflush( fd, TCIOFLUSH );
275 bool Modem::lockDevice()
280 if (flock(fd, LOCK_EX))
284 emit errorMessage(i18n( "Unable to lock device '%1'.").arg((*prefs).serialDevice()));
295 void Modem::unlockDevice()
297 if (fd != -1 && is_locked)
312 fprintf( stderr, "Modem: dsrOn(): File not open.\n" );
317 if ( ioctl( fd, TIOCMGET, &flags ) == -1 ) {
319 fprintf( stderr, "Modem: dsrOn(): ioctl() failed.\n" );
324 return ( flags & TIOCM_DSR ) != 0;
335 fprintf( stderr, "Modem: ctsOn(): File not open.\n" );
340 if ( ioctl( fd, TIOCMGET, &flags ) == -1) {
342 fprintf( stderr, "Modem: ctsOn(): ioctl() failed.\n" );
347 return ( flags & TIOCM_CTS ) != 0;
351 void Modem::writeChar( const char c )
353 write( fd, ( const void *) &c, 1 );
357 void Modem::writeLine( const char *line )
359 kdDebug() << "Modem::writeLine(): " << line << endl;
361 write( fd, ( const void *) line, strlen( line ) );
366 void Modem::timerStart( int msec )
368 timer->start( msec, true );
372 void Modem::receiveXModem( bool crc )
374 disconnect( sn, 0, this, 0 );
375 connect( sn, TQ_SIGNAL( activated( int ) ), TQ_SLOT( readXChar( int ) ) );
393 void Modem::abortXModem()
398 emit xmodemDone( false );
402 void Modem::timerDone()
405 fprintf( stderr, "Modem: timeout, xstate = %d.\n", xstate );
436 emit xmodemDone( false );
447 void Modem::readChar( int )
452 while ( read( fd, ( void *) &c, 1 ) == 1 ) {
454 buffer[ bufpos ] = 0;
456 emit gotLine( ( const char *) buffer );
459 if ( ( bufpos < 1000 ) && ( c != '\r' ) )
460 buffer[ bufpos++ ] = c;
465 void Modem::readXChar( int )
468 static uchar crc_hi, block, cblock;
471 while ( read( fd, ( void *) &c, 1 ) == 1 ) {
497 emit xmodemDone( true );
517 buffer[ bufpos++ ] = c;
518 if ( bufpos == xsize ) {
535 if ( (uchar) ( block ^ cblock ) != 0xff ) {
539 if ( block+1 == xblock ) {
543 if ( block != xblock ) {
547 emit xmodemDone( false );
551 if ( ( (ushort) crc_hi << 8 | (ushort) c ) != calcCRC() ) {
556 if ( c != calcChecksum() ) {
563 emit gotXBlock( buffer, xsize );
583 cflag = CS8 | CREAD | CLOCAL;
600 disconnect( sn, 0, this, 0 );
601 connect( sn, TQ_SIGNAL( activated( int ) ), TQ_SLOT( readChar( int ) ) );
606 uchar Modem::calcChecksum()
612 for ( i = 0; i < xsize; i++ )
619 ushort Modem::calcCRC()
625 for ( i = 0; i < xsize; i++ ) {
626 c ^= (ushort) buffer[ i ] << 8;
627 for ( j = 0; j < 8; j++ )
|