# The 2 cpps in the lock-app example ###### tags: `CHIP` `Matter` `Firmware` >2022/03/12 >CHIP git hash code 67b4746ad8 In this note, I will give you a brief idea about the cpp files(mostly main.cpp and ZclCallback.cpp) in lock-app example. Because we should focus on Matter stack, so I will skip most of the Silicon Lab SDK code. ## First step, open the main.cpp ### Initialize XXX First, initialize CHIP stack. ```cpp=126 // Init Chip memory management before the stack chip::Platform::MemoryInit(); /* Init persistent storage */ chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); /* Init the CHIP stack */ CHIP_ERROR ret = PlatformMgr().InitChipStack(); ``` These 3 line of code are quite easy, they just initialize CHIP stack. And the OpenThread stack initialization(assume you are using it) ```cpp=137 EFR32_LOG("Initializing OpenThread stack"); ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { EFR32_LOG("ThreadStackMgr().InitThreadStack() failed"); appError(ret); } ``` ### Start XXX ```cpp=153 // Start Chip stack EFR32_LOG("Starting Platform Manager Event Loop"); ret = PlatformMgr().StartEventLoopTask(); if (ret != CHIP_NO_ERROR) { EFR32_LOG("PlatformMgr().StartEventLoopTask() failed"); appError(ret); } ``` ```cpp=165 // Start OpenThread task ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { EFR32_LOG("ThreadStackMgr().StartThreadTask() failed"); appError(ret); } ``` ```cpp=174 // Start the app itself ret = GetAppTask().StartAppTask(); if (ret != CHIP_NO_ERROR) { EFR32_LOG("GetAppTask().Init() failed"); appError(ret); } ``` :::info Well, I kind of skip 2 lines of code chip::rpc::Init(); chip::startShellTask(); As I memtioned before, this project is still under development, and they certainly added new features to this example. I don't really know the detial of these 2 functions at this very moment. ::: ## Look closer As you can see, we have totally 3 threads running on the device now. We could do 2 things: * Push button, which will send an event to the app thread and change some status. * Send a command from the CHIP controller, which is much fun to check. Let's say we send out a zcl command to turn on the lock by the python controller. `zcl OnOff On 1234 1 0` And CHIP thread running on the device magically get that command. How exactly does CHIP thread pass this command(or event) to the application thread? So, it's time to check other cpps in the example. That is, the ZclCallbacks.cpp. ### What is ZCL?? It is Zigbee Cluster Library. From network stack perspective, it's a application layer framework. It defines functionality of IoT device, so functionality = cluster. And each cluster has its own attributes/commands. For example, there is a cluster called "OnOff" and it has attribtes like OnOff(on or off state), OnTime(the duration of "on" state) and others. Also, it has commands like On, Off and others. ZCL specification also defines the format of command and the format of metadata used to describe clusters and attributes. You can easily find the specificaiton by Google, it's open source. :::info In the architecture of ZCL, python controller is client, the device is server ::: ### ZclCallbacks So, as you can image, ZCL callbacks are usually used to notify application layer some attribute changes or there is an incoming command. In this lock-app example, we have this ```cpp=1 void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) { if (attributePath.mClusterId == OnOff::Id && attributePath.mAttributeId == OnOff::Attributes::OnOff::Id) { /* * If the cluster is OnOff and the changed attribute is OnOff, call the mgr to update the current lock state */ BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, *value ? BoltLockManager::LOCK_ACTION : BoltLockManager::UNLOCK_ACTION); } } ``` ## That's it?! In fact, I think if we only want to have an application using CHIP as protocol, that's all we need to know. The rest of the example is kind of only about the lock-app itself. Like how to manage the lock state, define the event after someone chagne the lock externally, etc.