Add otPlatRadioGetReceiveSensitivity() API (#1715)

* Add otPlatRadioGetReceiveSensitivity() API

* Add a new otPlatRadioGetReceiveSensitivity() API to get sensitivity value;

* Use the receive sensitivity value as the noise floor for link metric computation;

* Remove some unused noise floor related functions.

* Add SPINEL_PROP_PHY_RX_SENSITIVITY Spinel/NCP property
This commit is contained in:
Shu Chen
2017-05-05 11:38:37 +08:00
committed by Jonathan Hui
parent 849dcba11b
commit 66f6e7088d
18 changed files with 148 additions and 76 deletions
@@ -63,3 +63,10 @@ Value is the current RSSI (Received signal strength indication)
from the radio. This value can be used in energy scans and for
determining the ambient noise floor for the operating environment.
### PROP 39: PROP_PHY_RX_SENSITIVITY {#prop-phy-rx-sensitivity}
* Type: Read-Only
* Packed-Encoding: `c` (int8)
* Unit: dBm
Value is the radio receive sensitivity. This value can be used as
lower bound noise floor for link metrics computation.
+25
View File
@@ -814,6 +814,31 @@ void otPlatRadioSetDefaultTxPower(_In_ otInstance *otCtx, int8_t aPower)
}
}
int8_t otPlatRadioGetReceiveSensitivity(_In_ otInstance *otCtx)
{
NT_ASSERT(otCtx);
PMS_FILTER pFilter = otCtxToFilter(otCtx);
NTSTATUS status;
int8_t receiveSensitivity;
status =
otLwfCmdGetProp(
pFilter,
NULL,
SPINEL_PROP_PHY_RX_SENSITIVITY,
SPINEL_DATATYPE_INT8_S,
&receiveSensitivity
);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "Get SPINEL_PROP_PHY_RX_SENSITIVITY, failed, %!STATUS!", status);
return -100; // return default value -100dBm
}
return receiveSensitivity;
}
inline USHORT getDstShortAddress(const UCHAR *frame)
{
return (((USHORT)frame[IEEE802154_DSTADDR_OFFSET + 1]) << 8) | frame[IEEE802154_DSTADDR_OFFSET];
+11
View File
@@ -62,6 +62,11 @@ enum
CC2538_LQI_BIT_MASK = 0x7f,
};
enum
{
CC2538_RECEIVE_SENSITIVITY = -100, // dBm
};
static RadioPacket sTransmitFrame;
static RadioPacket sReceiveFrame;
static ThreadError sTransmitError;
@@ -793,3 +798,9 @@ void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
(void)aInstance;
(void)aPower;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return CC2538_RECEIVE_SENSITIVITY;
}
+11
View File
@@ -48,6 +48,11 @@
#include <driverlib/rf_ieee_cmd.h>
#include <driverlib/chipinfo.h>
enum
{
CC2650_RECEIVE_SENSITIVITY = -100, // dBm
};
/* phy state as defined by openthread */
static volatile cc2650_PhyState sState;
@@ -1799,3 +1804,9 @@ void cc2650RadioProcess(otInstance *aInstance)
sReceiveFrame.mLength = 0;
}
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return CC2650_RECEIVE_SENSITIVITY;
}
+10
View File
@@ -57,6 +57,11 @@
#define IEEE802154_ACK_REQUEST 1 << 5
#define IEEE802154_DSN_OFFSET 2
enum
{
DA15000_RECEIVE_SENSITIVITY = -100, // dBm
};
static otInstance *sThreadInstance;
static PhyState sRadioState = kStateDisabled;
@@ -500,3 +505,8 @@ void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
}
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return DA15000_RECEIVE_SENSITIVITY;
}
+11
View File
@@ -60,6 +60,11 @@ enum
IEEE802154_DSN_OFFSET = 2,
};
enum
{
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
};
static uint16_t sPanId = 0;
static uint8_t sChannel = 0;
static bool sTransmitBusy = false;
@@ -842,3 +847,9 @@ void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
(void)aInstance;
RAIL_TxPowerSet(aPower);
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return EFR32_RECEIVE_SENSITIVITY;
}
+11
View File
@@ -64,6 +64,11 @@
#define SHORT_ADDRESS_SIZE 2
#define EXTENDED_ADDRESS_SIZE 8
enum
{
NRF52840_RECEIVE_SENSITIVITY = -100, // dBm
};
static bool sDisabled;
static RadioPacket sReceivedFrames[RADIO_RX_BUFFERS];
@@ -608,3 +613,9 @@ void nrf_drv_radio802154_energy_detected(int8_t result)
setPendingEvent(kPendingEventEnergyDetected);
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return NRF52840_RECEIVE_SENSITIVITY;
}
+11
View File
@@ -75,6 +75,11 @@ enum
IEEE802154_MACCMD_DATA_REQ = 4,
};
enum
{
POSIX_RECEIVE_SENSITIVITY = -100, // dBm
};
OT_TOOL_PACKED_BEGIN
struct RadioMessage
{
@@ -749,3 +754,9 @@ void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
(void)aInstance;
(void)aPower;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return POSIX_RECEIVE_SENSITIVITY;
}
+9
View File
@@ -498,6 +498,15 @@ ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, u
*/
extern void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
/**
* Get the radio receive sensitivity value.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @returns The radio receive sensitivity value in dBm.
*/
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance);
/**
* @}
*
+1 -3
View File
@@ -156,8 +156,6 @@ Mac::Mac(ThreadNetif &aThreadNetif):
{
GenerateExtAddress(&mExtAddress);
ClearNoiseFloorAverage(mNoiseFloor);
memset(&mCounters, 0, sizeof(otMacCounters));
SetExtendedPanId(sExtendedPanidInit);
@@ -1417,7 +1415,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError)
if (neighbor != NULL)
{
neighbor->GetLinkInfo().AddRss(mNoiseFloor, aFrame->mPower);
neighbor->GetLinkInfo().AddRss(GetNoiseFloor(), aFrame->mPower);
if (aFrame->GetSecurityEnabled() == true)
{
+3 -5
View File
@@ -601,12 +601,12 @@ public:
otMacCounters &GetCounters(void) { return mCounters; }
/**
* This method returns the noise floor state.
* This method returns the noise floor value (currently use the radio receive sensitivity value).
*
* @returns A reference to the noise floor state.
* @returns The noise floor value in dBm.
*
*/
LinkQualityInfo &GetNoiseFloor(void) { return mNoiseFloor; }
int8_t GetNoiseFloor(void) { return otPlatRadioGetReceiveSensitivity(GetInstance()); }
/**
* This method indicates whether or not CSMA backoff is supported by the radio layer.
@@ -714,8 +714,6 @@ private:
int8_t mEnergyScanCurrentMaxRssi;
Tasklet mEnergyScanSampleRssiTask;
LinkQualityInfo mNoiseFloor;
otLinkPcapCallback mPcapCallback;
void *mPcapCallbackContext;
+7 -29
View File
@@ -76,7 +76,7 @@ void LinkQualityInfo::Clear(void)
mLastRss = 0;
}
void LinkQualityInfo::AddRss(LinkQualityInfo &aNoiseFloor, int8_t aRss)
void LinkQualityInfo::AddRss(int8_t aNoiseFloor, int8_t aRss)
{
uint16_t newValue;
uint16_t oldAverage;
@@ -178,12 +178,12 @@ exit:
return error;
}
uint8_t LinkQualityInfo::GetLinkMargin(LinkQualityInfo &aNoiseFloor) const
uint8_t LinkQualityInfo::GetLinkMargin(int8_t aNoiseFloor) const
{
return ConvertRssToLinkMargin(aNoiseFloor, GetAverageRss());
}
uint8_t LinkQualityInfo::GetLinkQuality(LinkQualityInfo &aNoiseFloor)
uint8_t LinkQualityInfo::GetLinkQuality(int8_t aNoiseFloor)
{
UpdateLinkQuality(aNoiseFloor);
@@ -195,7 +195,7 @@ int8_t LinkQualityInfo::GetLastRss(void) const
return mLastRss;
}
void LinkQualityInfo::UpdateLinkQuality(LinkQualityInfo &aNoiseFloor)
void LinkQualityInfo::UpdateLinkQuality(int8_t aNoiseFloor)
{
if (mCount != 0)
{
@@ -207,9 +207,9 @@ void LinkQualityInfo::UpdateLinkQuality(LinkQualityInfo &aNoiseFloor)
}
}
uint8_t LinkQualityInfo::ConvertRssToLinkMargin(LinkQualityInfo &aNoiseFloor, int8_t aRss)
uint8_t LinkQualityInfo::ConvertRssToLinkMargin(int8_t aNoiseFloor, int8_t aRss)
{
int8_t linkMargin = aRss - GetAverageNoiseFloor(aNoiseFloor);
int8_t linkMargin = aRss - aNoiseFloor;
if (linkMargin < 0 || aRss == kUnknownRss)
{
@@ -224,7 +224,7 @@ uint8_t LinkQualityInfo::ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin)
return CalculateLinkQuality(aLinkMargin, kNoLastLinkQualityValue);
}
uint8_t LinkQualityInfo::ConvertRssToLinkQuality(LinkQualityInfo &aNoiseFloor, int8_t aRss)
uint8_t LinkQualityInfo::ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss)
{
return ConvertLinkMarginToLinkQuality(ConvertRssToLinkMargin(aNoiseFloor, aRss));
}
@@ -277,26 +277,4 @@ uint8_t LinkQualityInfo::CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLast
return linkQuality;
}
int8_t GetAverageNoiseFloor(LinkQualityInfo &aNoiseFloor)
{
int8_t averageNoiseFloor = aNoiseFloor.GetAverageRss();
if (averageNoiseFloor == LinkQualityInfo::kUnknownRss)
{
averageNoiseFloor = kDefaultNoiseFloor;
}
return averageNoiseFloor;
}
void AddNoiseFloor(LinkQualityInfo &aNoiseFloor, int8_t aNoise)
{
aNoiseFloor.AddRss(aNoiseFloor, aNoise);
}
void ClearNoiseFloorAverage(LinkQualityInfo &aNoiseFloor)
{
aNoiseFloor.Clear();
}
} // namespace ot
+11 -38
View File
@@ -76,11 +76,11 @@ public:
/**
* This method adds a new received signal strength (RSS) value to the average.
*
* @param[in] aNoiseFloor A reference to the noise floor state.
* @param[in] aNoiseFloor The noise floor value (in dBm).
* @param[in] aRss A new received signal strength value (in dBm) to be added to the average.
*
*/
void AddRss(LinkQualityInfo &aNoiseFloor, int8_t aRss);
void AddRss(int8_t aNoiseFloor, int8_t aRss);
/**
* This method returns the current average signal strength value.
@@ -116,12 +116,12 @@ public:
* This method returns the link margin. The link margin is calculated using the link's current average received
* signal strength (RSS) and average noise floor.
*
* @param[in] aNoiseFloor A reference to the noise state.
* @param[in] aNoiseFloor The noise floor value (in dBm).
*
* @returns Link margin derived from average received signal strength and average noise floor.
*
*/
uint8_t GetLinkMargin(LinkQualityInfo &aNoiseFloor) const;
uint8_t GetLinkMargin(int8_t aNoiseFloor) const;
/**
* Returns the current one-way link quality value. The link quality value is a number 0-3.
@@ -134,11 +134,11 @@ public:
* frequent changes, a hysteresis of 2 dB is applied when determining the link quality. For example, the average
* link margin must be at least 12 dB to change a quality 1 link to a quality 2 link.
*
* @param[in] aNoiseFloor A reference to the noise state.
* @param[in] aNoiseFloor The noise floor value (in dBm).
*
* @returns The current link quality value (value 0-3 as per Thread specification).
*/
uint8_t GetLinkQuality(LinkQualityInfo &aNoiseFloor);
uint8_t GetLinkQuality(int8_t aNoiseFloor);
/**
* Returns the most recent RSS value.
@@ -151,13 +151,13 @@ public:
/**
* This method converts a received signal strength value to a link margin value.
*
* @param[in] aNoiseFloor A reference to the noise state.
* @param[in] aNoiseFloor The noise floor value (in dBm).
* @param[in] aRss The received signal strength value (in dBm).
*
* @returns The link margin value.
*
*/
static uint8_t ConvertRssToLinkMargin(LinkQualityInfo &aNoiseFloor, int8_t aRss);
static uint8_t ConvertRssToLinkMargin(int8_t aNoiseFloor, int8_t aRss);
/**
* This method converts a link margin value to a link quality value.
@@ -172,13 +172,13 @@ public:
/**
* This method converts a received signal strength value to a link quality value.
*
* @param[in] aNoiseFloor A reference to the noise state.
* @param[in] aNoiseFloor The noise floor value (in dBm).
* @param[in] aRss The received signal strength value (in dBm).
*
* @returns The link quality value (0-3).
*
*/
static uint8_t ConvertRssToLinkQuality(LinkQualityInfo &aNoiseFloor, int8_t aRss);
static uint8_t ConvertRssToLinkQuality(int8_t aNoiseFloor, int8_t aRss);
private:
enum
@@ -208,7 +208,7 @@ private:
/* Private method to update the mLinkQuality value. This is called when a new RSS value is added to average
* or when GetLinkQuality() is invoked.
*/
void UpdateLinkQuality(LinkQualityInfo &aNoiseFloor);
void UpdateLinkQuality(int8_t aNoiseFloor);
/* Static private method to calculate the link quality from a given link margin while taking into account the last
* link quality value and adding the hysteresis value to the thresholds. If there is no previous value for link
@@ -227,33 +227,6 @@ private:
int8_t mLastRss;
};
/**
* This function returns the current average noise floor level (in dBm).
*
* @param[in] aNoiseFloor A reference to the noise state.
*
* @returns The current average noise floor level (in dBm).
*/
int8_t GetAverageNoiseFloor(LinkQualityInfo &aNoiseFloor);
/**
* This function adds a new noise floor value (in dBm) to the running average.
*
* @param[in] aNoiseFloor A reference to the noise state.
* @param[in] aNoise A new noise floor value (in dBm) to be added to the average.
*
*/
void AddNoiseFloor(LinkQualityInfo &aNoiseFloor, int8_t aNoise);
/**
* This function clears the current average noise floor value.
*
* @param[in] aNoiseFloor A reference to the noise state.
*
*/
void ClearNoiseFloorAverage(LinkQualityInfo &aNoiseFloor);
/**
* @}
*/
+12
View File
@@ -124,6 +124,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
{ SPINEL_PROP_PHY_CHAN, &NcpBase::GetPropertyHandler_PHY_CHAN },
{ SPINEL_PROP_PHY_RSSI, &NcpBase::GetPropertyHandler_PHY_RSSI },
{ SPINEL_PROP_PHY_TX_POWER, &NcpBase::GetPropertyHandler_PHY_TX_POWER },
{ SPINEL_PROP_PHY_RX_SENSITIVITY, &NcpBase::GetPropertyHandler_PHY_RX_SENSITIVITY },
{ SPINEL_PROP_MAC_SCAN_STATE, &NcpBase::GetPropertyHandler_MAC_SCAN_STATE },
{ SPINEL_PROP_MAC_SCAN_MASK, &NcpBase::GetPropertyHandler_MAC_SCAN_MASK },
@@ -2007,6 +2008,17 @@ ThreadError NcpBase::GetPropertyHandler_PHY_TX_POWER(uint8_t header, spinel_prop
);
}
ThreadError NcpBase::GetPropertyHandler_PHY_RX_SENSITIVITY(uint8_t header, spinel_prop_key_t key)
{
return SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
SPINEL_DATATYPE_INT8_S,
otPlatRadioGetReceiveSensitivity(mInstance)
);
}
ThreadError NcpBase::GetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_prop_key_t key)
{
ThreadError errorCode = kThreadError_None;
+1
View File
@@ -342,6 +342,7 @@ private:
ThreadError GetPropertyHandler_PHY_CHAN(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_PHY_RSSI(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_PHY_TX_POWER(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_PHY_RX_SENSITIVITY(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_MAC_15_4_PANID(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_MAC_15_4_LADDR(uint8_t header, spinel_prop_key_t key);
+1
View File
@@ -529,6 +529,7 @@ typedef enum
SPINEL_PROP_PHY_CCA_THRESHOLD = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
SPINEL_PROP_PHY_TX_POWER = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
SPINEL_PROP_PHY_RSSI = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
SPINEL_PROP_PHY__END = 0x30,
SPINEL_PROP_PHY_EXT__BEGIN = 0x1200,
+1 -1
View File
@@ -61,7 +61,7 @@ struct RssTestData
uint8_t mExpectedLinkQuality; // Expected final link quality value.
};
static LinkQualityInfo sNoiseFloor;
int8_t sNoiseFloor = -100; // dBm
// Checks the encoded average RSS value to match the value from GetAverageRss().
void VerifyEncodedRssValue(LinkQualityInfo &aLinkInfo)
+5
View File
@@ -325,6 +325,11 @@ extern "C" {
(void)aPower;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
(void)aInstance;
return 0;
}
//
// Random
//