Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / cc13x2_26x2 / 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  *          CC13X2_26X2 platforms using the Texas Instruments SDK and the
23  *          OpenThread stack.
24  *
25  */
26
27 /* this file behaves like a config.h, comes first */
28 #include <platform/internal/CHIPDeviceLayerInternal.h>
29
30 #include <platform/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.cpp>
31 #include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp>
32
33 #include <mbedtls/platform.h>
34 #include <openthread/heap.h>
35 #include <platform/OpenThread/OpenThreadUtils.h>
36 #include <platform/ThreadStackManager.h>
37
38 // platform folder in the TI SDK example application
39 #include <platform/system.h>
40
41 // DMM Includes
42 #ifdef USE_DMM
43 #include "ti_dmm_application_policy.h"
44 #include <dmm/dmm_policy.h>
45 #include <dmm/dmm_priority_ble_thread.h>
46 #include <dmm/dmm_scheduler.h>
47 #endif
48
49 namespace chip {
50 namespace DeviceLayer {
51
52 using namespace ::chip::DeviceLayer::Internal;
53
54 ThreadStackManagerImpl ThreadStackManagerImpl::sInstance;
55
56 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0
57 static void * ot_calloc(size_t n, size_t size)
58 {
59     void * p_ptr = NULL;
60
61     p_ptr = pvPortMalloc(n * size);
62
63     memset(p_ptr, 0, n * size);
64
65     return p_ptr;
66 }
67
68 static void ot_free(void * p_ptr)
69 {
70     vPortFree(p_ptr);
71 }
72 #endif /* OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 */
73
74 CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void)
75 {
76     return InitThreadStack(NULL);
77 }
78
79 CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst)
80 {
81     CHIP_ERROR err = CHIP_NO_ERROR;
82
83     // Create FreeRTOS queue for platform driver messages
84     procQueue = xQueueCreate(16U, sizeof(ThreadStackManagerImpl::procQueueMsg));
85
86 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0
87     mbedtls_platform_set_calloc_free(ot_calloc, ot_free);
88 #endif /* OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 */
89
90     // Initialize the OpenThread platform layer
91     otSysInit(0, NULL);
92
93 #ifdef USE_DMM
94     // DMM Init
95     DMMSch_registerClient(xTaskGetCurrentTaskHandle(), DMMPolicy_StackRole_threadFtd);
96     DMMPolicy_updateStackState(DMMPolicy_StackRole_threadFtd, DMMPOLICY_THREAD_IDLE);
97 #endif
98
99     // Initialize the generic implementation base classes.
100     err = GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>::DoInit();
101     SuccessOrExit(err);
102     err = GenericThreadStackManagerImpl_OpenThread_LwIP<ThreadStackManagerImpl>::DoInit(otInst);
103     SuccessOrExit(err);
104
105 exit:
106     return err;
107 }
108
109 bool ThreadStackManagerImpl::IsInitialized()
110 {
111     return sInstance.mThreadStackLock != NULL;
112 }
113
114 void ThreadStackManagerImpl::_OnCHIPoBLEAdvertisingStart(void)
115 {
116     // If Thread-over-BLE is enabled, ensure that ToBLE advertising is stopped before
117     // starting CHIPoBLE advertising.  This is accomplished by disabling the OpenThread
118     // IPv6 interface via a call to otIp6SetEnabled(false).
119     //
120 #if OPENTHREAD_CONFIG_ENABLE_TOBLE
121     LockThreadStack();
122     otIp6SetEnabled(OTInstance(), false);
123     UnlockThreadStack();
124 #endif
125 }
126
127 void ThreadStackManagerImpl::_OnCHIPoBLEAdvertisingStop(void)
128 {
129     // If Thread-over-BLE is enabled, and a Thread provision exists, ensure that ToBLE
130     // advertising is re-activated once CHIPoBLE advertising stops.
131     //
132 #if OPENTHREAD_CONFIG_ENABLE_TOBLE
133     LockThreadStack();
134     if (otThreadGetDeviceRole(OTInstance()) != OT_DEVICE_ROLE_DISABLED && otDatasetIsCommissioned(OTInstance()))
135     {
136         otIp6SetEnabled(OTInstance(), true);
137     }
138     UnlockThreadStack();
139 #endif
140 }
141
142 void ThreadStackManagerImpl::_SendProcMessage(ThreadStackManagerImpl::procQueueMsg & procMsg)
143 {
144     xQueueSendFromISR(procQueue, &procMsg, NULL);
145
146     // signal processing loop
147     SignalThreadActivityPendingFromISR();
148 }
149
150 void ThreadStackManagerImpl::_ProcMessage(otInstance * aInstance)
151 {
152     procQueueMsg procMsg;
153     while (pdTRUE == xQueueReceive(procQueue, &procMsg, 0U))
154     {
155         switch (procMsg.cmd)
156         {
157         case procQueueCmd_alarm: {
158             platformAlarmProcess(aInstance);
159             break;
160         }
161
162         case procQueueCmd_radio: {
163             platformRadioProcess(aInstance, procMsg.arg);
164             break;
165         }
166
167         case procQueueCmd_tasklets: {
168             otTaskletsProcess(aInstance);
169             break;
170         }
171
172         case procQueueCmd_uart: {
173             platformUartProcess(procMsg.arg);
174             break;
175         }
176
177         case procQueueCmd_random: {
178             platformRandomProcess();
179             break;
180         }
181
182         case procQueueCmd_alarmu: {
183             platformAlarmMicroProcess(aInstance);
184             break;
185         }
186
187         default: {
188             break;
189         }
190         }
191     }
192 }
193
194 } // namespace DeviceLayer
195 } // namespace chip
196
197 using namespace ::chip::DeviceLayer;
198
199 /**
200  * Glue function called by alarm processing layer to notify OpenThread the driver needs processing.
201  */
202 extern "C" void platformAlarmSignal()
203 {
204     ThreadStackManagerImpl::procQueueMsg msg;
205     msg.cmd = ThreadStackManagerImpl::procQueueCmd_alarm;
206     ThreadStackMgrImpl()._SendProcMessage(msg);
207 }
208
209 /**
210  * Glue function called by alarm processing layer to notify OpenThread the driver needs processing.
211  */
212 extern "C" void platformAlarmMicroSignal()
213 {
214     ThreadStackManagerImpl::procQueueMsg msg;
215     msg.cmd = ThreadStackManagerImpl::procQueueCmd_alarmu;
216     ThreadStackMgrImpl()._SendProcMessage(msg);
217 }
218
219 /**
220  * Glue function called by radio processing layer to notify OpenThread the driver needs processing.
221  */
222 extern "C" void platformRadioSignal(uintptr_t arg)
223 {
224     ThreadStackManagerImpl::procQueueMsg msg;
225     msg.cmd = ThreadStackManagerImpl::procQueueCmd_radio;
226     msg.arg = arg;
227     ThreadStackMgrImpl()._SendProcMessage(msg);
228 }
229
230 /**
231  * Glue function called by UART processing layer to notify OpenThread the driver needs processing.
232  */
233 extern "C" void platformUartSignal(uintptr_t arg)
234 {
235     ThreadStackManagerImpl::procQueueMsg msg;
236     msg.cmd = ThreadStackManagerImpl::procQueueCmd_uart;
237     msg.arg = arg;
238     ThreadStackMgrImpl()._SendProcMessage(msg);
239 }
240
241 /**
242  * Glue function called directly by the OpenThread stack when tasklet processing work
243  * is pending.
244  */
245 extern "C" void otTaskletsSignalPending(otInstance * p_instance)
246 {
247     ThreadStackMgrImpl().SignalThreadActivityPending();
248 }
249
250 /**
251  * Process events from the drivers
252  */
253 extern "C" void otSysProcessDrivers(otInstance * aInstance)
254 {
255     ThreadStackMgrImpl()._ProcMessage(aInstance);
256 }