#include "PublishConfig.h"
#include "SubscribeConfig.h"
#include "DataPathEndConfig.h"
+#include "NanDataPathInformation.h"
#include "NanDefinitions.h"
#include "NanError.h"
#include "NanLog.h"
{
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
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:
void setPeerDataPathMac(const uint8_t *mac);
void setTimer(NanTimer *timer);
+ void setState(DataPathState state);
+ DataPathState getState();
+ int getStateAsInt();
private:
bool isValidLengthForIpv6AddressTlv(size_t length);
bool mIsConfirmed;
NanTimer *mTimer;
+
+ DataPathState mState;
};
NAN_NAMESPACE_END
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();
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;
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);
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);
}
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;
mPubSubId = id;
object = config->object;
invocation = config->invocation;
+ mDataPathInfo = info;
}
void NanDataPathRequestCommand::run(NanHal *hal)
}
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)
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)",
void NanDataPathInformation::setDataPathId(uint32_t id)
{
- NAN_LOGI("setDataPathId(%d)", id);
+ NAN_LOGI("setDataPathId. dataPathId %u", id);
mDataPathId = mConfig->dataPathId = id;
}
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;
}
}
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);
+}
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);
{
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;
}
}
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;
}
}
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;
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);
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);
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;
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)
};
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
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);
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;
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
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
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);
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);
}
}
-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;
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);
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);
}
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());
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.");
return;
}
+ NAN_LOGD("DataPathConfig %p", config.get());
runDataPathResponseCommand(config, client, info);
}
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);
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());
}