Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dialer.cpp

Go to the documentation of this file.
00001 #include "dialer.h"
00002 #include "io_modem.h"
00003 
00004 /* QT */
00005 #include <qlayout.h>
00006 #include <qprogressbar.h>
00007 #include <qlabel.h>
00008 #include <qpushbutton.h>
00009 #include <qapp.h>
00010 #include <qtimer.h>
00011 #include <qmessagebox.h>
00012 
00013 /* STD */
00014 #include <unistd.h>
00015 #include <string.h>
00016 #include <fcntl.h>
00017 #include <errno.h>
00018 
00019 // State machine:          | When an error occurs, we don't have to
00020 //                         | reset everything.
00021 // (init) <------+         | But if the user wants to reset,
00022 //   |           |         | we stop dialing immediately.
00023 //   v           |         |
00024 // (options) ----+         | Following the state machine is necessary
00025 //   |       \             | to get determinable results.
00026 //   v        ^            |
00027 // (dial) ----+            |
00028 //   |        ^            |
00029 //   v        |            |
00030 // (online) --+            |
00031 //   |                     |
00032 //   v                     |
00033 
00034 
00035 // from atconfigdialog
00036 //initStringLine->setText( config.readEntry("InitString", MODEM_DEFAULT_INIT_STRING ) );
00037 //resetStringLine->setText( config.readEntry("ResetString", MODEM_DEFAULT_RESET_STRING ) );
00038 //dialPref1Line->setText( config.readEntry("DialPrefix1", MODEM_DEFAULT_DIAL_PREFIX1 ) );
00039 //dialSuf1Line->setText( config.readEntry("DialSuffix1", MODEM_DEFAULT_DIAL_SUFFIX1 ) );
00040 //dialPref2Line->setText( config.readEntry("DialPrefix2", MODEM_DEFAULT_DIAL_PREFIX1 ) );
00041 //dialSuf2Line->setText( config.readEntry("DialSuffix2", MODEM_DEFAULT_DIAL_SUFFIX1 ) );
00042 //dialPref3Line->setText( config.readEntry("DialPrefix3", MODEM_DEFAULT_DIAL_PREFIX1 ) );
00043 //dialSuf3Line->setText( config.readEntry("DialSuffix3", MODEM_DEFAULT_DIAL_SUFFIX1 ) );
00044 //connectLine->setText( config.readEntry("DefaultConnect" MODEM_DEFAULT_CONNECT_STRING ) );
00045 //hangupLine->setText( config.readEntry("HangupString", MODEM_DEFAULT_HANGUP_STRING ) );
00046 
00047 // from modemconfigwidget
00048 //int rad_flow = prof.readNumEntry("Flow");
00049 //int rad_parity = prof.readNumEntry("Parity");
00050 //int speed = prof.readNumEntry("Speed");
00051 //QString number = prof.readEntry("Number");
00052 
00053 Dialer::Dialer(const Profile& profile, int fd, QWidget *parent, const char *name)
00054 : QDialog(parent, name, true), m_fd(fd), m_profile(profile)
00055 {
00056         QVBoxLayout *vbox;
00057         QLabel *desc;
00058 
00059 
00060         usercancel = 0;
00061         cleanshutdown = 0;
00062 
00063 
00064         desc = new QLabel(QObject::tr("Dialing number: %1").arg(m_profile.readEntry("Number")), this);
00065         progress = new QProgressBar(this);
00066         status = new QLabel("", this);
00067         status->setFrameStyle(QFrame::Panel | QFrame::Sunken);
00068         cancel = new QPushButton(QObject::tr("Cancel"), this);
00069 
00070         vbox = new QVBoxLayout(this, 2);
00071         vbox->add(desc);
00072         vbox->add(progress);
00073         vbox->add(status);
00074         vbox->add(cancel);
00075 
00076         connect(cancel, SIGNAL(clicked()), SLOT(slotCancel()));
00077 
00078         show();
00079 
00080         QTimer::singleShot(500, this, SLOT(slotAutostart()));
00081 }
00082 
00083 Dialer::~Dialer()
00084 {
00085 }
00086 
00087 void Dialer::setHangupOnly()
00088 {
00089         state = state_cancel;
00090         usercancel = 1;
00091         send( m_profile.readEntry("HangupString", MODEM_DEFAULT_HANGUP_STRING )+"\r" );
00092 }
00093 
00094 void Dialer::slotCancel()
00095 {
00096         if(state != state_online)
00097         {
00098                 usercancel = 1;
00099                 reset();
00100         }
00101         else {
00102             accept();
00103         }
00104 }
00105 
00106 void Dialer::reset()
00107 {
00108         switchState(state_cancel);
00109 }
00110 
00111 void Dialer::slotAutostart()
00112 {
00113         //state = state_preinit;
00114         dial(m_profile.readEntry("Number"));
00115 }
00116 
00117 void Dialer::dial(const QString& number)
00118 {
00119         while(state != state_online)
00120         {
00121                 if(!usercancel)
00122                 {
00123                         state = state_preinit;
00124                         trydial(number);
00125                 }
00126                 else break;
00127         }
00128 
00129         if(usercancel)
00130         {
00131                 // modem hangup
00132                 trydial(QString::null);
00133                 reject();
00134         }
00135 }
00136 
00137 void Dialer::trydial(const QString& number)
00138 {
00139         if(state != state_cancel) switchState(state_preinit);
00140         if(cleanshutdown)
00141         {
00142             send(m_profile.readEntry("HangupString", MODEM_DEFAULT_HANGUP_STRING ) + "\r");
00143         }
00144 
00145         if(state != state_cancel)
00146         {
00147                 switchState(state_init);
00148                 send(m_profile.readEntry("InitString",MODEM_DEFAULT_INIT_STRING ) + "\r");
00149                 QString response2 = receive();
00150                 if(!response2.contains("\nOK\r"))
00151                         reset();
00152         }
00153 
00154 /*      if(state != state_cancel)
00155         {
00156                 switchState(state_options);
00157 
00158                 owarn << "ATM3l3" << oendl; 
00159                 send("ATM3L3\r");
00160                 QString response3 = receive();
00161                 if(!response3.contains("\nOK\r"))
00162                         reset();
00163         }
00164 */
00165 
00166         if(state != state_cancel)
00167         {
00168                 switchState(state_dialtone);
00169 
00170                 send("ATX1\r");
00171                 QString response4 = receive();
00172                 if(!response4.contains("\nOK\r"))
00173                         reset();
00174         }
00175 
00176         if(state != state_cancel)
00177         {
00178                 switchState(state_dialing);
00179 
00180 //              send(QString("ATDT %1\r").arg(number));
00181                 send(QString("%1 %2\r").arg(m_profile.readEntry("DialPrefix1", MODEM_DEFAULT_DIAL_PREFIX1 ))
00182                      .arg(number));
00183 
00184                 QString response5 = receive();
00185                 if(!response5.contains("CONNECT") )
00186                 {
00187                         if(response5.contains("BUSY"))
00188                                 switchState(state_dialing);
00189                         else
00190                         {
00191                                 QMessageBox::warning(this,
00192                                         QObject::tr("Failure"),
00193                                         QObject::tr("<qt>Dialing the number failed.</qt>"));
00194                                 slotCancel();
00195                         }
00196                 }
00197         }
00198 
00199 
00200         if(state != state_cancel)
00201         {
00202             state = state_online;
00203             slotCancel();
00204         }
00205 }
00206 
00207 void Dialer::send(const QString& msg)
00208 {
00209         QString m = msg;
00210         int bytes;
00211         QString termination;
00212 
00213 
00214 /*      termination = "\r";
00215         //termination = m_profile.readEntry("Termination");
00216         if(termination == "\n") m = m + "\n";
00217         else if(termination == "\r") m = m + "\r";
00218         else m = m + "\r\n";
00219 */
00220         m = m.replace(QRegExp("\n"), "\r");
00221 
00222         bytes = ::write(m_fd, m.local8Bit(), strlen(m.local8Bit()));
00223         if(bytes < 0)
00224         {
00225                 reset();
00226         }
00227 }
00228 
00229 QString Dialer::receive()
00230 {
00231         QString buf;
00232         char buffer[1024];
00233         int ret;
00234         int counter = 0;
00235 
00236         while(1)
00237         {
00238                 ret = ::read(m_fd, buffer, sizeof(buffer));
00239 
00240                 if(ret > 0)
00241                 {
00242                         for(int i = 0; i < ret; i++)
00243                                 buffer[i] = buffer[i] & 0x7F;
00244                         buffer[ret] = 0;
00245                         buf.append(QString(buffer));
00246                         if(buf.contains("OK") || buf.contains("ERROR") || buf.contains("CONNECT") || (buf.contains("BUSY")))
00247                         {
00248                                 cleanshutdown = 1;
00249                                 return buf;
00250                         }else if (buf.contains("NO CARRIER") || buf.contains("NO DIALTONE")  ) {
00251                             cleanshutdown = 1;
00252                             return QString::null;
00253                         }
00254                 }
00255                 else if(ret < 0)
00256                 {
00257                         if(errno != EAGAIN) reset();
00258                         else if(!(counter++ % 100)) qApp->processEvents();
00259                 }
00260                 else if(!(counter++ % 100)) qApp->processEvents();
00261 
00262                 if(usercancel) return QString::null;
00263         }
00264 
00265         cleanshutdown = 1;
00266         return QString::null;
00267 }
00268 
00269 void Dialer::switchState(int newstate)
00270 {
00271         int oldstate = state;
00272         state = newstate;
00273 
00274         switch(state)
00275         {
00276                 case state_cancel:
00277                         status->setText(QObject::tr("Cancelling..."));
00278                         progress->setProgress(0);
00279                         break;
00280                 case state_preinit:
00281                         status->setText(QObject::tr("Searching modem"));
00282                         progress->setProgress(10);
00283                         break;
00284                 case state_init:
00285                         status->setText(QObject::tr("Initializing..."));
00286                         progress->setProgress(20);
00287                         break;
00288                 case state_options:
00289                         status->setText(QObject::tr("Reset speakers"));
00290                         progress->setProgress(30);
00291                         break;
00292                 case state_dialtone:
00293                         status->setText(QObject::tr("Turning off dialtone"));
00294                         progress->setProgress(40);
00295                         break;
00296                 case state_dialing:
00297                         if(oldstate != state_dialing) status->setText(QObject::tr("Dial number"));
00298                         else status->setText(QObject::tr("Line busy, redialing number"));
00299                         progress->setProgress(50);
00300                         break;
00301                 case state_online:
00302                         status->setText(QObject::tr("Connection established"));
00303                         progress->setProgress(100);
00304                         cancel->setText(QObject::tr("Dismiss"));
00305                         break;
00306         }
00307 }
00308 

Generated on Sat Nov 5 16:16:49 2005 for OPIE by  doxygen 1.4.2