From abbebecbfad140d113936bb40e3f9fa9bfce9d9b Mon Sep 17 00:00:00 2001 From: Sharad Binjola Date: Mon, 11 Dec 2023 15:08:22 -0800 Subject: [PATCH] ReadAll Endpoint info --- .../tv-casting-common/core/CastingPlayer.cpp | 32 +++- .../tv-casting-common/core/CastingPlayer.h | 7 +- .../tv-casting-common/core/Endpoint.h | 2 +- .../support/CastingStore.cpp | 163 +++++++++++++++++- .../support/ChipDeviceEventHandler.cpp | 5 +- 5 files changed, 193 insertions(+), 16 deletions(-) diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp index e77cb4e3f76295..cad2c8fdd017b9 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp @@ -71,10 +71,11 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectCallback onCompleted, uns ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection Connection to CastingPlayer successful"); CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_CONNECTED; - support::CastingStore::GetInstance()->AddOrUpdate(*CastingPlayer::GetTargetCastingPlayer()); - VerifyOrReturn(CastingPlayer::GetTargetCastingPlayer()->mOnCompleted); - CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(CHIP_NO_ERROR, - CastingPlayer::GetTargetCastingPlayer()); + + // this async call will Load all the endpoints with their respective attributes into the TargetCastingPlayer + // persist the TargetCastingPlayer information into the CastingStore and call mOnCompleted() + support::EndpointListLoader::GetInstance()->Initialize(&exchangeMgr, &sessionHandle); + support::EndpointListLoader::GetInstance()->Load(); }, [](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) { ChipLogError(AppServer, "CastingPlayer::VerifyOrEstablishConnection Connection to CastingPlayer failed"); @@ -122,6 +123,27 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectCallback onCompleted, uns } } +void CastingPlayer::RegisterEndpoint(const memory::Strong endpoint) +{ + if (mEndpoints.size() != 0) + { + auto it = std::find_if(mEndpoints.begin(), mEndpoints.end(), [endpoint](const memory::Strong & _endpoint) { + return _endpoint->GetId() == endpoint->GetId(); + }); + + // If existing endpoint, update mEndpoints. If new endpoint, add it to the vector mEndpoints + if (it != mEndpoints.end()) + { + unsigned index = (unsigned int) std::distance(mEndpoints.begin(), it); + mEndpoints[index] = endpoint; + } + else + { + mEndpoints.push_back(endpoint); + } + } +} + #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT CHIP_ERROR CastingPlayer::SendUserDirectedCommissioningRequest() { @@ -185,7 +207,7 @@ bool CastingPlayer::ContainsDesiredEndpoint(core::CastingPlayer * cachedCastingP match = match && (desiredEndpointFilter->vendorId == 0 || cachedEndpoint->GetVendorId() == desiredEndpointFilter->vendorId); match = match && (desiredEndpointFilter->productId == 0 || cachedEndpoint->GetProductId() == desiredEndpointFilter->productId); - // TODO: check deviceTypeList and clusterList as well + // TODO: check deviceTypeList and clusters/serverList as well if (match) { return true; diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h index dcf0ba1ad4729f..da2ad809baec73 100644 --- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h +++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h @@ -43,7 +43,6 @@ struct EndpointFilter uint16_t vendorId = 0; uint16_t productId = 0; std::vector requiredDeviceTypes; - std::vector requiredClusterIds; }; class CastingPlayerAttributes @@ -153,12 +152,12 @@ class CastingPlayer : public std::enable_shared_from_this void SetFabricIndex(chip::FabricIndex fabricIndex) { mAttributes.fabricIndex = fabricIndex; } - void RegisterEndpoint(const memory::Strong endpoint) { endpoints.push_back(endpoint); } + void RegisterEndpoint(const memory::Strong endpoint); - const std::vector> GetEndpoints() const { return endpoints; } + const std::vector> GetEndpoints() const { return mEndpoints; } private: - std::vector> endpoints; + std::vector> mEndpoints; ConnectionState mConnectionState = CASTING_PLAYER_NOT_CONNECTED; CastingPlayerAttributes mAttributes; static CastingPlayer * mTargetCastingPlayer; diff --git a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h index 54eed0a8a87142..e92905cbafdb60 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Endpoint.h +++ b/examples/tv-casting-app/tv-casting-common/core/Endpoint.h @@ -89,7 +89,7 @@ class Endpoint : public std::enable_shared_from_this std::vector GetServerList() { std::vector serverList; - for(auto const& cluster: mClusters) + for (auto const & cluster : mClusters) { serverList.push_back(cluster.first); } diff --git a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp index db07931d50379a..0a86bcda26593a 100644 --- a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp @@ -125,6 +125,7 @@ std::vector CastingStore::ReadAll() ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format())); core::CastingPlayerAttributes attributes; + std::vector endpointAttributesList; while ((err = reader.Next()) == CHIP_NO_ERROR) { chip::TLV::Tag castingPlayerContainerTag = reader.GetTag(); @@ -196,13 +197,170 @@ std::vector CastingStore::ReadAll() continue; } + if (castingPlayerContainerTagNum == kCastingPlayerEndpointsContainerTag) + { + // Entering Endpoints container + chip::TLV::TLVType endpointsContainerType = chip::TLV::kTLVType_Array; + err = reader.EnterContainer(endpointsContainerType); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + core::EndpointAttributes endpointAttributes; + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + // Entering Endpoint container + chip::TLV::TLVType endpointContainerType = chip::TLV::kTLVType_Structure; + err = reader.EnterContainer(endpointContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + chip::TLV::Tag endpointContainerTag = reader.GetTag(); + VerifyOrReturnValue(chip::TLV::IsContextTag(endpointContainerTag), std::vector(), + ChipLogError(AppServer, "Unexpected non-context TLV tag")); + + uint8_t endpointContainerTagNum = static_cast(chip::TLV::TagNumFromTag(endpointContainerTag)); + if (endpointContainerTagNum == kCastingPlayerEndpointIdTag) + { + err = reader.Get(endpointAttributes.mId); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + + if (endpointContainerTagNum == kCastingPlayerEndpointVendorIdTag) + { + err = reader.Get(endpointAttributes.mVendorId); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + + if (endpointContainerTagNum == kCastingPlayerEndpointProductIdTag) + { + err = reader.Get(endpointAttributes.mProductId); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + + std::vector deviceTypeList; + if (endpointContainerTagNum == kCastingPlayerEndpointDeviceTypeListContainerTag) + { + // Entering DeviceTypeList container + chip::TLV::TLVType deviceTypeListContainerType = chip::TLV::kTLVType_Array; + err = reader.EnterContainer(deviceTypeListContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + // Entering DeviceTypeStruct container + chip::TLV::TLVType deviceTypeStructContainerType = chip::TLV::kTLVType_Structure; + err = reader.EnterContainer(deviceTypeStructContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType deviceTypeStruct; + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + chip::TLV::Tag deviceTypeStructContainerTag = reader.GetTag(); + VerifyOrReturnValue(chip::TLV::IsContextTag(deviceTypeStructContainerTag), + std::vector(), + ChipLogError(AppServer, "Unexpected non-context TLV tag")); + + uint8_t deviceTypeStructContainerTagNum = + static_cast(chip::TLV::TagNumFromTag(deviceTypeStructContainerTag)); + if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeTag) + { + err = reader.Get(deviceTypeStruct.deviceType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + + if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeRevisionTag) + { + err = reader.Get(deviceTypeStruct.revision); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format())); + continue; + } + } + + if (err == CHIP_END_OF_TLV) + { + // Exiting DeviceTypeStruct container + err = reader.ExitContainer(deviceTypeStructContainerType); + VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, + "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, + err.Format())); + + deviceTypeList.push_back(deviceTypeStruct); + break; + } + } + if (err == CHIP_END_OF_TLV) + { + // Exiting DeviceTypeList container + err = reader.ExitContainer(deviceTypeListContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + endpointAttributes.mDeviceTypeList = deviceTypeList; + break; + } + continue; + } + } + + if (err == CHIP_END_OF_TLV) + { + // Exiting Endpoint container + err = reader.ExitContainer(endpointContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + endpointAttributesList.push_back(endpointAttributes); + break; + } + } + + if (err == CHIP_END_OF_TLV) + { + // Exiting Endpoints container + err = reader.ExitContainer(endpointsContainerType); + VerifyOrReturnValue( + err == CHIP_NO_ERROR, std::vector(), + ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + break; + } + + continue; + } + if (err == CHIP_END_OF_TLV) { // Exiting CastingPlayer container err = reader.ExitContainer(castingPlayerContainerType); VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(), ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format())); + + // create a castingPlayer with Endpoints and add it to the castingPlayers to be returned core::CastingPlayer castingPlayer(attributes); + for (core::EndpointAttributes endpointAttributes : endpointAttributesList) + { + std::shared_ptr endpoint(new core::Endpoint(&castingPlayer, endpointAttributes)); + castingPlayer.RegisterEndpoint(endpoint); + } castingPlayers.push_back(castingPlayer); break; } @@ -367,10 +525,9 @@ CHIP_ERROR CastingStore::WriteAll(std::vector castingPlayer ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointServerListContainerTag), chip::TLV::kTLVType_Array, serverListContainerType)); std::vector serverList = endpoint->GetServerList(); - for(chip::ClusterId clusterId : serverList) + for (chip::ClusterId clusterId : serverList) { - ReturnErrorOnFailure( - tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId)); + ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId)); } // ServerList container ends ReturnErrorOnFailure(tlvWriter.EndContainer(serverListContainerType)); diff --git a/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp b/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp index 0cf5a890c2d3e8..eaaf8dc44cc834 100644 --- a/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp @@ -68,10 +68,9 @@ void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * e ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle: Connection to CastingPlayer successful"); CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_CONNECTED; + // this async call will Load all the endpoints with their respective attributes into the TargetCastingPlayer + // persist the TargetCastingPlayer information into the CastingStore and call mOnCompleted() EndpointListLoader::GetInstance()->Initialize(&exchangeMgr, &sessionHandle); - - // this will load all the endpoints with their respective attributes into the TargetCastingPlayer - // and call mOnCompleted() EndpointListLoader::GetInstance()->Load(); }, [](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) {