Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / system / SystemLayer.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2016-2017 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  *      This file contains declarations of the
22  *      chip::System::Layer class and its related types, data and
23  *      functions.
24  */
25
26 #pragma once
27
28 // Include configuration headers
29 #include <system/SystemConfig.h>
30
31 #include <core/CHIPCallback.h>
32
33 #include <support/DLLUtil.h>
34 #include <system/SystemError.h>
35 #include <system/SystemEvent.h>
36 #include <system/SystemObject.h>
37
38 // Include dependent headers
39 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
40 #include <system/SystemWakeEvent.h>
41
42 #include <sys/select.h>
43 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
44
45 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
46 #include <pthread.h>
47 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
48
49 namespace chip {
50 namespace System {
51
52 class Layer;
53 class Timer;
54
55 #if CHIP_SYSTEM_CONFIG_USE_LWIP
56 class Object;
57 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
58
59 namespace Platform {
60 namespace Layer {
61
62 using ::chip::System::Error;
63 using ::chip::System::Layer;
64
65 #if CHIP_SYSTEM_CONFIG_USE_LWIP
66 using ::chip::System::Object;
67 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
68
69 extern Error WillInit(Layer & aLayer, void * aContext);
70 extern Error WillShutdown(Layer & aLayer, void * aContext);
71
72 extern void DidInit(Layer & aLayer, void * aContext, Error aStatus);
73 extern void DidShutdown(Layer & aLayer, void * aContext, Error aStatus);
74
75 #if CHIP_SYSTEM_CONFIG_USE_LWIP
76 extern Error PostEvent(Layer & aLayer, void * aContext, Object & aTarget, EventType aType, uintptr_t aArgument);
77 extern Error DispatchEvents(Layer & aLayer, void * aContext);
78 extern Error DispatchEvent(Layer & aLayer, void * aContext, Event aEvent);
79 extern Error StartTimer(Layer & aLayer, void * aContext, uint32_t aMilliseconds);
80 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
81
82 } // namespace Layer
83 } // namespace Platform
84
85 /**
86  *  @enum LayerState
87  *
88  *  The state of a Layer object.
89  */
90 enum LayerState
91 {
92     kLayerState_NotInitialized = 0, /**< Not initialized state. */
93     kLayerState_Initialized    = 1  /**< Initialized state. */
94 };
95
96 #if CHIP_SYSTEM_CONFIG_USE_LWIP
97 typedef Error (*LwIPEventHandlerFunction)(Object & aTarget, EventType aEventType, uintptr_t aArgument);
98
99 class LwIPEventHandlerDelegate
100 {
101     friend class Layer;
102
103 public:
104     bool IsInitialized(void) const;
105     void Init(LwIPEventHandlerFunction aFunction);
106     void Prepend(const LwIPEventHandlerDelegate *& aDelegateList);
107
108 private:
109     LwIPEventHandlerFunction mFunction;
110     const LwIPEventHandlerDelegate * mNextDelegate;
111 };
112 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
113
114 /**
115  *  @class Layer
116  *
117  *  @brief
118  *      This provides access to timers according to the configured event handling model.
119  *
120  *      For \c CHIP_SYSTEM_CONFIG_USE_SOCKETS, event readiness notification is handled via traditional poll/select implementation on
121  *      the platform adaptation.
122  *
123  *      For \c CHIP_SYSTEM_CONFIG_USE_LWIP, event readiness notification is handle via events / messages and platform- and
124  *      system-specific hooks for the event/message system.
125  */
126 class DLL_EXPORT Layer
127 {
128 public:
129     Layer();
130
131     Error Init(void * aContext);
132     Error Shutdown();
133
134     void * GetPlatformData() const;
135     void SetPlatformData(void * aPlatformData);
136
137     LayerState State() const;
138
139     Error NewTimer(Timer *& aTimerPtr);
140
141     void StartTimer(uint32_t aMilliseconds, chip::Callback::Callback<> * aCallback);
142     void DispatchTimerCallbacks(uint64_t kCurrentEpoch);
143
144     typedef void (*TimerCompleteFunct)(Layer * aLayer, void * aAppState, Error aError);
145     Error StartTimer(uint32_t aMilliseconds, TimerCompleteFunct aComplete, void * aAppState);
146     void CancelTimer(TimerCompleteFunct aOnComplete, void * aAppState);
147
148     Error ScheduleWork(TimerCompleteFunct aComplete, void * aAppState);
149
150 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
151     void PrepareSelect(int & aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet, struct timeval & aSleepTime);
152     void HandleSelectResult(int aSetSize, fd_set * aReadSet, fd_set * aWriteSet, fd_set * aExceptionSet);
153     void WakeSelect();
154 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
155
156 #if CHIP_SYSTEM_CONFIG_USE_LWIP
157     typedef Error (*EventHandler)(Object & aTarget, EventType aEventType, uintptr_t aArgument);
158     Error AddEventHandlerDelegate(LwIPEventHandlerDelegate & aDelegate);
159
160     // Event Handling
161     Error PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
162     Error DispatchEvents(void);
163     Error DispatchEvent(Event aEvent);
164     Error HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
165
166     // Timer Management
167     Error HandlePlatformTimer(void);
168 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
169
170     static uint64_t GetClock_Monotonic();
171     static uint64_t GetClock_MonotonicMS();
172     static uint64_t GetClock_MonotonicHiRes();
173     static Error GetClock_RealTime(uint64_t & curTime);
174     static Error GetClock_RealTimeMS(uint64_t & curTimeMS);
175     static Error SetClock_RealTime(uint64_t newCurTime);
176
177 private:
178     LayerState mLayerState;
179     void * mContext;
180     void * mPlatformData;
181     chip::Callback::CallbackDeque mTimerCallbacks;
182
183 #if CHIP_SYSTEM_CONFIG_USE_LWIP
184     static LwIPEventHandlerDelegate sSystemEventHandlerDelegate;
185
186     const LwIPEventHandlerDelegate * mEventDelegateList;
187     Timer * mTimerList;
188     bool mTimerComplete;
189 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
190
191 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
192     SystemWakeEvent mWakeEvent;
193 #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
194     pthread_t mHandleSelectThread;
195 #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
196 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
197
198 #if CHIP_SYSTEM_CONFIG_USE_LWIP
199     static Error HandleSystemLayerEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
200
201     Error StartPlatformTimer(uint32_t aDelayMilliseconds);
202
203     friend Error Platform::Layer::PostEvent(Layer & aLayer, void * aContext, Object & aTarget, EventType aType,
204                                             uintptr_t aArgument);
205     friend Error Platform::Layer::DispatchEvents(Layer & aLayer, void * aContext);
206     friend Error Platform::Layer::DispatchEvent(Layer & aLayer, void * aContext, Event aEvent);
207     friend Error Platform::Layer::StartTimer(Layer & aLayer, void * aContext, uint32_t aMilliseconds);
208 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
209
210     // Copy and assignment NOT DEFINED
211     Layer(const Layer &) = delete;
212     Layer & operator=(const Layer &) = delete;
213
214     friend class Timer;
215 };
216
217 /**
218  * This returns the current state of the layer object.
219  */
220 inline LayerState Layer::State() const
221 {
222     return this->mLayerState;
223 }
224
225 } // namespace System
226 } // namespace chip