controlsocket.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stringutil.h>
00018 #include "tcglobal.h"
00019
00020 #include "controlsocket.h"
00021 #include "sendcommandevent.h"
00022
00023
00024
00025 #define READ_TIMEOUT 250
00026
00027
00028
00029 ControlSocket::ControlSocket()
00030 {
00031 }
00032
00033
00034
00035 bool
00036 ControlSocket::isConnected()
00037 {
00038 return (isValid() && state() == QAbstractSocket::ConnectedState);
00039 }
00040
00041
00042
00043 void
00044 ControlSocket::customEvent(QEvent *event)
00045 {
00046 if (event->type() == CustomEventType::SendCommandEvent) {
00047 SendCommandEvent *sce = dynamic_cast<SendCommandEvent *>(event);
00048 if (! sce)
00049 return;
00050
00051 QString errmsg;
00052 bool result = sendCommand(sce->command(), &errmsg);
00053 if (sce->waiter())
00054 sce->waiter()->setResult(result, errmsg);
00055 sce->accept();
00056 }
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 bool
00067 ControlSocket::sendCommand(ControlCommand cmd, QString *errmsg)
00068 {
00069 if (!isConnected()) {
00070 return err(errmsg, tr("Control socket is not connected."));
00071 }
00072
00073
00074 QString strCmd = cmd.toString();
00075 tc::debug("Control Command: %1").arg(strCmd.trimmed());
00076
00077
00078 if (write(strCmd.toAscii()) != strCmd.length()) {
00079 return err(errmsg, tr("Error sending control command. [%1]")
00080 .arg(errorString()));
00081 }
00082 flush();
00083 return true;
00084 }
00085
00086
00087
00088 bool
00089 ControlSocket::readLineData(QString &line, QString *errmsg)
00090 {
00091 char buffer[1024];
00092 int bytesRecv = QAbstractSocket::readLine(buffer, 1024);
00093 while (bytesRecv != -1) {
00094 line.append(buffer);
00095 if (buffer[bytesRecv-1] == '\n') {
00096 break;
00097 }
00098 bytesRecv = QAbstractSocket::readLine(buffer, 1024);
00099 }
00100 if (bytesRecv == -1) {
00101 return err(errmsg, errorString());
00102 }
00103 return true;
00104 }
00105
00106
00107
00108
00109 bool
00110 ControlSocket::readLine(QString &line, QString *errmsg)
00111 {
00112
00113
00114 while (!canReadLine()) {
00115 if (!isConnected()) {
00116 return err(errmsg, tr("Socket disconnected while attempting "
00117 "to read a line of data."));
00118 }
00119 waitForReadyRead(READ_TIMEOUT);
00120 }
00121 line.clear();
00122 return readLineData(line, errmsg);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 bool
00138 ControlSocket::readReply(ControlReply &reply, QString *errmsg)
00139 {
00140 QChar c;
00141 QString line;
00142
00143 if (!isConnected()) {
00144 return false;
00145 }
00146
00147
00148
00149 do {
00150
00151 if (!readLine(line, errmsg)) {
00152 return false;
00153 }
00154
00155 if (line.length() < 4) {
00156 return err(errmsg, tr("Invalid control reply. [%1]").arg(line));
00157 }
00158
00159
00160 ReplyLine replyLine(line.mid(0, 3), line.mid(4));
00161 c = line.at(3);
00162
00163
00164
00165 if (c == QChar('+') &&
00166 !line.startsWith("250+PROTOCOLINFO")) {
00167
00168
00169
00170 while (true) {
00171 if (!readLine(line, errmsg)) {
00172 return false;
00173 }
00174 if (line.trimmed() == ".") {
00175 break;
00176 }
00177 replyLine.appendData(line);
00178 }
00179 }
00180 reply.appendLine(replyLine);
00181 } while (c != QChar(' '));
00182 return true;
00183 }
00184
00185
00186 QString
00187 ControlSocket::toString(const QAbstractSocket::SocketError error)
00188 {
00189 QString str;
00190 switch (error) {
00191 case ConnectionRefusedError:
00192 str = "Connection refused by peer."; break;
00193 case RemoteHostClosedError:
00194 str = "Remote host closed the connection."; break;
00195 case HostNotFoundError:
00196 str = "Host address not found."; break;
00197 case SocketAccessError:
00198 str = "Insufficient access privileges."; break;
00199 case SocketResourceError:
00200 str = "Insufficient resources."; break;
00201 case SocketTimeoutError:
00202 str = "Socket operation timed out."; break;
00203 case DatagramTooLargeError:
00204 str = "Datagram size exceeded the operating system limit."; break;
00205 case NetworkError:
00206 str = "Network error occurred."; break;
00207 case AddressInUseError:
00208 str = "Specified address already in use."; break;
00209 case SocketAddressNotAvailableError:
00210 str = "Specified address does not belong to the host."; break;
00211 case UnsupportedSocketOperationError:
00212 str = "The requested operation is not supported."; break;
00213 default:
00214 str = "An unidentified error occurred."; break;
00215 }
00216 return str;
00217 }
00218