diff --git a/distributedfile.gni b/distributedfile.gni index ecea88b2ebc741c042f0e2a42dac30c053f05a3f..8e358c0e5afa35f95cdf36db144dc238f4c8df19 100755 --- a/distributedfile.gni +++ b/distributedfile.gni @@ -15,4 +15,4 @@ distributedfile_path = "//foundation/filemanagement/dfs_service" utils_path = "${distributedfile_path}/utils" services_path = "${distributedfile_path}/services" -innerkits_native_path = "${distributedfile_path}/interfaces/innerkits/native" \ No newline at end of file +innerkits_native_path = "${distributedfile_path}/interfaces/innerkits/native" diff --git a/frameworks/native/service_proxy.cpp b/frameworks/native/service_proxy.cpp index ac73e3dfdc84666ddc941f203a3cca50a5764b56..8d9ae82395195bf436532e85d05a3cba269d5433 100644 --- a/frameworks/native/service_proxy.cpp +++ b/frameworks/native/service_proxy.cpp @@ -19,9 +19,25 @@ namespace OHOS { namespace Storage { namespace DistributedFile { -ServiceProxy::ServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} -ServiceProxy::~ServiceProxy() {} +int32_t ServiceProxy::SendFile(const std::string &cid, + const std::vector &sourceFileList, + const std::vector &destinationFileList, + const uint32_t fileCount) +{ + return 0; +} + +int32_t ServiceProxy::sendTest() +{ + LOGE("sendTest enter"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + int ret = Remote()->SendRequest(TEST_CODE, data, reply, option); + LOGE("sendTest sendrequest done %{public}d", ret); + return ret; +} } // namespace DistributedFile } // namespace Storage } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/service_proxy.h b/frameworks/native/service_proxy.h index 5b510e969284c69899ecf6ee0c2deb48f9597236..d5a2d52c4f2121ae4305bb5f94d7603ccb85d147 100644 --- a/frameworks/native/service_proxy.h +++ b/frameworks/native/service_proxy.h @@ -30,15 +30,19 @@ public: * * @param impl */ - explicit ServiceProxy(const sptr &impl); + explicit ServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} - virtual ~ServiceProxy(); + virtual ~ServiceProxy() = default; + int32_t SendFile(const std::string &cid, + const std::vector &sourceFileList, + const std::vector &destinationFileList, + const uint32_t fileCount) override; + int32_t sendTest() override; private: static inline BrokerDelegator delegator_; }; } // namespace DistributedFile } // namespace Storage } // namespace OHOS - -#endif \ No newline at end of file +#endif // DISTRIBUTEDFILE_SERVICE_PROXY_H \ No newline at end of file diff --git a/interfaces/innerkits/native/i_distributedfile_service.h b/interfaces/innerkits/native/i_distributedfile_service.h index 878461cbd84f9c3f3b76d53edc9f356dbc358fd2..725725020e874e1af4c243c9890f85af0609aef8 100644 --- a/interfaces/innerkits/native/i_distributedfile_service.h +++ b/interfaces/innerkits/native/i_distributedfile_service.h @@ -25,9 +25,11 @@ class IDistributedFileService : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedFile.IDistributedFileService"); // define the message code + enum DistributedFileSurfaceCode { INTERFACE1 = 0, SEND_FILE_DISTRIBUTED, TEST_CODE }; // define the error code enum { DISTRIBUTEDFILE_SUCCESS = 0, + GET_DISTRIBUTEDFILE_DISTRIBUTED_DIR_FAIL = 1, DISTRIBUTEDFILE_WRITE_DESCRIPTOR_TOKEN_FAIL, ERR_FLATTEN_OBJECT, DISTRIBUTEDFILE_NO_ERROR, @@ -42,10 +44,16 @@ public: DISTRIBUTEDFILE_PERMISSION_DENIED, ROOT_UID, SYSTEM_SERVICE_UID, + SEND_FILE_FAIL, + SEND_FILE_DISTRIBUTED_DESCRIPTION_FAIL }; + virtual int32_t SendFile(const std::string &cid, + const std::vector &sourceFileList, + const std::vector &destinationFileList, + const uint32_t fileCount) = 0; + virtual int32_t sendTest() = 0; }; } // namespace DistributedFile } // namespace Storage } // namespace OHOS - -#endif // I_YANGHU_TESt_SERVICE_H \ No newline at end of file +#endif // I_DISTRIBUTEDFILE_SERVICE_H \ No newline at end of file diff --git a/services/distributedfileservice/BUILD.gn b/services/distributedfileservice/BUILD.gn index 6238f1f11a675900b87dc9448ffb01b736c6e35a..a98b9383f68f25307f5098477fea936003f28d57 100644 --- a/services/distributedfileservice/BUILD.gn +++ b/services/distributedfileservice/BUILD.gn @@ -14,19 +14,25 @@ import("//build/ohos.gni") import("//foundation/filemanagement/dfs_service/distributedfile.gni") ohos_shared_library("libdistributedfileservice") { - include_dirs = [ "include/ipc" ] + include_dirs = [ + "include/ipc", + "include/device", + "include/network", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", + ] sources = [ + "src/device/device_manager_agent.cpp", "src/ipc/distributedfile_service.cpp", "src/ipc/distributedfile_service_stub.cpp", + "src/network/softbus_agent.cpp", + "src/network/softbus_dispatcher.cpp", ] configs = [ "${utils_path}:compiler_configs" ] external_deps = [ - "ability_base:want", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", + "dsoftbus_standard:softbus_client", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", @@ -35,6 +41,7 @@ ohos_shared_library("libdistributedfileservice") { deps = [ "${utils_path}:libdistributedfileutils", "../../interfaces/innerkits/native:libdistributedfile_innerkits", + "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp:devicemanagersdk", ] part_name = "dfs_service" diff --git a/services/distributedfileservice/include/device/device_manager_agent.h b/services/distributedfileservice/include/device/device_manager_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..b2a11da1a6652661e0a32748688780d05e09348d --- /dev/null +++ b/services/distributedfileservice/include/device/device_manager_agent.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DFS_DEVICE_MANAGER_AGENT_H +#define DFS_DEVICE_MANAGER_AGENT_H + +#include +#include +#include +#include +#include +#include +#include + +#include "device_manager.h" +#include "utils_singleton.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DeviceManagerAgent : public DistributedHardware::DmInitCallback, + public DistributedHardware::DeviceStateCallback, + public std::enable_shared_from_this, + public Utils::Singleton { + DECLARE_SINGLETON(DeviceManagerAgent); + +public: + void OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) override {} + void OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo) override {} + void OfflineAllDevice(); + void OnRemoteDied() override; + std::set getOnlineDevs() const + { + return alreadyOnlineDev_; + } + std::vector GetRemoteDevicesInfo(); + +private: + void StartInstance() override; + void StopInstance() override; + + void RegisterToExternalDm(); + void UnregisterFromExternalDm(); + + std::mutex devsRecordMutex_; + std::set alreadyOnlineDev_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DFS_DEVICE_MANAGER_AGENT_H \ No newline at end of file diff --git a/services/distributedfileservice/include/ipc/distributedfile_service.h b/services/distributedfileservice/include/ipc/distributedfile_service.h index 2ed0ef60ff154e574d10101d6b3359936594a2e7..8bca0a9200c4c23219b548164302e6336418b47f 100644 --- a/services/distributedfileservice/include/ipc/distributedfile_service.h +++ b/services/distributedfileservice/include/ipc/distributedfile_service.h @@ -18,23 +18,33 @@ #include "distributedfile_service_stub.h" #include "iremote_stub.h" -#include "singleton.h" #include "system_ability.h" -#include - namespace OHOS { namespace Storage { namespace DistributedFile { class DistributedFileService : public SystemAbility, public DistributedFileServiceStub, public std::enable_shared_from_this { - DECLARE_DELAYED_SINGLETON(DistributedFileService) DECLARE_SYSTEM_ABILITY(DistributedFileService) public: + DistributedFileService(int32_t saID, bool runOnCreate) : SystemAbility(saID, runOnCreate) {}; + ~DistributedFileService() {}; + void OnDump() override; void OnStart() override; void OnStop() override; + + int32_t SendFile(const std::string &cid, + const std::vector &sourceFileList, + const std::vector &destinationFileList, + const uint32_t fileCount) override; + int32_t sendTest() override; + + static inline const std::string pkgName_ { "ohos.storage.distributedfile.service" }; +private: + void PublishSA(); + void StartManagers(); }; } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfileservice/include/ipc/distributedfile_service_stub.h b/services/distributedfileservice/include/ipc/distributedfile_service_stub.h index 419f6782b9aa8d185260cad988e7a144b5599953..a4c18bb514b93da1cc069c7b7c1fcb68d535b537 100644 --- a/services/distributedfileservice/include/ipc/distributedfile_service_stub.h +++ b/services/distributedfileservice/include/ipc/distributedfile_service_stub.h @@ -36,9 +36,10 @@ private: using DistributedFileServiceFunc = int32_t (DistributedFileServiceStub::*)(MessageParcel &data, MessageParcel &reply); std::map memberFuncMap_; + int32_t SendFileStub(MessageParcel &data, MessageParcel &reply); + int test(MessageParcel &data, MessageParcel &reply); }; } // namespace DistributedFile } // namespace Storage } // namespace OHOS - #endif // DISTRIBUTEDFILE_SERVICE_STUB_H \ No newline at end of file diff --git a/services/distributedfileservice/include/network/softbus_agent.h b/services/distributedfileservice/include/network/softbus_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..ec93ec9661844ae731d6e777df7b998d15d44554 --- /dev/null +++ b/services/distributedfileservice/include/network/softbus_agent.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DFS_SOFTBUS_AGENT_H +#define DFS_SOFTBUS_AGENT_H + +#include +#include +#include +#include "utils_singleton.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAgent : public std::enable_shared_from_this, public Utils::Singleton { + DECLARE_SINGLETON(SoftbusAgent); + +public: + void RegisterSessionListener(); + void RegisterFileListener(); + void UnRegisterSessionListener(); + void OnDeviceOnline(const std::string &cid); + void OnDeviceOffline(const std::string &cid); + void AllDevicesOffline(); + void OnSessionOpened(const int sessionId, const int result); + void OnSessionClosed(int sessionId); + int SendFile(const std::string &cid, const char *sFileList[], const char *dFileList[], uint32_t fileCnt); + int OnSendFileFinished(const int sessionId, const std::string firstFile); + int OnFileTransError(const int sessionId); + void OnReceiveFileFinished(const int sessionId, const std::string files, int fileCnt); + +protected: + void StartInstance() override; + void StopInstance() override; + void OpenSession(const std::string &cid); + int CloseSession(const std::string &cid); + std::string GetPeerDevId(const int sessionId); + +private: + std::string sessionName_ { "DistributedFileService" }; + std::mutex sessionMapMux_; + std::unordered_map> cidToSessionID_; + + std::mutex getSessionCVMut_; + std::condition_variable getSessionCV_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DFS_SOFTBUS_AGENT_H \ No newline at end of file diff --git a/services/distributedfileservice/include/network/softbus_dispatcher.h b/services/distributedfileservice/include/network/softbus_dispatcher.h new file mode 100644 index 0000000000000000000000000000000000000000..79a14a61e6437935024b152b83bb4a3c1e17681a --- /dev/null +++ b/services/distributedfileservice/include/network/softbus_dispatcher.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DFS_SOFTBUS_SESSION_DISPATCHER_H +#define DFS_SOFTBUS_SESSION_DISPATCHER_H + +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { + +class SoftbusDispatcher final { +public: + SoftbusDispatcher() = delete; + ~SoftbusDispatcher() = delete; + static void RegisterSessionListener(); + static void UnregisterSessionListener(const std::string busName); + + static int OnSessionOpened(int sessionId, int result); + static void OnSessionClosed(int sessionId); + + // IFileSendListener + static int OnSendFileFinished(int sessionId, const char *firstFile); + static void OnFileTransError(int sessionId); + + // IFileReceiveListener + static void OnReceiveFileFinished(int sessionId, const char *files, int fileCnt); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DFS_SOFTBUS_SESSION_DISPATCHER_H \ No newline at end of file diff --git a/services/distributedfileservice/src/device/device_manager_agent.cpp b/services/distributedfileservice/src/device/device_manager_agent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11bb75834bcfa32adb01b3f3d6c43e328c110962 --- /dev/null +++ b/services/distributedfileservice/src/device/device_manager_agent.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "device_manager_agent.h" +#include "distributedfile_service.h" +#include "softbus_agent.h" +#include "utils_exception.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; +DeviceManagerAgent::DeviceManagerAgent() {} + +DeviceManagerAgent::~DeviceManagerAgent() +{ + StopInstance(); +} +void DeviceManagerAgent::StartInstance() +{ + // the time sequence can ensure there is no resource competition + alreadyOnlineDev_.clear(); + RegisterToExternalDm(); +} + +void DeviceManagerAgent::StopInstance() +{ + UnregisterFromExternalDm(); +} + +void DeviceManagerAgent::OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + std::unique_lock lock(devsRecordMutex_); + std::string cid = std::string(deviceInfo.deviceId); + alreadyOnlineDev_.insert(cid); + SoftbusAgent::GetInstance()->OnDeviceOnline(cid); +} + +void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + std::unique_lock lock(devsRecordMutex_); + std::string cid = std::string(deviceInfo.deviceId); + auto softBusAgent = SoftbusAgent::GetInstance(); + softBusAgent->OnDeviceOffline(cid); + + alreadyOnlineDev_.erase(cid); + LOGI("cid %{public}s offline, left online devices num %{public}d", cid.c_str(), alreadyOnlineDev_.size()); +} + +void DeviceManagerAgent::OnRemoteDied() +{ + LOGI("device manager service died"); + UnregisterFromExternalDm(); + RegisterToExternalDm(); +} + +void DeviceManagerAgent::RegisterToExternalDm() +{ + auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); + int errCode = deviceManager.InitDeviceManager(DistributedFileService::pkgName_, shared_from_this()); + if (errCode != 0) { + ThrowException(errCode, "Failed to InitDeviceManager"); + } + string extra = ""; + errCode = deviceManager.RegisterDevStateCallback(DistributedFileService::pkgName_, extra, shared_from_this()); + if (errCode != 0) { + ThrowException(errCode, "Failed to RegisterDevStateCallback"); + } + LOGI("RegisterToExternalDm Succeed"); +} + +void DeviceManagerAgent::UnregisterFromExternalDm() +{ + auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); + int errCode = deviceManager.UnRegisterDevStateCallback(DistributedFileService::pkgName_); + if (errCode != 0) { + ThrowException(errCode, "Failed to UnRegisterDevStateCallback"); + } + errCode = deviceManager.UnInitDeviceManager(DistributedFileService::pkgName_); + if (errCode != 0) { + ThrowException(errCode, "Failed to UnInitDeviceManager"); + } + LOGI("UnregisterFromExternalDm Succeed"); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfileservice/src/ipc/distributedfile_service.cpp b/services/distributedfileservice/src/ipc/distributedfile_service.cpp index e09d7636ea0fd31c90892a19e5c1f38d8af8963a..8bb1fb7d486268f6ae06085030165514dbf761cb 100644 --- a/services/distributedfileservice/src/ipc/distributedfile_service.cpp +++ b/services/distributedfileservice/src/ipc/distributedfile_service.cpp @@ -14,44 +14,67 @@ */ #include "distributedfile_service.h" -#include #include - -#include "bundle_mgr_interface.h" -#include "bundle_mgr_proxy.h" -#include "ipc_skeleton.h" -#include "iservice_registry.h" -#include "message_parcel.h" -#include "parcel.h" -#include "utils_directory.h" +#include "device_manager_agent.h" +#include "utils_exception.h" #include "utils_log.h" +#include "softbus_agent.h" namespace OHOS { namespace Storage { namespace DistributedFile { using namespace std; -DistributedFileService::DistributedFileService() : SystemAbility(STORAGE_DISTRIBUTED_FILE_SERVICE_SA_ID, false) {} - -DistributedFileService::~DistributedFileService() {} +REGISTER_SYSTEM_ABILITY_BY_ID(DistributedFileService, STORAGE_DISTRIBUTED_FILE_SERVICE_SA_ID, false); void DistributedFileService::OnDump() { LOGI("OnDump"); } -void DistributedFileService::OnStart() +void DistributedFileService::PublishSA() { - bool ret = SystemAbility::Publish(DelayedSingleton::GetInstance().get()); + LOGI("Begin to init, pull the service SA"); + bool ret = SystemAbility::Publish(this); if (!ret) { - LOGE("Leave, publishing DistributedFileService failed!"); - return; + throw runtime_error("publishing DistributedFileService failed"); + } + LOGI("Init finished successfully"); +} + +void DistributedFileService::StartManagers() +{ + DeviceManagerAgent::GetInstance(); +} + +void DistributedFileService::OnStart() +{ + LOGI("DistributedFileService::OnStart"); + try { + PublishSA(); + StartManagers(); + } catch (const Exception &e) { + LOGE("%{public}s", e.what()); } } void DistributedFileService::OnStop() { - LOGI("DistributedFileService::OnStop start"); + LOGI("DistributedFileService::OnStop"); +} + +int32_t DistributedFileService::sendTest() +{ + LOGI("DistributedFileService::sendTest"); + return 0; +} + +int32_t DistributedFileService::SendFile(const std::string &cid, + const std::vector &sourceFileList, + const std::vector &destinationFileList, + const uint32_t fileCount) +{ + return 0; } } // namespace DistributedFile } // namespace Storage diff --git a/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp b/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp index 08c7f202fd044b261d4caf14b0a59920a99fb4a7..79391881666a9c2e5754955a30a38755467220db 100644 --- a/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp +++ b/services/distributedfileservice/src/ipc/distributedfile_service_stub.cpp @@ -25,6 +25,8 @@ namespace Storage { namespace DistributedFile { DistributedFileServiceStub::DistributedFileServiceStub() { + memberFuncMap_[SEND_FILE_DISTRIBUTED] = &DistributedFileServiceStub::SendFileStub; + memberFuncMap_[TEST_CODE] = &DistributedFileServiceStub::test; } DistributedFileServiceStub::~DistributedFileServiceStub() @@ -37,12 +39,7 @@ int DistributedFileServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &reply, MessageOption &option) { - std::u16string myDescriptor = DistributedFileServiceStub::GetDescriptor(); - std::u16string remoteDescriptor = data.ReadInterfaceToken(); - if (myDescriptor != remoteDescriptor) { - return DISTRIBUTEDFILE_BAD_TYPE; - } - + LOGD("DistributedFileServiceStub : OnRemoteRequest enter, code %{public}d ", code); auto itFunc = memberFuncMap_.find(code); if (itFunc != memberFuncMap_.end()) { auto memberFunc = itFunc->second; @@ -53,6 +50,18 @@ int DistributedFileServiceStub::OnRemoteRequest(uint32_t code, return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } + +int DistributedFileServiceStub::test(MessageParcel &data, MessageParcel &reply) +{ + LOGD(" DistributedFileServiceStub : sendTest enter"); + sendTest(); + return 0; +} + +int32_t DistributedFileServiceStub::SendFileStub(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} } // namespace DistributedFile } // namespace Storage } // namespace OHOS \ No newline at end of file diff --git a/services/distributedfileservice/src/network/softbus_agent.cpp b/services/distributedfileservice/src/network/softbus_agent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da2acb13dda5521fc4529be9c60752e19451d70c --- /dev/null +++ b/services/distributedfileservice/src/network/softbus_agent.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_agent.h" + +#include +#include +#include +#include "device_manager_agent.h" +#include "distributedfile_service.h" +#include "session.h" +#include "softbus_dispatcher.h" +#include "utils_exception.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; +constexpr int32_t SOFTBUS_OK = 0; +constexpr int32_t DEVICE_ID_SIZE_MAX = 65; +constexpr int32_t IS_CLIENT = 0; +const std::string DEFAULT_ROOT_PATH = "/data/service/el2/100/hmdfs/non_account/data/"; + +SoftbusAgent::SoftbusAgent() {} + +SoftbusAgent::~SoftbusAgent() +{ + StopInstance(); +} +void SoftbusAgent::StartInstance() +{ + RegisterSessionListener(); + RegisterFileListener(); +} + +void SoftbusAgent::StopInstance() +{ + for (auto iter = cidToSessionID_.begin(); iter != cidToSessionID_.end();) { + CloseSession(iter->first); + iter = cidToSessionID_.erase(iter); + } + getSessionCV_.notify_all(); + UnRegisterSessionListener(); +} + +void SoftbusAgent::OnDeviceOnline(const std::string &cid) +{ + // todo:测试接口SendFile + const char *sFileList[1] = {"/data/user/0/xhl_sendfile_test/1.txt"}; + + static int sendfile_cnt = 0; + int ret = SendFile(cid, sFileList, nullptr, 1); + if (ret != 0) { + LOGE("sendfile failed, ret %{public}d", ret); + return; + } + LOGE("sendfile... ret %{public}d, sendfile_cnt %{public}d", ret, sendfile_cnt); +} + +int SoftbusAgent::SendFile(const std::string &cid, const char *sFileList[], const char *dFileList[], uint32_t fileCnt) +{ + // first check whether the sessionId available + auto alreadyOnliceDev = DeviceManagerAgent::GetInstance()->getOnlineDevs(); + if (alreadyOnliceDev.find(cid) == alreadyOnliceDev.end()) { + LOGE("cid:%{public}s has not been online yet, sendfile maybe will fail, try", cid.c_str()); + } + int sessionId = -1; + { + std::unique_lock lock(sessionMapMux_); + if (cidToSessionID_.find(cid) != cidToSessionID_.end() && + cidToSessionID_[cid].empty() == false) { // to avoid list is empty + sessionId = cidToSessionID_[cid].front(); + } + } + + // build socket synchronously + if (sessionId == -1) { + OpenSession(cid); + // wait for get sessionId + LOGD("openSession, wait"); + std::unique_lock lock(getSessionCVMut_); + getSessionCV_.wait(lock, [this, cid]() { return !cidToSessionID_[cid].empty(); }); + LOGD("openSession success, wakeup"); + if (cidToSessionID_[cid].empty()) { // wakeup check + LOGE("there is no sessionId of cid:%{public}s", cid.c_str()); + return -1; + } + sessionId = cidToSessionID_[cid].front(); + } + + int ret = ::SendFile(sessionId, sFileList, dFileList, fileCnt); + LOGE("sendfile is processing, sessionId:%{publid}d, ret %{public}d", sessionId, ret); + return ret; +} + +void SoftbusAgent::OpenSession(const std::string &cid) +{ + SessionAttribute attr; + attr.dataType = TYPE_FILE; // files use UDP, CHANNEL_TYPE_UDP + + LOGD("Start to Open Session, cid:%{public}s", cid.c_str()); + int sessionId = ::OpenSession(sessionName_.c_str(), sessionName_.c_str(), cid.c_str(), "DFS_wifiGroup", &attr); + if (sessionId < 0) { + LOGE("Failed to open session, cid:%{public}s, sessionId:%{public}d", cid.c_str(), sessionId); + return; + } + LOGD("Open Session SUCCESS, cid:%{public}s, sessionId %{public}d", cid.c_str(), sessionId); +} + +void SoftbusAgent::OnSessionOpened(const int sessionId, const int result) +{ + LOGD("get session res:%{public}d, sessionId:%{public}d", result, sessionId); + if (result != 0) { + LOGE("open failed, result:%{public}d, sessionId:%{public}d", result, sessionId); + return; + } + std::string cid = GetPeerDevId(sessionId); + if (cid == "") { + LOGE("get peer device id failed"); + return; + } + + // client session priority use, so insert list head + { + std::unique_lock lock(sessionMapMux_); + if (::GetSessionSide(sessionId) == IS_CLIENT) { + cidToSessionID_[cid].push_front(sessionId); + } else { + cidToSessionID_[cid].push_back(sessionId); + } + } + + // cv 唤醒等待的sendfile流程 + getSessionCV_.notify_one(); + LOGD("get session SUCCESS, sessionId:%{public}d", sessionId); +} + +int SoftbusAgent::OnSendFileFinished(const int sessionId, const std::string firstFile) +{ + LOGD("send file finish, sessionId:%{public}d, firstFile %{public}s", sessionId, firstFile.c_str()); + return 0; +} + +int SoftbusAgent::OnFileTransError(const int sessionId) +{ + LOGD("file trans error, sessionId:%{public}d", sessionId); + return 0; +} + +void SoftbusAgent::OnReceiveFileFinished(const int sessionId, const std::string files, int fileCnt) +{ + LOGD("recv file finish, sessionId:%{public}d, files %{public}s, cnt %{public}d", sessionId, files.c_str(), fileCnt); +} + +void SoftbusAgent::OnSessionClosed(int sessionId) +{ + std::string cid = GetPeerDevId(sessionId); + if (cid == "") { + LOGE("get peer device id failed"); + return; + } + std::unique_lock lock(sessionMapMux_); + if (cidToSessionID_.find(cid) != cidToSessionID_.end()) { + cidToSessionID_[cid].remove(sessionId); + } + return; +} + +std::string SoftbusAgent::GetPeerDevId(const int sessionId) +{ + std::string cid; + char peerDevId[DEVICE_ID_SIZE_MAX] = ""; + int ret = ::GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); + if (ret != SOFTBUS_OK) { + LOGE("get my peer device id failed, errno:%{public}d, sessionId:%{public}d", ret, sessionId); + cid = ""; + } else { + cid = string(peerDevId); + } + return cid; +} + +int SoftbusAgent::CloseSession(const std::string &cid) +{ + if (cidToSessionID_.find(cid) == cidToSessionID_.end()) { + LOGE("not find this dev-cid:%{public}s", cid.c_str()); + return -1; + } + for (auto sessionId : cidToSessionID_[cid]) { + ::CloseSession(sessionId); + } + LOGD("Close Session done, cid:%{public}s", cid.c_str()); + return 0; +} + +void SoftbusAgent::OnDeviceOffline(const std::string &cid) +{ + if (CloseSession(cid) == -1) { + return; + } + std::unique_lock lock(sessionMapMux_); + cidToSessionID_.erase(cid); +} + +void SoftbusAgent::RegisterSessionListener() +{ + ISessionListener sessionListener = { + .OnSessionOpened = SoftbusDispatcher::OnSessionOpened, + .OnSessionClosed = SoftbusDispatcher::OnSessionClosed, + }; + int ret = ::CreateSessionServer(DistributedFileService::pkgName_.c_str(), sessionName_.c_str(), &sessionListener); + if (ret != 0) { + stringstream ss; + ss << "Failed to CreateSessionServer, errno:" << ret; + LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str()); + return throw runtime_error(ss.str()); + } + LOGD("Succeed to CreateSessionServer, pkgName %{public}s, sbusName:%{public}s", + DistributedFileService::pkgName_.c_str(), sessionName_.c_str()); +} + +void SoftbusAgent::RegisterFileListener() +{ + IFileSendListener fileSendListener = { + .OnSendFileFinished = SoftbusDispatcher::OnSendFileFinished, + .OnFileTransError = SoftbusDispatcher::OnFileTransError, + }; + std::string pkgName = DistributedFileService::pkgName_; + int ret = ::SetFileSendListener(pkgName.c_str(), sessionName_.c_str(), &fileSendListener); + if (ret != 0) { + stringstream ss; + ss << "Failed to SetFileSendListener, errno:" << ret; + LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str()); + throw runtime_error(ss.str()); + } + LOGD("Succeed to SetFileSendListener, pkgName %{public}s, sbusName:%{public}s", pkgName.c_str(), + sessionName_.c_str()); + + IFileReceiveListener fileRecvListener = { + .OnReceiveFileFinished = SoftbusDispatcher::OnReceiveFileFinished, + .OnFileTransError = SoftbusDispatcher::OnFileTransError, + }; + ret = ::SetFileReceiveListener(pkgName.c_str(), sessionName_.c_str(), &fileRecvListener, + DEFAULT_ROOT_PATH.c_str()); + if (ret != 0) { + stringstream ss; + ss << "Failed to SetFileReceiveListener, errno:" << ret; + LOGE("%{public}s, sessionName:%{public}s", ss.str().c_str(), sessionName_.c_str()); + throw runtime_error(ss.str()); + } + LOGD("Succeed to SetFileReceiveListener, pkgName %{public}s, sbusName:%{public}s", pkgName.c_str(), + sessionName_.c_str()); +} +void SoftbusAgent::UnRegisterSessionListener() +{ + int ret = ::RemoveSessionServer(DistributedFileService::pkgName_.c_str(), sessionName_.c_str()); + if (ret != 0) { + stringstream ss; + ss << "Failed to RemoveSessionServer, errno:" << ret; + LOGE("%{public}s", ss.str().c_str()); + throw runtime_error(ss.str()); + } + LOGD("RemoveSessionServer success!"); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/services/distributedfileservice/src/network/softbus_dispatcher.cpp b/services/distributedfileservice/src/network/softbus_dispatcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..542f089c0577b63f8bac3e7920caa54da28b77fc --- /dev/null +++ b/services/distributedfileservice/src/network/softbus_dispatcher.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_dispatcher.h" +#include "softbus_agent.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { + +int SoftbusDispatcher::OnSessionOpened(int sessionId, int result) +{ + LOGD("get session res:%{public}d, sessionId:%{public}d", result, sessionId); + SoftbusAgent::GetInstance()->OnSessionOpened(sessionId, result); + return 0; +} + +void SoftbusDispatcher::OnSessionClosed(int sessionId) +{ + LOGD("sessionId:%{public}d", sessionId); + SoftbusAgent::GetInstance()->OnSessionClosed(sessionId); +} + +int SoftbusDispatcher::OnSendFileFinished(int sessionId, const char *firstFile) +{ + LOGD("sessionId:%{public}d", sessionId); + SoftbusAgent::GetInstance()->OnSendFileFinished(sessionId, std::string(firstFile)); + return 0; +} + +void SoftbusDispatcher::OnFileTransError(int sessionId) +{ + LOGD("sessionId:%{public}d", sessionId); + SoftbusAgent::GetInstance()->OnFileTransError(sessionId); +} + +void SoftbusDispatcher::OnReceiveFileFinished(int sessionId, const char *files, int fileCnt) +{ + LOGD("sessionId:%{public}d", sessionId); + SoftbusAgent::GetInstance()->OnReceiveFileFinished(sessionId, std::string(files), fileCnt); +} +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS \ No newline at end of file diff --git a/utils/system/include/utils_singleton.h b/utils/system/include/utils_singleton.h index 14c9dd03e268f28af83973d6245d83a06407a09a..ffa1b58b5ea85b36a353e5cd77661c5c8673132a 100644 --- a/utils/system/include/utils_singleton.h +++ b/utils/system/include/utils_singleton.h @@ -25,12 +25,14 @@ namespace OHOS { namespace Storage { namespace DistributedFile { namespace Utils { -#define DECLARE_SINGLETON(MyClass) \ -public: \ - ~MyClass(); \ - \ -private: \ - friend Singleton; \ +#define DECLARE_SINGLETON(MyClass) \ +public: \ + ~MyClass(); \ + MyClass(const MyClass&) = delete; \ + MyClass& operator=(const MyClass&) = delete; \ + \ +private: \ + friend Singleton; \ MyClass(); template