-rw-r--r-- | noncore/apps/opie-console/dialer.cpp | 24 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_modem.cpp | 10 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_serial.cpp | 7 |
3 files changed, 29 insertions, 12 deletions
diff --git a/noncore/apps/opie-console/dialer.cpp b/noncore/apps/opie-console/dialer.cpp index ce2b688..8524422 100644 --- a/noncore/apps/opie-console/dialer.cpp +++ b/noncore/apps/opie-console/dialer.cpp @@ -1,311 +1,319 @@ #include "dialer.h" #include <qlayout.h> #include <qprogressbar.h> #include <qlabel.h> #include <qpushbutton.h> #include <qapp.h> #include <qtimer.h> #include <qmessagebox.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <errno.h> // State machine: | When an error occurs, we don't have to // | reset everything. // (init) <------+ | But if the user wants to reset, // | | | we stop dialing immediately. // v | | // (options) ----+ | Following the state machine is necessary // | \ | to get determinable results. // v ^ | // (dial) ----+ | // | ^ | // v | | // (online) --+ | // | | // v | // from atconfigdialog //initStringLine->setText( config.readEntry("InitString", MODEM_DEFAULT_INIT_STRING ) ); //resetStringLine->setText( config.readEntry("ResetString", MODEM_DEFAULT_RESET_STRING ) ); //dialPref1Line->setText( config.readEntry("DialPrefix1", MODEM_DEFAULT_DIAL_PREFIX1 ) ); //dialSuf1Line->setText( config.readEntry("DialSuffix1", MODEM_DEFAULT_DIAL_SUFFIX1 ) ); //dialPref2Line->setText( config.readEntry("DialPrefix2", MODEM_DEFAULT_DIAL_PREFIX1 ) ); //dialSuf2Line->setText( config.readEntry("DialSuffix2", MODEM_DEFAULT_DIAL_SUFFIX1 ) ); //dialPref3Line->setText( config.readEntry("DialPrefix3", MODEM_DEFAULT_DIAL_PREFIX1 ) ); //dialSuf3Line->setText( config.readEntry("DialSuffix3", MODEM_DEFAULT_DIAL_SUFFIX1 ) ); //connectLine->setText( config.readEntry("DefaultConnect" MODEM_DEFAULT_CONNECT_STRING ) ); //hangupLine->setText( config.readEntry("HangupString", MODEM_DEFAULT_HANGUP_STRING ) ); // from modemconfigwidget //int rad_flow = prof.readNumEntry("Flow"); //int rad_parity = prof.readNumEntry("Parity"); //int speed = prof.readNumEntry("Speed"); //QString number = prof.readEntry("Number"); Dialer::Dialer(const Profile& profile, int fd, QWidget *parent, const char *name) : QDialog(parent, name, true), m_fd(fd), m_profile(profile) { QVBoxLayout *vbox; QLabel *desc; //m_profile.writeEntry("InitString", "ATZ"); //m_profile.writeEntry("DialPrefix1", "ATDT"); //m_profile.writeEntry("Termination", "\n"); usercancel = 0; cleanshutdown = 0; // fcntl(m_fd, F_SETFL, O_NONBLOCK); desc = new QLabel(QObject::tr("Dialing number: %1").arg(m_profile.readEntry("Number")), this); progress = new QProgressBar(this); status = new QLabel("", this); status->setFrameStyle(QFrame::Panel | QFrame::Sunken); cancel = new QPushButton(QObject::tr("Cancel"), this); vbox = new QVBoxLayout(this, 2); vbox->add(desc); vbox->add(progress); vbox->add(status); vbox->add(cancel); connect(cancel, SIGNAL(clicked()), SLOT(slotCancel())); show(); QTimer::singleShot(500, this, SLOT(slotAutostart())); } Dialer::~Dialer() { } void Dialer::setHangupOnly() { state = state_cancel; usercancel = 1; + send("+++ATH\r"); } void Dialer::slotCancel() { if(state != state_online) { usercancel = 1; reset(); } - else accept(); + else { + accept(); + } } void Dialer::reset() { qWarning("reset"); switchState(state_cancel); } void Dialer::slotAutostart() { //state = state_preinit; dial(m_profile.readEntry("Number")); } void Dialer::dial(const QString& number) { while(state != state_online) { if(!usercancel) { state = state_preinit; trydial(number); } else break; } if(usercancel) { // modem hangup trydial(QString::null); reject(); } } void Dialer::trydial(const QString& number) { qWarning("TryDial:%s", number.latin1() ); if(state != state_cancel) switchState(state_preinit); if(cleanshutdown) { qWarning("HangupString " + m_profile.readEntry("HangupString")); - send(m_profile.readEntry("HangupString")); - //send("+++ATH"); - send(""); + //send(m_profile.readEntry("HangupString")); + send("+++ATH\r"); + //send(""); } if(state != state_cancel) { switchState(state_init); //send("ATZ"); qWarning("Init String " + m_profile.readEntry("InitString") ); // send(m_profile.readEntry("InitString", "AT")); send("AT\r"); QString response2 = receive(); if(!response2.contains("\nOK\r")) reset(); } /* if(state != state_cancel) { switchState(state_options); qWarning("ATM3l3"); send("ATM3L3\r"); QString response3 = receive(); if(!response3.contains("\nOK\r")) reset(); } */ if(state != state_cancel) { switchState(state_dialtone); send("ATX1\r"); QString response4 = receive(); if(!response4.contains("\nOK\r")) reset(); } if(state != state_cancel) { qWarning("progress"); switchState(state_dialing); send(QString("ATDT %1\r").arg(number)); // send(QString("%1 %2").arg(m_profile.readEntry("DialPrefix1")).arg(number)); QString response5 = receive(); - if(!response5.contains("\n" + m_profile.readEntry("DefaultConnect"))) + if(!response5.contains("CONNECT") ) { if(response5.contains("BUSY")) switchState(state_dialing); else { QMessageBox::warning(this, QObject::tr("Failure"), QObject::tr("Dialing the number failed.")); slotCancel(); } } } + if(state != state_cancel) { - switchState(state_online); + state = state_online; + slotCancel(); } } void Dialer::send(const QString& msg) { QString m = msg; int bytes; QString termination; qWarning("Sending: %s", m.latin1()); /* termination = "\r"; //termination = m_profile.readEntry("Termination"); if(termination == "\n") m = m + "\n"; else if(termination == "\r") m = m + "\r"; else m = m + "\r\n"; */ m = m.replace(QRegExp("\n"), "\r"); bytes = ::write(m_fd, m.local8Bit(), strlen(m.local8Bit())); if(bytes < 0) { reset(); } } QString Dialer::receive() { QString buf; char buffer[1024]; int ret; int counter = 0; while(1) { ret = ::read(m_fd, buffer, sizeof(buffer)); if(ret > 0) { for(int i = 0; i < ret; i++) buffer[i] = buffer[i] & 0x7F; buffer[ret] = 0; - //qWarning("Got: '%s'", buffer); + qWarning("Got: %s", buffer); buf.append(QString(buffer)); if(buf.contains("OK") || buf.contains("ERROR") || buf.contains("CONNECT") || (buf.contains("BUSY"))) { //qWarning("Receiving: '%s'", buf.latin1()); cleanshutdown = 1; return buf; - } + }else if (buf.contains("NO CARRIER") || buf.contains("NO DIALTONE") ) { + cleanshutdown = 1; + return QString::null; + } } else if(ret < 0) { if(errno != EAGAIN) reset(); else if(!(counter++ % 100)) qApp->processEvents(); } else if(!(counter++ % 100)) qApp->processEvents(); if(usercancel) return QString::null; } cleanshutdown = 1; return QString::null; } void Dialer::switchState(int newstate) { int oldstate = state; state = newstate; switch(state) { case state_cancel: status->setText(QObject::tr("Cancelling...")); progress->setProgress(0); break; case state_preinit: status->setText(QObject::tr("Searching modem")); progress->setProgress(10); break; case state_init: status->setText(QObject::tr("Initializing...")); progress->setProgress(20); break; case state_options: status->setText(QObject::tr("Reset speakers")); progress->setProgress(30); break; case state_dialtone: status->setText(QObject::tr("Turning off dialtone")); progress->setProgress(40); break; case state_dialing: if(oldstate != state_dialing) status->setText(QObject::tr("Dial number")); else status->setText(QObject::tr("Line busy, redialing number")); progress->setProgress(50); break; case state_online: status->setText(QObject::tr("Connection established")); progress->setProgress(100); cancel->setText(QObject::tr("Dismiss")); break; } } diff --git a/noncore/apps/opie-console/io_modem.cpp b/noncore/apps/opie-console/io_modem.cpp index b7901b9..896c24f 100644 --- a/noncore/apps/opie-console/io_modem.cpp +++ b/noncore/apps/opie-console/io_modem.cpp @@ -1,93 +1,95 @@ #include "io_modem.h" #include "dialer.h" IOModem::IOModem( const Profile &profile ) : IOSerial( profile ) { m_profile = profile; } IOModem::~IOModem() { } void IOModem::close() { // Hangup, discarding result - int fd = rawIO(); - Dialer d(m_profile, fd); +// int fd = rawIO(); + internDetach(); + Dialer d(m_profile, m_fd); d.setHangupOnly(); - d.exec(); - closeRawIO(fd); + //d.exec(); + internAttach(); +// closeRawIO(fd); IOSerial::close(); } bool IOModem::open() { bool ret = IOSerial::open(); if(!ret) return false; // int fd = rawIO(); internDetach(); Dialer d(m_profile, m_fd); int result = d.exec(); internAttach(); // closeRawIO(fd); if(result == QDialog::Accepted) { return true; } else { close(); return false; } } void IOModem::reload( const Profile &config ) { m_device = config.readEntry("Device", MODEM_DEFAULT_DEVICE); m_baud = config.readNumEntry("Baud", MODEM_DEFAULT_BAUD); m_parity = config.readNumEntry("Parity", MODEM_DEFAULT_PARITY); m_dbits = config.readNumEntry("DataBits", MODEM_DEFAULT_DBITS); m_sbits = config.readNumEntry("StopBits", MODEM_DEFAULT_SBITS); m_flow = config.readNumEntry("Flow", MODEM_DEFAULT_FLOW); m_initString = config.readEntry("InitString", MODEM_DEFAULT_INIT_STRING ); m_resetString = config.readEntry("ResetString", MODEM_DEFAULT_RESET_STRING ); m_dialPref1 = config.readEntry("DialPrefix1", MODEM_DEFAULT_DIAL_PREFIX1 ); m_dialSuf1 = config.readEntry("DialSuffix1", MODEM_DEFAULT_DIAL_SUFFIX1 ); m_dialPref2 = config.readEntry("DialPrefix2", MODEM_DEFAULT_DIAL_PREFIX1 ); m_dialSuf2 = config.readEntry("DialSuffix2", MODEM_DEFAULT_DIAL_SUFFIX1 ); m_dialPref3 = config.readEntry("DialPrefix3", MODEM_DEFAULT_DIAL_PREFIX1 ); m_dialSuf3 = config.readEntry("DialSuffix3", MODEM_DEFAULT_DIAL_SUFFIX1 ); m_connect = config.readEntry("DefaultConnect" MODEM_DEFAULT_CONNECT_STRING ); m_hangup = config.readEntry("HangupString", MODEM_DEFAULT_HANGUP_STRING ); m_cancel = config.readEntry("CancelString", MODEM_DEFAULT_CANCEL_STRING ); m_dialTime = config.readNumEntry("DialTime", MODEM_DEFAULT_DIAL_TIME ); m_delayRedial = config.readNumEntry("DelayRedial", MODEM_DEFAULT_DELAY_REDIAL ); m_numberTries = config.readNumEntry("NumberTries", MODEM_DEFAULT_NUMBER_TRIES ); m_dtrDropTime = config.readNumEntry("DTRDRopTime", MODEM_DEFAULT_DTR_DROP_TIME ); m_bpsDetect = config.readBoolEntry("BPSDetect", MODEM_DEFAULT_BPS_DETECT ); m_dcdLines = config.readBoolEntry("DCDLines", MODEM_DEFAULT_DCD_LINES ); m_multiLineUntag = config.readBoolEntry("MultiLineUntag", MODEM_DEFAULT_MULTI_LINE_UNTAG ); } QString IOModem::identifier() const { return "modem"; } QString IOModem::name() const { return "Modem IO Layer"; } void IOModem::slotExited(OProcess* proc ){ close(); /* delete it afterwards */ delete proc; } diff --git a/noncore/apps/opie-console/io_serial.cpp b/noncore/apps/opie-console/io_serial.cpp index 0540d9e..03e92dd 100644 --- a/noncore/apps/opie-console/io_serial.cpp +++ b/noncore/apps/opie-console/io_serial.cpp @@ -1,228 +1,235 @@ #include <fcntl.h> #include <termios.h> #include <errno.h> #include <unistd.h> +#include <stdio.h> + #include "io_serial.h" IOSerial::IOSerial(const Profile &config) : IOLayer(config) { m_read = 0l; m_error = 0l; m_fd = 0; m_connected = false; reload(config); } IOSerial::~IOSerial() { if (m_fd) { close(); } } void IOSerial::send(const QByteArray &data) { if (m_fd) { write(m_fd, data.data(), data.size()); } else { emit error(Refuse, tr("Not connected")); } } void IOSerial::close() { if (m_fd) { delete m_read; delete m_error; ::close(m_fd); m_fd = 0; m_connected = false; } else { m_connected = false; emit error(Refuse, tr("Not connected")); } } bool IOSerial::open() { if (!m_fd) { struct termios tty; m_fd = ::open(m_device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (m_fd < 0) { emit error(CouldNotOpen, strerror(errno)); m_fd = 0; return FALSE; } tcgetattr(m_fd, &tty); /* Baud rate */ int speed = baud(m_baud); if (speed == -1) { emit error(Refuse, tr("Invalid baud rate")); } cfsetospeed(&tty, speed); cfsetispeed(&tty, speed); /* Take care of Space / Mark parity */ if (m_dbits == 7 && (m_parity == ParitySpace || m_parity == ParityMark)) { m_dbits = 8; } /* Data bits */ switch (m_dbits) { case 5: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5; break; case 6: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6; break; case 7: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7; break; case 8: tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; break; default: break; } /* Raw, no echo mode */ tty.c_iflag = IGNBRK; tty.c_lflag = 0; tty.c_oflag = 0; tty.c_cflag |= CLOCAL | CREAD; /* Stop bits */ if (m_sbits == 2) { tty.c_cflag |= CSTOPB; } else { tty.c_cflag &= ~CSTOPB; } tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 5; /* Flow control */ if (m_flow & FlowSW) tty.c_iflag |= IXON | IXOFF; else tty.c_iflag &= ~(IXON|IXOFF|IXANY); if (m_flow & FlowHW) tty.c_cflag |= CRTSCTS; else tty.c_cflag &= ~CRTSCTS; /* Parity */ tty.c_cflag &= ~(PARENB | PARODD); if (m_parity & ParityEven) tty.c_cflag |= PARENB; else if (m_parity & ParityOdd) tty.c_cflag |= (PARENB | PARODD); /* Set the changes */ tcsetattr(m_fd, TCSANOW, &tty); /* Notifications on read & errors */ m_read = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); m_error = new QSocketNotifier(m_fd, QSocketNotifier::Exception, this); connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); m_connected = false; return TRUE; } else { emit error(Refuse, tr("Device is already connected")); m_fd = 0; return FALSE; } } void IOSerial::reload(const Profile &config) { m_device = config.readEntry("Device", SERIAL_DEFAULT_DEVICE); m_baud = config.readNumEntry("Speed", SERIAL_DEFAULT_BAUD); m_parity = config.readNumEntry("Parity", SERIAL_DEFAULT_PARITY); m_dbits = config.readNumEntry("DataBits", SERIAL_DEFAULT_DBITS); m_sbits = config.readNumEntry("StopBits", SERIAL_DEFAULT_SBITS); m_flow = config.readNumEntry("Flow", SERIAL_DEFAULT_FLOW); } int IOSerial::baud(int baud) const { switch (baud) { case 300: return B300; break; case 600: return B600; break; case 1200: return B1200; break; case 2400: return B2400; break; case 4800: return B4800; break; case 9600: return B9600; break; case 19200: return B19200; break; case 38400: return B38400; break; case 57600: return B57600; break; case 115200: return B115200; break; } return -1; } void IOSerial::errorOccured() { emit error(ClosedUnexpected, strerror(errno)); close(); } void IOSerial::dataArrived() { QByteArray array(4097); int len = read(m_fd, array.data(), 4096); if (len == 0) close(); if (len < 0) return; + qWarning("got from layer"); + for (int i = 0; i < len; i++ ) { + printf("%c", array[i] ); + } + printf("\n"); array.resize( len ); emit received(array); } QString IOSerial::identifier() const { return "serial"; } QString IOSerial::name() const { return "RS232 Serial IO Layer"; } int IOSerial::rawIO()const { if (m_read ) disconnect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); if (m_error ) disconnect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); int fd = ::open(m_device, O_RDWR ); return fd; }; void IOSerial::closeRawIO(int fd) { if (m_read ) connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); if (m_error ) connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); ::close( fd ); } QBitArray IOSerial::supports()const { QBitArray ar(3); ar[0] = ar[2] = 0; ar[1] = 1; return ar; } bool IOSerial::isConnected() { return m_connected; } /* * this is used to give the * class below IOSerial * the possibility of * exclusive usage */ void IOSerial::internDetach() { if (m_read ) disconnect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); if (m_error ) disconnect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); } /* * give power back */ void IOSerial::internAttach() { if (m_read ) connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); if (m_error ) connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); } |