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