diff --git a/src/mqtt/qmqtt_client_p.cpp b/src/mqtt/qmqtt_client_p.cpp index a5a7eac..f62887d 100644 --- a/src/mqtt/qmqtt_client_p.cpp +++ b/src/mqtt/qmqtt_client_p.cpp @@ -344,12 +344,14 @@ void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid) quint16 QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos) { quint16 msgid = sendSubscribe(topic, qos); + _midToTopic[msgid] = topic; return msgid; } void QMQTT::ClientPrivate::unsubscribe(const QString& topic) { - sendUnsubscribe(topic); + quint16 msgid = sendUnsubscribe(topic); + _midToTopic[msgid] = topic; } void QMQTT::ClientPrivate::onNetworkDisconnected() @@ -357,6 +359,7 @@ void QMQTT::ClientPrivate::onNetworkDisconnected() Q_Q(Client); stopKeepAlive(); + clearMidToTopic(); emit q->disconnected(); } @@ -403,10 +406,11 @@ void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm) case SUBACK: mid = frame.readInt(); qos = frame.readChar(); - handleSuback(topic, qos); + handleSuback(midToTopic(mid), qos); break; case UNSUBACK: - handleUnsuback(topic); + mid = frame.readInt(); + handleUnsuback(midToTopic(mid)); break; case PINGRESP: @@ -476,6 +480,22 @@ void QMQTT::ClientPrivate::handleUnsuback(const QString &topic) { emit q->unsubscribed(topic); } +QString QMQTT::ClientPrivate::midToTopic(const quint16 mid) +{ + QString result; + QHash::Iterator it = _midToTopic.find(mid); + if (it != _midToTopic.end()) { + result = it.value(); + _midToTopic.erase(it); + } + return result; +} + +void QMQTT::ClientPrivate::clearMidToTopic() +{ + _midToTopic.clear(); +} + bool QMQTT::ClientPrivate::autoReconnect() const { return _network->autoReconnect(); diff --git a/src/mqtt/qmqtt_client_p.h b/src/mqtt/qmqtt_client_p.h index 8bec3ba..fcffdcc 100644 --- a/src/mqtt/qmqtt_client_p.h +++ b/src/mqtt/qmqtt_client_p.h @@ -75,7 +75,7 @@ class ClientPrivate bool _willRetain; QString _willMessage; QHash _socketErrorHash; - + QHash _midToTopic; Client* const q_ptr; @@ -105,6 +105,8 @@ class ClientPrivate void handleUnsuback(const QString& topic); void handlePubcomp(const Message& message); void handlePingresp(); + QString midToTopic(const quint16 mid); + void clearMidToTopic(); bool autoReconnect() const; void setAutoReconnect(const bool autoReconnect); bool autoReconnectInterval() const; diff --git a/src/mqtt/qmqtt_frame.h b/src/mqtt/qmqtt_frame.h index c9e6ee5..15e27dc 100644 --- a/src/mqtt/qmqtt_frame.h +++ b/src/mqtt/qmqtt_frame.h @@ -56,8 +56,8 @@ #define PINGRESP 0xD0 #define DISCONNECT 0xE0 -#define LSB(A) (quint8)(A & 0x00FF) -#define MSB(A) (quint8)((A & 0xFF00) >> 8) +#define LSB(A) quint8(A & 0x00FF) +#define MSB(A) quint8((A & 0xFF00) >> 8) /* |-------------------------------------- diff --git a/tests/gtest/tests/clienttest.cpp b/tests/gtest/tests/clienttest.cpp index 0089847..2493ec1 100644 --- a/tests/gtest/tests/clienttest.cpp +++ b/tests/gtest/tests/clienttest.cpp @@ -426,28 +426,27 @@ TEST_F(ClientTest, networkReceivedSendsPublishEmitsReceivedSignal_Test) EXPECT_EQ(1, spy.count()); } -// todo: should happen on suback TEST_F(ClientTest, subscribeEmitsSubscribedSignal_Test) { EXPECT_CALL(*_networkMock, sendFrame(_)); QSignalSpy spy(_client.data(), &QMQTT::Client::subscribed); - _client->subscribe("topic", QOS2); + quint16 msgid = _client->subscribe("topic", QOS2); QByteArray payLoad; - payLoad.append((char)0x12); // message ID - payLoad.append((char)0x23); // message ID + payLoad.append((char)(msgid >> 8)); // message ID MSB + payLoad.append((char)(msgid && 0xFF)); // message ID LSB payLoad.append((char)QOS2); // QOS QMQTT::Frame frame(SUBACK_TYPE, payLoad); emit _networkMock->received(frame); ASSERT_EQ(1, spy.count()); + EXPECT_EQ("topic", spy.at(0).at(0).toString()); EXPECT_EQ(QOS2, spy.at(0).at(1).toInt()); } // todo: network received sends suback triggers a subscribed signal (other things?) -// todo: should happen on unsuback TEST_F(ClientTest, unsubscribeEmitsUnsubscribedSignal_Test) { EXPECT_CALL(*_networkMock, sendFrame(_)); @@ -455,11 +454,14 @@ TEST_F(ClientTest, unsubscribeEmitsUnsubscribedSignal_Test) _client->unsubscribe("topic"); - QMQTT::Frame frame(UNSUBACK_TYPE, QByteArray()); + QByteArray payLoad; + payLoad.append((char)0x00); // message ID MSB + payLoad.append((char)0x01); // message ID LSB + QMQTT::Frame frame(UNSUBACK_TYPE, payLoad); emit _networkMock->received(frame); - EXPECT_EQ(1, spy.count()); - // EXPECT_EQ("topic", spy.at(0).at(0).toString()); + ASSERT_EQ(1, spy.count()); + EXPECT_EQ("topic", spy.at(0).at(0).toString()); } // todo: network received sends unsuback then emit unsubscribed signal (only then?)