Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / EFR32 / ThreadStackManagerImpl.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2019 Nest Labs, Inc.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *          Provides an implementation of the ThreadStackManager object for
22  *          EFR32 platforms using the Silicon Labs SDK and the OpenThread
23  *          stack.
24  *
25  */
26 /* this file behaves like a config.h, comes first */
27 #include <platform/internal/CHIPDeviceLayerInternal.h>
28
29 #include <platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp>
30 #include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp>
31
32 #include <platform/OpenThread/OpenThreadUtils.h>
33 #include <platform/ThreadStackManager.h>
34
35 #include <openthread/platform/entropy.h>
36
37 #include <support/CHIPPlatformMemory.h>
38
39 namespace chip {
40 namespace DeviceLayer {
41
42 using namespace ::chip::DeviceLayer::Internal;
43
44 ThreadStackManagerImpl ThreadStackManagerImpl::sInstance;
45
46 CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void)
47 {
48     return InitThreadStack(NULL);
49 }
50
51 CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst)
52 {
53     CHIP_ERROR err = CHIP_NO_ERROR;
54
55     // Initialize the generic implementation base classes.
56     err = GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>::DoInit();
57     SuccessOrExit(err);
58     err = GenericThreadStackManagerImpl_OpenThread_LwIP<ThreadStackManagerImpl>::DoInit(otInst);
59     SuccessOrExit(err);
60
61 exit:
62     return err;
63 }
64
65 bool ThreadStackManagerImpl::IsInitialized()
66 {
67     return sInstance.mThreadStackLock != NULL;
68 }
69
70 void ThreadStackManagerImpl::_OnCHIPoBLEAdvertisingStart(void)
71 {
72     // If Thread-over-BLE is enabled, ensure that ToBLE advertising is stopped before
73     // starting CHIPoBLE advertising.  This is accomplished by disabling the OpenThread
74     // IPv6 interface via a call to otIp6SetEnabled(false).
75     //
76     // On platforms where there is no native support for simultaneous BLE advertising
77     // it is necessary to coordinate between the different
78     // advertising modes a CHIP device may employ.  This arises in particular when a
79     // device supports both CHIPoBLE and ToBLE, each of which requires a separate advertising
80     // regime.  The OnCHIPoBLEAdvertisingStart()/OnCHIPoBLEAdvertisingStop() methods handle
81     // the switching between the two modes.
82     //
83 #if OPENTHREAD_CONFIG_ENABLE_TOBLE
84     LockThreadStack();
85     otIp6SetEnabled(OTInstance(), false);
86     UnlockThreadStack();
87 #endif
88 }
89
90 void ThreadStackManagerImpl::_OnCHIPoBLEAdvertisingStop(void)
91 {
92     // If Thread-over-BLE is enabled, and a Thread provision exists, ensure that ToBLE
93     // advertising is re-activated once CHIPoBLE advertising stops.
94     //
95 #if OPENTHREAD_CONFIG_ENABLE_TOBLE
96     LockThreadStack();
97     if (otThreadGetDeviceRole(OTInstance()) != OT_DEVICE_ROLE_DISABLED && otDatasetIsCommissioned(OTInstance()))
98     {
99         otIp6SetEnabled(OTInstance(), true);
100     }
101     UnlockThreadStack();
102 #endif
103 }
104
105 } // namespace DeviceLayer
106 } // namespace chip
107
108 using namespace ::chip::DeviceLayer;
109
110 /**
111  * Glue function called directly by the OpenThread stack when tasklet processing work
112  * is pending.
113  */
114 extern "C" void otTaskletsSignalPending(otInstance * p_instance)
115 {
116     ThreadStackMgrImpl().SignalThreadActivityPending();
117 }
118
119 /**
120  * Glue function called directly by the OpenThread stack when system event processing work
121  * is pending.
122  */
123 extern "C" void otSysEventSignalPending(void)
124 {
125     BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR();
126     portYIELD_FROM_ISR(yieldRequired);
127 }
128
129 extern "C" void * otPlatCAlloc(size_t aNum, size_t aSize)
130 {
131     return CHIPPlatformMemoryCalloc(aNum, aSize);
132 }
133
134 extern "C" void otPlatFree(void * aPtr)
135 {
136     CHIPPlatformMemoryFree(aPtr);
137 }
138
139 /**
140  * @brief Openthread UART implementation for the CLI is conflicting
141  *        with the UART implemented for Pigweed RPC as they use the same UART port
142  *
143  *        We now only build the uart as implemented in
144  *        connectedhomeip/examples/platform/efr32/uart.c
145  *        and remap OT functions to use our uart api.
146  *
147  *        For now OT CLI isn't usable when the examples are built with pw_rpc
148  */
149
150 #ifndef PW_RPC_ENABLED
151 #include "uart.h"
152 #endif
153
154 extern "C" __WEAK otError otPlatUartEnable(void)
155 {
156 #ifdef PW_RPC_ENABLED
157     return OT_ERROR_NOT_IMPLEMENTED;
158 #else
159     uartConsoleInit();
160     return OT_ERROR_NONE;
161 #endif
162 }
163
164 extern "C" __WEAK otError otPlatUartSend(const uint8_t * aBuf, uint16_t aBufLength)
165 {
166 #ifdef PW_RPC_ENABLED
167     return OT_ERROR_NOT_IMPLEMENTED;
168 #else
169     if (uartConsoleWrite((const char *) aBuf, aBufLength) > 0)
170     {
171         otPlatUartSendDone();
172         return OT_ERROR_NONE;
173     }
174     return OT_ERROR_FAILED;
175 #endif
176 }
177
178 extern "C" __WEAK void efr32UartProcess(void)
179 {
180 #ifndef PW_RPC_ENABLED
181     uint8_t tempBuf[128] = { 0 };
182     // will read the data available up to 128bytes
183     uint16_t count = uartConsoleRead((char *) tempBuf, 128);
184     if (count > 0)
185     {
186         // ot process Received data for CLI cmds
187         otPlatUartReceived(tempBuf, count);
188     }
189 #endif
190 }
191
192 extern "C" __WEAK otError otPlatUartFlush(void)
193 {
194     return OT_ERROR_NOT_IMPLEMENTED;
195 }
196
197 extern "C" __WEAK otError otPlatUartDisable(void)
198 {
199     return OT_ERROR_NOT_IMPLEMENTED;
200 }