diff --git a/src/mqtt/qmqtt_client_p.cpp b/src/mqtt/qmqtt_client_p.cpp index 7d3c5b3..550e804 100644 --- a/src/mqtt/qmqtt_client_p.cpp +++ b/src/mqtt/qmqtt_client_p.cpp @@ -336,12 +336,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() @@ -349,6 +351,7 @@ void QMQTT::ClientPrivate::onNetworkDisconnected() Q_Q(Client); stopKeepAlive(); + clearMidToTopic(); emit q->disconnected(); } @@ -395,10 +398,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: @@ -468,6 +472,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 0ab1288..23bbe3e 100644 --- a/src/mqtt/qmqtt_client_p.h +++ b/src/mqtt/qmqtt_client_p.h @@ -74,6 +74,7 @@ class ClientPrivate bool _willRetain; QString _willMessage; QHash _socketErrorHash; + QHash _midToTopic; Client* const q_ptr; @@ -103,6 +104,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/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?)