Manage DataPathInformation with DataPathState
authorCheoleun Moon <chleun.moon@samsung.com>
Thu, 9 Apr 2020 07:17:15 +0000 (16:17 +0900)
committerCheoleun Moon <chleun.moon@samsung.com>
Thu, 9 Apr 2020 07:17:15 +0000 (16:17 +0900)
include/NanCommand.h
include/NanDataPathInformation.h
include/NanDataPathManager.h
include/NanEventCallback.h
include/NanServiceProvider.h
src/NanCommand.cpp
src/NanDataPathInformation.cpp
src/NanDataPathManager.cpp
src/NanHal.cpp
src/NanHalEventCallbackHandler.cpp
src/NanServiceProvider.cpp

index 1940c00524315221731fc74c8c057a5241d4f138..5586f5ff274f93756f055f94121e634bf2903526 100644 (file)
@@ -25,6 +25,7 @@
 #include "PublishConfig.h"
 #include "SubscribeConfig.h"
 #include "DataPathEndConfig.h"
+#include "NanDataPathInformation.h"
 #include "NanDefinitions.h"
 #include "NanError.h"
 #include "NanLog.h"
@@ -179,21 +180,26 @@ class NanDataPathRequestCommand : public NanCommand
 {
 public:
        NanDataPathRequestCommand(std::shared_ptr<DataPathConfig> config,
-                       int clientId, uint16_t id);
+                       int clientId, uint16_t id, NanDataPathInformation *info);
        ~NanDataPathRequestCommand() {}
 
        void run(NanHal *hal);
        void response(NanError error);
+
+       NanDataPathInformation *mDataPathInfo;
 };
 
 class NanDataPathResponseCommand : public NanCommand
 {
 public:
-       NanDataPathResponseCommand(std::shared_ptr<DataPathConfig> config, int clientId);
+       NanDataPathResponseCommand(std::shared_ptr<DataPathConfig> config, int clientId,
+                       NanDataPathInformation *info);
        ~NanDataPathResponseCommand() {}
 
        void run(NanHal *hal);
        void response(NanError error);
+
+       NanDataPathInformation *mDataPathInfo;
 };
 
 class NanDataPathEndCommand : public NanCommand
index 7539712fdba1c0fabd033482890244585636d168..ec6d29573bf65ae32bfecd33267107a26c2807fa 100644 (file)
 
 NAN_NAMESPACE_BEGIN
 
+enum class DataPathState {
+       IDLE = 0,
+       INITIATOR_WAIT_FOR_REQUEST_RESPONSE = 1,
+       RESPONDER_WAIT_FOR_REQUEST = 2,
+       RESPONDER_WAIT_FOR_RESPOND_RESPONSE = 3,
+       WAIT_FOR_CONFIRM = 4,
+       CONFIRMED = 5,
+};
+
 class NanDataPathInformation
 {
 public:
@@ -59,6 +68,9 @@ public:
        void setPeerDataPathMac(const uint8_t *mac);
 
        void setTimer(NanTimer *timer);
+       void setState(DataPathState state);
+       DataPathState getState();
+       int getStateAsInt();
 
 private:
        bool isValidLengthForIpv6AddressTlv(size_t length);
@@ -84,6 +96,8 @@ private:
 
        bool mIsConfirmed;
        NanTimer *mTimer;
+
+       DataPathState mState;
 };
 
 NAN_NAMESPACE_END
index 09fb3b061f427425602ad879f8999c1632c157d5..5030bd862d8253b72d8d406c277830963966f29f 100644 (file)
@@ -44,7 +44,8 @@ public:
        void removeDataPathInfo(uint16_t pubSubId);
        NanDataPathInformation *getDataPathInfo(uint32_t dataPathId);
        NanDataPathInformation *getDataPathInfo(uint16_t pubSubId, uint32_t peerId);
-       NanDataPathInformation *getDataPathInfo(uint16_t pubSubId, const uint8_t *peerMac);
+       NanDataPathInformation *getDataPathInfo(uint16_t pubSubId,
+               const uint8_t *peerMac, DataPathState state);
 
        void clear();
 
index dc48b07bc67c09eb65c78c554c32a009d679fd04..e96bae629b3670152fe41f30a0efc5540a52b1bc 100644 (file)
@@ -37,7 +37,7 @@ struct NanEventCallback {
        std::function<void(uint16_t, NanError)> on_notify_dp_interface_create_response;
        std::function<void(uint16_t, NanError)> on_notify_dp_interface_delete_response;
        std::function<void(uint16_t, NanError, uint32_t)> on_notify_dp_init_response;
-       std::function<void(uint16_t, NanError, uint32_t)> on_notify_dp_respond_response;
+       std::function<void(uint16_t, NanError)> on_notify_dp_respond_response;
        std::function<void(uint16_t, NanError)> on_notify_dp_terminate_response;
        std::function<void(uint16_t, NanError, const NanCapabilitiesInfo&)> on_notify_capabilities_response;
 
index 2a301c68fe0c6f73a4d1c25206959e2896f42561..aeeceada33992ba7f7ae5483a95bf56878c2b020 100644 (file)
@@ -80,7 +80,7 @@ public:
        void receiveCreateDataPathInterfaceResponse(NanError error);
        void receiveDeleteDataPathInterfaceResponse(NanError error);
        void receiveDataPathInitiateResponse(NanError error, uint32_t dataPathId);
-       void receiveDataPathRespondResponse(NanError error, uint32_t dataPathId);
+       void receiveDataPathRespondResponse(NanError error);
        void receiveDataPathEndResponse(NanError error);
 
        void receiveDisabledEvent(const NanDisabledEvent& event);
@@ -120,6 +120,8 @@ private:
        void createAllNanInterfaces(bool needRequest);
        void deleteAllNanInterfaces();
 
+       void emitDataPathOpenResultEventWithError(NanClient *client, NanError error);
+       NanError handleDataPathInitiateResponse(NanDataPathInformation *info, uint32_t dataPathId);
        bool checkMatchFilter(const uint8_t *pubFilter, uint16_t pubFilterLen,
                const uint8_t *rxFilter, uint16_t rxFilterLen);
 
index d1ca1fad9e8ee2d9f694b685b3ec11e897295245..2334247631ef189c734149de53a2051565225c56 100644 (file)
@@ -219,7 +219,7 @@ void NanTransmitFollowupCommand::response(NanError error)
 }
 
 NanDataPathRequestCommand::NanDataPathRequestCommand(std::shared_ptr<DataPathConfig> config,
-               int clientId, uint16_t id)
+               int clientId, uint16_t id, NanDataPathInformation *info)
 {
        mType = NanCommandType::DATA_PATH_INIT;
        mConfig = config;
@@ -227,6 +227,7 @@ NanDataPathRequestCommand::NanDataPathRequestCommand(std::shared_ptr<DataPathCon
        mPubSubId = id;
        object = config->object;
        invocation = config->invocation;
+       mDataPathInfo = info;
 }
 
 void NanDataPathRequestCommand::run(NanHal *hal)
@@ -241,13 +242,14 @@ void NanDataPathRequestCommand::response(NanError error)
 }
 
 NanDataPathResponseCommand::NanDataPathResponseCommand(std::shared_ptr<DataPathConfig> config,
-               int clientId)
+               int clientId, NanDataPathInformation *info)
 {
        mType = NanCommandType::DATA_PATH_RESP;
        mConfig = config;
        mClientId = clientId;
        object = config->object;
        invocation = config->invocation;
+       mDataPathInfo = info;
 }
 
 void NanDataPathResponseCommand::run(NanHal *hal)
index 22559b6ac915434655544a28c6f5d107c6977c81..d67eaf178cf91db32c921e0650589a20ba474ea4 100644 (file)
@@ -48,7 +48,7 @@ NanDataPathInformation::NanDataPathInformation(uint16_t pubSubId,
                NanPeer *peer, std::shared_ptr<DataPathConfig> config)
        : mDataPathId(0), mPubSubId(pubSubId), mPeer(peer), mConfig(config),
        mInterface(""), mPeerIpv6Address(""), mPeerPort(-1), mTransportProtocol(-1),
-       mIsConfirmed(false), mTimer(nullptr)
+       mIsConfirmed(false), mTimer(nullptr), mState(DataPathState::IDLE)
 {
        if (mPeer != nullptr)
                NAN_LOGD("New DataPathInformation(pubSubId: %u, peer: %p, peerId: %u)",
@@ -73,7 +73,7 @@ uint32_t NanDataPathInformation::getDataPathId()
 
 void NanDataPathInformation::setDataPathId(uint32_t id)
 {
-       NAN_LOGI("setDataPathId(%d)", id);
+       NAN_LOGI("setDataPathId. dataPathId %u", id);
        mDataPathId = mConfig->dataPathId = id;
 }
 
@@ -122,7 +122,7 @@ void NanDataPathInformation::setConfirmedState(bool confirmed)
 
 bool NanDataPathInformation::isConfirmed(void)
 {
-       NAN_LOGI("%d data path is%s",
+       NAN_LOGI("dataPathId %u is %s",
                        mDataPathId, mIsConfirmed ? " confirmed." : "n't confirmed.");
        return mIsConfirmed;
 }
@@ -317,3 +317,19 @@ void NanDataPathInformation::setTimer(NanTimer *timer)
        }
        mTimer = timer;
 }
+
+void NanDataPathInformation::setState(DataPathState state)
+{
+       NAN_LOGD("DataPathState %d --> %d", static_cast<int>(mState), static_cast<int>(state));
+       mState = state;
+}
+
+DataPathState NanDataPathInformation::getState()
+{
+       return mState;
+}
+
+int NanDataPathInformation::getStateAsInt()
+{
+       return static_cast<int>(mState);
+}
index bde516df887bf407dd68caf7b2f8b006c103cdb6..aec89abf12fc3a83bb0f0192e2b0e2c5f52da061 100644 (file)
@@ -118,7 +118,7 @@ void NanDataPathManager::deleteDataPathInfo(NanDataPathInformation *dataPathInfo
 
 void NanDataPathManager::removeDataPathInfo(NanDataPathInformation *dataPathInfo)
 {
-    NAN_LOGI("Remove data path(%u/%p)", dataPathInfo->getDataPathId(), dataPathInfo);
+    NAN_LOGI("Remove data path. dataPathId %u, dataPathInfo %p", dataPathInfo->getDataPathId(), dataPathInfo);
        for (auto it = mDataPathInfoMap.begin(); it != mDataPathInfoMap.end(); ++it) {
                if (it->second == dataPathInfo) {
                        it = mDataPathInfoMap.erase(it);
@@ -148,7 +148,7 @@ NanDataPathInformation *NanDataPathManager::getDataPathInfo(uint32_t dataPathId)
 {
        for (const auto &kv : mDataPathInfoMap) {
                if (kv.second->getDataPathId() == dataPathId) {
-                       NAN_LOGI("found! (%u/%p)", dataPathId, kv.second);
+                       NAN_LOGI("found! dataPathId %u, dataPathInfo %p", dataPathId, kv.second);
                        return kv.second;
                }
        }
@@ -165,14 +165,17 @@ NanDataPathInformation *NanDataPathManager::getDataPathInfo(uint16_t pubSubId, u
        return iter->second;
 }
 
-NanDataPathInformation *NanDataPathManager::getDataPathInfo(uint16_t pubSubId, const uint8_t *peerMac)
+NanDataPathInformation *NanDataPathManager::getDataPathInfo(uint16_t pubSubId,
+               const uint8_t *peerMac, DataPathState state)
 {
        for (const auto &kv : mDataPathInfoMap) {
                if (kv.first.first != pubSubId)
                        continue;
+               if (kv.second->getState() != state)
+                       continue;
                NanPeer *peer = kv.second->getPeer();
                if (peer != nullptr && isSameMacAddress(peer->getMacAddr(), peerMac)) {
-                       NAN_LOGI("found! pubSubId: %u, ndpId: %d)", pubSubId, kv.second->getDataPathId());
+                       NAN_LOGI("found! pubSubId: %u, ndpId: (%d)", pubSubId, kv.second->getDataPathId());
                        return kv.second;
                }
        }
index aab9e22619d22357c5e39e3369dbd3fb79a26528..44f0c379a1334753a30e49023f823c20e78dda6c 100644 (file)
@@ -454,7 +454,7 @@ void NanHal::respondToDataPath(std::shared_ptr<DataPathConfig> config)
                NAN_LOGE("Failed to convert from DataPathResponse to ");
                if (mUserCallbacks.on_notify_dp_respond_response) {
                        mUserCallbacks.on_notify_dp_respond_response(ERROR_TRANSACTION_ID,
-                                       NAN_ERROR_INVALID_PARAMETER, 0);
+                                       NAN_ERROR_INVALID_PARAMETER);
                }
                __NAN_LOG_FUNC_EXIT__;
                return;
@@ -468,7 +468,7 @@ void NanHal::respondToDataPath(std::shared_ptr<DataPathConfig> config)
        error = convertLegacyErrorToNanError(ret);
        if (error != NAN_ERROR_NONE && mUserCallbacks.on_notify_dp_respond_response) {
                NAN_LOGE("Failed to response NDP [%d:%d]", error, ret);
-               mUserCallbacks.on_notify_dp_respond_response(transactionId, error, config->dataPathId);
+               mUserCallbacks.on_notify_dp_respond_response(transactionId, error);
        }
 
        free(ndpIndicationResp);
@@ -1088,6 +1088,7 @@ NanDataPathIndicationResponse* NanHal::convertDataPathConfigToLegacyResponse(std
        memcpy(&ndpIndicationResp->service_name,
                        config->serviceName, ndpIndicationResp->service_name_len);
 
+       NAN_LOGI("ndpID(%u)", ndpIndicationResp->ndp_instance_id);
        NAN_LOGI("accept(%d)", ndpIndicationResp->rsp_code);
        NAN_LOGI("security(%d)", ndpIndicationResp->ndp_cfg.security_cfg);
 
index e120df3ada3732f0b1da3a6b9e0788556d580105..3a1b0b75028fcf650670455c5ce08e94fcc2e41e 100644 (file)
@@ -42,7 +42,7 @@ std::function<void(uint16_t, NanError)> on_notify_config_response;
 std::function<void(uint16_t, NanError)> on_notify_dp_interface_create_response;
 std::function<void(uint16_t, NanError)> on_notify_dp_interface_delete_response;
 std::function<void(uint16_t, NanError, uint32_t)> on_notify_dp_init_response;
-std::function<void(uint16_t, NanError, uint32_t)> on_notify_dp_respond_response;
+std::function<void(uint16_t, NanError)> on_notify_dp_respond_response;
 std::function<void(uint16_t, NanError)> on_notify_dp_terminate_response;
 std::function<void(uint16_t, NanError, NanCapabilitiesInfo&)> on_notify_capabilities_response;
 
@@ -191,8 +191,7 @@ void onNotifyResponse(transaction_id id, NanResponseMsg *rsp_data)
                        break;
                case NAN_DP_RESPONDER_RESPONSE:
                        if (on_notify_dp_respond_response)
-                               on_notify_dp_respond_response(id, error,
-                                               rsp_data->body.data_request_response.ndp_instance_id);
+                               on_notify_dp_respond_response(id, error);
                        break;
                case NAN_DP_END:
                        if (on_notify_dp_terminate_response)
index 232ae90e9129785d0ab1965ff3625e55a5ee3b47..c84f5b84f505c2660ba96907ef7fbad558b322fc 100644 (file)
@@ -104,8 +104,8 @@ void NanServiceProvider::registerCallbacks()
                };
 
        callbacks.on_notify_dp_respond_response
-               = [=](uint16_t transactionId, NanError error, uint32_t dataPathId) {
-                       return receiveDataPathRespondResponse(error, dataPathId);
+               = [=](uint16_t transactionId, NanError error) {
+                       return receiveDataPathRespondResponse(error);
                };
 
        callbacks.on_notify_dp_terminate_response
@@ -474,8 +474,10 @@ NanError NanServiceProvider::openDataPath(std::shared_ptr<DataPathConfig> config
 
        config->requestorId = peer->getRequestorId();
        memcpy(config->peerAddr, peer->getMacAddr(), NAN_MAC_ADDR_LEN);
-       NAN_LOGD("Find peer %p. requestorId %u, mac %x:%x:%x:%x:%x:%x)", peer, requestorId,
-                       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+       NAN_LOGD("Find peer %p. requestorId %u, mac %x:%x:%x:%x:%x:%x)",
+                       peer, config->requestorId,
+                       config->peerAddr[0], config->peerAddr[1], config->peerAddr[2],
+                       config->peerAddr[3], config->peerAddr[4], config->peerAddr[5]);
 
        // Add a data path information.
        NanDataPathInformation *info = mDataPathManager.createDataPathInformation(pubSubId, peer, config);
@@ -501,15 +503,17 @@ NanError NanServiceProvider::openDataPath(std::shared_ptr<DataPathConfig> config
        NanCommand *cmd = nullptr;
        if (role == NAN_DATA_PATH_INITIATOR) {
                NAN_LOGI("Create Command for [DATA_PATH_INITIATE]");
-               cmd = new NanDataPathRequestCommand(config, clientId, pubSubId);
+               cmd = new NanDataPathRequestCommand(config, clientId, pubSubId, info);
                if (cmd == nullptr) {
                        NAN_LOGE("Out of memory");
                        return NAN_ERROR_MEMORY;
                }
                scheduleCommand(cmd);
+               info->setState(DataPathState::INITIATOR_WAIT_FOR_REQUEST_RESPONSE);
                mDataPathManager.startOpenDataPathTimer(info, client->getClientPath());
        } else {
                NAN_LOGI("Wait for DataPathRequest event.");
+               info->setState(DataPathState::RESPONDER_WAIT_FOR_REQUEST);
        }
 
        return NAN_ERROR_NONE;
@@ -874,7 +878,7 @@ void NanServiceProvider::receiveCreateDataPathInterfaceResponse(NanError error)
        stopResponseTimer();
 
        if (error == NAN_ERROR_NONE) {
-               NanCreateInterfaceCommand *cmd = dynamic_cast<NanCreateInterfaceCommand*>(mCurrentCommand);
+               NanCreateInterfaceCommand *cmd = dynamic_cast<NanCreateInterfaceCommand *>(mCurrentCommand);
                if (cmd != nullptr)
                        mDataPathManager.addDataPathInterface(cmd->getInterface());
                else
@@ -904,7 +908,7 @@ void NanServiceProvider::receiveDeleteDataPathInterfaceResponse(NanError error)
        stopResponseTimer();
 
        if (error == NAN_ERROR_NONE) {
-               NanDeleteInterfaceCommand *cmd = dynamic_cast<NanDeleteInterfaceCommand*>(mCurrentCommand);
+               NanDeleteInterfaceCommand *cmd = dynamic_cast<NanDeleteInterfaceCommand *>(mCurrentCommand);
                if (cmd)
                        mDataPathManager.removeDataPathInterface(cmd->getInterface());
                else
@@ -915,6 +919,36 @@ void NanServiceProvider::receiveDeleteDataPathInterfaceResponse(NanError error)
        setCurrentState(READY_STATE);
 }
 
+void NanServiceProvider::emitDataPathOpenResultEventWithError(NanClient *client, NanError error)
+{
+       if (error == NAN_ERROR_NONE)
+               return;
+
+       if (client == nullptr) {
+               NAN_LOGE("No client. Cannot emit event");
+               return;
+       }
+
+       NanDbusHandler::dataPathOpenResultEvent(client->getClientPath(),
+                       0, "", "", -1, error);
+}
+
+NanError NanServiceProvider::handleDataPathInitiateResponse(NanDataPathInformation *info, uint32_t dataPathId)
+{
+       if (info == nullptr) {
+               NAN_LOGE("DataPathInfomation is nullptr");
+               return NAN_ERROR_ABORT;
+       }
+       if (info->getState() != DataPathState::INITIATOR_WAIT_FOR_REQUEST_RESPONSE) {
+               NAN_LOGE("Invalid DataPath State %d", info->getStateAsInt());
+               return NAN_ERROR_ABORT;
+       }
+
+       info->setDataPathId(dataPathId);
+       info->setState(DataPathState::WAIT_FOR_CONFIRM);
+       return NAN_ERROR_NONE;
+}
+
 void NanServiceProvider::receiveDataPathInitiateResponse(NanError error, uint32_t dataPathId)
 {
        NAN_LOGI("Receive Response for [DATA_PATH_INITIATE] (error: %d) dataPathId: %u", error, dataPathId);
@@ -934,29 +968,18 @@ void NanServiceProvider::receiveDataPathInitiateResponse(NanError error, uint32_
 
        stopResponseTimer();
 
-       NanClient *client = mClientManager.getClientWithPubSubId(mCurrentCommand->getPubSubId());
-       if (client != nullptr) {
-               if (error == NAN_ERROR_NONE) {
-                       [&]() {
-                               std::shared_ptr<DataPathConfig> config =
-                                       std::dynamic_pointer_cast<DataPathConfig>(mCurrentCommand->getNanConfig());
-                               RET_IF_NULL(config);
+       NanDataPathRequestCommand *cmd = dynamic_cast<NanDataPathRequestCommand *>(mCurrentCommand);
+       if (cmd == nullptr) {
+               NAN_LOGE("dynamic_cast failed");
+               return;
+       }
 
-                               NanPeer *peer = mPeerManager.findPeer(config->requestorId, config->peerAddr);
-                               RET_IF_NULL(peer);
+       if (error == NAN_ERROR_NONE)
+               error = handleDataPathInitiateResponse(cmd->mDataPathInfo, dataPathId);
 
-                               NanDataPathInformation *info
-                                       = mDataPathManager.getDataPathInfo(mCurrentCommand->getPubSubId(), peer->getPeerId());
-                               RET_IF_NULL(info);
-
-                               info->setDataPathId(dataPathId);
-                       }();
-               }
-               else {
-                       NanDbusHandler::dataPathOpenResultEvent(client->getClientPath(),
-                                       0, "", "", -1, error);
-               }
-       }
+       emitDataPathOpenResultEventWithError(
+                       mClientManager.getClientWithPubSubId(mCurrentCommand->getPubSubId()),
+                       error);
 
        deleteCurrentCommand();
        setCurrentState(READY_STATE);
@@ -995,9 +1018,9 @@ void NanServiceProvider::closeDataPathInternal(uint32_t dataPathId)
        }
 }
 
-void NanServiceProvider::receiveDataPathRespondResponse(NanError error, uint32_t dataPathId)
+void NanServiceProvider::receiveDataPathRespondResponse(NanError error)
 {
-       NAN_LOGI("Receive Response for [DATA_PATH_RESPOND] (error: %d) dataPathId: %u", error, dataPathId);
+       NAN_LOGI("Receive Response for [DATA_PATH_RESPOND] (error: %d)", error);
 
        if (mCurrentState != WAIT_RESPONSE_STATE) {
                return;
@@ -1011,8 +1034,32 @@ void NanServiceProvider::receiveDataPathRespondResponse(NanError error, uint32_t
 
        stopResponseTimer();
 
-       if (error != NAN_ERROR_NONE)
-               closeDataPathInternal(dataPathId);
+       NanDataPathResponseCommand *cmd = dynamic_cast<NanDataPathResponseCommand *>(mCurrentCommand);
+       if (cmd == nullptr) {
+               NAN_LOGE("dynamic_cast failed");
+               return;
+       }
+
+       NanDataPathInformation *info = cmd->mDataPathInfo;
+       if (info == nullptr) {
+               NAN_LOGE("DataPathInfomation is nullptr");
+               if (error == NAN_ERROR_NONE)
+                       error = NAN_ERROR_ABORT;
+       }
+
+       if (error != NAN_ERROR_NONE) {
+               closeDataPathInternal(info->getDataPathId());
+       }
+       else {
+               if (info->getState() != DataPathState::RESPONDER_WAIT_FOR_RESPOND_RESPONSE) {
+                       NAN_LOGE("Invalid state %d", info->getStateAsInt());
+                       closeDataPathInternal(info->getDataPathId());
+                       error = NAN_ERROR_ABORT;
+               }
+               else {
+                       info->setState(DataPathState::WAIT_FOR_CONFIRM);
+               }
+       }
 
        mCurrentCommand->response(error);
 
@@ -1220,7 +1267,7 @@ void NanServiceProvider::receiveMessageReceivedEvent(const NanFollowupEvent& eve
 void NanServiceProvider::receiveDataPathRequestEvent(const NanDataPathRequestEvent& event)
 {
        NAN_LOGI("Receive Event [DATA_PATH_REQUEST]");
-       NAN_LOGI("serviceId(%u) DataPathId(%u)", event.serviceId, event.dataPathId);
+       NAN_LOGI("serviceId(%u) dataPathId(%u)", event.serviceId, event.dataPathId);
 
        NanClient *client = mClientManager.getClientWithPubSubId(event.serviceId);
 
@@ -1231,7 +1278,8 @@ void NanServiceProvider::receiveDataPathRequestEvent(const NanDataPathRequestEve
        }
 
        NanDataPathInformation *info
-               = mDataPathManager.getDataPathInfo(event.serviceId, event.addr);
+               = mDataPathManager.getDataPathInfo(event.serviceId, event.addr,
+                               DataPathState::RESPONDER_WAIT_FOR_REQUEST);
        if (!info) {
                NAN_LOGE("No matched DataPathInfo. Send End event");
                closeDataPathInternal(event.dataPathId, client->getClientId());
@@ -1242,8 +1290,6 @@ void NanServiceProvider::receiveDataPathRequestEvent(const NanDataPathRequestEve
        info->setDataPathId(event.dataPathId);
 
        std::shared_ptr<DataPathConfig> config = info->getConfig();
-       NAN_LOGD("DataPathConfig %p", config.get());
-       NAN_LOGD("appInfoLen %u", config->appInfoLen);
 
        if (!config) {
                NAN_LOGE("DataPathConfig doesn't exist.");
@@ -1251,6 +1297,7 @@ void NanServiceProvider::receiveDataPathRequestEvent(const NanDataPathRequestEve
                return;
        }
 
+       NAN_LOGD("DataPathConfig %p", config.get());
        runDataPathResponseCommand(config, client, info);
 }
 
@@ -1274,8 +1321,15 @@ void NanServiceProvider::receiveDataPathConfirmEvent(const NanDataPathConfirmEve
                return;
        }
 
+       if (info->getState() != DataPathState::WAIT_FOR_CONFIRM) {
+               NAN_LOGE("Invalid state %d", info->getStateAsInt());
+               closeDataPathInternal(event.dataPathId, client->getClientId());
+               return;
+       }
+
        mDataPathManager.stopOpenDataPathTimer(info);
        info->setConfirmedState(true);
+       info->setState(DataPathState::CONFIRMED);
 
        if (event.result == NAN_ERROR_NONE) {
                info->setInfoWithAppInfo(event.appInfo, event.appInfoLen);
@@ -1392,12 +1446,17 @@ void NanServiceProvider::runDataPathResponseCommand(std::shared_ptr<DataPathConf
        NAN_LOGI("Create Command for [DATA_PATH_RESPONSE] client: %p", client);
        RET_IF_NULL(client);
 
-       NanCommand *cmd = new NanDataPathResponseCommand(config, client->getClientId());
+       NanCommand *cmd = new NanDataPathResponseCommand(config, client->getClientId(), info);
        if (cmd == nullptr) {
                NAN_LOGE("Out of memory");
                return;
        }
 
+       NAN_LOGD("requestorId %u", config->requestorId);
+       NAN_LOGD("dataPathId %u", config->dataPathId);
+       NAN_LOGD("appInfoLen %u", config->appInfoLen);
+
+       info->setState(DataPathState::RESPONDER_WAIT_FOR_RESPOND_RESPONSE);
        scheduleCommand(cmd);
        mDataPathManager.startOpenDataPathTimer(info, client->getClientPath());
 }