forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMatterConfig.cpp
362 lines (298 loc) · 12.4 KB
/
MatterConfig.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2022 Silabs.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* 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.
*/
#include "AppConfig.h"
#include "BaseApplication.h"
#include "OTAConfig.h"
#include <MatterConfig.h>
#include <cmsis_os2.h>
#include <mbedtls/platform.h>
#ifdef SL_WIFI
#include "wfx_host_events.h"
#endif /* SL_WIFI */
#if PW_RPC_ENABLED
#include "Rpc.h"
#endif
#ifdef ENABLE_CHIP_SHELL
#include "matter_shell.h"
#endif
#ifdef HEAP_MONITORING
#include "MemMonitoring.h"
#endif
#ifdef SLI_SI91X_MCU_INTERFACE
#include "wfx_rsi.h"
#endif /* SLI_SI91X_MCU_INTERFACE */
#include <crypto/CHIPCryptoPAL.h>
// If building with the EFR32-provided crypto backend, we can use the
// opaque keystore
#if CHIP_CRYPTO_PLATFORM && !(defined(SLI_SI91X_MCU_INTERFACE))
#include <platform/silabs/efr32/Efr32PsaOperationalKeystore.h>
static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeystore;
#endif
#include <ProvisionManager.h>
#include <app/InteractionModelEngine.h>
#include <app/TimerDelegates.h>
#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED
#include "SilabsTestEventTriggerDelegate.h" // nogncheck
#endif
#if CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED
#include <app/reporting/SynchronizedReportSchedulerImpl.h>
#else
#include <app/reporting/ReportSchedulerImpl.h>
#endif
#include <lib/support/BytesToHex.h>
#ifdef PERFORMANCE_TEST_ENABLED
#include <performance_test_commands.h>
#endif
#include <AppTask.h>
#include <DeviceInfoProviderImpl.h>
#include <app/server/Server.h>
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
/**********************************************************
* Defines
*********************************************************/
using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::DeviceLayer;
using namespace ::chip::Credentials;
using namespace chip::DeviceLayer::Silabs;
#if CHIP_ENABLE_OPENTHREAD
#include <inet/EndPointStateOpenThread.h>
#include <openthread/cli.h>
#include <openthread/dataset.h>
#include <openthread/error.h>
#include <openthread/heap.h>
#include <openthread/icmp6.h>
#include <openthread/instance.h>
#include <openthread/link.h>
#include <openthread/platform/openthread-system.h>
#include <openthread/tasklet.h>
#include <openthread/thread.h>
// ================================================================================
// Matter Networking Callbacks
// ================================================================================
void LockOpenThreadTask(void)
{
chip::DeviceLayer::ThreadStackMgr().LockThreadStack();
}
void UnlockOpenThreadTask(void)
{
chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack();
}
// ================================================================================
// SilabsMatterConfig Methods
// ================================================================================
CHIP_ERROR SilabsMatterConfig::InitOpenThread(void)
{
SILABS_LOG("Initializing OpenThread stack");
ReturnErrorOnFailure(ThreadStackMgr().InitThreadStack());
#if CHIP_DEVICE_CONFIG_THREAD_FTD
ReturnErrorOnFailure(ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router));
#else // CHIP_DEVICE_CONFIG_THREAD_FTD
#if CHIP_CONFIG_ENABLE_ICD_SERVER
#if CHIP_DEVICE_CONFIG_THREAD_SSED
ReturnErrorOnFailure(ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SynchronizedSleepyEndDevice));
#else
ReturnErrorOnFailure(ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice));
#endif
#else // CHIP_CONFIG_ENABLE_ICD_SERVER
ReturnErrorOnFailure(ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice));
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
#endif // CHIP_DEVICE_CONFIG_THREAD_FTD
SILABS_LOG("Starting OpenThread task");
return ThreadStackMgrImpl().StartThreadTask();
}
#endif // CHIP_ENABLE_OPENTHREAD
namespace {
constexpr uint32_t kMainTaskStackSize = (1024 * 5);
// Task is dynamically allocated with max priority. This task gets deleted once the inits are completed.
constexpr osThreadAttr_t kMainTaskAttr = { .name = "main",
.attr_bits = osThreadDetached,
.cb_mem = NULL,
.cb_size = 0U,
.stack_mem = NULL,
.stack_size = kMainTaskStackSize,
.priority = osPriorityRealtime7 };
osThreadId_t sMainTaskHandle;
static chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
void ApplicationStart(void * unused)
{
CHIP_ERROR err = SilabsMatterConfig::InitMatter(BLE_DEV_NAME);
if (err != CHIP_NO_ERROR)
appError(err);
gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage());
chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
chip::DeviceLayer::PlatformMgr().LockChipStack();
// Initialize device attestation config
SetDeviceAttestationCredentialsProvider(&Provision::Manager::GetInstance().GetStorage());
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
SILABS_LOG("Starting App Task");
err = AppTask::GetAppTask().StartAppTask();
if (err != CHIP_NO_ERROR)
appError(err);
VerifyOrDie(osThreadTerminate(sMainTaskHandle) == osOK); // Deleting the main task should never fail.
sMainTaskHandle = nullptr;
}
} // namespace
void SilabsMatterConfig::AppInit()
{
GetPlatform().Init();
sMainTaskHandle = osThreadNew(ApplicationStart, nullptr, &kMainTaskAttr);
SILABS_LOG("Starting scheduler");
VerifyOrDie(sMainTaskHandle); // We can't proceed if the Main Task creation failed.
GetPlatform().StartScheduler();
// Should never get here.
chip::Platform::MemoryShutdown();
SILABS_LOG("Start Scheduler Failed");
appError(CHIP_ERROR_INTERNAL);
}
#if SILABS_OTA_ENABLED
void SilabsMatterConfig::InitOTARequestorHandler(System::Layer * systemLayer, void * appState)
{
OTAConfig::Init();
}
#endif
void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event, intptr_t arg)
{
// Initialize OTA only when Thread or WiFi connectivity is established
if (((event->Type == DeviceEventType::kThreadConnectivityChange) &&
(event->ThreadConnectivityChange.Result == kConnectivity_Established)) ||
((event->Type == DeviceEventType::kInternetConnectivityChange) &&
(event->InternetConnectivityChange.IPv6 == kConnectivity_Established)))
{
#if SILABS_OTA_ENABLED
SILABS_LOG("Scheduling OTA Requestor initialization")
chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(OTAConfig::kInitOTARequestorDelaySec),
InitOTARequestorHandler, nullptr);
#endif
}
}
CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
{
CHIP_ERROR err;
#ifdef SL_WIFI
// Because OpenThread needs to use memory allocation during its Key operations, we initialize the memory management for thread
// and set the allocation functions inside sl_ot_create_instance, which is called by sl_system_init in the OpenThread stack
// initialization.
mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
#endif
SILABS_LOG("==================================================");
SILABS_LOG("%s starting", appName);
SILABS_LOG("==================================================");
#if PW_RPC_ENABLED
chip::rpc::Init();
#endif
#ifdef HEAP_MONITORING
MemMonitoring::StartMonitor();
#endif
//==============================================
// Init Matter Stack
//==============================================
SILABS_LOG("Init CHIP Stack");
#ifdef SL_WIFI
// Init Chip memory management before the stack
// See comment above about OpenThread memory allocation as to why this is WIFI only here.
ReturnErrorOnFailure(chip::Platform::MemoryInit());
ReturnErrorOnFailure(InitWiFi());
#endif
ReturnErrorOnFailure(PlatformMgr().InitChipStack());
// Provision Manager
Silabs::Provision::Manager & provision = Silabs::Provision::Manager::GetInstance();
ReturnErrorOnFailure(provision.Init());
SetDeviceInstanceInfoProvider(&provision.GetStorage());
SetCommissionableDataProvider(&provision.GetStorage());
chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName);
#if CHIP_ENABLE_OPENTHREAD
ReturnErrorOnFailure(InitOpenThread());
#endif
// Stop Matter event handling while setting up resources
chip::DeviceLayer::PlatformMgr().LockChipStack();
// Create initParams with SDK example defaults here
// TODO: replace with our own init param to avoid double allocation in examples
static chip::CommonCaseDeviceServerInitParams initParams;
// Report scheduler and timer delegate instance
static chip::app::DefaultTimerDelegate sTimerDelegate;
#if CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED
static chip::app::reporting::SynchronizedReportSchedulerImpl sReportScheduler(&sTimerDelegate);
#else
static chip::app::reporting::ReportSchedulerImpl sReportScheduler(&sTimerDelegate);
#endif
initParams.reportScheduler = &sReportScheduler;
#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED
static SilabsTestEventTriggerDelegate sTestEventTriggerDelegate;
initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate;
#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED
#if CHIP_CRYPTO_PLATFORM && !(defined(SLI_SI91X_MCU_INTERFACE))
// When building with EFR32 crypto, use the opaque key store
// instead of the default (insecure) one.
gOperationalKeystore.Init();
initParams.operationalKeystore = &gOperationalKeystore;
#endif
// Initialize the remaining (not overridden) providers to the SDK example defaults
(void) initParams.InitializeStaticResourcesBeforeServerInit();
#if CHIP_ENABLE_OPENTHREAD
// Set up OpenThread configuration when OpenThread is included
chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams;
nativeParams.lockCb = LockOpenThreadTask;
nativeParams.unlockCb = UnlockOpenThreadTask;
nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance();
initParams.endpointNativeParams = static_cast<void *>(&nativeParams);
#endif
initParams.appDelegate = &BaseApplication::sAppDelegate;
// Init Matter Server and Start Event Loop
err = chip::Server::GetInstance().Init(initParams);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
ReturnErrorOnFailure(err);
// OTA Requestor initialization will be triggered by the connectivity events
PlatformMgr().AddEventHandler(ConnectivityEventCallback, reinterpret_cast<intptr_t>(nullptr));
SILABS_LOG("Starting Platform Manager Event Loop");
ReturnErrorOnFailure(PlatformMgr().StartEventLoopTask());
#ifdef ENABLE_CHIP_SHELL
chip::startShellTask();
#endif
return CHIP_NO_ERROR;
}
#ifdef SL_WIFI
CHIP_ERROR SilabsMatterConfig::InitWiFi(void)
{
#ifdef WF200_WIFI
// Start wfx bus communication task.
wfx_bus_start();
#ifdef SL_WFX_USE_SECURE_LINK
wfx_securelink_task_start(); // start securelink key renegotiation task
#endif // SL_WFX_USE_SECURE_LINK
#endif /* WF200_WIFI */
#ifdef SLI_SI91X_MCU_INTERFACE
sl_status_t status;
if ((status = wfx_wifi_rsi_init()) != SL_STATUS_OK)
{
ReturnErrorOnFailure((CHIP_ERROR) status);
}
#endif // SLI_SI91X_MCU_INTERFACE
return CHIP_NO_ERROR;
}
#endif // SL_WIFI
// ================================================================================
// FreeRTOS Callbacks
// ================================================================================
extern "C" void vApplicationIdleHook(void)
{
#if (SLI_SI91X_MCU_INTERFACE && CHIP_CONFIG_ENABLE_ICD_SERVER)
sl_si91x_invoke_btn_press_event();
#endif
}