mirror of
https://github.com/espressif/openthread.git
synced 2026-10-04 23:07:37 +00:00
`RestoreProperties()` re-applies the max power table behind `#if
OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE`, but
`radio_spinel.cpp` never sees that macro. It is a POSIX macro, and
this is a platform-agnostic library whose only project config hook is
OPENTHREAD_PROJECT_LIB_CONFIG_FILE, from `OT_LIB_CONFIG`, which is not
set anywhere. `-DOT_POSIX_MAX_POWER_TABLE=ON` puts the definition on
`ot-posix-config`, which only `openthread-posix` links.
So the block is compiled out everywhere, including in
`script/cmake-build posix` and `script/check-posix-pty`, which passes
`max-power-table` in its radio URL. The values are applied at startup
and silently lost on the next RCP reset.
Dropping the guard exposes a second problem. An RCP without
`SPINEL_PROP_PHY_CHAN_MAX_POWER` answers
`SPINEL_STATUS_PROP_NOT_FOUND`, which `spinel_status_to_ot_error()`
maps to `OT_ERROR_NOT_IMPLEMENTED` -- not the `OT_ERROR_NOT_FOUND` the
code tolerates. Every RCP reset would then be fatal. The loop now
warns once, clears `mMaxPowerTableSet` and stops, so a refusing RCP is
not asked again on later recoveries either.
That flag also guards the loop, following the `mTransmitPowerSet` and
`mCcaEnergyDetectThresholdSet` flags beside it, and is set only after
`Set()` succeeds. The loop calls `Set()` directly rather than
`SetChannelMaxTransmitPower()`, as the other restores here do: the
channel range was already checked when the value was configured, and
writing the value back into the table it was just read from would be
circular now that the setter also raises the flag. `MaxPowerTable`
initialises every channel to `kPowerDefault`, so without it the loop
would issue 16 blocking transactions on every restore for everyone,
including those who never pass `max-power-table`. Comparing against
`kPowerDefault` instead would have been cheaper but not equivalent: it
cannot tell an unconfigured channel from one deliberately set to 30
dBm.
With the macro no longer used outside the POSIX platform, enabling it by
default there makes `max-power-table` reachable, like `cca-threshold` and
`fem-lnagain` already are.
Three gtest cases cover it. The fake platform has to implement
`otPlatRadioSetChannelMaxTransmitPower` for them: the weak default in
`radio_platform.cpp` reports `kErrorNotImplemented`, so without an
implementation a test cannot tell a correct restore from one that
never arrived.
shouldRestoreEachChannelWithItsOwnPower three channels, distinct
powers, asserted per channel
after a restore
shouldNotTouchTheRcpWhenNoChannelWasConfigured pins the flag
shouldSurviveAnRcpThatDoesNotImplementIt refusing RCP, must not abort
and must not retry
The first and third fail without the corresponding fix; the second
passes either way, because the removed guard takes the same loop with
it.
Also measured against a simulated RCP behind a socat PTY, with an RCP
reset forced by freezing the RCP process, using
`SPINEL_PROP_MAC_15_4_PANID` as the control for whether a restore ran
at all:
config startup control restored alive
before 16 10x 0 yes
after 16 10x 80 yes
after, no max-power-table in the URL 0 10x 0 yes
old error handling, block on, old RCP 0 6x 0 NO
after, old RCP 0 10x 0 yes
old error handling, block on, capable RCP 16 10x 80 yes
Built and tested with OT_RCP_RESTORATION_MAX_COUNT at both 0 and 2.
690 lines
22 KiB
C++
690 lines
22 KiB
C++
/*
|
|
* Copyright (c) 2024, The OpenThread Authors.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the copyright holder nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "fake_platform.hpp"
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <openthread/error.h>
|
|
#include <openthread/instance.h>
|
|
#include <openthread/tasklet.h>
|
|
#include <openthread/tcat.h>
|
|
#include <openthread/platform/ble.h>
|
|
#include <openthread/platform/diag.h>
|
|
#include <openthread/platform/dnssd.h>
|
|
#include <openthread/platform/dso_transport.h>
|
|
#include <openthread/platform/entropy.h>
|
|
#include <openthread/platform/logging.h>
|
|
#include <openthread/platform/misc.h>
|
|
#include <openthread/platform/toolchain.h>
|
|
#include <openthread/platform/trel.h>
|
|
#include <openthread/platform/udp.h>
|
|
|
|
using namespace ot;
|
|
|
|
bool operator<(const otExtAddress &aLeft, const otExtAddress &aRight)
|
|
{
|
|
return memcmp(&aLeft, &aRight, sizeof(aLeft)) < 0;
|
|
}
|
|
|
|
namespace ot {
|
|
|
|
FakePlatform *FakePlatform::sPlatform = nullptr;
|
|
|
|
FakePlatform::FakePlatform()
|
|
{
|
|
assert(sPlatform == nullptr);
|
|
sPlatform = this;
|
|
|
|
fprintf(stderr, "fake platform start\r\n");
|
|
mTransmitFrame.mPsdu = mTransmitBuffer;
|
|
|
|
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
|
|
#if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
|
|
mInstance = otInstanceInitMultiple(0);
|
|
#else
|
|
{
|
|
size_t instanceBufferLength = 0;
|
|
void *instanceBuffer = nullptr;
|
|
|
|
otInstanceInit(nullptr, &instanceBufferLength);
|
|
|
|
instanceBuffer = malloc(instanceBufferLength);
|
|
assert(instanceBuffer != nullptr);
|
|
memset(instanceBuffer, 0, instanceBufferLength);
|
|
|
|
mInstance = otInstanceInit(instanceBuffer, &instanceBufferLength);
|
|
}
|
|
#endif
|
|
#else
|
|
mInstance = otInstanceInitSingle();
|
|
#endif
|
|
}
|
|
|
|
FakePlatform::~FakePlatform()
|
|
{
|
|
otInstanceFinalize(mInstance);
|
|
sPlatform = nullptr;
|
|
}
|
|
|
|
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
|
void FakePlatform::StartMicroAlarm(uint32_t aT0, uint32_t aDt)
|
|
{
|
|
uint64_t start = mNow;
|
|
uint32_t now = mNow;
|
|
|
|
if (static_cast<int32_t>(aT0 - now) > 0 || static_cast<int32_t>(aT0 - now) + static_cast<int64_t>(aDt) > 0)
|
|
{
|
|
start += static_cast<uint64_t>(aDt) + static_cast<int32_t>(aT0 - now);
|
|
}
|
|
|
|
mMicroAlarmStart = start;
|
|
}
|
|
|
|
void FakePlatform::StopMicroAlarm() { mMicroAlarmStart = kAlarmStop; }
|
|
#endif
|
|
|
|
void FakePlatform::StartMilliAlarm(uint32_t aT0, uint32_t aDt)
|
|
{
|
|
uint64_t start = mNow - (mNow % OT_US_PER_MS);
|
|
uint32_t now = (mNow / OT_US_PER_MS);
|
|
|
|
if (static_cast<int32_t>(aT0 - now) > 0 || static_cast<int32_t>(aT0 - now) + static_cast<int64_t>(aDt) > 0)
|
|
{
|
|
start += (static_cast<uint64_t>(aDt) + static_cast<int32_t>(aT0 - now)) * OT_US_PER_MS;
|
|
}
|
|
|
|
mMilliAlarmStart = start;
|
|
}
|
|
|
|
void FakePlatform::StopMilliAlarm() { mMilliAlarmStart = kAlarmStop; }
|
|
|
|
template <> void FakePlatform::HandleSchedule<&FakePlatform::mReceiveAtStart>() { mChannel = mReceiveAtChannel; }
|
|
|
|
template <> void FakePlatform::HandleSchedule<&FakePlatform::mReceiveAtEnd>() { mChannel = 0; }
|
|
|
|
void FakePlatform::ProcessSchedules(uint64_t &aTimeout)
|
|
{
|
|
uint64_t guard = mNow + aTimeout;
|
|
|
|
uint64_t *alarm = &guard;
|
|
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
|
if (mMicroAlarmStart < *alarm)
|
|
{
|
|
alarm = &mMicroAlarmStart;
|
|
}
|
|
#endif
|
|
if (mMilliAlarmStart < *alarm)
|
|
{
|
|
alarm = &mMilliAlarmStart;
|
|
}
|
|
if (mReceiveAtStart < *alarm)
|
|
{
|
|
alarm = &mReceiveAtStart;
|
|
}
|
|
else if (mReceiveAtEnd < *alarm)
|
|
{
|
|
alarm = &mReceiveAtEnd;
|
|
}
|
|
|
|
if (mNow < *alarm)
|
|
{
|
|
aTimeout -= *alarm - mNow;
|
|
mNow = *alarm;
|
|
}
|
|
*alarm = kAlarmStop;
|
|
|
|
if (alarm == &guard)
|
|
{
|
|
// nothing scheduled within this period.
|
|
}
|
|
else if (alarm == &mReceiveAtEnd)
|
|
{
|
|
FakePlatform::HandleSchedule<&FakePlatform::mReceiveAtEnd>();
|
|
}
|
|
else if (alarm == &mReceiveAtStart)
|
|
{
|
|
FakePlatform::HandleSchedule<&FakePlatform::mReceiveAtStart>();
|
|
}
|
|
else if (alarm == &mMilliAlarmStart)
|
|
{
|
|
FakePlatform::HandleSchedule<&FakePlatform::mMilliAlarmStart>();
|
|
}
|
|
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
|
else if (alarm == &mMicroAlarmStart)
|
|
{
|
|
FakePlatform::HandleSchedule<&FakePlatform::mMicroAlarmStart>();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
uint64_t FakePlatform::Run(uint64_t aTimeoutInUs)
|
|
{
|
|
if (otTaskletsArePending(mInstance))
|
|
{
|
|
otTaskletsProcess(mInstance);
|
|
}
|
|
else
|
|
{
|
|
ProcessSchedules(aTimeoutInUs);
|
|
}
|
|
|
|
return aTimeoutInUs;
|
|
}
|
|
|
|
void FakePlatform::GoInUs(uint64_t aTimeoutInUs)
|
|
{
|
|
while ((aTimeoutInUs = Run(aTimeoutInUs)) > 0)
|
|
{
|
|
// nothing
|
|
}
|
|
}
|
|
|
|
otError FakePlatform::Transmit(otRadioFrame *aFrame)
|
|
{
|
|
otPlatRadioTxStarted(mInstance, aFrame);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError FakePlatform::SettingsGet(uint16_t aKey, uint16_t aIndex, uint8_t *aValue, uint16_t *aValueLength) const
|
|
{
|
|
auto setting = mSettings.find(aKey);
|
|
|
|
if (setting == mSettings.end())
|
|
{
|
|
return OT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
if (aIndex >= setting->second.size())
|
|
{
|
|
return OT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
if (aValueLength == nullptr)
|
|
{
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
const auto &data = setting->second[aIndex];
|
|
|
|
if (aValue == nullptr)
|
|
{
|
|
*aValueLength = data.size();
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
if (*aValueLength >= data.size())
|
|
{
|
|
*aValueLength = data.size();
|
|
}
|
|
|
|
memcpy(aValue, &data[0], *aValueLength);
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError FakePlatform::SettingsSet(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
|
{
|
|
auto setting = std::vector<uint8_t>(aValue, aValue + aValueLength);
|
|
|
|
mSettings[aKey].clear();
|
|
mSettings[aKey].push_back(setting);
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError FakePlatform::SettingsAdd(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
|
{
|
|
auto setting = std::vector<uint8_t>(aValue, aValue + aValueLength);
|
|
|
|
mSettings[aKey].push_back(setting);
|
|
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError FakePlatform::SettingsDelete(uint16_t aKey, int aIndex)
|
|
{
|
|
auto setting = mSettings.find(aKey);
|
|
if (setting == mSettings.end())
|
|
{
|
|
return OT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
if (aIndex == -1)
|
|
{
|
|
mSettings.erase(setting);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
if (aIndex < 0 || static_cast<std::size_t>(aIndex) >= setting->second.size())
|
|
{
|
|
return OT_ERROR_NOT_FOUND;
|
|
}
|
|
setting->second.erase(setting->second.begin() + aIndex);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
void FakePlatform::SettingsWipe() { mSettings.clear(); }
|
|
|
|
void FakePlatform::FlashInit() { memset(mFlash, 0xff, sizeof(mFlash)); }
|
|
void FakePlatform::FlashErase(uint8_t aSwapIndex)
|
|
{
|
|
uint32_t address;
|
|
|
|
assert(aSwapIndex < kFlashSwapNum);
|
|
|
|
address = aSwapIndex ? kFlashSwapSize : 0;
|
|
|
|
memset(mFlash + address, 0xff, kFlashSwapSize);
|
|
}
|
|
|
|
void FakePlatform::FlashRead(uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize) const
|
|
{
|
|
uint32_t address;
|
|
|
|
assert(aSwapIndex < kFlashSwapNum);
|
|
assert(aSize <= kFlashSwapSize);
|
|
assert(aOffset <= (kFlashSwapSize - aSize));
|
|
|
|
address = aSwapIndex ? kFlashSwapSize : 0;
|
|
|
|
memcpy(aData, mFlash + address + aOffset, aSize);
|
|
}
|
|
|
|
void FakePlatform::FlashWrite(uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
|
|
{
|
|
uint32_t address;
|
|
|
|
assert(aSwapIndex < kFlashSwapNum);
|
|
assert(aSize <= kFlashSwapSize);
|
|
assert(aOffset <= (kFlashSwapSize - aSize));
|
|
|
|
address = aSwapIndex ? kFlashSwapSize : 0;
|
|
|
|
for (uint32_t index = 0; index < aSize; index++)
|
|
{
|
|
mFlash[address + aOffset + index] &= static_cast<const uint8_t *>(aData)[index];
|
|
}
|
|
}
|
|
|
|
} // namespace ot
|
|
|
|
extern "C" {
|
|
|
|
void otTaskletsSignalPending(otInstance *) {}
|
|
|
|
void otPlatAlarmMilliStop(otInstance *) { FakePlatform::CurrentPlatform().StopMilliAlarm(); }
|
|
|
|
void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
|
|
{
|
|
FakePlatform::CurrentPlatform().StartMilliAlarm(aT0, aDt);
|
|
}
|
|
|
|
uint32_t otPlatAlarmMilliGetNow(void) { return FakePlatform::CurrentPlatform().GetNow() / OT_US_PER_MS; }
|
|
|
|
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
|
void otPlatAlarmMicroStop(otInstance *) { FakePlatform::CurrentPlatform().StopMicroAlarm(); }
|
|
void otPlatAlarmMicroStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
|
|
{
|
|
FakePlatform::CurrentPlatform().StartMicroAlarm(aT0, aDt);
|
|
}
|
|
#endif
|
|
|
|
uint64_t otPlatTimeGet(void) { return FakePlatform::CurrentPlatform().GetNow(); }
|
|
uint16_t otPlatTimeGetXtalAccuracy(void) { return 0; }
|
|
|
|
uint32_t otPlatAlarmMicroGetNow(void) { return otPlatTimeGet(); }
|
|
|
|
void otPlatRadioGetIeeeEui64(otInstance *, uint8_t *aIeeeEui64)
|
|
{
|
|
uint64_t eui64 = FakePlatform::CurrentPlatform().GetEui64();
|
|
memcpy(aIeeeEui64, &eui64, sizeof(eui64));
|
|
}
|
|
|
|
void otPlatRadioSetPanId(otInstance *, uint16_t) {}
|
|
|
|
void otPlatRadioSetExtendedAddress(otInstance *, const otExtAddress *) {}
|
|
|
|
void otPlatRadioSetShortAddress(otInstance *, uint16_t) {}
|
|
|
|
void otPlatRadioSetPromiscuous(otInstance *, bool) {}
|
|
|
|
void otPlatRadioSetRxOnWhenIdle(otInstance *, bool) {}
|
|
|
|
bool otPlatRadioIsEnabled(otInstance *) { return true; }
|
|
|
|
otError otPlatRadioEnable(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioDisable(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioSleep(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioReceive(otInstance *, uint8_t aChannel) { return FakePlatform::CurrentPlatform().Receive(aChannel); }
|
|
|
|
otError otPlatRadioReceiveAt(otInstance *, uint8_t aChannel, otRadioTime32 aStart, uint32_t aDuration)
|
|
{
|
|
return FakePlatform::CurrentPlatform().ReceiveAt(aChannel, aStart, aDuration);
|
|
}
|
|
|
|
otError otPlatRadioTransmit(otInstance *, otRadioFrame *aFrame)
|
|
{
|
|
return FakePlatform::CurrentPlatform().Transmit(aFrame);
|
|
}
|
|
|
|
otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return FakePlatform::CurrentPlatform().GetTransmitBuffer(); }
|
|
|
|
int8_t otPlatRadioGetRssi(otInstance *) { return 0; }
|
|
|
|
otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_NONE; }
|
|
|
|
bool otPlatRadioGetPromiscuous(otInstance *) { return false; }
|
|
|
|
void otPlatRadioEnableSrcMatch(otInstance *, bool aEnabled)
|
|
{
|
|
FakePlatform::CurrentPlatform().SrcMatchEnable(aEnabled);
|
|
}
|
|
|
|
// Overrides the weak default in radio_platform.cpp, which reports
|
|
// `kErrorNotImplemented`. Without this the fake RCP cannot accept a max power
|
|
// table at all, so a test could not tell a correct restore from a missing one.
|
|
otError otPlatRadioSetChannelMaxTransmitPower(otInstance *, uint8_t aChannel, int8_t aMaxPower)
|
|
{
|
|
return FakePlatform::CurrentPlatform().ChannelMaxTxPowerSet(aChannel, aMaxPower);
|
|
}
|
|
|
|
otError otPlatRadioAddSrcMatchShortEntry(otInstance *, uint16_t aShortAddr)
|
|
{
|
|
FakePlatform::CurrentPlatform().SrcMatchAddShortEntry(aShortAddr);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError otPlatRadioAddSrcMatchExtEntry(otInstance *, const otExtAddress *aExtAddr)
|
|
{
|
|
FakePlatform::CurrentPlatform().SrcMatchAddExtEntry(*aExtAddr);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError otPlatRadioClearSrcMatchShortEntry(otInstance *, uint16_t aShortAddr)
|
|
{
|
|
FakePlatform::CurrentPlatform().SrcMatchClearShortEntry(aShortAddr);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
otError otPlatRadioClearSrcMatchExtEntry(otInstance *, const otExtAddress *aExtAddr)
|
|
{
|
|
FakePlatform::CurrentPlatform().SrcMatchClearExtEntry(*aExtAddr);
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
void otPlatRadioClearSrcMatchShortEntries(otInstance *) { FakePlatform::CurrentPlatform().SrcMatchClearShortEntries(); }
|
|
|
|
void otPlatRadioClearSrcMatchExtEntries(otInstance *) { FakePlatform::CurrentPlatform().SrcMatchClearExtEntries(); }
|
|
|
|
otError otPlatRadioEnergyScan(otInstance *, uint8_t, uint16_t) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
otError otPlatRadioSetTransmitPower(otInstance *, int8_t) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
int8_t otPlatRadioGetReceiveSensitivity(otInstance *) { return -100; }
|
|
|
|
otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *, int8_t) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *, int8_t *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioGetCoexMetrics(otInstance *, otRadioCoexMetrics *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatRadioGetTransmitPower(otInstance *, int8_t *) { return OT_ERROR_NONE; }
|
|
|
|
bool otPlatRadioIsCoexEnabled(otInstance *) { return true; }
|
|
|
|
otError otPlatRadioSetCoexEnabled(otInstance *, bool) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
otError otPlatRadioConfigureEnhAckProbing(otInstance *, otLinkMetrics, otShortAddress, const otExtAddress *)
|
|
{
|
|
return OT_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
// Add WEAK here because in some unit test there is an implementation for `otPlatRadioSetChannelTargetPower`
|
|
OT_TOOL_WEAK otError otPlatRadioSetChannelTargetPower(otInstance *, uint8_t, int16_t) { return OT_ERROR_NONE; }
|
|
|
|
void otPlatReset(otInstance *) {}
|
|
|
|
otPlatResetReason otPlatGetResetReason(otInstance *) { return OT_PLAT_RESET_REASON_POWER_ON; }
|
|
|
|
void otPlatWakeHost(void) {}
|
|
|
|
otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
|
|
assert(aOutput != nullptr);
|
|
|
|
for (uint16_t length = 0; length < aOutputLength; length++)
|
|
{
|
|
aOutput[length] = static_cast<uint8_t>(rand());
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
void otPlatDiagSetOutputCallback(otInstance *, otPlatDiagOutputCallback, void *) {}
|
|
|
|
void otPlatDiagModeSet(bool) {}
|
|
|
|
bool otPlatDiagModeGet() { return false; }
|
|
|
|
void otPlatDiagChannelSet(uint8_t) {}
|
|
|
|
void otPlatDiagTxPowerSet(int8_t) {}
|
|
|
|
void otPlatDiagRadioReceived(otInstance *, otRadioFrame *, otError) {}
|
|
|
|
void otPlatDiagAlarmCallback(otInstance *) {}
|
|
|
|
OT_TOOL_WEAK void otPlatLogOutput(otInstance *, otLogLevel, const char *) {}
|
|
|
|
OT_TOOL_WEAK void otPlatLog(otLogLevel, otLogRegion, const char *, ...) {}
|
|
|
|
void *otPlatCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
|
|
|
|
void otPlatFree(void *aPtr) { free(aPtr); }
|
|
|
|
bool otPlatInfraIfHasAddress(otInstance *, uint32_t, const otIp6Address *) { return false; }
|
|
|
|
otError otPlatInfraIfSendIcmp6Nd(otInstance *, uint32_t, const otIp6Address *, const uint8_t *, uint16_t)
|
|
{
|
|
return OT_ERROR_FAILED;
|
|
}
|
|
|
|
otError otPlatInfraIfDiscoverNat64Prefix(otInstance *, uint32_t) { return OT_ERROR_FAILED; }
|
|
|
|
void otPlatDsoEnableListening(otInstance *, bool) {}
|
|
|
|
void otPlatDsoConnect(otPlatDsoConnection *, const otSockAddr *) {}
|
|
|
|
void otPlatDsoSend(otPlatDsoConnection *, otMessage *) {}
|
|
|
|
void otPlatDsoDisconnect(otPlatDsoConnection *, otPlatDsoDisconnectMode) {}
|
|
|
|
otError otPlatBleEnable(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleDisable(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGetAdvertisementBuffer(otInstance *, uint8_t **) { return OT_ERROR_NO_BUFS; }
|
|
|
|
otError otPlatBleGapAdvStart(otInstance *, uint16_t) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGapAdvStop(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGapDisconnect(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGattMtuGet(otInstance *, uint16_t *) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGattServerIndicate(otInstance *, uint16_t, const otBleRadioPacket *) { return OT_ERROR_NONE; }
|
|
|
|
void otPlatBleGetLinkCapabilities(otInstance *, otBleLinkCapabilities *) {}
|
|
|
|
bool otPlatBleSupportsMultiRadio(otInstance *) { return false; }
|
|
|
|
otError otPlatBleGapAdvSetData(otInstance *, uint8_t *, uint16_t) { return OT_ERROR_NONE; }
|
|
|
|
otError otPlatBleGapAdvUpdateData(otInstance *, uint8_t *, uint16_t) { return OT_ERROR_NONE; }
|
|
|
|
OT_TOOL_WEAK otError otPlatRadioAddCalibratedPower(otInstance *, uint8_t, int16_t, const uint8_t *, uint16_t)
|
|
{
|
|
return OT_ERROR_NONE;
|
|
}
|
|
|
|
OT_TOOL_WEAK otError otPlatRadioClearCalibratedPowers(otInstance *) { return OT_ERROR_NONE; }
|
|
|
|
void otPlatSettingsInit(otInstance *, const uint16_t *, uint16_t) {}
|
|
|
|
void otPlatSettingsDeinit(otInstance *) {}
|
|
|
|
otError otPlatSettingsGet(otInstance *, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
|
|
{
|
|
return FakePlatform::CurrentPlatform().SettingsGet(aKey, aIndex, aValue, aValueLength);
|
|
}
|
|
|
|
otError otPlatSettingsSet(otInstance *, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
|
{
|
|
return FakePlatform::CurrentPlatform().SettingsSet(aKey, aValue, aValueLength);
|
|
}
|
|
|
|
otError otPlatSettingsAdd(otInstance *, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
|
{
|
|
return FakePlatform::CurrentPlatform().SettingsAdd(aKey, aValue, aValueLength);
|
|
}
|
|
|
|
otError otPlatSettingsDelete(otInstance *, uint16_t aKey, int aIndex)
|
|
{
|
|
return FakePlatform::CurrentPlatform().SettingsDelete(aKey, aIndex);
|
|
}
|
|
|
|
void otPlatSettingsWipe(otInstance *) { FakePlatform::CurrentPlatform().SettingsWipe(); }
|
|
|
|
void otPlatFlashInit(otInstance *) { return FakePlatform::CurrentPlatform().FlashInit(); }
|
|
|
|
uint32_t otPlatFlashGetSwapSize(otInstance *) { return FakePlatform::CurrentPlatform().FlashGetSwapSize(); }
|
|
|
|
void otPlatFlashErase(otInstance *, uint8_t aSwapIndex) { FakePlatform::CurrentPlatform().FlashErase(aSwapIndex); }
|
|
|
|
void otPlatFlashRead(otInstance *, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
|
|
{
|
|
FakePlatform::CurrentPlatform().FlashRead(aSwapIndex, aOffset, aData, aSize);
|
|
}
|
|
|
|
void otPlatFlashWrite(otInstance *, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
|
|
{
|
|
FakePlatform::CurrentPlatform().FlashWrite(aSwapIndex, aOffset, aData, aSize);
|
|
}
|
|
|
|
void otPlatTrelEnable(otInstance *, uint16_t *) {}
|
|
void otPlatTrelDisable(otInstance *) {}
|
|
void otPlatTrelNotifyPeerSocketAddressDifference(otInstance *, const otSockAddr *, const otSockAddr *) {}
|
|
void otPlatTrelRegisterService(otInstance *, uint16_t, const uint8_t *, uint8_t) {}
|
|
void otPlatTrelSend(otInstance *, const uint8_t *, uint16_t, const otSockAddr *) {}
|
|
const otPlatTrelCounters *otPlatTrelGetCounters(otInstance *) { return nullptr; }
|
|
void otPlatTrelResetCounters(otInstance *) {}
|
|
|
|
otError otPlatUdpSocket(otUdpSocket *) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpClose(otUdpSocket *) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpBind(otUdpSocket *) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpBindToNetif(otUdpSocket *, otNetifIdentifier) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpConnect(otUdpSocket *) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpSend(otUdpSocket *, otMessage *, const otMessageInfo *) { return OT_ERROR_NOT_IMPLEMENTED; }
|
|
otError otPlatUdpJoinMulticastGroup(otUdpSocket *, otNetifIdentifier, const otIp6Address *)
|
|
{
|
|
return OT_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
otError otPlatUdpLeaveMulticastGroup(otUdpSocket *, otNetifIdentifier, const otIp6Address *)
|
|
{
|
|
return OT_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
otPlatDnssdState otPlatDnssdGetState(otInstance *) { return OT_PLAT_DNSSD_STOPPED; }
|
|
|
|
void otPlatDnssdRegisterService(otInstance *,
|
|
const otPlatDnssdService *,
|
|
otPlatDnssdRequestId,
|
|
otPlatDnssdRegisterCallback)
|
|
{
|
|
}
|
|
|
|
void otPlatDnssdUnregisterService(otInstance *,
|
|
const otPlatDnssdService *,
|
|
otPlatDnssdRequestId,
|
|
otPlatDnssdRegisterCallback)
|
|
{
|
|
}
|
|
|
|
void otPlatDnssdRegisterHost(otInstance *, const otPlatDnssdHost *, otPlatDnssdRequestId, otPlatDnssdRegisterCallback)
|
|
{
|
|
}
|
|
|
|
void otPlatDnssdUnregisterHost(otInstance *, const otPlatDnssdHost *, otPlatDnssdRequestId, otPlatDnssdRegisterCallback)
|
|
{
|
|
}
|
|
|
|
void otPlatDnssdRegisterKey(otInstance *, const otPlatDnssdKey *, otPlatDnssdRequestId, otPlatDnssdRegisterCallback) {}
|
|
|
|
void otPlatDnssdUnregisterKey(otInstance *, const otPlatDnssdKey *, otPlatDnssdRequestId, otPlatDnssdRegisterCallback)
|
|
{
|
|
}
|
|
|
|
void otPlatDnssdStartBrowser(otInstance *, const otPlatDnssdBrowser *) {}
|
|
|
|
void otPlatDnssdStopBrowser(otInstance *, const otPlatDnssdBrowser *) {}
|
|
|
|
void otPlatDnssdStartSrvResolver(otInstance *, const otPlatDnssdSrvResolver *) {}
|
|
|
|
void otPlatDnssdStopSrvResolver(otInstance *, const otPlatDnssdSrvResolver *) {}
|
|
|
|
void otPlatDnssdStartTxtResolver(otInstance *, const otPlatDnssdTxtResolver *) {}
|
|
|
|
void otPlatDnssdStopTxtResolver(otInstance *, const otPlatDnssdTxtResolver *) {}
|
|
|
|
void otPlatDnssdStartIp6AddressResolver(otInstance *, const otPlatDnssdAddressResolver *) {}
|
|
|
|
void otPlatDnssdStopIp6AddressResolver(otInstance *, const otPlatDnssdAddressResolver *) {}
|
|
|
|
void otPlatDnssdStartIp4AddressResolver(otInstance *, const otPlatDnssdAddressResolver *) {}
|
|
|
|
void otPlatDnssdStopIp4AddressResolver(otInstance *, const otPlatDnssdAddressResolver *) {}
|
|
|
|
void otPlatDnssdStartRecordQuerier(otInstance *, const otPlatDnssdRecordQuerier *) {}
|
|
|
|
void otPlatDnssdStopRecordQuerier(otInstance *, const otPlatDnssdRecordQuerier *) {}
|
|
|
|
void otPlatAssertFail(const char *, int) {}
|
|
} // extern "C"
|