Skip to content

Commit 8e49f2c

Browse files
committed
Add RPC Event Service draft
1 parent f29ccbe commit 8e49f2c

File tree

13 files changed

+1067
-2
lines changed

13 files changed

+1067
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/*
2+
*
3+
* Copyright (c) 2022 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include "AllClustersCommandDelegate.h"
20+
21+
#include <app-common/zap-generated/attributes/Accessors.h>
22+
#include <app/clusters/general-diagnostics-server/general-diagnostics-server.h>
23+
#include <app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h>
24+
#include <app/clusters/software-diagnostics-server/software-diagnostics-server.h>
25+
#include <app/clusters/switch-server/switch-server.h>
26+
#include <app/server/Server.h>
27+
#include <app/util/att-storage.h>
28+
#include <app/util/attribute-storage.h>
29+
#include <platform/PlatformManager.h>
30+
31+
#include <string>
32+
33+
using namespace chip;
34+
using namespace chip::app;
35+
using namespace chip::app::Clusters;
36+
using namespace chip::DeviceLayer;
37+
38+
ChefRpcCommandHandler * ChefRpcCommandHandler::FromJSON(const char * json)
39+
{
40+
Json::Reader reader;
41+
Json::Value value;
42+
43+
if (!reader.parse(json, value))
44+
{
45+
ChipLogError(NotSpecified,
46+
"AllClusters App: Error parsing JSON with error %s:", reader.getFormattedErrorMessages().c_str());
47+
return nullptr;
48+
}
49+
50+
if (value.empty() || !value.isObject())
51+
{
52+
ChipLogError(NotSpecified, "AllClusters App: Invalid JSON command received");
53+
return nullptr;
54+
}
55+
56+
if (!value.isMember("Name") || !value["Name"].isString())
57+
{
58+
ChipLogError(NotSpecified, "AllClusters App: Invalid JSON command received: command name is missing");
59+
return nullptr;
60+
}
61+
62+
return Platform::New<ChefRpcCommandHandler>(std::move(value));
63+
}
64+
65+
void ChefRpcCommandHandler::HandleCommand(intptr_t context)
66+
{
67+
auto * self = reinterpret_cast<ChefRpcCommandHandler *>(context);
68+
std::string name = self->mJsonValue["Name"].asString();
69+
70+
VerifyOrExit(!self->mJsonValue.empty(), ChipLogError(NotSpecified, "Invalid JSON event command received"));
71+
72+
if (name == "SwitchLatched")
73+
{
74+
uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
75+
self->OnSwitchLatchedHandler(newPosition);
76+
}
77+
else if (name == "InitialPress")
78+
{
79+
uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
80+
self->OnSwitchInitialPressedHandler(newPosition);
81+
}
82+
else if (name == "LongPress")
83+
{
84+
uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
85+
self->OnSwitchLongPressedHandler(newPosition);
86+
}
87+
else if (name == "ShortRelease")
88+
{
89+
uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
90+
self->OnSwitchShortReleasedHandler(previousPosition);
91+
}
92+
else if (name == "LongRelease")
93+
{
94+
uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
95+
self->OnSwitchLongReleasedHandler(previousPosition);
96+
}
97+
else if (name == "MultiPressOngoing")
98+
{
99+
uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
100+
uint8_t count = static_cast<uint8_t>(self->mJsonValue["CurrentNumberOfPressesCounted"].asUInt());
101+
self->OnSwitchMultiPressOngoingHandler(newPosition, count);
102+
}
103+
else if (name == "MultiPressComplete")
104+
{
105+
uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
106+
uint8_t count = static_cast<uint8_t>(self->mJsonValue["TotalNumberOfPressesCounted"].asUInt());
107+
self->OnSwitchMultiPressCompleteHandler(previousPosition, count);
108+
}
109+
else
110+
{
111+
ChipLogError(NotSpecified, "Unhandled command: Should never happens");
112+
}
113+
114+
exit:
115+
Platform::Delete(self);
116+
}
117+
118+
bool ChefRpcCommandHandler::IsClusterPresentOnAnyEndpoint(ClusterId clusterId)
119+
{
120+
EnabledEndpointsWithServerCluster enabledEndpoints(clusterId);
121+
122+
return (enabledEndpoints.begin() != enabledEndpoints.end());
123+
}
124+
125+
void ChefRpcCommandHandler::OnSwitchLatchedHandler(uint8_t newPosition)
126+
{
127+
EndpointId endpoint = 1;
128+
129+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition);
130+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
131+
ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
132+
ChipLogDetail(NotSpecified, "The latching switch is moved to a new position:%d", newPosition);
133+
134+
Clusters::SwitchServer::Instance().OnSwitchLatch(endpoint, newPosition);
135+
}
136+
137+
void ChefRpcCommandHandler::OnSwitchInitialPressedHandler(uint8_t newPosition)
138+
{
139+
EndpointId endpoint = 1;
140+
141+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition);
142+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
143+
ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
144+
ChipLogDetail(NotSpecified, "The new position when the momentary switch starts to be pressed:%d", newPosition);
145+
146+
Clusters::SwitchServer::Instance().OnInitialPress(endpoint, newPosition);
147+
}
148+
149+
void ChefRpcCommandHandler::OnSwitchLongPressedHandler(uint8_t newPosition)
150+
{
151+
EndpointId endpoint = 1;
152+
153+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition);
154+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
155+
ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
156+
ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed for a long time:%d", newPosition);
157+
158+
Clusters::SwitchServer::Instance().OnLongPress(endpoint, newPosition);
159+
160+
// Long press to trigger smokeco self-test
161+
SmokeCoAlarmServer::Instance().RequestSelfTest(endpoint);
162+
}
163+
164+
void ChefRpcCommandHandler::OnSwitchShortReleasedHandler(uint8_t previousPosition)
165+
{
166+
EndpointId endpoint = 1;
167+
168+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0);
169+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
170+
ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
171+
ChipLogDetail(NotSpecified, "The the previous value of the CurrentPosition when the momentary switch has been released:%d",
172+
previousPosition);
173+
174+
Clusters::SwitchServer::Instance().OnShortRelease(endpoint, previousPosition);
175+
}
176+
177+
void ChefRpcCommandHandler::OnSwitchLongReleasedHandler(uint8_t previousPosition)
178+
{
179+
EndpointId endpoint = 1;
180+
181+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0);
182+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
183+
ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
184+
ChipLogDetail(NotSpecified,
185+
"The the previous value of the CurrentPosition when the momentary switch has been released after having been "
186+
"pressed for a long time:%d",
187+
previousPosition);
188+
189+
Clusters::SwitchServer::Instance().OnLongRelease(endpoint, previousPosition);
190+
}
191+
192+
void ChefRpcCommandHandler::OnSwitchMultiPressOngoingHandler(uint8_t newPosition, uint8_t count)
193+
{
194+
EndpointId endpoint = 1;
195+
196+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition);
197+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
198+
ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
199+
ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed in a multi-press sequence:%d",
200+
newPosition);
201+
ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count);
202+
203+
Clusters::SwitchServer::Instance().OnMultiPressOngoing(endpoint, newPosition, count);
204+
}
205+
206+
void ChefRpcCommandHandler::OnSwitchMultiPressCompleteHandler(uint8_t previousPosition, uint8_t count)
207+
{
208+
EndpointId endpoint = 1;
209+
210+
Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0);
211+
VerifyOrReturn(Protocols::InteractionModel::Status::Success == status,
212+
ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
213+
ChipLogDetail(NotSpecified, "The previous position when the momentary switch has been pressed in a multi-press sequence:%d",
214+
previousPosition);
215+
ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count);
216+
217+
Clusters::SwitchServer::Instance().OnMultiPressComplete(endpoint, previousPosition, count);
218+
}
219+
220+
221+
void ChefRpcCommandDelegate::OnEventCommandReceived(const char * json)
222+
{
223+
auto handler = ChefRpcCommandHandler::FromJSON(json);
224+
if (nullptr == handler)
225+
{
226+
ChipLogError(NotSpecified, "AllClusters App: Unable to instantiate a command handler");
227+
return;
228+
}
229+
230+
chip::DeviceLayer::PlatformMgr().ScheduleWork(ChefRpcCommandHandler::HandleCommand, reinterpret_cast<intptr_t>(handler));
231+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
*
3+
* Copyright (c) 2022 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include "NamedPipeCommands.h"
22+
23+
#include <json/json.h>
24+
#include <platform/DiagnosticDataProvider.h>
25+
26+
#include <string>
27+
28+
class ChefRpcCommandHandler
29+
{
30+
public:
31+
static ChefRpcCommandHandler * FromJSON(const char * json);
32+
33+
static void HandleCommand(intptr_t context);
34+
35+
ChefRpcCommandHandler(Json::Value && jasonValue) : mJsonValue(std::move(jasonValue)) {}
36+
37+
private:
38+
Json::Value mJsonValue;
39+
40+
bool IsClusterPresentOnAnyEndpoint(chip::ClusterId clusterId);
41+
42+
/**
43+
* Should be called when the latching switch is moved to a new position.
44+
*/
45+
void OnSwitchLatchedHandler(uint8_t newPosition);
46+
47+
/**
48+
* Should be called when the momentary switch starts to be pressed.
49+
*/
50+
void OnSwitchInitialPressedHandler(uint8_t newPosition);
51+
52+
/**
53+
* Should be called when the momentary switch has been pressed for a "long" time.
54+
*/
55+
void OnSwitchLongPressedHandler(uint8_t newPosition);
56+
57+
/**
58+
* Should be called when the momentary switch has been released.
59+
*/
60+
void OnSwitchShortReleasedHandler(uint8_t previousPosition);
61+
62+
/**
63+
* Should be called when the momentary switch has been released after having been pressed for a long time.
64+
*/
65+
void OnSwitchLongReleasedHandler(uint8_t previousPosition);
66+
67+
/**
68+
* Should be called to indicate how many times the momentary switch has been pressed in a multi-press
69+
* sequence, during that sequence.
70+
*/
71+
void OnSwitchMultiPressOngoingHandler(uint8_t newPosition, uint8_t count);
72+
73+
/**
74+
* Should be called to indicate how many times the momentary switch has been pressed in a multi-press
75+
* sequence, after it has been detected that the sequence has ended.
76+
*/
77+
void OnSwitchMultiPressCompleteHandler(uint8_t previousPosition, uint8_t count);
78+
79+
};
80+
81+
class ChefRpcCommandDelegate
82+
{
83+
public:
84+
void OnEventCommandReceived(const char * json) override;
85+
};

0 commit comments

Comments
 (0)