qmqtt_client_p.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. /*
  2. * qmqtt_client_p.cpp - qmqtt client private
  3. *
  4. * Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * * Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * * Neither the name of mqttc nor the names of its contributors may be used
  16. * to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. */
  32. #include "qmqtt_client_p.h"
  33. #include "qmqtt_network_p.h"
  34. #include "qmqtt_frame.h"
  35. #include "qmqtt_message.h"
  36. #include <QLoggingCategory>
  37. #include <QUuid>
  38. #ifndef QT_NO_SSL
  39. #include <QFile>
  40. #include <QSslConfiguration>
  41. #include <QSslKey>
  42. #endif // QT_NO_SSL
  43. Q_LOGGING_CATEGORY(client, "qmqtt.client")
  44. static const quint8 QOS0 = 0x00;
  45. static const quint8 QOS1 = 0x01;
  46. static const quint8 QOS2 = 0x02;
  47. QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr)
  48. : _host(QHostAddress::LocalHost)
  49. , _port(1883)
  50. , _gmid(1)
  51. , _version(MQTTVersion::V3_1_0)
  52. , _clientId(QUuid::createUuid().toString())
  53. , _cleanSession(false)
  54. , _connectionState(STATE_INIT)
  55. , _willQos(0)
  56. , _willRetain(false)
  57. , q_ptr(qq_ptr)
  58. {
  59. setKeepAlive(300);
  60. }
  61. QMQTT::ClientPrivate::~ClientPrivate()
  62. {
  63. }
  64. void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network)
  65. {
  66. Q_Q(Client);
  67. _host = host;
  68. _port = port;
  69. if(network == NULL)
  70. {
  71. init(new Network(q));
  72. }
  73. else
  74. {
  75. init(network);
  76. }
  77. }
  78. #ifndef QT_NO_SSL
  79. void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port,
  80. const QSslConfiguration &config, const bool ignoreSelfSigned)
  81. {
  82. Q_Q(Client);
  83. _hostName = hostName;
  84. _port = port;
  85. _ignoreSelfSigned = ignoreSelfSigned;
  86. init(new Network(config, q));
  87. QObject::connect(_network.data(), &QMQTT::Network::sslErrors, q, &QMQTT::Client::onSslErrors);
  88. }
  89. #endif // QT_NO_SSL
  90. void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl,
  91. const bool ignoreSelfSigned)
  92. {
  93. Q_Q(Client);
  94. _hostName = hostName;
  95. _port = port;
  96. if (ssl)
  97. {
  98. #ifndef QT_NO_SSL
  99. QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration();
  100. QList<QSslCertificate> certs = QSslCertificate::fromPath(QStringLiteral("./cert.crt"));
  101. if (!certs.isEmpty())
  102. sslConf.setLocalCertificate(certs.first());
  103. QFile file(QStringLiteral("./cert.key"));
  104. if (file.open(QIODevice::ReadOnly)) {
  105. sslConf.setPrivateKey(QSslKey(file.readAll(), QSsl::Rsa));
  106. }
  107. sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
  108. init(hostName, port, sslConf, ignoreSelfSigned);
  109. #else
  110. Q_UNUSED(ignoreSelfSigned)
  111. qCritical() << "SSL not supported in this QT build";
  112. #endif // QT_NO_SSL
  113. }
  114. else
  115. {
  116. init(new Network(q));
  117. }
  118. }
  119. #ifdef QT_WEBSOCKETS_LIB
  120. #ifndef QT_NO_SSL
  121. void QMQTT::ClientPrivate::init(const QString& url,
  122. const QString& origin,
  123. QWebSocketProtocol::Version version,
  124. const QSslConfiguration* sslConfig,
  125. bool ignoreSelfSigned)
  126. {
  127. Q_Q(Client);
  128. _hostName = url;
  129. _ignoreSelfSigned = ignoreSelfSigned;
  130. init(new Network(origin, version, sslConfig, q));
  131. }
  132. #endif // QT_NO_SSL
  133. void QMQTT::ClientPrivate::init(const QString& url,
  134. const QString& origin,
  135. QWebSocketProtocol::Version version)
  136. {
  137. Q_Q(Client);
  138. _hostName = url;
  139. init(new Network(origin, version, q));
  140. }
  141. #endif // QT_WEBSOCKETS_LIB
  142. void QMQTT::ClientPrivate::init(NetworkInterface* network)
  143. {
  144. Q_Q(Client);
  145. _network.reset(network);
  146. _timer.setSingleShot(true);
  147. _pingResponseTimer.setSingleShot(true);
  148. QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
  149. QObject::connect(&_pingResponseTimer, &QTimer::timeout, q, &Client::onPingTimeout);
  150. QObject::connect(_network.data(), &Network::connected,
  151. q, &Client::onNetworkConnected);
  152. QObject::connect(_network.data(), &Network::disconnected,
  153. q, &Client::onNetworkDisconnected);
  154. QObject::connect(_network.data(), &Network::received,
  155. q, &Client::onNetworkReceived);
  156. QObject::connect(_network.data(), &Network::error,
  157. q, &Client::onNetworkError);
  158. }
  159. void QMQTT::ClientPrivate::connectToHost()
  160. {
  161. _connectionState = ConnectionState::STATE_CONNECTING;
  162. if (_hostName.isEmpty())
  163. {
  164. _network->connectToHost(_host, _port);
  165. }
  166. else
  167. {
  168. _network->connectToHost(_hostName, _port);
  169. }
  170. }
  171. void QMQTT::ClientPrivate::onNetworkConnected()
  172. {
  173. sendConnect();
  174. }
  175. void QMQTT::ClientPrivate::sendConnect()
  176. {
  177. quint8 header = CONNECT;
  178. quint8 flags = 0;
  179. //header
  180. Frame frame(header);
  181. //flags
  182. flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 );
  183. flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1);
  184. if (!willTopic().isEmpty())
  185. {
  186. flags = FLAG_WILLQOS(flags, willQos());
  187. flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0);
  188. }
  189. if (!username().isEmpty())
  190. {
  191. flags = FLAG_USERNAME(flags, 1);
  192. flags = FLAG_PASSWD(flags, !password().isEmpty() ? 1 : 0);
  193. }
  194. //payload
  195. if(_version == V3_1_1)
  196. {
  197. frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_1));
  198. }
  199. else
  200. {
  201. frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_0));
  202. }
  203. frame.writeChar(_version);
  204. frame.writeChar(flags);
  205. frame.writeInt(keepAlive());
  206. frame.writeString(_clientId);
  207. if(!willTopic().isEmpty())
  208. {
  209. frame.writeString(willTopic());
  210. // According to the specs (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031)
  211. // the will message gets always sent together with the topic, also when it is empty which is perfectly valid.
  212. frame.writeByteArray(_willMessage);
  213. }
  214. if (!_username.isEmpty())
  215. {
  216. frame.writeString(_username);
  217. if (!_password.isEmpty())
  218. {
  219. frame.writeByteArray(_password);
  220. }
  221. }
  222. sendFrame(frame);
  223. }
  224. quint16 QMQTT::ClientPrivate::sendPublish(const Message &message)
  225. {
  226. quint16 msgid = message.id();
  227. quint8 header = PUBLISH;
  228. header = SETRETAIN(header, message.retain() ? 1 : 0);
  229. header = SETQOS(header, message.qos());
  230. header = SETDUP(header, message.dup() ? 1 : 0);
  231. Frame frame(header);
  232. frame.writeString(message.topic());
  233. if(message.qos() > QOS0) {
  234. if (msgid == 0)
  235. msgid = nextmid();
  236. frame.writeInt(msgid);
  237. }
  238. if(!message.payload().isEmpty()) {
  239. frame.writeRawData(message.payload());
  240. }
  241. sendFrame(frame);
  242. return msgid;
  243. }
  244. void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid)
  245. {
  246. Frame frame(type);
  247. frame.writeInt(mid);
  248. sendFrame(frame);
  249. }
  250. quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos)
  251. {
  252. quint16 mid = nextmid();
  253. Frame frame(SETQOS(SUBSCRIBE, QOS1));
  254. frame.writeInt(mid);
  255. frame.writeString(topic);
  256. frame.writeChar(qos);
  257. sendFrame(frame);
  258. return mid;
  259. }
  260. quint16 QMQTT::ClientPrivate::sendUnsubscribe(const QString &topic)
  261. {
  262. quint16 mid = nextmid();
  263. Frame frame(SETQOS(UNSUBSCRIBE, QOS1));
  264. frame.writeInt(mid);
  265. frame.writeString(topic);
  266. sendFrame(frame);
  267. return mid;
  268. }
  269. void QMQTT::ClientPrivate::onTimerPingReq()
  270. {
  271. if (!isConnectedToHost())
  272. return;
  273. Frame frame(PINGREQ);
  274. sendFrame(frame);
  275. _pingResponseTimer.start();
  276. }
  277. void QMQTT::ClientPrivate::onPingTimeout()
  278. {
  279. Q_Q(Client);
  280. emit q->error(MqttNoPingResponse);
  281. disconnectFromHost();
  282. }
  283. void QMQTT::ClientPrivate::disconnectFromHost()
  284. {
  285. _connectionState = ConnectionState::STATE_DISCONNECTED;
  286. sendDisconnect();
  287. _network->disconnectFromHost();
  288. }
  289. void QMQTT::ClientPrivate::sendDisconnect()
  290. {
  291. Frame frame(DISCONNECT);
  292. sendFrame(frame);
  293. }
  294. void QMQTT::ClientPrivate::sendFrame(const Frame &frame)
  295. {
  296. _network->sendFrame(frame);
  297. _timer.start();
  298. }
  299. void QMQTT::ClientPrivate::stopKeepAlive()
  300. {
  301. _timer.stop();
  302. _pingResponseTimer.stop();
  303. }
  304. quint16 QMQTT::ClientPrivate::nextmid()
  305. {
  306. return _gmid++;
  307. }
  308. quint16 QMQTT::ClientPrivate::publish(const Message& message)
  309. {
  310. Q_Q(Client);
  311. quint16 msgid = sendPublish(message);
  312. // Emit published only at QOS0
  313. if (message.qos() == QOS0)
  314. emit q->published(message, msgid);
  315. else
  316. _midToMessage[msgid] = message;
  317. return msgid;
  318. }
  319. void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid)
  320. {
  321. sendPuback(type, msgid);
  322. }
  323. void QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos)
  324. {
  325. quint16 msgid = sendSubscribe(topic, qos);
  326. _midToTopic[msgid] = topic;
  327. }
  328. void QMQTT::ClientPrivate::unsubscribe(const QString& topic)
  329. {
  330. quint16 msgid = sendUnsubscribe(topic);
  331. _midToTopic[msgid] = topic;
  332. }
  333. void QMQTT::ClientPrivate::onNetworkDisconnected()
  334. {
  335. Q_Q(Client);
  336. stopKeepAlive();
  337. _midToTopic.clear();
  338. _midToMessage.clear();
  339. emit q->disconnected();
  340. }
  341. void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm)
  342. {
  343. QMQTT::Frame frame(frm);
  344. quint8 qos = 0;
  345. bool retain, dup;
  346. QString topic;
  347. quint16 mid = 0;
  348. quint8 header = frame.header();
  349. quint8 type = GETTYPE(header);
  350. switch(type)
  351. {
  352. case CONNACK:
  353. frame.readChar();
  354. handleConnack(frame.readChar());
  355. break;
  356. case PUBLISH:
  357. qos = GETQOS(header);
  358. retain = GETRETAIN(header);
  359. dup = GETDUP(header);
  360. topic = frame.readString();
  361. if( qos > QOS0) {
  362. mid = frame.readInt();
  363. }
  364. handlePublish(Message(mid, topic, frame.data(), qos, retain, dup));
  365. break;
  366. case PUBACK:
  367. case PUBREC:
  368. case PUBREL:
  369. case PUBCOMP:
  370. mid = frame.readInt();
  371. handlePuback(type, mid);
  372. break;
  373. case SUBACK:
  374. mid = frame.readInt();
  375. topic = _midToTopic.take(mid);
  376. qos = frame.readChar();
  377. handleSuback(topic, qos);
  378. break;
  379. case UNSUBACK:
  380. mid = frame.readInt();
  381. topic = _midToTopic.take(mid);
  382. handleUnsuback(topic);
  383. break;
  384. case PINGRESP:
  385. handlePingresp();
  386. break;
  387. default:
  388. break;
  389. }
  390. }
  391. void QMQTT::ClientPrivate::handleConnack(const quint8 ack)
  392. {
  393. Q_Q(Client);
  394. switch (ack)
  395. {
  396. case 0:
  397. _connectionState = ConnectionState::STATE_CONNECTED;
  398. emit q->connected();
  399. break;
  400. case 1:
  401. emit q->error(MqttUnacceptableProtocolVersionError);
  402. break;
  403. case 2:
  404. emit q->error(MqttIdentifierRejectedError);
  405. break;
  406. case 3:
  407. emit q->error(MqttServerUnavailableError);
  408. break;
  409. case 4:
  410. emit q->error(MqttBadUserNameOrPasswordError);
  411. break;
  412. case 5:
  413. emit q->error(MqttNotAuthorizedError);
  414. break;
  415. default:
  416. emit q->error(UnknownError);
  417. break;
  418. }
  419. }
  420. void QMQTT::ClientPrivate::handlePublish(const Message& message)
  421. {
  422. Q_Q(Client);
  423. if(message.qos() == QOS1)
  424. {
  425. sendPuback(PUBACK, message.id());
  426. }
  427. else if(message.qos() == QOS2)
  428. {
  429. sendPuback(PUBREC, message.id());
  430. }
  431. emit q->received(message);
  432. }
  433. void QMQTT::ClientPrivate::handlePuback(const quint8 type, const quint16 msgid)
  434. {
  435. Q_Q(Client);
  436. switch (type)
  437. {
  438. case PUBREC:
  439. sendPuback(SETQOS(PUBREL, QOS1), msgid);
  440. break;
  441. case PUBREL:
  442. sendPuback(PUBCOMP, msgid);
  443. break;
  444. case PUBACK:
  445. case PUBCOMP:
  446. // Emit published on PUBACK at QOS1 and on PUBCOMP at QOS2
  447. emit q->published(_midToMessage.take(msgid), msgid);
  448. break;
  449. }
  450. }
  451. void QMQTT::ClientPrivate::handlePingresp()
  452. {
  453. // Stop the ping response timer to prevent disconnection. It will be restarted when the next
  454. // ping request has been sent.
  455. _pingResponseTimer.stop();
  456. Q_Q(Client);
  457. emit q->pingresp();
  458. }
  459. void QMQTT::ClientPrivate::handleSuback(const QString &topic, const quint8 qos)
  460. {
  461. Q_Q(Client);
  462. emit q->subscribed(topic, qos);
  463. }
  464. void QMQTT::ClientPrivate::handleUnsuback(const QString &topic) {
  465. Q_Q(Client);
  466. emit q->unsubscribed(topic);
  467. }
  468. bool QMQTT::ClientPrivate::autoReconnect() const
  469. {
  470. return _network->autoReconnect();
  471. }
  472. void QMQTT::ClientPrivate::setAutoReconnect(const bool autoReconnect)
  473. {
  474. _network->setAutoReconnect(autoReconnect);
  475. }
  476. int QMQTT::ClientPrivate::autoReconnectInterval() const
  477. {
  478. return _network->autoReconnectInterval();
  479. }
  480. void QMQTT::ClientPrivate::setAutoReconnectInterval(const int autoReconnectInterval)
  481. {
  482. _network->setAutoReconnectInterval(autoReconnectInterval);
  483. }
  484. bool QMQTT::ClientPrivate::isConnectedToHost() const
  485. {
  486. return _network->isConnectedToHost();
  487. }
  488. QMQTT::ConnectionState QMQTT::ClientPrivate::connectionState() const
  489. {
  490. return _connectionState;
  491. }
  492. void QMQTT::ClientPrivate::setCleanSession(const bool cleanSession)
  493. {
  494. _cleanSession = cleanSession;
  495. }
  496. bool QMQTT::ClientPrivate::cleanSession() const
  497. {
  498. return _cleanSession;
  499. }
  500. void QMQTT::ClientPrivate::setKeepAlive(const quint16 keepAlive)
  501. {
  502. // _timer will be started when a message is sent.
  503. _timer.setInterval(keepAlive*1000);
  504. // The MQTT specification does not mention a timeout value in this case, so we use 10% of the
  505. // keep alive interval.
  506. _pingResponseTimer.setInterval(qBound(keepAlive * 100, 10000, keepAlive * 1000));
  507. }
  508. quint16 QMQTT::ClientPrivate::keepAlive() const
  509. {
  510. return _timer.interval() / 1000;
  511. }
  512. void QMQTT::ClientPrivate::setPassword(const QByteArray& password)
  513. {
  514. _password = password;
  515. }
  516. QByteArray QMQTT::ClientPrivate::password() const
  517. {
  518. return _password;
  519. }
  520. void QMQTT::ClientPrivate::setUsername(const QString& username)
  521. {
  522. _username = username;
  523. }
  524. QString QMQTT::ClientPrivate::username() const
  525. {
  526. return _username;
  527. }
  528. void QMQTT::ClientPrivate::setVersion(const MQTTVersion version)
  529. {
  530. _version = version;
  531. }
  532. QMQTT::MQTTVersion QMQTT::ClientPrivate::version() const
  533. {
  534. return _version;
  535. }
  536. void QMQTT::ClientPrivate::setClientId(const QString& clientId)
  537. {
  538. if(clientId.isEmpty())
  539. {
  540. _clientId = QUuid::createUuid().toString();
  541. }
  542. else
  543. {
  544. _clientId = clientId;
  545. }
  546. }
  547. QString QMQTT::ClientPrivate::clientId() const
  548. {
  549. return _clientId;
  550. }
  551. void QMQTT::ClientPrivate::setPort(const quint16 port)
  552. {
  553. _port = port;
  554. }
  555. quint16 QMQTT::ClientPrivate::port() const
  556. {
  557. return _port;
  558. }
  559. void QMQTT::ClientPrivate::setHost(const QHostAddress& host)
  560. {
  561. _host = host;
  562. }
  563. QHostAddress QMQTT::ClientPrivate::host() const
  564. {
  565. return _host;
  566. }
  567. void QMQTT::ClientPrivate::setHostName(const QString& hostName)
  568. {
  569. _hostName = hostName;
  570. }
  571. QString QMQTT::ClientPrivate::hostName() const
  572. {
  573. return _hostName;
  574. }
  575. QString QMQTT::ClientPrivate::willTopic() const
  576. {
  577. return _willTopic;
  578. }
  579. void QMQTT::ClientPrivate::setWillTopic(const QString& willTopic)
  580. {
  581. _willTopic = willTopic;
  582. }
  583. quint8 QMQTT::ClientPrivate::willQos() const
  584. {
  585. return _willQos;
  586. }
  587. void QMQTT::ClientPrivate::setWillQos(const quint8 willQos)
  588. {
  589. _willQos = willQos;
  590. }
  591. bool QMQTT::ClientPrivate::willRetain() const
  592. {
  593. return _willRetain;
  594. }
  595. void QMQTT::ClientPrivate::setWillRetain(const bool willRetain)
  596. {
  597. _willRetain = willRetain;
  598. }
  599. QByteArray QMQTT::ClientPrivate::willMessage() const
  600. {
  601. return _willMessage;
  602. }
  603. void QMQTT::ClientPrivate::setWillMessage(const QByteArray& willMessage)
  604. {
  605. _willMessage = willMessage;
  606. }
  607. void QMQTT::ClientPrivate::onNetworkError(QAbstractSocket::SocketError socketError)
  608. {
  609. Q_Q(Client);
  610. switch (socketError)
  611. {
  612. case QAbstractSocket::ConnectionRefusedError:
  613. emit q->error(SocketConnectionRefusedError);
  614. break;
  615. case QAbstractSocket::RemoteHostClosedError:
  616. emit q->error(SocketRemoteHostClosedError);
  617. break;
  618. case QAbstractSocket::HostNotFoundError:
  619. emit q->error(SocketHostNotFoundError);
  620. break;
  621. case QAbstractSocket::SocketAccessError:
  622. emit q->error(SocketAccessError);
  623. break;
  624. case QAbstractSocket::SocketResourceError:
  625. emit q->error(SocketResourceError);
  626. break;
  627. case QAbstractSocket::SocketTimeoutError:
  628. emit q->error(SocketTimeoutError);
  629. break;
  630. case QAbstractSocket::DatagramTooLargeError:
  631. emit q->error(SocketDatagramTooLargeError);
  632. break;
  633. case QAbstractSocket::NetworkError:
  634. emit q->error(SocketNetworkError);
  635. break;
  636. case QAbstractSocket::AddressInUseError:
  637. emit q->error(SocketAddressInUseError);
  638. break;
  639. case QAbstractSocket::SocketAddressNotAvailableError:
  640. emit q->error(SocketAddressNotAvailableError);
  641. break;
  642. case QAbstractSocket::UnsupportedSocketOperationError:
  643. emit q->error(SocketUnsupportedSocketOperationError);
  644. break;
  645. case QAbstractSocket::UnfinishedSocketOperationError:
  646. emit q->error(SocketUnfinishedSocketOperationError);
  647. break;
  648. case QAbstractSocket::ProxyAuthenticationRequiredError:
  649. emit q->error(SocketProxyAuthenticationRequiredError);
  650. break;
  651. case QAbstractSocket::SslHandshakeFailedError:
  652. emit q->error(SocketSslHandshakeFailedError);
  653. break;
  654. case QAbstractSocket::ProxyConnectionRefusedError:
  655. emit q->error(SocketProxyConnectionRefusedError);
  656. break;
  657. case QAbstractSocket::ProxyConnectionClosedError:
  658. emit q->error(SocketProxyConnectionClosedError);
  659. break;
  660. case QAbstractSocket::ProxyConnectionTimeoutError:
  661. emit q->error(SocketProxyConnectionTimeoutError);
  662. break;
  663. case QAbstractSocket::ProxyNotFoundError:
  664. emit q->error(SocketProxyNotFoundError);
  665. break;
  666. case QAbstractSocket::ProxyProtocolError:
  667. emit q->error(SocketProxyProtocolError);
  668. break;
  669. case QAbstractSocket::OperationError:
  670. emit q->error(SocketOperationError);
  671. break;
  672. case QAbstractSocket::SslInternalError:
  673. emit q->error(SocketSslInternalError);
  674. break;
  675. case QAbstractSocket::SslInvalidUserDataError:
  676. emit q->error(SocketSslInvalidUserDataError);
  677. break;
  678. case QAbstractSocket::TemporaryError:
  679. emit q->error(SocketTemporaryError);
  680. break;
  681. default:
  682. emit q->error(UnknownError);
  683. break;
  684. }
  685. }
  686. #ifndef QT_NO_SSL
  687. void QMQTT::ClientPrivate::ignoreSslErrors()
  688. {
  689. _network->ignoreSslErrors();
  690. }
  691. void QMQTT::ClientPrivate::ignoreSslErrors(const QList<QSslError>& errors)
  692. {
  693. _network->ignoreSslErrors(errors);
  694. }
  695. QSslConfiguration QMQTT::ClientPrivate::sslConfiguration() const
  696. {
  697. return _network->sslConfiguration();
  698. }
  699. void QMQTT::ClientPrivate::setSslConfiguration(const QSslConfiguration& config)
  700. {
  701. _network->setSslConfiguration(config);
  702. }
  703. void QMQTT::ClientPrivate::onSslErrors(const QList<QSslError>& errors)
  704. {
  705. Q_Q(Client);
  706. emit q->sslErrors(errors);
  707. if (!_ignoreSelfSigned)
  708. return;
  709. foreach (QSslError error, errors)
  710. {
  711. if (error.error() != QSslError::SelfSignedCertificate &&
  712. error.error() != QSslError::SelfSignedCertificateInChain)
  713. {
  714. return;
  715. }
  716. }
  717. ignoreSslErrors();
  718. }
  719. #endif // QT_NO_SSL