owned this note
owned this note
Published
Linked with GitHub
# 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.