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