Skip to content

Commit 2419900

Browse files
Jaehoon-Youpull[bot]
authored andcommitted
virtual-device-app: Add DoorLock/PowerSource Manager for DoorLock (#28784)
Signed-off-by: Jaehoon You <[email protected]> Signed-off-by: Charles Kim <[email protected]>
1 parent f5090b6 commit 2419900

File tree

10 files changed

+563
-1
lines changed

10 files changed

+563
-1
lines changed

examples/virtual-device-app/android/BUILD.gn

+6
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ shared_library("jni") {
3030
"java/ColorControlManager.cpp",
3131
"java/ColorControlManager.h",
3232
"java/DeviceApp-JNI.cpp",
33+
"java/DoorLockManager.cpp",
34+
"java/DoorLockManager.h",
3335
"java/JNIDACProvider.cpp",
3436
"java/JNIDACProvider.h",
3537
"java/OnOffManager.cpp",
3638
"java/OnOffManager.h",
39+
"java/PowerSourceManager.cpp",
40+
"java/PowerSourceManager.h",
3741
]
3842

3943
deps = [
@@ -72,7 +76,9 @@ android_library("java") {
7276
"java/src/com/matter/virtual/device/app/DeviceApp.java",
7377
"java/src/com/matter/virtual/device/app/DeviceAppCallback.java",
7478
"java/src/com/matter/virtual/device/app/DeviceEventType.java",
79+
"java/src/com/matter/virtual/device/app/DoorLockManager.java",
7580
"java/src/com/matter/virtual/device/app/OnOffManager.java",
81+
"java/src/com/matter/virtual/device/app/PowerSourceManager.java",
7682
]
7783

7884
javac_flags = [ "-Xlint:deprecation" ]

examples/virtual-device-app/android/java/ClusterChangeAttribute.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "ColorControlManager.h"
20+
#include "DoorLockManager.h"
2021
#include "OnOffManager.h"
2122
#include <app-common/zap-generated/attributes/Accessors.h>
2223
#include <app-common/zap-generated/ids/Attributes.h>
@@ -89,6 +90,19 @@ static void ColorControlClusterAttributeChangeCallback(const app::ConcreteAttrib
8990
}
9091
}
9192

93+
static void DoorLockClusterAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint16_t size, uint8_t * value)
94+
{
95+
if (attributePath.mAttributeId == DoorLock::Attributes::LockState::Id)
96+
{
97+
uint8_t lockState = *value;
98+
99+
ChipLogProgress(Zcl, "Received lock state command endpoint %d value = %d", static_cast<int>(attributePath.mEndpointId),
100+
lockState);
101+
102+
DoorLockManager().PostLockStateChanged(attributePath.mEndpointId, lockState);
103+
}
104+
}
105+
92106
void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
93107
uint8_t * value)
94108
{
@@ -103,6 +117,9 @@ void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attrib
103117
case ColorControl::Id:
104118
ColorControlClusterAttributeChangeCallback(attributePath, size, value);
105119
break;
120+
case DoorLock::Id:
121+
DoorLockClusterAttributeChangeCallback(attributePath, size, value);
122+
break;
106123

107124
default:
108125
break;

examples/virtual-device-app/android/java/DeviceApp-JNI.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
#include "JNIDACProvider.h"
2222

2323
#include "ColorControlManager.h"
24+
#include "DoorLockManager.h"
2425
#include "OnOffManager.h"
26+
#include "PowerSourceManager.h"
2527
#include "credentials/DeviceAttestationCredsProvider.h"
2628
#include <app/app-platform/ContentAppPlatform.h>
2729
#include <app/server/Dnssd.h>
@@ -166,3 +168,67 @@ JNI_METHOD(void, setColorControlManager)(JNIEnv *, jobject, jint endpoint, jobje
166168
{
167169
ColorControlManager::NewManager(endpoint, manager);
168170
}
171+
172+
/*
173+
* Door Lock Manager
174+
*/
175+
JNI_METHOD(void, setDoorLockManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
176+
{
177+
DoorLockManager::NewManager(endpoint, manager);
178+
}
179+
180+
JNI_METHOD(jboolean, setLockType)(JNIEnv *, jobject, jint endpoint, jint value)
181+
{
182+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetLockType(endpoint, value); }) ==
183+
CHIP_NO_ERROR;
184+
}
185+
186+
JNI_METHOD(jboolean, setLockState)(JNIEnv *, jobject, jint endpoint, jint value)
187+
{
188+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetLockState(endpoint, value); }) ==
189+
CHIP_NO_ERROR;
190+
}
191+
192+
JNI_METHOD(jboolean, setActuatorEnabled)(JNIEnv *, jobject, jint endpoint, jboolean value)
193+
{
194+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetActuatorEnabled(endpoint, value); }) ==
195+
CHIP_NO_ERROR;
196+
}
197+
198+
JNI_METHOD(jboolean, setAutoRelockTime)(JNIEnv *, jobject, jint endpoint, jint value)
199+
{
200+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetAutoRelockTime(endpoint, value); }) ==
201+
CHIP_NO_ERROR;
202+
}
203+
204+
JNI_METHOD(jboolean, setOperatingMode)(JNIEnv *, jobject, jint endpoint, jint value)
205+
{
206+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetOperatingMode(endpoint, value); }) ==
207+
CHIP_NO_ERROR;
208+
}
209+
210+
JNI_METHOD(jboolean, setSupportedOperatingModes)(JNIEnv *, jobject, jint endpoint, jint value)
211+
{
212+
return DeviceLayer::SystemLayer().ScheduleLambda(
213+
[endpoint, value] { DoorLockManager::SetSupportedOperatingModes(endpoint, value); }) == CHIP_NO_ERROR;
214+
}
215+
216+
JNI_METHOD(jboolean, sendLockAlarmEvent)(JNIEnv *, jobject, jint endpoint)
217+
{
218+
return DeviceLayer::SystemLayer().ScheduleLambda([endpoint] { DoorLockManager::SendLockAlarmEvent(endpoint); }) ==
219+
CHIP_NO_ERROR;
220+
}
221+
222+
/*
223+
* Power Source Manager
224+
*/
225+
JNI_METHOD(void, setPowerSourceManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
226+
{
227+
PowerSourceManager::NewManager(endpoint, manager);
228+
}
229+
230+
JNI_METHOD(jboolean, setBatPercentRemaining)(JNIEnv *, jobject, jint endpoint, jint value)
231+
{
232+
return DeviceLayer::SystemLayer().ScheduleLambda(
233+
[endpoint, value] { PowerSourceManager::SetBatPercentRemaining(endpoint, value); }) == CHIP_NO_ERROR;
234+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/**
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#include "DoorLockManager.h"
18+
#include "DeviceApp-JNI.h"
19+
#include <app-common/zap-generated/attributes/Accessors.h>
20+
#include <app-common/zap-generated/ids/Clusters.h>
21+
#include <app/ConcreteAttributePath.h>
22+
#include <app/clusters/door-lock-server/door-lock-server.h>
23+
#include <app/reporting/reporting.h>
24+
#include <app/util/af.h>
25+
#include <jni.h>
26+
#include <lib/support/CHIPJNIError.h>
27+
#include <lib/support/JniReferences.h>
28+
#include <lib/support/JniTypeWrappers.h>
29+
#include <lib/support/ZclString.h>
30+
#include <platform/PlatformManager.h>
31+
#include <vector>
32+
33+
using namespace chip;
34+
using namespace chip::app::Clusters;
35+
using namespace chip::app::Clusters::DoorLock;
36+
using namespace chip::DeviceLayer;
37+
38+
static constexpr size_t kDoorLockManagerTableSize =
39+
EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
40+
41+
namespace {
42+
43+
DoorLockManager * gDoorLockManagerTable[kDoorLockManagerTableSize] = { nullptr };
44+
45+
}
46+
47+
void emberAfDoorLockClusterInitCallback(EndpointId endpoint)
48+
{
49+
ChipLogProgress(Zcl, "Device App::DoorLock::PostClusterInit");
50+
DeviceAppJNIMgr().PostClusterInit(chip::app::Clusters::DoorLock::Id, endpoint);
51+
DoorLockServer::Instance().InitServer(endpoint);
52+
EmberAfStatus status = DoorLock::Attributes::FeatureMap::Set(endpoint, 0);
53+
if (status != EMBER_ZCL_STATUS_SUCCESS)
54+
{
55+
ChipLogProgress(Zcl, "Device App::DoorLock::emberAfDoorLockClusterInitCallback()::Updating feature map %x", status);
56+
}
57+
}
58+
59+
bool emberAfPluginDoorLockOnDoorLockCommand(EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
60+
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
61+
OperationErrorEnum & err)
62+
{
63+
ChipLogProgress(Zcl, "Device App::DoorLock::emberAfPluginDoorLockOnDoorLockCommand");
64+
return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked);
65+
}
66+
67+
bool emberAfPluginDoorLockOnDoorUnlockCommand(EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
68+
const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
69+
OperationErrorEnum & err)
70+
{
71+
ChipLogProgress(Zcl, "Device App::DoorLock::emberAfPluginDoorLockOnDoorUnlockCommand");
72+
return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked);
73+
}
74+
75+
void DoorLockManager::NewManager(jint endpoint, jobject manager)
76+
{
77+
ChipLogProgress(Zcl, "Device App: DoorLockManager::NewManager");
78+
uint16_t ep = emberAfGetClusterServerEndpointIndex(static_cast<chip::EndpointId>(endpoint), app::Clusters::DoorLock::Id,
79+
EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT);
80+
VerifyOrReturn(ep < kDoorLockManagerTableSize,
81+
ChipLogError(Zcl, "Device App::DoorLock::NewManager: endpoint %d not found", endpoint));
82+
83+
VerifyOrReturn(gDoorLockManagerTable[ep] == nullptr,
84+
ChipLogError(Zcl, "Device App::DoorLock::NewManager: endpoint %d already has a manager", endpoint));
85+
DoorLockManager * mgr = new DoorLockManager();
86+
CHIP_ERROR err = mgr->InitializeWithObjects(manager);
87+
if (err != CHIP_NO_ERROR)
88+
{
89+
ChipLogError(Zcl, "Device App::DoorLock::NewManager: failed to initialize manager for endpoint %d", endpoint);
90+
delete mgr;
91+
}
92+
else
93+
{
94+
gDoorLockManagerTable[ep] = mgr;
95+
}
96+
}
97+
98+
DoorLockManager * GetDoorLockManager(EndpointId endpoint)
99+
{
100+
uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::DoorLock::Id,
101+
EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT);
102+
return ((ep >= kDoorLockManagerTableSize) ? nullptr : gDoorLockManagerTable[ep]);
103+
}
104+
105+
jboolean DoorLockManager::SetLockType(jint endpoint, jint value)
106+
{
107+
EmberAfStatus status = app::Clusters::DoorLock::Attributes::LockType::Set(
108+
static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::DlLockType>(value));
109+
return status == EMBER_ZCL_STATUS_SUCCESS;
110+
}
111+
112+
jboolean DoorLockManager::SetLockState(jint endpoint, jint value)
113+
{
114+
return DoorLockServer::Instance().SetLockState(static_cast<chip::EndpointId>(endpoint),
115+
static_cast<app::Clusters::DoorLock::DlLockState>(value));
116+
}
117+
118+
jboolean DoorLockManager::SetActuatorEnabled(jint endpoint, jboolean value)
119+
{
120+
return DoorLockServer::Instance().SetActuatorEnabled(static_cast<chip::EndpointId>(endpoint), value);
121+
}
122+
123+
jboolean DoorLockManager::SetAutoRelockTime(jint endpoint, jint value)
124+
{
125+
return DoorLockServer::Instance().SetAutoRelockTime(static_cast<chip::EndpointId>(endpoint), static_cast<uint32_t>(value));
126+
}
127+
128+
jboolean DoorLockManager::SetOperatingMode(jint endpoint, jint value)
129+
{
130+
EmberAfStatus status = app::Clusters::DoorLock::Attributes::OperatingMode::Set(
131+
static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::OperatingModeEnum>(value));
132+
return status == EMBER_ZCL_STATUS_SUCCESS;
133+
}
134+
135+
jboolean DoorLockManager::SetSupportedOperatingModes(jint endpoint, jint value)
136+
{
137+
EmberAfStatus status = app::Clusters::DoorLock::Attributes::SupportedOperatingModes::Set(
138+
static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::DlSupportedOperatingModes>(value));
139+
return status == EMBER_ZCL_STATUS_SUCCESS;
140+
}
141+
142+
jboolean DoorLockManager::SendLockAlarmEvent(jint endpoint)
143+
{
144+
return DoorLockServer::Instance().SendLockAlarmEvent(static_cast<chip::EndpointId>(endpoint), AlarmCodeEnum::kDoorForcedOpen);
145+
}
146+
147+
void DoorLockManager::PostLockStateChanged(chip::EndpointId endpoint, int value)
148+
{
149+
ChipLogProgress(Zcl, "Device App: DoorLockManager::PostLockStateChanged:%d", value);
150+
DoorLockManager * mgr = GetDoorLockManager(endpoint);
151+
VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "DoorLockManager null"));
152+
153+
mgr->HandleLockStateChanged(static_cast<int>(endpoint), value);
154+
}
155+
156+
CHIP_ERROR DoorLockManager::InitializeWithObjects(jobject managerObject)
157+
{
158+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
159+
VerifyOrReturnLogError(env != nullptr, CHIP_ERROR_INCORRECT_STATE);
160+
161+
mDoorLockManagerObject = env->NewGlobalRef(managerObject);
162+
VerifyOrReturnLogError(mDoorLockManagerObject != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
163+
164+
jclass DoorLockManagerClass = env->GetObjectClass(managerObject);
165+
VerifyOrReturnLogError(DoorLockManagerClass != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
166+
167+
mHandleLockStateChangedMethod = env->GetMethodID(DoorLockManagerClass, "handleLockStateChanged", "(I)V");
168+
if (mHandleLockStateChangedMethod == nullptr)
169+
{
170+
ChipLogError(Zcl, "Failed to access DoorLockManager 'handleLockStateChanged' method");
171+
env->ExceptionClear();
172+
return CHIP_ERROR_INVALID_ARGUMENT;
173+
}
174+
175+
return CHIP_NO_ERROR;
176+
}
177+
178+
void DoorLockManager::HandleLockStateChanged(jint endpoint, jint value)
179+
{
180+
ChipLogProgress(Zcl, "DoorLockManager::HandleLockStateChanged:%d", value);
181+
182+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
183+
VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null"));
184+
VerifyOrReturn(mDoorLockManagerObject != nullptr, ChipLogProgress(Zcl, "mDoorLockManagerObject null"));
185+
VerifyOrReturn(mHandleLockStateChangedMethod != nullptr, ChipLogProgress(Zcl, "mHandleLockStateChangedMethod null"));
186+
187+
env->ExceptionClear();
188+
env->CallVoidMethod(mDoorLockManagerObject, mHandleLockStateChangedMethod, value);
189+
if (env->ExceptionCheck())
190+
{
191+
ChipLogError(AppServer, "Java exception in DoorLockManager::HandleLockStateChanged");
192+
env->ExceptionDescribe();
193+
env->ExceptionClear();
194+
}
195+
}

0 commit comments

Comments
 (0)