Line data Source code
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 : #include <system/SystemConfig.h>
20 :
21 : /**
22 : * @file
23 : * Implementation of the fault-injection utilities for CHIP System Layer.
24 : */
25 : /* module header, also carries config, comes first */
26 : #include <system/SystemFaultInjection.h>
27 :
28 : #include <string.h>
29 :
30 : namespace chip {
31 : namespace System {
32 : namespace FaultInjection {
33 :
34 : using nl::FaultInjection::Manager;
35 : using nl::FaultInjection::Name;
36 : using nl::FaultInjection::Record;
37 :
38 : static Record sFaultRecordArray[kFault_NumberOfFaultIdentifiers];
39 : static Manager sManager;
40 : static int32_t sFault_AsyncEvent_Arguments[1];
41 : static const Name sManagerName = "CHIPSys";
42 : static const Name sFaultNames[] = {
43 : "PacketBufferNew",
44 : "TimeoutImmediate",
45 : "AsyncEvent",
46 : };
47 :
48 : static int32_t (*sGetNumEventsAvailable)();
49 : static void (*sInjectAsyncEvent)(int32_t index);
50 :
51 6680109 : Manager & GetManager()
52 : {
53 6680109 : if (0 == sManager.GetNumFaults())
54 : {
55 65 : sManager.Init(kFault_NumberOfFaultIdentifiers, sFaultRecordArray, sManagerName, sFaultNames);
56 :
57 : memset(&sFault_AsyncEvent_Arguments, 0, sizeof(sFault_AsyncEvent_Arguments));
58 65 : sFaultRecordArray[kFault_AsyncEvent].mArguments = sFault_AsyncEvent_Arguments;
59 65 : sFaultRecordArray[kFault_AsyncEvent].mLengthOfArguments =
60 : static_cast<uint16_t>(sizeof(sFault_AsyncEvent_Arguments) / sizeof(sFault_AsyncEvent_Arguments[0]));
61 : }
62 :
63 6680109 : return sManager;
64 : }
65 :
66 51 : void InjectAsyncEvent()
67 : {
68 51 : int32_t numEventsAvailable = 0;
69 51 : chip::System::FaultInjection::Id faultID = kFault_AsyncEvent;
70 :
71 51 : if (sGetNumEventsAvailable)
72 : {
73 0 : numEventsAvailable = sGetNumEventsAvailable();
74 :
75 0 : if (numEventsAvailable)
76 : {
77 0 : FaultInjection::Manager & mgr = chip::System::FaultInjection::GetManager();
78 0 : const FaultInjection::Record * record = &(mgr.GetFaultRecords()[faultID]);
79 :
80 0 : if (record->mNumArguments == 0)
81 : {
82 0 : int32_t maxEventIndex = numEventsAvailable - 1;
83 :
84 0 : mgr.StoreArgsAtFault(faultID, 1, &maxEventIndex);
85 : }
86 :
87 0 : nlFAULT_INJECT_WITH_ARGS(
88 : mgr, faultID,
89 : // Code executed with the Manager's lock:
90 : int32_t index = 0;
91 : if (numFaultArgs > 0) { index = faultArgs[0]; },
92 : // Code executed without the Manager's lock:
93 : if (sInjectAsyncEvent) { sInjectAsyncEvent(index); });
94 : }
95 : }
96 51 : }
97 :
98 0 : void SetAsyncEventCallbacks(int32_t (*aGetNumEventsAvailable)(), void (*aInjectAsyncEvent)(int32_t index))
99 : {
100 0 : sGetNumEventsAvailable = aGetNumEventsAvailable;
101 0 : sInjectAsyncEvent = aInjectAsyncEvent;
102 0 : }
103 :
104 : } // namespace FaultInjection
105 : } // namespace System
106 : } // namespace chip
|