1 /*
2 * Copyright (c) 2024, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef OT_GTEST_FAKE_PLATFORM_HPP_
30 #define OT_GTEST_FAKE_PLATFORM_HPP_
31
32 #include "openthread-core-config.h"
33
34 #include <map>
35 #include <vector>
36
37 #include <inttypes.h>
38
39 #include <openthread/error.h>
40 #include <openthread/instance.h>
41 #include <openthread/platform/alarm-micro.h>
42 #include <openthread/platform/alarm-milli.h>
43 #include <openthread/platform/radio.h>
44 #include <openthread/platform/time.h>
45
46 namespace ot {
47
48 class FakePlatform
49 {
50 public:
51 FakePlatform();
52 virtual ~FakePlatform();
53
CurrentPlatform()54 static FakePlatform &CurrentPlatform() { return *sPlatform; }
CurrentInstance()55 static otInstance *CurrentInstance() { return CurrentPlatform().mInstance; }
56
57 /**
58 * Run until something happened or timeout.
59 *
60 * @param aTimeout The timeout in us.
61 *
62 * @returns the remaining timeout.
63 */
64 uint64_t Run(uint64_t aTimeoutInUs = 0);
65
66 void GoInUs(uint64_t aTimeoutInUs = 0);
67
GoInMs(uint32_t aTimeoutInMs=0)68 void GoInMs(uint32_t aTimeoutInMs = 0) { GoInUs(aTimeoutInMs * OT_US_PER_MS); }
69
GetNow() const70 virtual uint64_t GetNow() const { return mNow; }
71
72 virtual void StartMilliAlarm(uint32_t aT0, uint32_t aDt);
73 virtual void StopMilliAlarm();
74 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
75 virtual void StartMicroAlarm(uint32_t aT0, uint32_t aDt);
76 virtual void StopMicroAlarm();
77 #endif
78
GetReceiveChannel(void) const79 uint8_t GetReceiveChannel(void) const { return mChannel; }
GetTransmitBuffer()80 virtual otRadioFrame *GetTransmitBuffer() { return &mTransmitFrame; }
81 virtual otError Transmit(otRadioFrame *aFrame);
ReceiveAt(uint8_t aChannel,uint32_t aStart,uint32_t aDuration)82 virtual otError ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
83 {
84 mReceiveAtChannel = aChannel;
85 mReceiveAtStart = mNow + aStart;
86 mReceiveAtEnd = mReceiveAtStart + aDuration;
87
88 return OT_ERROR_NONE;
89 }
90
Receive(uint8_t aChannel)91 virtual otError Receive(uint8_t aChannel)
92 {
93 mChannel = aChannel;
94 return OT_ERROR_NONE;
95 }
96
97 virtual otError SettingsGet(uint16_t aKey, uint16_t aIndex, uint8_t *aValue, uint16_t *aValueLength) const;
98 virtual otError SettingsSet(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
99 virtual otError SettingsAdd(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
100 virtual otError SettingsDelete(uint16_t aKey, int aIndex);
101 virtual void SettingsWipe();
102
103 virtual void FlashInit();
104 virtual void FlashErase(uint8_t aSwapIndex);
105 virtual void FlashRead(uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize) const;
106 virtual void FlashWrite(uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize);
FlashGetSwapSize() const107 virtual uint32_t FlashGetSwapSize() const { return kFlashSwapSize; }
108
GetEui64() const109 virtual uint64_t GetEui64() const { return 0; }
110
111 protected:
112 void ProcessSchedules(uint64_t &aTimeout);
113
114 static constexpr uint64_t kAlarmStop = 0xffffffffffffffffUL;
115
116 static constexpr uint32_t kFlashSwapSize = 2048;
117 static constexpr uint32_t kFlashSwapNum = 2;
118
119 static FakePlatform *sPlatform;
120
121 otInstance *mInstance = nullptr;
122
123 uint64_t mNow = 0;
124 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
125 uint64_t mMicroAlarmStart = kAlarmStop;
126 #endif
127 uint64_t mMilliAlarmStart = kAlarmStop;
128
129 uint64_t mReceiveAtStart = kAlarmStop;
130 uint64_t mReceiveAtEnd = kAlarmStop;
131
132 template <uint64_t FakePlatform::*T> void HandleSchedule();
133
134 otRadioFrame mTransmitFrame;
135 uint8_t mTransmitBuffer[OT_RADIO_FRAME_MAX_SIZE];
136 uint8_t mChannel = 0;
137 uint8_t mReceiveAtChannel = 0;
138
139 uint8_t mFlash[kFlashSwapSize * kFlashSwapNum];
140
141 std::map<uint32_t, std::vector<std::vector<uint8_t>>> mSettings;
142 };
143
HandleSchedule()144 template <> inline void FakePlatform::HandleSchedule<&FakePlatform::mMilliAlarmStart>()
145 {
146 otPlatAlarmMilliFired(mInstance);
147 }
148
149 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
HandleSchedule()150 template <> inline void FakePlatform::HandleSchedule<&FakePlatform::mMicroAlarmStart>()
151 {
152 otPlatAlarmMicroFired(mInstance);
153 }
154 #endif
155
156 } // namespace ot
157
158 #endif // OT_GTEST_FAKE_PLATFORM_HPP_
159