forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThreadStackManagerImpl.cpp
250 lines (213 loc) · 6.85 KB
/
ThreadStackManagerImpl.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
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2019 Nest Labs, Inc.
*
* 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.
*/
/**
* @file
* Provides an implementation of the ThreadStackManager object for
* EFR32 platforms using the Silicon Labs SDK and the OpenThread
* stack.
*
*/
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <platform/NetworkCommissioning.h>
#include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp>
#include <platform/OpenThread/OpenThreadUtils.h>
#include <platform/ThreadStackManager.h>
#include <openthread/platform/entropy.h>
#include <lib/support/CHIPPlatformMemory.h>
#include <lib/support/CodeUtils.h>
#include <mbedtls/platform.h>
extern "C" {
#include "platform-efr32.h"
otInstance * otGetInstance(void);
#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI
void otAppCliInit(otInstance * aInstance);
#endif // CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI
}
namespace chip {
namespace DeviceLayer {
namespace {
otInstance * sOTInstance = NULL;
// Network commissioning
#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_
NetworkCommissioning::GenericThreadDriver sGenericThreadDriver;
app::Clusters::NetworkCommissioning::Instance sThreadNetworkCommissioningInstance(0 /* Endpoint Id */, &sGenericThreadDriver);
#endif
void initStaticNetworkCommissioningThreadDriver(void)
{
#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_
sThreadNetworkCommissioningInstance.Init();
#endif
}
void shutdownStaticNetworkCommissioningThreadDriver(void)
{
#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_
sThreadNetworkCommissioningInstance.Shutdown();
#endif
}
}; // namespace
using namespace ::chip::DeviceLayer::Internal;
ThreadStackManagerImpl ThreadStackManagerImpl::sInstance;
CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void)
{
return InitThreadStack(sOTInstance);
}
CHIP_ERROR ThreadStackManagerImpl::_StartThreadTask(void)
{
// Stubbed since our thread task is created in the InitThreadStack function and it will start once the scheduler starts.
return CHIP_NO_ERROR;
}
void ThreadStackManagerImpl::_LockThreadStack(void)
{
sl_ot_rtos_acquire_stack_mutex();
}
bool ThreadStackManagerImpl::_TryLockThreadStack(void)
{
// TODO: Implement a non-blocking version of the mutex lock
sl_ot_rtos_acquire_stack_mutex();
return true;
}
void ThreadStackManagerImpl::_UnlockThreadStack(void)
{
sl_ot_rtos_release_stack_mutex();
}
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete()
{
// Only 1 task can be blocked on a srpClearAll request
if (mSrpClearAllRequester == NULL)
{
mSrpClearAllRequester = osThreadGetId();
// Wait on OnSrpClientNotification which confirms the clearing is done.
// It will notify this current task with NotifySrpClearAllComplete.
// However, we won't wait more than 2s.
osThreadFlagsWait(threadSrpClearAllFlags, osFlagsWaitAny, pdMS_TO_TICKS(2000));
mSrpClearAllRequester = NULL;
}
}
void ThreadStackManagerImpl::_NotifySrpClearAllComplete()
{
if (mSrpClearAllRequester)
{
osThreadFlagsSet(mSrpClearAllRequester, threadSrpClearAllFlags);
}
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst)
{
CHIP_ERROR err = CHIP_NO_ERROR;
err = GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>::ConfigureThreadStack(otInst);
initStaticNetworkCommissioningThreadDriver();
return err;
}
void ThreadStackManagerImpl::FactoryResetThreadStack(void)
{
VerifyOrReturn(sOTInstance != NULL);
otInstanceFactoryReset(sOTInstance);
shutdownStaticNetworkCommissioningThreadDriver();
}
bool ThreadStackManagerImpl::IsInitialized()
{
return otGetInstance() != NULL;
}
} // namespace DeviceLayer
} // namespace chip
using namespace ::chip::DeviceLayer;
#ifndef SL_COMPONENT_CATALOG_PRESENT
extern "C" __WEAK void sl_openthread_init(void)
{
#error "This shouldn't compile"
// Place holder for enabling Silabs specific features available only through Simplicity Studio
}
#endif
/**
* @brief Openthread UART implementation for the CLI is conflicting
* with the UART implemented for Pigweed RPC as they use the same UART port
*
* We now only build the uart as implemented in
* connectedhomeip/examples/platform/efr32/uart.c
* and remap OT functions to use our uart api.
*
* For now OT CLI isn't usable when the examples are built with pw_rpc
*/
#ifndef PW_RPC_ENABLED
#include "uart.h"
#endif
extern "C" otError otPlatUartEnable(void)
{
#ifdef PW_RPC_ENABLED
return OT_ERROR_NOT_IMPLEMENTED;
#else
// Uart Init is handled in init_efrPlatform.cpp
return OT_ERROR_NONE;
#endif
}
extern "C" otInstance * otGetInstance(void)
{
return sOTInstance;
}
extern "C" void sl_ot_create_instance(void)
{
VerifyOrDie(chip::Platform::MemoryInit() == CHIP_NO_ERROR);
mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
sOTInstance = otInstanceInitSingle();
}
extern "C" void sl_ot_cli_init(void)
{
#if !defined(PW_RPC_ENABLED) && CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI
VerifyOrDie(sOTInstance != NULL);
otAppCliInit(sOTInstance);
#endif
}
#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI
extern "C" otError otPlatUartSend(const uint8_t * aBuf, uint16_t aBufLength)
{
#ifdef PW_RPC_ENABLED
return OT_ERROR_NOT_IMPLEMENTED;
#else
if (uartConsoleWrite((const char *) aBuf, aBufLength) > 0)
{
otPlatUartSendDone();
return OT_ERROR_NONE;
}
return OT_ERROR_FAILED;
#endif
}
extern "C" void efr32UartProcess(void)
{
#if !defined(PW_RPC_ENABLED) && !defined(ENABLE_CHIP_SHELL)
uint8_t tempBuf[128] = { 0 };
// will read the data available up to 128bytes
int16_t count = uartConsoleRead((char *) tempBuf, 128);
if (count > 0)
{
// ot process Received data for CLI cmds
otPlatUartReceived(tempBuf, count);
}
#endif
}
extern "C" __WEAK otError otPlatUartFlush(void)
{
return OT_ERROR_NOT_IMPLEMENTED;
}
extern "C" __WEAK otError otPlatUartDisable(void)
{
return OT_ERROR_NOT_IMPLEMENTED;
}
#endif // CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI