diff --git a/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h b/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h index 7370e9630665c09aa1f15945dc6f6157af80bd97..1675fa52a626dbef30681a76856bc80de14eec97 100644 --- a/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h +++ b/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h @@ -17,8 +17,11 @@ #define OHOS_RELATIONSHIP_SYNC_MGR_H #include +#include +#include #include "cJSON.h" #include "dm_single_instance.h" +#include "dm_timer.h" namespace OHOS { namespace DistributedHardware { enum class RelationShipChangeType : uint32_t { @@ -61,6 +64,7 @@ struct RelationShipChangeMsg { std::vector userIdInfos; std::string credId; bool isNewEvent; + uint8_t broadCastId; explicit RelationShipChangeMsg(); bool ToBroadcastPayLoad(uint8_t *&msg, uint32_t &len) const; @@ -86,6 +90,7 @@ struct RelationShipChangeMsg { bool FromDelUserPayLoad(const cJSON *payloadJson); bool FromStopUserPayLoad(const cJSON *payloadJson); bool FromShareUnbindPayLoad(const cJSON *payloadJson); + bool GetBroadCastId(const cJSON *payloadJson, uint32_t userIdNum); std::string ToJson() const; bool FromJson(const std::string &msgJson); @@ -96,8 +101,18 @@ struct RelationShipChangeMsg { class ReleationShipSyncMgr { DM_DECLARE_SINGLE_INSTANCE(ReleationShipSyncMgr); public: - std::string SyncTrustRelationShip(const RelationShipChangeMsg &msg); + std::string SyncTrustRelationShip(RelationShipChangeMsg &msg); RelationShipChangeMsg ParseTrustRelationShipChange(const std::string &msgJson); + bool IsNewBroadCastId(RelationShipChangeMsg &msg); + void SetBroadIsDeal(RelationShipChangeMsg &msg); +private: + void HandleSendBroadCastTimeout(std::string &key); + void HandleRecvBroadCastTimeout(std::string &key); + std::map sendBroadCastIdMap_; + std::map recvBroadCastIdMap_; + std::map newBroadMap_; + std::shared_ptr timer_; + std::mutex lock_; }; const std::string GetUserIdInfoList(const std::vector &list); diff --git a/services/service/src/device_manager_service.cpp b/services/service/src/device_manager_service.cpp index a1785e60012d6d97e71548c7ef72354f3a77b64d..f24fd1a84b490c9ade3a782582842eca0387e749 100644 --- a/services/service/src/device_manager_service.cpp +++ b/services/service/src/device_manager_service.cpp @@ -2909,6 +2909,11 @@ void DeviceManagerService::HandleDeviceTrustedChange(const std::string &msg) } RelationShipChangeMsg relationShipMsg = ReleationShipSyncMgr::GetInstance().ParseTrustRelationShipChange(msg); LOGI("Receive trust change msg: %{public}s", relationShipMsg.ToString().c_str()); + if (!ReleationShipSyncMgr::GetInstance().IsNewBroadCastId(relationShipMsg)) { + LOGI("is not new broadcast"); + return; + } + ReleationShipSyncMgr::GetInstance().SetBroadIsDeal(relationShipMsg); bool ret = ParseRelationShipChangeType(relationShipMsg); if (!ret) { LOGI("ParseRelationShipChangeType failed"); diff --git a/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp b/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp index 723e43fc3583b0143ede6eabf3d48166b750d62b..1f697c4f08d1d245a24660cc921810ca393d8f32 100644 --- a/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp +++ b/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp @@ -16,36 +16,37 @@ #include "relationship_sync_mgr.h" #include "dm_anonymous.h" #include "dm_log.h" +#include "dm_random.h" namespace OHOS { namespace DistributedHardware { DM_IMPLEMENT_SINGLE_INSTANCE(ReleationShipSyncMgr); namespace { /** - * @brief account logout payload length 8 bytes - * | 2 bytes | 6 bytes | - * | userid lower 2 bytes | account id first 6 bytes | + * @brief account logout payload length 9 bytes + * | 2 bytes | 6 bytes | 1 bytes | + * | userid lower 2 bytes | account id first 6 bytes | broadcastId | */ - const int32_t ACCOUNT_LOGOUT_PAYLOAD_LEN = 8; + const int32_t ACCOUNT_LOGOUT_PAYLOAD_LEN = 9; /** * @brief device unbind payload length 2 bytes - * | 2 bytes | - * | userid lower 2 bytes | + * | 2 bytes | 1 bytes | + * | userid lower 2 bytes | broadcastId | */ - const int32_t DEVICE_UNBIND_PAYLOAD_LEN = 2; + const int32_t DEVICE_UNBIND_PAYLOAD_LEN = 3; /** * @brief app unbind payload length 6 bytes - * | 2 bytes | 4 bytes | - * | userid lower 2 bytes | token id lower 4 bytes | + * | 2 bytes | 4 bytes | 1 bytes | + * | userid lower 2 bytes | token id lower 4 bytes | broadcastId | */ - const int32_t APP_UNBIND_PAYLOAD_LEN = 10; + const int32_t APP_UNBIND_PAYLOAD_LEN = 11; /** * @brief delete user payload length 2 bytes - * | 2 bytes | - * | userid lower 2 bytes | + * | 2 bytes | 1 bytes | + * | userid lower 2 bytes | broadcastId | */ - const int32_t DEL_USER_PAYLOAD_LEN = 2; - const int32_t STOP_USER_PAYLOAD_LEN = 2; + const int32_t DEL_USER_PAYLOAD_LEN = 3; + const int32_t STOP_USER_PAYLOAD_LEN = 3; const int32_t SHARE_UNBIND_PAYLOAD_LEN = 8; /** * @brief the userid payload cost 2 bytes. @@ -60,6 +61,11 @@ namespace { const int32_t BITS_PER_BYTE = 8; const int32_t INVALIED_PAYLOAD_SIZE = 12; const int32_t CREDID_PAYLOAD_LEN = 8; + const int32_t ACCOUNT_LOGOUT_BROADCAST_LEN = 8; + const int32_t BROADCAST_PAYLOAD_LEN = 10; + const int32_t DM_BROADCAST_MIN_RANDOM = 1; + const int32_t DM_BROADCAST_MAX_RAMDOM = 254; + const int32_t BROADCAST_TIMEOUT_S = 5; const char * const MSG_TYPE = "TYPE"; const char * const MSG_VALUE = "VALUE"; @@ -89,7 +95,7 @@ namespace { const uint16_t FOREGROUND_USERID_LEN_MASK = 0b00000111; const uint16_t ALL_USERID_NUM_MASK = 0b00111000; const uint32_t MAX_MEM_MALLOC_SIZE = 4 * 1024; - const uint32_t MAX_USER_ID_NUM = 5; + const uint32_t MAX_USER_ID_NUM = 4; } RelationShipChangeMsg::RelationShipChangeMsg() : type(RelationShipChangeType::TYPE_MAX), @@ -303,9 +309,13 @@ void RelationShipChangeMsg::ToAccountLogoutPayLoad(uint8_t *&msg, uint32_t &len) msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF; } - for (int j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) { + for (int j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_BROADCAST_LEN; j++) { msg[j] = accountId[j - USERID_PAYLOAD_LEN]; } + + for (int j = ACCOUNT_LOGOUT_BROADCAST_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) { + msg[j] |= (broadCastId >> ((j - ACCOUNT_LOGOUT_BROADCAST_LEN) * BITS_PER_BYTE)) & 0xFF; + } len = ACCOUNT_LOGOUT_PAYLOAD_LEN; } @@ -315,6 +325,9 @@ void RelationShipChangeMsg::ToDeviceUnbindPayLoad(uint8_t *&msg, uint32_t &len) for (int i = 0; i < USERID_PAYLOAD_LEN; i++) { msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF; } + for (int i = USERID_PAYLOAD_LEN; i < DEVICE_UNBIND_PAYLOAD_LEN; i++) { + msg[i] |= (broadCastId >> ((i - USERID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; + } len = DEVICE_UNBIND_PAYLOAD_LEN; } @@ -329,10 +342,14 @@ void RelationShipChangeMsg::ToAppUnbindPayLoad(uint8_t *&msg, uint32_t &len) con msg[i] |= (tokenId >> ((i - USERID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; } - for (int i = TOKENID_PAYLOAD_LEN; i < APP_UNBIND_PAYLOAD_LEN; i++) { + for (int i = TOKENID_PAYLOAD_LEN; i < BROADCAST_PAYLOAD_LEN; i++) { msg[i] |= (peerTokenId >> ((i - TOKENID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; } + for (int i = BROADCAST_PAYLOAD_LEN; i < APP_UNBIND_PAYLOAD_LEN; i++) { + msg[i] |= (broadCastId >> ((i - BROADCAST_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; + } + len = APP_UNBIND_PAYLOAD_LEN; } @@ -349,9 +366,9 @@ bool RelationShipChangeMsg::ToSyncFrontOrBackUserIdPayLoad(uint8_t *&msg, uint32 return false; } - len = userIdNum * USERID_BYTES + 1; + len = (userIdNum + 1) * USERID_BYTES; - if (len > MAX_MEM_MALLOC_SIZE) { + if (len > INVALIED_PAYLOAD_SIZE) { LOGE("len too long"); return false; } @@ -376,6 +393,7 @@ bool RelationShipChangeMsg::ToSyncFrontOrBackUserIdPayLoad(uint8_t *&msg, uint32 idx += USERID_BYTES; userIdIdx++; } + msg[userIdNum * USERID_BYTES + 1] |= broadCastId & 0xFF; return true; } @@ -383,18 +401,24 @@ void RelationShipChangeMsg::ToDelUserPayLoad(uint8_t *&msg, uint32_t &len) const { len = DEL_USER_PAYLOAD_LEN; msg = new uint8_t[DEL_USER_PAYLOAD_LEN](); - for (int i = 0; i < DEL_USER_PAYLOAD_LEN; i++) { + for (int i = 0; i < USERID_PAYLOAD_LEN; i++) { msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF; } + for (int i = USERID_PAYLOAD_LEN; i < DEL_USER_PAYLOAD_LEN; i++) { + msg[i] |= (broadCastId >> ((i - USERID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; + } } void RelationShipChangeMsg::ToStopUserPayLoad(uint8_t *&msg, uint32_t &len) const { len = STOP_USER_PAYLOAD_LEN; msg = new uint8_t[STOP_USER_PAYLOAD_LEN](); - for (int i = 0; i < STOP_USER_PAYLOAD_LEN; i++) { + for (int i = 0; i < USERID_PAYLOAD_LEN; i++) { msg[i] |= (userId >> (i * BITS_PER_BYTE)) & 0xFF; } + for (int i = USERID_PAYLOAD_LEN; i < STOP_USER_PAYLOAD_LEN; i++) { + msg[i] |= (broadCastId >> ((i - USERID_PAYLOAD_LEN) * BITS_PER_BYTE)) & 0xFF; + } } bool RelationShipChangeMsg::FromAccountLogoutPayLoad(const cJSON *payloadJson) @@ -417,13 +441,22 @@ bool RelationShipChangeMsg::FromAccountLogoutPayLoad(const cJSON *payloadJson) } } accountId = ""; - for (uint32_t j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) { + for (uint32_t j = USERID_PAYLOAD_LEN; j < ACCOUNT_LOGOUT_BROADCAST_LEN; j++) { cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); CHECK_NULL_RETURN(payloadItem, false); if (cJSON_IsNumber(payloadItem)) { accountId += static_cast(payloadItem->valueint); } } + broadCastId = 0; + for (uint32_t j = ACCOUNT_LOGOUT_BROADCAST_LEN; j < ACCOUNT_LOGOUT_PAYLOAD_LEN; j++) { + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + broadCastId |= (static_cast(payloadItem->valueint)) << + ((j - ACCOUNT_LOGOUT_BROADCAST_LEN) * BITS_PER_BYTE); + } + } return true; } @@ -434,7 +467,7 @@ bool RelationShipChangeMsg::FromDeviceUnbindPayLoad(const cJSON *payloadJson) return false; } int32_t arraySize = cJSON_GetArraySize(payloadJson); - if (arraySize < ACCOUNT_LOGOUT_PAYLOAD_LEN || arraySize >= INVALIED_PAYLOAD_SIZE) { + if (arraySize < DEVICE_UNBIND_PAYLOAD_LEN || arraySize >= INVALIED_PAYLOAD_SIZE) { LOGE("Payload invalied,the size is %{public}d.", arraySize); return false; } @@ -446,6 +479,15 @@ bool RelationShipChangeMsg::FromDeviceUnbindPayLoad(const cJSON *payloadJson) userId |= (static_cast(payloadItem->valueint)) << (i * BITS_PER_BYTE); } } + broadCastId = 0; + for (uint32_t j = USERID_PAYLOAD_LEN; j < DEVICE_UNBIND_PAYLOAD_LEN; j++) { + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + broadCastId |= (static_cast(payloadItem->valueint)) << + ((j - USERID_PAYLOAD_LEN) * BITS_PER_BYTE); + } + } return true; } @@ -477,7 +519,7 @@ bool RelationShipChangeMsg::FromAppUnbindPayLoad(const cJSON *payloadJson) } } peerTokenId = 0; - for (uint32_t j = TOKENID_PAYLOAD_LEN; j < APP_UNBIND_PAYLOAD_LEN; j++) { + for (uint32_t j = TOKENID_PAYLOAD_LEN; j < BROADCAST_PAYLOAD_LEN; j++) { cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); CHECK_NULL_RETURN(payloadItem, false); if (cJSON_IsNumber(payloadItem)) { @@ -485,6 +527,15 @@ bool RelationShipChangeMsg::FromAppUnbindPayLoad(const cJSON *payloadJson) ((j - TOKENID_PAYLOAD_LEN) * BITS_PER_BYTE); } } + broadCastId = 0; + for (uint32_t j = BROADCAST_PAYLOAD_LEN; j < APP_UNBIND_PAYLOAD_LEN; j++) { + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + broadCastId |= (static_cast(payloadItem->valueint)) << + ((j - BROADCAST_PAYLOAD_LEN) * BITS_PER_BYTE); + } + } return true; } @@ -493,6 +544,17 @@ bool RelationShipChangeMsg::FromServiceUnbindPayLoad(const cJSON *payloadJson) return FromAppUnbindPayLoad(payloadJson); } +bool RelationShipChangeMsg::GetBroadCastId(const cJSON *payloadJson, uint32_t userIdNum) +{ + broadCastId = 0; + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, userIdNum * USERID_BYTES + 1); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + broadCastId |= static_cast(payloadItem->valueint); + } + return true; +} + bool RelationShipChangeMsg::FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloadJson) { if (payloadJson == NULL) { @@ -517,7 +579,7 @@ bool RelationShipChangeMsg::FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloa userIdNum = ((static_cast(payloadItem->valueint)) & FOREGROUND_USERID_LEN_MASK); } - int32_t effectiveLen = static_cast(userIdNum * USERID_BYTES + 1); + int32_t effectiveLen = static_cast((userIdNum + 1) * USERID_BYTES); if (effectiveLen > arraySize) { LOGE("payload userIdNum invalid, userIdNum: %{public}u, arraySize: %{public}d", userIdNum, arraySize); return false; @@ -546,7 +608,7 @@ bool RelationShipChangeMsg::FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloa isForegroundUser = false; } } - return true; + return GetBroadCastId(payloadJson, userIdNum); } bool RelationShipChangeMsg::FromDelUserPayLoad(const cJSON *payloadJson) @@ -569,6 +631,15 @@ bool RelationShipChangeMsg::FromDelUserPayLoad(const cJSON *payloadJson) this->userId |= (static_cast(payloadItem->valueint)) << (i * BITS_PER_BYTE); } } + this->broadCastId = 0; + for (uint32_t j = USERID_PAYLOAD_LEN; j < DEL_USER_PAYLOAD_LEN; j++) { + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + this->broadCastId |= (static_cast(payloadItem->valueint)) << + ((j - USERID_PAYLOAD_LEN) * BITS_PER_BYTE); + } + } return true; } @@ -592,6 +663,15 @@ bool RelationShipChangeMsg::FromStopUserPayLoad(const cJSON *payloadJson) this->userId |= (static_cast(payloadItem->valueint)) << (i * BITS_PER_BYTE); } } + this->broadCastId = 0; + for (uint32_t j = USERID_PAYLOAD_LEN; j < STOP_USER_PAYLOAD_LEN; j++) { + cJSON *payloadItem = cJSON_GetArrayItem(payloadJson, j); + CHECK_NULL_RETURN(payloadItem, true); + if (cJSON_IsNumber(payloadItem)) { + this->broadCastId |= (static_cast(payloadItem->valueint)) << + ((j - USERID_PAYLOAD_LEN) * BITS_PER_BYTE); + } + } return true; } @@ -723,8 +803,52 @@ bool RelationShipChangeMsg::FromJson(const std::string &msgJson) return true; } -std::string ReleationShipSyncMgr::SyncTrustRelationShip(const RelationShipChangeMsg &msg) +void ReleationShipSyncMgr::HandleSendBroadCastTimeout(std::string &key) +{ + std::lock_guard autoLock(lock_); + auto iter = sendBroadCastIdMap_.find(key); + if (iter != sendBroadCastIdMap_.end()) { + sendBroadCastIdMap_.erase(iter); + } +} + +void ReleationShipSyncMgr::HandleRecvBroadCastTimeout(std::string &key) +{ + std::lock_guard autoLock(lock_); + auto iter = recvBroadCastIdMap_.find(key); + if (iter != recvBroadCastIdMap_.end()) { + recvBroadCastIdMap_.erase(iter); + } + + auto item = newBroadMap_.find(key); + if (item != newBroadMap_.end()) { + newBroadMap_.erase(item); + } +} + +std::string ReleationShipSyncMgr::SyncTrustRelationShip(RelationShipChangeMsg &msg) { + msg.broadCastId = GenRandInt(DM_BROADCAST_MIN_RANDOM, DM_BROADCAST_MAX_RAMDOM); + if (timer_ == nullptr) { + timer_ = std::make_shared(); + } + std::lock_guard autoLock(lock_); + for (auto peerUdid : msg.peerUdids) { + std::string key = GetAnonyString(peerUdid) + "_" + std::to_string(static_cast(msg.type)); + auto iter = sendBroadCastIdMap_.find(key); + if (iter == sendBroadCastIdMap_.end()) { + sendBroadCastIdMap_[key] = msg.broadCastId; + timer_->StartTimer(key, BROADCAST_TIMEOUT_S, [this](std::string key) { + ReleationShipSyncMgr::HandleSendBroadCastTimeout(key); + }); + } else { + timer_->DeleteTimer(key); + sendBroadCastIdMap_[key] = msg.broadCastId; + timer_->StartTimer(key, BROADCAST_TIMEOUT_S, [this](std::string key) { + ReleationShipSyncMgr::HandleSendBroadCastTimeout(key); + }); + } + } return msg.ToJson(); } @@ -734,9 +858,45 @@ RelationShipChangeMsg ReleationShipSyncMgr::ParseTrustRelationShipChange(const s if (!msgObj.FromJson(msgJson)) { LOGE("Parse json failed"); } + if (timer_ == nullptr) { + timer_ = std::make_shared(); + } + std::string key = GetAnonyString(msgObj.peerUdid) + "_" + std::to_string(static_cast(msgObj.type)); + std::lock_guard autoLock(lock_); + auto iter = recvBroadCastIdMap_.find(key); + if (iter == recvBroadCastIdMap_.end()) { + recvBroadCastIdMap_[key] = msgObj.broadCastId; + newBroadMap_[key] = true; + timer_->StartTimer(key, BROADCAST_TIMEOUT_S, [this](std::string key) { + newBroadMap_[key] = false; + ReleationShipSyncMgr::HandleRecvBroadCastTimeout(key); + }); + } return msgObj; } +bool ReleationShipSyncMgr::IsNewBroadCastId(RelationShipChangeMsg &msg) +{ + std::lock_guard autoLock(lock_); + std::string key = GetAnonyString(msg.peerUdid) + "_" + std::to_string(static_cast(msg.type)); + auto iter = newBroadMap_.find(key); + if (iter == newBroadMap_.end()) { + return false; + } + return newBroadMap_[key]; +} + +void ReleationShipSyncMgr::SetBroadIsDeal(RelationShipChangeMsg &msg) +{ + std::lock_guard autoLock(lock_); + std::string key = GetAnonyString(msg.peerUdid) + "_" + std::to_string(static_cast(msg.type)); + auto iter = newBroadMap_.find(key); + if (iter == newBroadMap_.end()) { + return; + } + newBroadMap_[key] = false; +} + const std::string RelationShipChangeMsg::ToString() const { std::string ret; @@ -750,7 +910,8 @@ const std::string RelationShipChangeMsg::ToString() const ret += ", peerUdid: " + GetAnonyString(peerUdid); ret += ", accountName: " + GetAnonyString(accountName); ret += ", syncUserIdFlag: " + std::to_string(syncUserIdFlag); - ret += ", userIds: " + GetUserIdInfoList(userIdInfos) + " }"; + ret += ", userIds: " + GetUserIdInfoList(userIdInfos); + ret += ", broadCastId: " + std::to_string(broadCastId) + " }"; return ret; } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 7c4fc11e88271855d5ca46b4c9709c867c881b79..f0af8d78f5bd582c7e922368ee98b3acc709e454 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -1780,6 +1780,7 @@ ohos_unittest("UTTest_relationship_sync_mgr") { external_deps = [ "cJSON:cjson", + "ffrt:libffrt", "hilog:libhilog", ] }