OnOffManager.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 "OnOffManager.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/util/af.h>
  22. #include <app/util/config.h>
  23. #include <jni.h>
  24. #include <lib/support/CHIPJNIError.h>
  25. #include <lib/support/JniReferences.h>
  26. #include <lib/support/JniTypeWrappers.h>
  27. using namespace chip;
  28. static constexpr size_t kOnffManagerTableSize = EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT;
  29. namespace {
  30. OnOffManager * gOnOffManagerTable[kOnffManagerTableSize] = { nullptr };
  31. static_assert(kOnffManagerTableSize <= kEmberInvalidEndpointIndex, "gOnOffManagerTable table size error");
  32. } // namespace
  33. void emberAfOnOffClusterInitCallback(EndpointId endpoint)
  34. {
  35. ChipLogProgress(Zcl, "Device App::OnOff::PostClusterInit");
  36. DeviceAppJNIMgr().PostClusterInit(chip::app::Clusters::OnOff::Id, endpoint);
  37. }
  38. void OnOffManager::NewManager(jint endpoint, jobject manager)
  39. {
  40. ChipLogProgress(Zcl, "Device App: OnOffManager::NewManager");
  41. uint16_t ep = emberAfGetClusterServerEndpointIndex(static_cast<chip::EndpointId>(endpoint), app::Clusters::OnOff::Id,
  42. EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT);
  43. VerifyOrReturn(ep < kOnffManagerTableSize, ChipLogError(Zcl, "Device App::OnOff::NewManager: endpoint %d not found", endpoint));
  44. VerifyOrReturn(gOnOffManagerTable[ep] == nullptr,
  45. ChipLogError(Zcl, "Device App::OnOff::NewManager: endpoint %d already has a manager", endpoint));
  46. OnOffManager * mgr = new OnOffManager();
  47. CHIP_ERROR err = mgr->InitializeWithObjects(manager);
  48. if (err != CHIP_NO_ERROR)
  49. {
  50. ChipLogError(Zcl, "Device App::OnOff::NewManager: failed to initialize manager for endpoint %d", endpoint);
  51. delete mgr;
  52. }
  53. else
  54. {
  55. gOnOffManagerTable[ep] = mgr;
  56. }
  57. }
  58. OnOffManager * GetOnOffManager(EndpointId endpoint)
  59. {
  60. uint16_t ep =
  61. emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OnOff::Id, EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT);
  62. return (ep >= kOnffManagerTableSize ? nullptr : gOnOffManagerTable[ep]);
  63. }
  64. void OnOffManager::PostOnOffChanged(chip::EndpointId endpoint, bool value)
  65. {
  66. ChipLogProgress(Zcl, "Device App: OnOffManager::PostOnOffChange");
  67. OnOffManager * mgr = GetOnOffManager(endpoint);
  68. VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "OnOffManager null"));
  69. mgr->HandleOnOffChanged(value);
  70. }
  71. jboolean OnOffManager::SetOnOff(jint endpoint, bool value)
  72. {
  73. EmberAfStatus status = app::Clusters::OnOff::Attributes::OnOff::Set(static_cast<chip::EndpointId>(endpoint), value);
  74. return status == EMBER_ZCL_STATUS_SUCCESS;
  75. }
  76. CHIP_ERROR OnOffManager::InitializeWithObjects(jobject managerObject)
  77. {
  78. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  79. VerifyOrReturnLogError(env != nullptr, CHIP_ERROR_INCORRECT_STATE);
  80. mOnOffManagerObject = env->NewGlobalRef(managerObject);
  81. VerifyOrReturnLogError(mOnOffManagerObject != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
  82. jclass OnOffManagerClass = env->GetObjectClass(managerObject);
  83. VerifyOrReturnLogError(OnOffManagerClass != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
  84. mHandleOnOffChangedMethod = env->GetMethodID(OnOffManagerClass, "handleOnOffChanged", "(Z)V");
  85. if (mHandleOnOffChangedMethod == nullptr)
  86. {
  87. ChipLogError(Zcl, "Failed to access OnOffManager 'handleOnOffChanged' method");
  88. env->ExceptionClear();
  89. return CHIP_ERROR_INVALID_ARGUMENT;
  90. }
  91. return CHIP_NO_ERROR;
  92. }
  93. void OnOffManager::HandleOnOffChanged(bool value)
  94. {
  95. ChipLogProgress(Zcl, "OnOffManager::HandleOnOffChanged");
  96. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  97. VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null"));
  98. VerifyOrReturn(mOnOffManagerObject != nullptr, ChipLogProgress(Zcl, "mOnOffManagerObject null"));
  99. VerifyOrReturn(mHandleOnOffChangedMethod != nullptr, ChipLogProgress(Zcl, "mHandleOnOffChangedMethod null"));
  100. env->ExceptionClear();
  101. env->CallVoidMethod(mOnOffManagerObject, mHandleOnOffChangedMethod, static_cast<jboolean>(value));
  102. if (env->ExceptionCheck())
  103. {
  104. ChipLogError(AppServer, "Java exception in OnOffManager::HandleOnOffChanged");
  105. env->ExceptionDescribe();
  106. env->ExceptionClear();
  107. }
  108. }