DoorLockManager.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. using namespace chip;
  33. using namespace chip::app::Clusters;
  34. using namespace chip::app::Clusters::DoorLock;
  35. using namespace chip::DeviceLayer;
  36. static constexpr size_t kDoorLockManagerTableSize =
  37. EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
  38. namespace {
  39. DoorLockManager * gDoorLockManagerTable[kDoorLockManagerTableSize] = { nullptr };
  40. }
  41. void emberAfDoorLockClusterInitCallback(EndpointId endpoint)
  42. {
  43. ChipLogProgress(Zcl, "Device App::DoorLock::PostClusterInit");
  44. DeviceAppJNIMgr().PostClusterInit(chip::app::Clusters::DoorLock::Id, endpoint);
  45. DoorLockServer::Instance().InitServer(endpoint);
  46. EmberAfStatus status = DoorLock::Attributes::FeatureMap::Set(endpoint, 0);
  47. if (status != EMBER_ZCL_STATUS_SUCCESS)
  48. {
  49. ChipLogProgress(Zcl, "Device App::DoorLock::emberAfDoorLockClusterInitCallback()::Updating feature map %x", status);
  50. }
  51. }
  52. bool emberAfPluginDoorLockOnDoorLockCommand(EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
  53. const Nullable<chip::NodeId> & nodeId, const Optional<ByteSpan> & pinCode,
  54. OperationErrorEnum & err)
  55. {
  56. ChipLogProgress(Zcl, "Device App::DoorLock::emberAfPluginDoorLockOnDoorLockCommand");
  57. return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked);
  58. }
  59. bool emberAfPluginDoorLockOnDoorUnlockCommand(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::emberAfPluginDoorLockOnDoorUnlockCommand");
  64. return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked);
  65. }
  66. void DoorLockManager::NewManager(jint endpoint, jobject manager)
  67. {
  68. ChipLogProgress(Zcl, "Device App: DoorLockManager::NewManager");
  69. uint16_t ep = emberAfGetClusterServerEndpointIndex(static_cast<chip::EndpointId>(endpoint), app::Clusters::DoorLock::Id,
  70. EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT);
  71. VerifyOrReturn(ep < kDoorLockManagerTableSize,
  72. ChipLogError(Zcl, "Device App::DoorLock::NewManager: endpoint %d not found", endpoint));
  73. VerifyOrReturn(gDoorLockManagerTable[ep] == nullptr,
  74. ChipLogError(Zcl, "Device App::DoorLock::NewManager: endpoint %d already has a manager", endpoint));
  75. DoorLockManager * mgr = new DoorLockManager();
  76. CHIP_ERROR err = mgr->InitializeWithObjects(manager);
  77. if (err != CHIP_NO_ERROR)
  78. {
  79. ChipLogError(Zcl, "Device App::DoorLock::NewManager: failed to initialize manager for endpoint %d", endpoint);
  80. delete mgr;
  81. }
  82. else
  83. {
  84. gDoorLockManagerTable[ep] = mgr;
  85. }
  86. }
  87. DoorLockManager * GetDoorLockManager(EndpointId endpoint)
  88. {
  89. uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::DoorLock::Id,
  90. EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT);
  91. return ((ep >= kDoorLockManagerTableSize) ? nullptr : gDoorLockManagerTable[ep]);
  92. }
  93. jboolean DoorLockManager::SetLockType(jint endpoint, jint value)
  94. {
  95. EmberAfStatus status = app::Clusters::DoorLock::Attributes::LockType::Set(
  96. static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::DlLockType>(value));
  97. return status == EMBER_ZCL_STATUS_SUCCESS;
  98. }
  99. jboolean DoorLockManager::SetLockState(jint endpoint, jint value)
  100. {
  101. return DoorLockServer::Instance().SetLockState(static_cast<chip::EndpointId>(endpoint),
  102. static_cast<app::Clusters::DoorLock::DlLockState>(value));
  103. }
  104. jboolean DoorLockManager::SetActuatorEnabled(jint endpoint, jboolean value)
  105. {
  106. return DoorLockServer::Instance().SetActuatorEnabled(static_cast<chip::EndpointId>(endpoint), value);
  107. }
  108. jboolean DoorLockManager::SetAutoRelockTime(jint endpoint, jint value)
  109. {
  110. return DoorLockServer::Instance().SetAutoRelockTime(static_cast<chip::EndpointId>(endpoint), static_cast<uint32_t>(value));
  111. }
  112. jboolean DoorLockManager::SetOperatingMode(jint endpoint, jint value)
  113. {
  114. EmberAfStatus status = app::Clusters::DoorLock::Attributes::OperatingMode::Set(
  115. static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::OperatingModeEnum>(value));
  116. return status == EMBER_ZCL_STATUS_SUCCESS;
  117. }
  118. jboolean DoorLockManager::SetSupportedOperatingModes(jint endpoint, jint value)
  119. {
  120. EmberAfStatus status = app::Clusters::DoorLock::Attributes::SupportedOperatingModes::Set(
  121. static_cast<chip::EndpointId>(endpoint), static_cast<app::Clusters::DoorLock::DlSupportedOperatingModes>(value));
  122. return status == EMBER_ZCL_STATUS_SUCCESS;
  123. }
  124. jboolean DoorLockManager::SendLockAlarmEvent(jint endpoint)
  125. {
  126. return DoorLockServer::Instance().SendLockAlarmEvent(static_cast<chip::EndpointId>(endpoint), AlarmCodeEnum::kDoorForcedOpen);
  127. }
  128. void DoorLockManager::PostLockStateChanged(chip::EndpointId endpoint, int value)
  129. {
  130. ChipLogProgress(Zcl, "Device App: DoorLockManager::PostLockStateChanged:%d", value);
  131. DoorLockManager * mgr = GetDoorLockManager(endpoint);
  132. VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "DoorLockManager null"));
  133. mgr->HandleLockStateChanged(static_cast<int>(endpoint), value);
  134. }
  135. CHIP_ERROR DoorLockManager::InitializeWithObjects(jobject managerObject)
  136. {
  137. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  138. VerifyOrReturnLogError(env != nullptr, CHIP_ERROR_INCORRECT_STATE);
  139. mDoorLockManagerObject = env->NewGlobalRef(managerObject);
  140. VerifyOrReturnLogError(mDoorLockManagerObject != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
  141. jclass DoorLockManagerClass = env->GetObjectClass(managerObject);
  142. VerifyOrReturnLogError(DoorLockManagerClass != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
  143. mHandleLockStateChangedMethod = env->GetMethodID(DoorLockManagerClass, "handleLockStateChanged", "(I)V");
  144. if (mHandleLockStateChangedMethod == nullptr)
  145. {
  146. ChipLogError(Zcl, "Failed to access DoorLockManager 'handleLockStateChanged' method");
  147. env->ExceptionClear();
  148. return CHIP_ERROR_INVALID_ARGUMENT;
  149. }
  150. return CHIP_NO_ERROR;
  151. }
  152. void DoorLockManager::HandleLockStateChanged(jint endpoint, jint value)
  153. {
  154. ChipLogProgress(Zcl, "DoorLockManager::HandleLockStateChanged:%d", value);
  155. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  156. VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null"));
  157. VerifyOrReturn(mDoorLockManagerObject != nullptr, ChipLogProgress(Zcl, "mDoorLockManagerObject null"));
  158. VerifyOrReturn(mHandleLockStateChangedMethod != nullptr, ChipLogProgress(Zcl, "mHandleLockStateChangedMethod null"));
  159. env->ExceptionClear();
  160. env->CallVoidMethod(mDoorLockManagerObject, mHandleLockStateChangedMethod, value);
  161. if (env->ExceptionCheck())
  162. {
  163. ChipLogError(AppServer, "Java exception in DoorLockManager::HandleLockStateChanged");
  164. env->ExceptionDescribe();
  165. env->ExceptionClear();
  166. }
  167. }