b901299e20191ee1d2d5baa76fc826aa6ceb90a6
[platform/upstream/connectedhomeip.git] / src / platform / Zephyr / GenericThreadStackManagerImpl_Zephyr.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    All rights reserved.
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 generic implementation of ThreadStackManager features
22  *          for use on Zephyr platforms.
23  */
24
25 #pragma once
26
27 #include <net/openthread.h>
28 #include <zephyr.h>
29
30 #include <support/logging/CHIPLogging.h>
31
32 namespace chip {
33 namespace DeviceLayer {
34
35 class ThreadStackManagerImpl;
36
37 namespace Internal {
38
39 /**
40  * Provides a generic implementation of ThreadStackManager features that works on Zephyr platforms.
41  *
42  * This template contains implementations of select features from the ThreadStackManager abstract
43  * interface that are suitable for use on Zephyr-based platforms.  It is intended to be
44  * inherited, directly or indirectly, by the ThreadStackManagerImpl class, which also appears as
45  * the template's ImplClass parameter.
46  *
47  * Any task using this class must have cooperative scheduling priority.
48  */
49 template <class ImplClass>
50 class GenericThreadStackManagerImpl_Zephyr : public GenericThreadStackManagerImpl_OpenThread<ImplClass>
51 {
52 public:
53     // ===== Methods that implement the ThreadStackManager abstract interface.
54     CHIP_ERROR _InitThreadStack();
55
56 protected:
57     // ===== Methods that implement the ThreadStackManager abstract interface.
58
59     CHIP_ERROR _StartThreadTask();
60     void _LockThreadStack();
61     bool _TryLockThreadStack();
62     void _UnlockThreadStack();
63
64     // ===== Methods that override the GenericThreadStackManagerImpl_OpenThread abstract interface.
65
66     void _ProcessThreadActivity();
67     void _OnCHIPoBLEAdvertisingStart();
68     void _OnCHIPoBLEAdvertisingStop();
69
70 private:
71     // ===== Private members for use by this class only.
72
73     inline ImplClass * Impl() { return static_cast<ImplClass *>(this); }
74 };
75
76 // Instruct the compiler to instantiate the template only when explicitly told to do so.
77 extern template class GenericThreadStackManagerImpl_Zephyr<ThreadStackManagerImpl>;
78
79 template <class ImplClass>
80 CHIP_ERROR GenericThreadStackManagerImpl_Zephyr<ImplClass>::_InitThreadStack()
81 {
82     return GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(openthread_get_default_instance());
83 }
84
85 template <class ImplClass>
86 CHIP_ERROR GenericThreadStackManagerImpl_Zephyr<ImplClass>::_StartThreadTask()
87 {
88     // Intentionally empty.
89     return CHIP_NO_ERROR;
90 }
91
92 template <class ImplClass>
93 void GenericThreadStackManagerImpl_Zephyr<ImplClass>::_LockThreadStack()
94 {
95     openthread_api_mutex_lock(openthread_get_default_context());
96 }
97
98 template <class ImplClass>
99 bool GenericThreadStackManagerImpl_Zephyr<ImplClass>::_TryLockThreadStack()
100 {
101     // There's no openthread_api_mutex_try_lock() in Zephyr, so until it's contributed we must use the low-level API
102     return k_mutex_lock(&openthread_get_default_context()->api_lock, K_NO_WAIT) == 0;
103 }
104
105 template <class ImplClass>
106 void GenericThreadStackManagerImpl_Zephyr<ImplClass>::_UnlockThreadStack()
107 {
108     openthread_api_mutex_unlock(openthread_get_default_context());
109 }
110
111 template <class ImplClass>
112 void GenericThreadStackManagerImpl_Zephyr<ImplClass>::_ProcessThreadActivity()
113 {
114     // Intentionally empty.
115 }
116
117 template <class ImplClass>
118 void GenericThreadStackManagerImpl_Zephyr<ImplClass>::_OnCHIPoBLEAdvertisingStart()
119 {
120     ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__);
121 }
122
123 template <class ImplClass>
124 void GenericThreadStackManagerImpl_Zephyr<ImplClass>::_OnCHIPoBLEAdvertisingStop()
125 {
126     ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__);
127 }
128
129 } // namespace Internal
130 } // namespace DeviceLayer
131 } // namespace chip