From 316904491dddf165bf01564e9b272ed91f7b790c Mon Sep 17 00:00:00 2001 From: Dustin Crossman Date: Wed, 8 Dec 2021 17:24:56 -0800 Subject: [PATCH] Working on door-lock implementation. --- examples/lock-app/linux/BUILD.gn | 5 +- examples/lock-app/linux/include/LockManager.h | 19 ++++--- examples/lock-app/linux/main.cpp | 48 ++++++++++++----- examples/lock-app/linux/src/LockManager.cpp | 20 +++++++ .../door-lock-server/door-lock-server.cpp | 52 ++++++++++++++----- .../door-lock-server/door-lock-server.h | 14 ++++- 6 files changed, 120 insertions(+), 38 deletions(-) diff --git a/examples/lock-app/linux/BUILD.gn b/examples/lock-app/linux/BUILD.gn index d50e23fe803a4b..2430f886f8f8ad 100644 --- a/examples/lock-app/linux/BUILD.gn +++ b/examples/lock-app/linux/BUILD.gn @@ -17,7 +17,7 @@ import("//build_overrides/chip.gni") executable("chip-lock-app") { sources = [ - #"include/tv-callbacks.cpp", + "src/LockManager.cpp", "main.cpp", ] @@ -28,7 +28,8 @@ executable("chip-lock-app") { ] include_dirs = - [ "${chip_root}/examples/lock-app/lock-common/include" ] + [ "${chip_root}/examples/lock-app/lock-common/include", + "include" ] cflags = [ "-Wconversion" ] diff --git a/examples/lock-app/linux/include/LockManager.h b/examples/lock-app/linux/include/LockManager.h index a21d3813cecc2a..cb4af10d7fb04e 100644 --- a/examples/lock-app/linux/include/LockManager.h +++ b/examples/lock-app/linux/include/LockManager.h @@ -40,19 +40,24 @@ class LockManager kState_Unlocked, } State; - int Init(); - bool InitiateAction(Action_t aAction); + void Init(); + //bool InitiateAction(Action_t aAction); - using LockCallback_fn = std::function; + bool CheckPin(const char* pin); - void SetCallbacks(LockCallback_fn aActionInitiated_CB, LockCallback_fn aActionCompleted_CB); + //using LockCallback_fn = std::function; + + //void SetCallbacks(LockCallback_fn aActionInitiated_CB, LockCallback_fn aActionCompleted_CB); private: friend LockManager & LockMgr(void); - State_t mState; - LockCallback_fn mActionInitiated_CB; - LockCallback_fn mActionCompleted_CB; + //State_t mState; + + bool mLocked; + + //LockCallback_fn mActionInitiated_CB; + //LockCallback_fn mActionCompleted_CB; static LockManager sLock; }; diff --git a/examples/lock-app/linux/main.cpp b/examples/lock-app/linux/main.cpp index b5a349cf790cbc..af3331cc882013 100644 --- a/examples/lock-app/linux/main.cpp +++ b/examples/lock-app/linux/main.cpp @@ -20,6 +20,8 @@ #include #include +#include "LockManager.h" + #include "AppMain.h" /* Current proposed DoorLockServer API: @@ -29,7 +31,7 @@ class DoorLockServer void InitServer(); - bool SetLockState(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::DlLockState newLockState); + bool SetLockState(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::DlLockState newLockState); bool SetActuatorState(chip::EndpointId endpointId, bool actuatorState); bool SetDoorState(chip::EndpointId endpointId, chip::app::Clusters::DoorLock::DlLockState doorState); @@ -57,24 +59,31 @@ bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, ...); bool emberAfPluginDoorLockClearCredential(chip::EndpointId endpointId, ...); */ -// Many of these should just be implemented in src/app/clusters/door-lock-server/*. +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DoorLock; + bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const char * PINCode) { - // TODO: Set LockState, ActuatorEnabled - // call SetLockState - // call SetActuatorState - return true; + if(LockMgr().CheckPin(PINCode)) + { + return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kLocked); + } + + return false; } bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const char * PINCode) { - // TODO: Set LockState, ActuatorEnabled - // call SetLockState - // call SetActuatorState - return true; -} + if(LockMgr().CheckPin(PINCode)) + { + return DoorLockServer::Instance().SetLockState(endpointId, DlLockState::kUnlocked); + } + return false; +} +/* bool emberAfPluginDoorLockGetUsers(chip::EndpointId endpointId, ...) { // TODO: Get (how to get? send out msg somehow?) @@ -111,23 +120,36 @@ bool emberAfPluginDoorLockClearCredential(chip::EndpointId endpointId, ...) // TODO: return true; } +*/ - +/* TODO: Don't think we need this bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::Command * commandObj) { emberAfSendDefaultResponse(emberAfCurrentCommand(), EMBER_ZCL_STATUS_SUCCESS); return true; } +*/ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) { - // Watch for LockState, DoorState, Mode, etc changes and trigger appropriate action + // TODO: Watch for LockState, DoorState, Mode, etc changes and trigger appropriate action + if (attributePath.mClusterId == DoorLock::Id) + { + emberAfDoorLockClusterPrintln("Door Lock attribute changed"); + } } +void emberAfDoorLockClusterInitCallback(EndpointId endpoint) +{ + // TODO: Implement if needed +} + + int main(int argc, char * argv[]) { VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + LockMgr().Init(); ChipLinuxAppMainLoop(); return 0; } diff --git a/examples/lock-app/linux/src/LockManager.cpp b/examples/lock-app/linux/src/LockManager.cpp index 7dc7b726ef91d7..def493b3e4c8cf 100644 --- a/examples/lock-app/linux/src/LockManager.cpp +++ b/examples/lock-app/linux/src/LockManager.cpp @@ -19,7 +19,27 @@ #include "LockManager.h" #include +#include #include LockManager LockManager::sLock; +void LockManager::Init() +{ + mLocked = false; +} + +bool LockManager::CheckPin(const char* pin) +{ + // TODO: Remove pin hardcode + if(pin != NULL && std::strncmp(pin, "1234", 4) == 0) + { + mLocked = true; + + return true; + } + else + { + return false; + } +} diff --git a/src/app/clusters/door-lock-server/door-lock-server.cpp b/src/app/clusters/door-lock-server/door-lock-server.cpp index b450b58e0920bb..95331cbbe740e3 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.cpp +++ b/src/app/clusters/door-lock-server/door-lock-server.cpp @@ -12,8 +12,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License. - */ + * limitations under the License. */ /**************************************************************************** * @file @@ -70,8 +69,8 @@ bool DoorLockServer::SetLockState(chip::EndpointId endpointId, DlLockState newLo emberAfDoorLockClusterPrintln("Setting Lock State to '%hhu'", lockState); - bool status = Attributes::LockState::Set(endpointId, lockState); - if (!status) + auto status = Attributes::LockState::Set(endpointId, lockState); + if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Unable to set the Lock State to %hhu: internal error", lockState); } @@ -86,7 +85,7 @@ bool DoorLockServer::SetActuatorState(chip::EndpointId endpointId, bool newActua emberAfDoorLockClusterPrintln("Setting Actuator State to '%hhu'", actuatorState); bool status = Attributes::LockState::Set(endpointId, actuatorState); - if (!status) + if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Unable to set the Actuator State to %hhu: internal error", actuatorState); } @@ -101,7 +100,7 @@ bool DoorLockServer::SetDoorState(chip::EndpointId endpointId, DlLockState newDo emberAfDoorLockClusterPrintln("Setting Door State to '%hhu'", doorState); bool status = Attributes::DoorState::Set(endpointId, doorState); - if (!status) + if (status != EMBER_ZCL_STATUS_SUCCESS) { ChipLogError(Zcl, "Unable to set the Door State to %hhu: internal error", doorState); } @@ -140,23 +139,48 @@ bool emberAfDoorLockClusterLockDoorCallback(chip::app::CommandHandler * commandO const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::DoorLock::Commands::LockDoor::DecodableType & commandData) { - emberAfDoorLockClusterPrintln("Received Lock Door command (not implemented)"); + emberAfDoorLockClusterPrintln("Received Lock Door command (implementing currently!)"); + bool success = false; - // TODO: Implement door locking by calling emberAfPluginDoorLockOnDoorLockCommand + // TODO: Get actual endpoint id + chip::EndpointId endpoint = 1; - emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); - return true; + if(commandData.pinCode.HasValue()) + { + success = emberAfPluginDoorLockOnDoorLockCommand(endpoint, + reinterpret_cast(commandData.pinCode.Value().data())); + } + else + { + success = emberAfPluginDoorLockOnDoorLockCommand(endpoint, NULL); + } + + emberAfSendImmediateDefaultResponse(success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); + return success; } bool emberAfDoorLockClusterUnlockDoorCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::DoorLock::Commands::UnlockDoor::DecodableType & commandData) { - emberAfDoorLockClusterPrintln("Received Unlock Door command (not implemented)"); + emberAfDoorLockClusterPrintln("Received Unlock Door command (implementing currently!)"); + bool success = false; - // TODO: Implement door unlocking by calling emberAfPluginDoorLockOnDoorUnlockCommand - emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); - return true; + // TODO: Get actual endpoint id + chip::EndpointId endpoint = 1; + + if(commandData.pinCode.HasValue()) + { + success = emberAfPluginDoorLockOnDoorUnlockCommand(endpoint, + reinterpret_cast(commandData.pinCode.Value().data())); + } + else + { + success = emberAfPluginDoorLockOnDoorUnlockCommand(endpoint, NULL); + } + + emberAfSendImmediateDefaultResponse(success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE); + return success; } bool emberAfDoorLockClusterSetUserCallback(chip::app::CommandHandler * commandObj, diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h index 2810a4aafd2826..fa2672ab03cb54 100644 --- a/src/app/clusters/door-lock-server/door-lock-server.h +++ b/src/app/clusters/door-lock-server/door-lock-server.h @@ -34,7 +34,19 @@ class DoorLockServer { +public: + enum LockState + { + LOCKED, + UNLOCKED, + UNKNOWN + }; + + // Where should this actually live? + char *pin; + static DoorLockServer & Instance(); + static DoorLockServer instance; void InitServer(chip::EndpointId endpointId); @@ -49,8 +61,6 @@ class DoorLockServer bool SetOneTouchLocking(chip::EndpointId endpointId, bool isEnabled); bool SetPrivacyModeButton(chip::EndpointId endpointId, bool isEnabled); -private: - static DoorLockServer instance; }; bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const char * PINCOde);