Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2018 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 : * Contains non-inline method definitions for the
22 : * GenericPlatformManagerImpl<> template.
23 : */
24 :
25 : #ifndef GENERIC_PLATFORM_MANAGER_IMPL_CPP
26 : #define GENERIC_PLATFORM_MANAGER_IMPL_CPP
27 :
28 : #include <inttypes.h>
29 : #include <new>
30 : #include <platform/DiagnosticDataProvider.h>
31 : #include <platform/PlatformManager.h>
32 : #include <platform/internal/BLEManager.h>
33 : #include <platform/internal/CHIPDeviceLayerInternal.h>
34 : #include <platform/internal/EventLogging.h>
35 : #include <platform/internal/GenericPlatformManagerImpl.h>
36 : #include <platform/internal/NFCCommissioningManager.h>
37 :
38 : #include <lib/support/CHIPMem.h>
39 : #include <lib/support/CodeUtils.h>
40 : #include <lib/support/logging/CHIPLogging.h>
41 :
42 : namespace chip {
43 : namespace DeviceLayer {
44 :
45 : namespace Internal {
46 :
47 : extern CHIP_ERROR InitEntropy();
48 :
49 : template <class ImplClass>
50 56 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_InitChipStack()
51 : {
52 : CHIP_ERROR err;
53 :
54 56 : mMsgLayerWasActive = false;
55 :
56 : // Arrange for CHIP core errors to be translated to text
57 56 : RegisterCHIPLayerErrorFormatter();
58 :
59 : // Arrange for Device Layer errors to be translated to text.
60 56 : RegisterDeviceLayerErrorFormatter();
61 :
62 56 : err = InitEntropy();
63 112 : if (err != CHIP_NO_ERROR)
64 : {
65 0 : ChipLogError(DeviceLayer, "Entropy initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
66 : }
67 56 : SuccessOrExit(err);
68 :
69 : // Initialize the CHIP system layer.
70 56 : err = SystemLayer().Init();
71 112 : if (err != CHIP_NO_ERROR)
72 : {
73 0 : ChipLogError(DeviceLayer, "SystemLayer initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
74 : }
75 56 : SuccessOrExit(err);
76 :
77 : // Initialize the Configuration Manager.
78 56 : err = ConfigurationMgr().Init();
79 112 : if (err != CHIP_NO_ERROR)
80 : {
81 0 : ChipLogError(DeviceLayer, "Configuration Manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
82 : }
83 56 : SuccessOrExit(err);
84 :
85 : // Initialize the CHIP UDP layer.
86 56 : err = UDPEndPointManager()->Init(SystemLayer());
87 112 : if (err != CHIP_NO_ERROR)
88 : {
89 0 : ChipLogError(DeviceLayer, "UDP initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
90 : }
91 56 : SuccessOrExit(err);
92 :
93 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
94 : // Initialize the CHIP TCP layer.
95 56 : err = TCPEndPointManager()->Init(SystemLayer());
96 112 : if (err != CHIP_NO_ERROR)
97 : {
98 0 : ChipLogError(DeviceLayer, "TCP initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
99 : }
100 56 : SuccessOrExit(err);
101 : #endif
102 :
103 : // TODO Perform dynamic configuration of the core CHIP objects based on stored settings.
104 :
105 : // Initialize the CHIP BLE manager.
106 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
107 56 : err = BLEMgr().Init();
108 112 : if (err != CHIP_NO_ERROR)
109 : {
110 0 : ChipLogError(DeviceLayer, "BLEManager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
111 : }
112 56 : SuccessOrExit(err);
113 : #endif
114 :
115 : // Initialize the Connectivity Manager object.
116 56 : err = ConnectivityMgr().Init();
117 112 : if (err != CHIP_NO_ERROR)
118 : {
119 0 : ChipLogError(DeviceLayer, "Connectivity Manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
120 : }
121 56 : SuccessOrExit(err);
122 :
123 : // Initialize the NFC onboarding payload manager
124 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_ONBOARDING_PAYLOAD
125 : err = NFCOnboardingPayloadMgr().Init();
126 : VerifyOrExit(
127 : err == CHIP_NO_ERROR,
128 : ChipLogError(DeviceLayer, "NFC onboarding payload manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format()));
129 : #endif
130 :
131 : // Initialize the CHIP NFC manager for NFC-based Commissioning
132 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
133 : err = NFCCommissioningMgr().Init();
134 : if (err != CHIP_NO_ERROR)
135 : {
136 : ChipLogError(DeviceLayer, "NFC-based Commissioning Manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
137 : }
138 : SuccessOrExit(err);
139 : #endif
140 :
141 : // TODO Initialize CHIP Event Logging.
142 :
143 : // TODO Initialize the Time Sync Manager object.
144 :
145 56 : SuccessOrExit(err);
146 :
147 56 : exit:
148 56 : return err;
149 : }
150 :
151 : template <class ImplClass>
152 56 : void GenericPlatformManagerImpl<ImplClass>::_Shutdown()
153 : {
154 56 : ChipLogProgress(DeviceLayer, "Inet Layer shutdown");
155 56 : UDPEndPointManager()->Shutdown();
156 :
157 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
158 56 : TCPEndPointManager()->Shutdown();
159 : #endif
160 :
161 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
162 56 : ChipLogProgress(DeviceLayer, "BLE Layer shutdown");
163 56 : BLEMgr().Shutdown();
164 : #endif
165 :
166 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
167 56 : ChipLogProgress(DeviceLayer, "WiFi-PAF Layer shutdown");
168 56 : WiFiPAF::WiFiPAFLayer::GetWiFiPAFLayer().Shutdown();
169 : #endif
170 :
171 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
172 : ChipLogProgress(DeviceLayer, "NFCCommissioningMgr shutdown");
173 : NFCCommissioningMgr().Shutdown();
174 : #endif
175 :
176 56 : ChipLogProgress(DeviceLayer, "System Layer shutdown");
177 56 : SystemLayer().Shutdown();
178 56 : }
179 :
180 : template <class ImplClass>
181 42 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_AddEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
182 : {
183 42 : CHIP_ERROR err = CHIP_NO_ERROR;
184 : AppEventHandler * eventHandler;
185 :
186 : // Do nothing if the event handler is already registered.
187 71 : for (eventHandler = mAppEventHandlerList; eventHandler != nullptr; eventHandler = eventHandler->Next)
188 : {
189 62 : if (eventHandler->Handler == handler && eventHandler->Arg == arg)
190 : {
191 33 : ExitNow();
192 : }
193 : }
194 :
195 9 : eventHandler = (AppEventHandler *) chip::Platform::MemoryAlloc(sizeof(AppEventHandler));
196 9 : VerifyOrExit(eventHandler != nullptr, err = CHIP_ERROR_NO_MEMORY);
197 :
198 9 : eventHandler->Next = mAppEventHandlerList;
199 9 : eventHandler->Handler = handler;
200 9 : eventHandler->Arg = arg;
201 :
202 9 : mAppEventHandlerList = eventHandler;
203 :
204 42 : exit:
205 42 : return err;
206 : }
207 :
208 : template <class ImplClass>
209 16 : void GenericPlatformManagerImpl<ImplClass>::_RemoveEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
210 : {
211 : AppEventHandler ** eventHandlerIndirectPtr;
212 :
213 43 : for (eventHandlerIndirectPtr = &mAppEventHandlerList; *eventHandlerIndirectPtr != nullptr;)
214 : {
215 27 : AppEventHandler * eventHandler = (*eventHandlerIndirectPtr);
216 :
217 27 : if (eventHandler->Handler == handler && eventHandler->Arg == arg)
218 : {
219 3 : *eventHandlerIndirectPtr = eventHandler->Next;
220 3 : chip::Platform::MemoryFree(eventHandler);
221 : }
222 : else
223 : {
224 24 : eventHandlerIndirectPtr = &eventHandler->Next;
225 : }
226 : }
227 16 : }
228 :
229 : template <class ImplClass>
230 1 : void GenericPlatformManagerImpl<ImplClass>::_HandleServerStarted()
231 : {
232 1 : PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
233 :
234 1 : if (platformManagerDelegate != nullptr)
235 : {
236 : uint32_t softwareVersion;
237 :
238 0 : if (ConfigurationMgr().GetSoftwareVersion(softwareVersion) == CHIP_NO_ERROR)
239 0 : platformManagerDelegate->OnStartUp(softwareVersion);
240 : }
241 1 : }
242 :
243 : template <class ImplClass>
244 1 : void GenericPlatformManagerImpl<ImplClass>::_HandleServerShuttingDown()
245 : {
246 1 : PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
247 :
248 1 : if (platformManagerDelegate != nullptr)
249 : {
250 0 : platformManagerDelegate->OnShutDown();
251 : }
252 1 : }
253 :
254 : template <class ImplClass>
255 83 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
256 : {
257 83 : ChipDeviceEvent event{ .Type = DeviceEventType::kCallWorkFunct };
258 83 : event.CallWorkFunct = { .WorkFunct = workFunct, .Arg = arg };
259 83 : CHIP_ERROR err = Impl()->PostEvent(&event);
260 166 : if (err != CHIP_NO_ERROR)
261 : {
262 0 : ChipLogError(DeviceLayer, "Failed to schedule work: %" CHIP_ERROR_FORMAT, err.Format());
263 : }
264 83 : return err;
265 : }
266 :
267 : template <class ImplClass>
268 8 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_ScheduleBackgroundWork(AsyncWorkFunct workFunct, intptr_t arg)
269 : {
270 8 : ChipDeviceEvent event{ .Type = DeviceEventType::kCallWorkFunct };
271 8 : event.CallWorkFunct = { .WorkFunct = workFunct, .Arg = arg };
272 8 : CHIP_ERROR err = Impl()->PostBackgroundEvent(&event);
273 16 : if (err != CHIP_NO_ERROR)
274 : {
275 0 : ChipLogError(DeviceLayer, "Failed to schedule background work: %" CHIP_ERROR_FORMAT, err.Format());
276 : }
277 8 : return err;
278 : }
279 :
280 : template <class ImplClass>
281 8 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_PostBackgroundEvent(const ChipDeviceEvent * event)
282 : {
283 : // Impl class must override to implement background event processing
284 8 : return Impl()->PostEvent(event);
285 : }
286 :
287 : template <class ImplClass>
288 0 : void GenericPlatformManagerImpl<ImplClass>::_RunBackgroundEventLoop(void)
289 : {
290 : // Impl class must override to implement background event processing
291 0 : }
292 :
293 : template <class ImplClass>
294 0 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_StartBackgroundEventLoopTask(void)
295 : {
296 : // Impl class must override to implement background event processing
297 0 : return CHIP_NO_ERROR;
298 : }
299 :
300 : template <class ImplClass>
301 0 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_StopBackgroundEventLoopTask(void)
302 : {
303 : // Impl class must override to implement background event processing
304 0 : return CHIP_NO_ERROR;
305 : }
306 :
307 : template <class ImplClass>
308 136 : void GenericPlatformManagerImpl<ImplClass>::_DispatchEvent(const ChipDeviceEvent * event)
309 : {
310 : #if (CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0)
311 136 : System::Clock::Timestamp start = System::SystemClock().GetMonotonicTimestamp();
312 : #endif // CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0
313 :
314 136 : switch (event->Type)
315 : {
316 0 : case DeviceEventType::kNoOp:
317 : // Do nothing for no-op events.
318 0 : break;
319 :
320 20 : case DeviceEventType::kChipLambdaEvent:
321 20 : event->LambdaEvent();
322 20 : break;
323 :
324 91 : case DeviceEventType::kCallWorkFunct:
325 : // If the event is a "call work function" event, call the specified function.
326 91 : event->CallWorkFunct.WorkFunct(event->CallWorkFunct.Arg);
327 91 : break;
328 :
329 25 : default:
330 : // For all other events, deliver the event to each of the components in the Device Layer.
331 25 : Impl()->DispatchEventToDeviceLayer(event);
332 :
333 : // If the event is not an internal event, also deliver it to the application's registered
334 : // event handlers.
335 25 : if (!event->IsInternal())
336 : {
337 25 : Impl()->DispatchEventToApplication(event);
338 : }
339 :
340 25 : break;
341 : }
342 :
343 : #if (CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0)
344 136 : uint32_t deltaMs = System::Clock::Milliseconds32(System::SystemClock().GetMonotonicTimestamp() - start).count();
345 136 : if (deltaMs > CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS)
346 : {
347 2 : ChipLogError(DeviceLayer, "Long dispatch time: %" PRIu32 " ms, for event type %d", deltaMs, event->Type);
348 : }
349 : #endif // CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0
350 136 : }
351 :
352 : template <class ImplClass>
353 25 : void GenericPlatformManagerImpl<ImplClass>::DispatchEventToDeviceLayer(const ChipDeviceEvent * event)
354 : {
355 : // Dispatch the event to all the components in the Device Layer.
356 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
357 25 : BLEMgr().OnPlatformEvent(event);
358 : #endif
359 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
360 25 : ThreadStackMgr().OnPlatformEvent(event);
361 : #endif
362 25 : ConnectivityMgr().OnPlatformEvent(event);
363 25 : }
364 :
365 : template <class ImplClass>
366 25 : void GenericPlatformManagerImpl<ImplClass>::DispatchEventToApplication(const ChipDeviceEvent * event)
367 : {
368 : // Dispatch the event to each of the registered application event handlers.
369 48 : for (AppEventHandler * eventHandler = mAppEventHandlerList; eventHandler != nullptr;)
370 : {
371 23 : AppEventHandler * nextEventHandler = eventHandler->Next;
372 23 : eventHandler->Handler(event, eventHandler->Arg);
373 23 : eventHandler = nextEventHandler;
374 : }
375 25 : }
376 :
377 : template <class ImplClass>
378 0 : void GenericPlatformManagerImpl<ImplClass>::HandleMessageLayerActivityChanged(bool messageLayerIsActive)
379 : {
380 0 : GenericPlatformManagerImpl<ImplClass> & self = PlatformMgrImpl();
381 :
382 0 : if (messageLayerIsActive != self.mMsgLayerWasActive)
383 : {
384 0 : self.mMsgLayerWasActive = messageLayerIsActive;
385 : }
386 0 : }
387 :
388 : // Fully instantiate the generic implementation class in whatever compilation unit includes this file.
389 : // NB: This must come after all templated class members are defined.
390 : template class GenericPlatformManagerImpl<PlatformManagerImpl>;
391 :
392 : } // namespace Internal
393 : } // namespace DeviceLayer
394 : } // namespace chip
395 :
396 : #endif // GENERIC_PLATFORM_MANAGER_IMPL_CPP
|