stubs.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include <app-common/zap-generated/attributes/Accessors.h>
  2. #include <app-common/zap-generated/callback.h>
  3. #include <app/data-model/Nullable.h>
  4. #include <app/util/config.h>
  5. #include <lib/core/DataModelTypes.h>
  6. using chip::app::DataModel::Nullable;
  7. using namespace chip;
  8. // Include door lock callbacks only when the server is enabled
  9. #ifdef EMBER_AF_PLUGIN_DOOR_LOCK_SERVER
  10. #include <app/clusters/door-lock-server/door-lock-server.h>
  11. class LockManager
  12. {
  13. public:
  14. static constexpr uint32_t kNumEndpoints = 1;
  15. static constexpr uint32_t kNumUsersPerEndpoint = 2;
  16. static constexpr uint32_t kNumCredentialsPerEndpoint = 20;
  17. static constexpr uint32_t kNumCredentialsPerUser = 10;
  18. static constexpr uint32_t kMaxNameLength = 32;
  19. static constexpr uint32_t kMaxDataLength = 16;
  20. struct Credential
  21. {
  22. bool set(DlCredentialStatus status, CredentialTypeEnum type, chip::ByteSpan newData)
  23. {
  24. if (newData.size() > kMaxDataLength || type != CredentialTypeEnum::kPin)
  25. return false;
  26. memcpy(data, newData.data(), newData.size());
  27. info = EmberAfPluginDoorLockCredentialInfo{
  28. status,
  29. type,
  30. chip::ByteSpan(data, newData.size()),
  31. };
  32. return true;
  33. }
  34. EmberAfPluginDoorLockCredentialInfo info = { DlCredentialStatus::kAvailable };
  35. uint8_t data[kMaxDataLength];
  36. };
  37. struct User
  38. {
  39. void set(chip::CharSpan newName, uint32_t userId, UserStatusEnum userStatus, UserTypeEnum type,
  40. CredentialRuleEnum credentialRule)
  41. {
  42. size_t sz = std::min(sizeof(name), newName.size());
  43. memcpy(name, newName.data(), sz);
  44. info = EmberAfPluginDoorLockUserInfo{
  45. chip::CharSpan(name, sz), chip::Span<const CredentialStruct>(), userId, userStatus, type, credentialRule,
  46. };
  47. }
  48. bool addCredential(CredentialTypeEnum type, uint16_t index)
  49. {
  50. if (info.credentials.size() == kNumCredentialsPerUser)
  51. return false;
  52. auto & cr = credentialMap[info.credentials.size()];
  53. cr.credentialType = type;
  54. cr.credentialIndex = index;
  55. info.credentials = chip::Span<const CredentialStruct>(credentialMap, info.credentials.size() + 1);
  56. return true;
  57. }
  58. EmberAfPluginDoorLockUserInfo info = { .userStatus = UserStatusEnum::kAvailable };
  59. char name[kMaxNameLength];
  60. CredentialStruct credentialMap[kNumCredentialsPerUser];
  61. };
  62. struct Endpoint
  63. {
  64. chip::EndpointId id;
  65. User users[kNumUsersPerEndpoint];
  66. Credential credentials[kNumCredentialsPerEndpoint];
  67. };
  68. static LockManager & Instance()
  69. {
  70. static LockManager instance;
  71. return instance;
  72. }
  73. LockManager() { defaultInitialize(); }
  74. bool getUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
  75. {
  76. auto ep = findEndpoint(endpointId);
  77. if (!ep)
  78. return false;
  79. if (userIndex >= kNumUsersPerEndpoint)
  80. return false;
  81. user = ep->users[userIndex].info;
  82. return true;
  83. }
  84. bool setUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
  85. const chip::CharSpan & userName, uint32_t uniqueId, UserStatusEnum userStatus, UserTypeEnum usertype,
  86. CredentialRuleEnum credentialRule, const CredentialStruct * credentials, size_t totalCredentials)
  87. {
  88. auto ep = findEndpoint(endpointId);
  89. if (!ep)
  90. return false;
  91. if (userIndex >= kNumUsersPerEndpoint || totalCredentials > kNumCredentialsPerUser)
  92. return false;
  93. ep->users[userIndex].set(userName, uniqueId, userStatus, usertype, credentialRule);
  94. ep->users[userIndex].info.creationSource = DlAssetSource::kMatterIM;
  95. ep->users[userIndex].info.createdBy = creator;
  96. ep->users[userIndex].info.modificationSource = DlAssetSource::kMatterIM;
  97. ep->users[userIndex].info.lastModifiedBy = modifier;
  98. for (size_t i = 0; i < totalCredentials; i++)
  99. ep->users[userIndex].addCredential(credentials[i].credentialType, credentials[i].credentialIndex);
  100. return true;
  101. }
  102. bool getCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
  103. EmberAfPluginDoorLockCredentialInfo & credential)
  104. {
  105. auto ep = findEndpoint(endpointId);
  106. if (!ep)
  107. return false;
  108. if (credentialIndex >= kNumCredentialsPerEndpoint)
  109. return false;
  110. if (credentialType != CredentialTypeEnum::kPin)
  111. return false;
  112. credential = ep->credentials[credentialIndex].info;
  113. return true;
  114. }
  115. bool setCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier,
  116. DlCredentialStatus credentialStatus, CredentialTypeEnum credentialType,
  117. const chip::ByteSpan & credentialData)
  118. {
  119. auto ep = findEndpoint(endpointId);
  120. if (!ep)
  121. return false;
  122. if (credentialIndex >= kNumCredentialsPerEndpoint)
  123. return false;
  124. if (credentialType != CredentialTypeEnum::kPin)
  125. return false;
  126. auto & credential = ep->credentials[credentialIndex];
  127. if (!credential.set(credentialStatus, credentialType, credentialData))
  128. return false;
  129. credential.info.creationSource = DlAssetSource::kMatterIM;
  130. credential.info.createdBy = creator;
  131. credential.info.modificationSource = DlAssetSource::kMatterIM;
  132. credential.info.lastModifiedBy = modifier;
  133. return true;
  134. }
  135. bool checkPin(chip::EndpointId endpointId, const chip::Optional<chip::ByteSpan> & pinCode,
  136. chip::app::Clusters::DoorLock::OperationErrorEnum & err)
  137. {
  138. if (!pinCode.HasValue())
  139. {
  140. err = OperationErrorEnum::kInvalidCredential;
  141. return false;
  142. }
  143. auto ep = findEndpoint(endpointId);
  144. if (!ep)
  145. return false;
  146. for (auto & pin : ep->credentials)
  147. {
  148. if (pin.info.status == DlCredentialStatus::kOccupied && pin.info.credentialData.data_equal(pinCode.Value()))
  149. {
  150. return true;
  151. }
  152. }
  153. err = OperationErrorEnum::kInvalidCredential;
  154. return false;
  155. }
  156. private:
  157. Endpoint * findEndpoint(chip::EndpointId endpointId)
  158. {
  159. for (auto & e : endpoints)
  160. {
  161. if (e.id == endpointId)
  162. return &e;
  163. }
  164. return nullptr;
  165. }
  166. void defaultInitialize()
  167. {
  168. endpoints[0].id = 1;
  169. uint8_t pin[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
  170. endpoints[0].credentials[0].set(DlCredentialStatus::kOccupied, CredentialTypeEnum::kPin, chip::ByteSpan(pin));
  171. endpoints[0].users[0].set(chip::CharSpan("default"), 1, UserStatusEnum::kOccupiedEnabled, UserTypeEnum::kUnrestrictedUser,
  172. CredentialRuleEnum::kSingle);
  173. endpoints[0].users[0].addCredential(CredentialTypeEnum::kPin, 1);
  174. }
  175. Endpoint endpoints[kNumEndpoints];
  176. };
  177. bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
  178. const Nullable<chip::NodeId> & nodeId, const chip::Optional<chip::ByteSpan> & pinCode,
  179. chip::app::Clusters::DoorLock::OperationErrorEnum & err)
  180. {
  181. err = OperationErrorEnum::kUnspecified;
  182. return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked);
  183. }
  184. bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Nullable<chip::FabricIndex> & fabricIdx,
  185. const Nullable<chip::NodeId> & nodeId, const chip::Optional<chip::ByteSpan> & pinCode,
  186. chip::app::Clusters::DoorLock::OperationErrorEnum & err)
  187. {
  188. err = OperationErrorEnum::kUnspecified;
  189. return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked);
  190. }
  191. bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user)
  192. {
  193. return LockManager::Instance().getUser(endpointId, userIndex - 1, user);
  194. }
  195. bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator,
  196. chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId,
  197. UserStatusEnum userStatus, UserTypeEnum usertype, CredentialRuleEnum credentialRule,
  198. const CredentialStruct * credentials, size_t totalCredentials)
  199. {
  200. return LockManager::Instance().setUser(endpointId, userIndex - 1, creator, modifier, userName, uniqueId, userStatus, usertype,
  201. credentialRule, credentials, totalCredentials);
  202. }
  203. bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType,
  204. EmberAfPluginDoorLockCredentialInfo & credential)
  205. {
  206. return LockManager::Instance().getCredential(endpointId, credentialIndex - 1, credentialType, credential);
  207. }
  208. bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator,
  209. chip::FabricIndex modifier, DlCredentialStatus credentialStatus,
  210. CredentialTypeEnum credentialType, const chip::ByteSpan & credentialData)
  211. {
  212. return LockManager::Instance().setCredential(endpointId, credentialIndex - 1, creator, modifier, credentialStatus,
  213. credentialType, credentialData);
  214. }
  215. #endif /* EMBER_AF_PLUGIN_DOOR_LOCK_SERVER */
  216. #ifdef EMBER_AF_PLUGIN_CHANNEL_SERVER
  217. #include <chef-channel-manager.h>
  218. void emberAfChannelClusterInitCallback(EndpointId endpoint)
  219. {
  220. app::Clusters::Channel::SetDefaultDelegate(endpoint,
  221. static_cast<app::Clusters::Channel::Delegate *>(&(ChefChannelManager::Instance())));
  222. }
  223. #endif // EMBER_AF_PLUGIN_CHANNEL_SERVER
  224. void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) {}