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 59 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_InitChipStack()
51 : {
52 : CHIP_ERROR err;
53 :
54 59 : mMsgLayerWasActive = false;
55 :
56 : // Arrange for CHIP core errors to be translated to text
57 59 : RegisterCHIPLayerErrorFormatter();
58 :
59 : // Arrange for Device Layer errors to be translated to text.
60 59 : RegisterDeviceLayerErrorFormatter();
61 :
62 59 : err = InitEntropy();
63 118 : if (err != CHIP_NO_ERROR)
64 : {
65 0 : ChipLogError(DeviceLayer, "Entropy initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
66 : }
67 59 : SuccessOrExit(err);
68 :
69 : // Initialize the CHIP system layer.
70 59 : err = SystemLayer().Init();
71 118 : if (err != CHIP_NO_ERROR)
72 : {
73 0 : ChipLogError(DeviceLayer, "SystemLayer initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
74 : }
75 59 : SuccessOrExit(err);
76 :
77 : // Initialize the Configuration Manager.
78 59 : err = ConfigurationMgr().Init();
79 118 : if (err != CHIP_NO_ERROR)
80 : {
81 0 : ChipLogError(DeviceLayer, "Configuration Manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
82 : }
83 59 : SuccessOrExit(err);
84 :
85 : // Initialize the CHIP UDP layer.
86 59 : err = UDPEndPointManager()->Init(SystemLayer());
87 118 : if (err != CHIP_NO_ERROR)
88 : {
89 0 : ChipLogError(DeviceLayer, "UDP initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
90 : }
91 59 : SuccessOrExit(err);
92 :
93 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
94 : // Initialize the CHIP TCP layer.
95 59 : err = TCPEndPointManager()->Init(SystemLayer());
96 118 : if (err != CHIP_NO_ERROR)
97 : {
98 0 : ChipLogError(DeviceLayer, "TCP initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
99 : }
100 59 : 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 59 : err = BLEMgr().Init();
108 118 : if (err != CHIP_NO_ERROR)
109 : {
110 0 : ChipLogError(DeviceLayer, "BLEManager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
111 : }
112 59 : SuccessOrExit(err);
113 : #endif
114 :
115 : // Initialize the Connectivity Manager object.
116 59 : err = ConnectivityMgr().Init();
117 118 : if (err != CHIP_NO_ERROR)
118 : {
119 0 : ChipLogError(DeviceLayer, "Connectivity Manager initialization failed: %" CHIP_ERROR_FORMAT, err.Format());
120 : }
121 59 : 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 59 : SuccessOrExit(err);
146 :
147 59 : exit:
148 59 : return err;
149 : }
150 :
151 : template <class ImplClass>
152 59 : void GenericPlatformManagerImpl<ImplClass>::_Shutdown()
153 : {
154 59 : ChipLogProgress(DeviceLayer, "Inet Layer shutdown");
155 59 : UDPEndPointManager()->Shutdown();
156 :
157 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
158 59 : TCPEndPointManager()->Shutdown();
159 : #endif
160 :
161 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
162 59 : ChipLogProgress(DeviceLayer, "BLE Layer shutdown");
163 59 : BLEMgr().Shutdown();
164 : #endif
165 :
166 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
167 59 : ChipLogProgress(DeviceLayer, "WiFi-PAF Layer shutdown");
168 59 : 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 59 : ChipLogProgress(DeviceLayer, "System Layer shutdown");
177 59 : SystemLayer().Shutdown();
178 59 : }
179 :
180 : template <class ImplClass>
181 67 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_AddEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
182 : {
183 67 : CHIP_ERROR err = CHIP_NO_ERROR;
184 : AppEventHandler * eventHandler;
185 :
186 : // Do nothing if the event handler is already registered.
187 97 : for (eventHandler = mAppEventHandlerList; eventHandler != nullptr; eventHandler = eventHandler->Next)
188 : {
189 54 : if (eventHandler->Handler == handler && eventHandler->Arg == arg)
190 : {
191 24 : ExitNow();
192 : }
193 : }
194 :
195 43 : eventHandler = (AppEventHandler *) chip::Platform::MemoryAlloc(sizeof(AppEventHandler));
196 43 : VerifyOrExit(eventHandler != nullptr, err = CHIP_ERROR_NO_MEMORY);
197 :
198 43 : eventHandler->Next = mAppEventHandlerList;
199 43 : eventHandler->Handler = handler;
200 43 : eventHandler->Arg = arg;
201 :
202 43 : mAppEventHandlerList = eventHandler;
203 :
204 67 : exit:
205 67 : return err;
206 : }
207 :
208 : template <class ImplClass>
209 42 : void GenericPlatformManagerImpl<ImplClass>::_RemoveEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg)
210 : {
211 : AppEventHandler ** eventHandlerIndirectPtr;
212 :
213 88 : for (eventHandlerIndirectPtr = &mAppEventHandlerList; *eventHandlerIndirectPtr != nullptr;)
214 : {
215 46 : AppEventHandler * eventHandler = (*eventHandlerIndirectPtr);
216 :
217 46 : if (eventHandler->Handler == handler && eventHandler->Arg == arg)
218 : {
219 41 : *eventHandlerIndirectPtr = eventHandler->Next;
220 41 : chip::Platform::MemoryFree(eventHandler);
221 : }
222 : else
223 : {
224 5 : eventHandlerIndirectPtr = &eventHandler->Next;
225 : }
226 : }
227 42 : }
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 90 : CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
256 : {
257 90 : ChipDeviceEvent event{ .Type = DeviceEventType::kCallWorkFunct };
258 90 : event.CallWorkFunct = { .WorkFunct = workFunct, .Arg = arg };
259 90 : CHIP_ERROR err = Impl()->PostEvent(&event);
260 180 : if (err != CHIP_NO_ERROR)
261 : {
262 0 : ChipLogError(DeviceLayer, "Failed to schedule work: %" CHIP_ERROR_FORMAT, err.Format());
263 : }
264 90 : 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 149 : void GenericPlatformManagerImpl<ImplClass>::_DispatchEvent(const ChipDeviceEvent * event)
309 : {
310 : #if (CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0)
311 149 : System::Clock::Timestamp start = System::SystemClock().GetMonotonicTimestamp();
312 : #endif // CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0
313 :
314 149 : switch (event->Type)
315 : {
316 0 : case DeviceEventType::kNoOp:
317 : // Do nothing for no-op events.
318 0 : break;
319 :
320 24 : case DeviceEventType::kChipLambdaEvent:
321 24 : event->LambdaEvent();
322 24 : break;
323 :
324 98 : case DeviceEventType::kCallWorkFunct:
325 : // If the event is a "call work function" event, call the specified function.
326 98 : event->CallWorkFunct.WorkFunct(event->CallWorkFunct.Arg);
327 98 : break;
328 :
329 27 : default:
330 : // For all other events, deliver the event to each of the components in the Device Layer.
331 27 : 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 27 : if (!event->IsInternal())
336 : {
337 27 : Impl()->DispatchEventToApplication(event);
338 : }
339 :
340 27 : break;
341 : }
342 :
343 : #if (CHIP_DISPATCH_EVENT_LONG_DISPATCH_TIME_WARNING_THRESHOLD_MS != 0)
344 149 : uint32_t deltaMs = System::Clock::Milliseconds32(System::SystemClock().GetMonotonicTimestamp() - start).count();
345 149 : 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 149 : }
351 :
352 : template <class ImplClass>
353 27 : 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 27 : BLEMgr().OnPlatformEvent(event);
358 : #endif
359 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
360 27 : ThreadStackMgr().OnPlatformEvent(event);
361 : #endif
362 27 : ConnectivityMgr().OnPlatformEvent(event);
363 27 : }
364 :
365 : template <class ImplClass>
366 27 : void GenericPlatformManagerImpl<ImplClass>::DispatchEventToApplication(const ChipDeviceEvent * event)
367 : {
368 : // Dispatch the event to each of the registered application event handlers.
369 51 : for (AppEventHandler * eventHandler = mAppEventHandlerList; eventHandler != nullptr;)
370 : {
371 24 : AppEventHandler * nextEventHandler = eventHandler->Next;
372 24 : eventHandler->Handler(event, eventHandler->Arg);
373 24 : eventHandler = nextEventHandler;
374 : }
375 27 : }
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
|