-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
9,663 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
/** | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* 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 <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/callback.h> | ||
#include <app/util/config.h> | ||
#include <vector> | ||
|
||
// Include Channel Cluster Server callbacks only when the server is enabled | ||
#ifdef EMBER_AF_PLUGIN_CHANNEL_SERVER | ||
#include <chef-channel-manager.h> | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
using namespace chip::app::Clusters::Channel; | ||
using namespace chip::Uint8; | ||
|
||
ChefChannelManager::ChefChannelManager() | ||
{ | ||
ChannelInfoType abc; | ||
abc.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KAAL")); | ||
abc.callSign = MakeOptional(chip::CharSpan::fromCharString("KAAL-TV")); | ||
abc.name = MakeOptional(chip::CharSpan::fromCharString("ABC")); | ||
abc.majorNumber = static_cast<uint8_t>(6); | ||
abc.minorNumber = static_cast<uint16_t>(0); | ||
mChannels.push_back(abc); | ||
|
||
ChannelInfoType pbs; | ||
pbs.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); | ||
pbs.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); | ||
pbs.name = MakeOptional(chip::CharSpan::fromCharString("PBS")); | ||
pbs.majorNumber = static_cast<uint8_t>(9); | ||
pbs.minorNumber = static_cast<uint16_t>(1); | ||
mChannels.push_back(pbs); | ||
|
||
ChannelInfoType pbsKids; | ||
pbsKids.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); | ||
pbsKids.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); | ||
pbsKids.name = MakeOptional(chip::CharSpan::fromCharString("PBS Kids")); | ||
pbsKids.majorNumber = static_cast<uint8_t>(9); | ||
pbsKids.minorNumber = static_cast<uint16_t>(2); | ||
mChannels.push_back(pbsKids); | ||
|
||
ChannelInfoType worldChannel; | ||
worldChannel.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); | ||
worldChannel.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); | ||
worldChannel.name = MakeOptional(chip::CharSpan::fromCharString("World Channel")); | ||
worldChannel.majorNumber = static_cast<uint8_t>(9); | ||
worldChannel.minorNumber = static_cast<uint16_t>(3); | ||
mChannels.push_back(worldChannel); | ||
|
||
mCurrentChannelIndex = 0; | ||
mCurrentChannel = mChannels[mCurrentChannelIndex]; | ||
} | ||
|
||
static bool isChannelMatched(const ChannelInfoType & channel, const CharSpan & match) | ||
{ | ||
char number[32]; | ||
sprintf(number, "%d.%d", channel.majorNumber, channel.minorNumber); | ||
bool nameMatch = channel.name.HasValue() ? channel.name.Value().data_equal(match) : false; | ||
bool affiliateCallSignMatch = | ||
channel.affiliateCallSign.HasValue() ? channel.affiliateCallSign.Value().data_equal(match) : false; | ||
bool callSignMatch = channel.callSign.HasValue() ? channel.callSign.Value().data_equal(match) : false; | ||
bool numberMatch = match.data_equal(chip::CharSpan::fromCharString(number)); | ||
|
||
return affiliateCallSignMatch || callSignMatch || nameMatch || numberMatch; | ||
} | ||
|
||
CHIP_ERROR ChefChannelManager::HandleGetChannelList(app::AttributeValueEncoder & aEncoder) | ||
{ | ||
// TODO: Insert code here | ||
return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { | ||
for (auto const & channel : ChefChannelManager().mChannels) | ||
{ | ||
ReturnErrorOnFailure(encoder.Encode(channel)); | ||
} | ||
return CHIP_NO_ERROR; | ||
}); | ||
} | ||
|
||
CHIP_ERROR ChefChannelManager::HandleGetLineup(app::AttributeValueEncoder & aEncoder) | ||
{ | ||
LineupInfoType lineup; | ||
lineup.operatorName = chip::CharSpan::fromCharString("Comcast"); | ||
lineup.lineupName = MakeOptional(chip::CharSpan::fromCharString("Comcast King County")); | ||
lineup.postalCode = MakeOptional(chip::CharSpan::fromCharString("98052")); | ||
lineup.lineupInfoType = chip::app::Clusters::Channel::LineupInfoTypeEnum::kMso; | ||
|
||
return aEncoder.Encode(lineup); | ||
} | ||
|
||
CHIP_ERROR ChefChannelManager::HandleGetCurrentChannel(app::AttributeValueEncoder & aEncoder) | ||
{ | ||
return aEncoder.Encode(mCurrentChannel); | ||
} | ||
|
||
void ChefChannelManager::HandleChangeChannel(CommandResponseHelper<ChangeChannelResponseType> & helper, | ||
const chip::CharSpan & match) | ||
{ | ||
std::vector<ChannelInfoType> matchedChannels; | ||
uint16_t index = 0; | ||
for (auto const & channel : mChannels) | ||
{ | ||
// verify if CharSpan matches channel name | ||
// or callSign or affiliateCallSign or majorNumber.minorNumber | ||
if (isChannelMatched(channel, match)) | ||
{ | ||
matchedChannels.push_back(channel); | ||
} | ||
else if (matchedChannels.size() == 0) | ||
{ | ||
// "index" is only used when we end up with matchedChannels.size() == 1. | ||
// In that case, we want it to be the number of non-matching channels we saw before | ||
// the matching one. | ||
index++; | ||
} | ||
} | ||
|
||
ChangeChannelResponseType response; | ||
|
||
// Error: Found multiple matches | ||
if (matchedChannels.size() > 1) | ||
{ | ||
response.status = chip::app::Clusters::Channel::ChannelStatusEnum::kMultipleMatches; | ||
helper.Success(response); | ||
} | ||
else if (matchedChannels.size() == 0) | ||
{ | ||
// Error: Found no match | ||
response.status = chip::app::Clusters::Channel::ChannelStatusEnum::kNoMatches; | ||
helper.Success(response); | ||
} | ||
else | ||
{ | ||
response.status = chip::app::Clusters::Channel::ChannelStatusEnum::kSuccess; | ||
response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); | ||
mCurrentChannel = matchedChannels[0]; | ||
mCurrentChannelIndex = index; | ||
helper.Success(response); | ||
} | ||
} | ||
|
||
bool ChefChannelManager::HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) | ||
{ | ||
// TODO: Insert code here | ||
bool channelChanged = false; | ||
uint16_t index = 0; | ||
for (auto const & channel : mChannels) | ||
{ | ||
// verify if major & minor matches one of the channel from the list | ||
if (channel.minorNumber == minorNumber && channel.majorNumber == majorNumber) | ||
{ | ||
// verify if channel changed by comparing values of current channel with the requested channel | ||
if (channel.minorNumber != mCurrentChannel.minorNumber || channel.majorNumber != mCurrentChannel.majorNumber) | ||
{ | ||
channelChanged = true; | ||
mCurrentChannelIndex = index; | ||
mCurrentChannel = channel; | ||
} | ||
} | ||
index++; | ||
} | ||
return channelChanged; | ||
} | ||
|
||
bool ChefChannelManager::HandleSkipChannel(const int16_t & count) | ||
{ | ||
int32_t newChannelIndex = static_cast<int32_t>(count) + static_cast<int32_t>(mCurrentChannelIndex); | ||
uint16_t channelsSize = static_cast<uint16_t>(mChannels.size()); | ||
|
||
// handle newChannelIndex out of range. | ||
newChannelIndex = newChannelIndex % channelsSize; | ||
|
||
if (newChannelIndex < 0) | ||
{ | ||
newChannelIndex = newChannelIndex + channelsSize; | ||
} | ||
|
||
mCurrentChannelIndex = static_cast<uint16_t>(newChannelIndex); | ||
mCurrentChannel = mChannels[mCurrentChannelIndex]; | ||
return true; | ||
} | ||
|
||
uint32_t ChefChannelManager::GetFeatureMap(chip::EndpointId endpoint) | ||
{ | ||
if (endpoint > EMBER_AF_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) | ||
{ | ||
return 0; | ||
} | ||
|
||
uint32_t featureMap = 0; | ||
Attributes::FeatureMap::Get(endpoint, &featureMap); | ||
return featureMap; | ||
} | ||
|
||
#endif /* EMBER_AF_PLUGIN_CHANNEL_SERVER */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* | ||
* Copyright (c) 2021 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <app/clusters/channel-server/channel-server.h> | ||
#include <vector> | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
|
||
using chip::CharSpan; | ||
using chip::app::AttributeValueEncoder; | ||
using chip::app::CommandResponseHelper; | ||
using ChannelDelegate = chip::app::Clusters::Channel::Delegate; | ||
using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; | ||
using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type; | ||
using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; | ||
|
||
class ChefChannelManager : public ChannelDelegate | ||
{ | ||
|
||
public: | ||
ChefChannelManager(); | ||
|
||
CHIP_ERROR HandleGetChannelList(app::AttributeValueEncoder & aEncoder); | ||
CHIP_ERROR HandleGetLineup(app::AttributeValueEncoder & aEncoder); | ||
CHIP_ERROR HandleGetCurrentChannel(app::AttributeValueEncoder & aEncoder); | ||
|
||
void HandleChangeChannel(CommandResponseHelper<ChangeChannelResponseType> & helper, const chip::CharSpan & match); | ||
bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber); | ||
bool HandleSkipChannel(const int16_t & count); | ||
|
||
static ChefChannelManager & Instance() | ||
{ | ||
static ChefChannelManager instance; | ||
return instance; | ||
} | ||
|
||
// bool HasFeature(chip::EndpointId endpoint, Feature feature); | ||
uint32_t GetFeatureMap(chip::EndpointId endpoint); | ||
|
||
~ChefChannelManager() = default; | ||
|
||
protected: | ||
uint16_t mCurrentChannelIndex; | ||
ChannelInfoType mCurrentChannel; | ||
std::vector<ChannelInfoType> mChannels; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.