00001 #include "dialer.h"
00002 #include "io_modem.h"
00003
00004
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
00014 #include <unistd.h>
00015 #include <string.h>
00016 #include <fcntl.h>
00017 #include <errno.h>
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
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
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
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
00155
00156
00157
00158
00159
00160
00161
00162
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
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
00215
00216
00217
00218
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