[link-raw] set receive done callback when enabled (#5108)

This commit is contained in:
Yakun Xu
2020-06-17 14:42:39 -07:00
committed by GitHub
parent f5d7f50f44
commit 3b362071e5
10 changed files with 154 additions and 62 deletions
+3 -1
View File
@@ -117,6 +117,8 @@ static bool sSrcMatchEnabled = false;
static bool sRadioCoexEnabled = true;
#endif
otRadioCaps gRadioCaps = OT_RADIO_CAPS_NONE;
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
{
for (size_t i = 0; i < sizeof(*aReversed); i++)
@@ -462,7 +464,7 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
assert(aInstance != NULL);
return OT_RADIO_CAPS_NONE;
return gRadioCaps;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
+19 -8
View File
@@ -47,10 +47,12 @@
#include <openthread/tasklet.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
uint32_t gNodeId = 1;
extern bool gPlatformPseudoResetWasRequested;
extern bool gPlatformPseudoResetWasRequested;
extern otRadioCaps gRadioCaps;
static volatile bool gTerminate = false;
@@ -65,6 +67,7 @@ void otSysInit(int aArgCount, char *aArgVector[])
{
char * endptr;
uint32_t speedUpFactor = 1;
int argIndex = 0;
if (gPlatformPseudoResetWasRequested)
{
@@ -74,31 +77,39 @@ void otSysInit(int aArgCount, char *aArgVector[])
if (aArgCount < 2)
{
fprintf(stderr, "Syntax:\n %s NodeId [TimeSpeedUpFactor]\n", aArgVector[0]);
fprintf(stderr, "Syntax:\n %s [--sleep-to-tx] NodeId [TimeSpeedUpFactor]\n", aArgVector[0]);
exit(EXIT_FAILURE);
}
openlog(basename(aArgVector[0]), LOG_PID, LOG_USER);
openlog(basename(aArgVector[argIndex++]), LOG_PID, LOG_USER);
setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
signal(SIGTERM, &handleSignal);
signal(SIGHUP, &handleSignal);
gNodeId = (uint32_t)strtol(aArgVector[1], &endptr, 0);
if (!strcmp(aArgVector[argIndex], "--sleep-to-tx"))
{
gRadioCaps |= OT_RADIO_CAPS_SLEEP_TO_TX;
++argIndex;
}
gNodeId = (uint32_t)strtol(aArgVector[argIndex], &endptr, 0);
if (*endptr != '\0' || gNodeId < 1 || gNodeId >= WELLKNOWN_NODE_ID)
{
fprintf(stderr, "Invalid NodeId: %s\n", aArgVector[1]);
fprintf(stderr, "Invalid NodeId: %s\n", aArgVector[argIndex]);
exit(EXIT_FAILURE);
}
if (aArgCount > 2)
++argIndex;
if (aArgCount > argIndex)
{
speedUpFactor = (uint32_t)strtol(aArgVector[2], &endptr, 0);
speedUpFactor = (uint32_t)strtol(aArgVector[argIndex], &endptr, 0);
if (*endptr != '\0' || speedUpFactor == 0)
{
fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[2]);
fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[argIndex]);
exit(EXIT_FAILURE);
}
}
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (6)
#define OPENTHREAD_API_VERSION (7)
/**
* @addtogroup api-instance
+17 -16
View File
@@ -51,17 +51,30 @@ extern "C" {
*
*/
/**
* This function pointer on receipt of a IEEE 802.15.4 frame.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aFrame A pointer to the received frame or NULL if the receive operation was aborted.
* @param[in] aError OT_ERROR_NONE when successfully received a frame.
* OT_ERROR_ABORT when reception was aborted and a frame was not received.
*
*/
typedef void (*otLinkRawReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
/**
* This function enables/disables the raw link-layer.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aEnabled TRUE to enable raw link-layer, FALSE otherwise.
* @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame. NULL to disable the
* raw-link layer.
*
* @retval OT_ERROR_NONE If the enable state was successfully set.
* @retval OT_ERROR_FAILED The radio could not be enabled/disabled.
* @retval OT_ERROR_INVALID_STATE If the OpenThread Ip6 interface is already enabled.
* @retval OT_ERROR_NONE If the enable state was successfully set.
*
*/
otError otLinkRawSetEnable(otInstance *aInstance, bool aEnabled);
otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback);
/**
* This function indicates whether or not the raw link-layer is enabled.
@@ -122,29 +135,17 @@ otError otLinkRawSetShortAddress(otInstance *aInstance, uint16_t aShortAddress);
*/
otError otLinkRawSleep(otInstance *aInstance);
/**
* This function pointer on receipt of a IEEE 802.15.4 frame.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aFrame A pointer to the received frame or NULL if the receive operation was aborted.
* @param[in] aError OT_ERROR_NONE when successfully received a frame.
* OT_ERROR_ABORT when reception was aborted and a frame was not received.
*
*/
typedef void (*otLinkRawReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
/**
* Transitioning the radio from Sleep to Receive.
* Turn on the radio.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame.
*
* @retval OT_ERROR_NONE Successfully transitioned to Receive.
* @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
*
*/
otError otLinkRawReceive(otInstance *aInstance, otLinkRawReceiveDone aCallback);
otError otLinkRawReceive(otInstance *aInstance);
/**
* The radio transitions from Transmit to Receive.
+4 -4
View File
@@ -50,9 +50,9 @@
using namespace ot;
otError otLinkRawSetEnable(otInstance *aInstance, bool aEnabled)
otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback)
{
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetEnabled(aEnabled);
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetReceiveDone(aCallback);
}
bool otLinkRawIsEnabled(otInstance *aInstance)
@@ -95,9 +95,9 @@ exit:
return error;
}
otError otLinkRawReceive(otInstance *aInstance, otLinkRawReceiveDone aCallback)
otError otLinkRawReceive(otInstance *aInstance)
{
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Receive(aCallback);
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().Receive();
}
otRadioFrame *otLinkRawGetTransmitBuffer(otInstance *aInstance)
+5 -7
View File
@@ -51,7 +51,6 @@ namespace Mac {
LinkRaw::LinkRaw(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(false)
, mReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mPanId(kPanIdBroadcast)
, mReceiveDoneCallback(NULL)
@@ -65,17 +64,17 @@ LinkRaw::LinkRaw(Instance &aInstance)
{
}
otError LinkRaw::SetEnabled(bool aEnabled)
otError LinkRaw::SetReceiveDone(otLinkRawReceiveDone aCallback)
{
otError error = OT_ERROR_NONE;
otLogDebgMac("LinkRaw::Enabled(%s)", aEnabled ? "true" : "false");
otLogDebgMac("LinkRaw::Enabled(%s)", (aCallback != NULL ? "true" : "false"));
#if OPENTHREAD_MTD || OPENTHREAD_FTD
VerifyOrExit(!Get<ThreadNetif>().IsUp(), error = OT_ERROR_INVALID_STATE);
#endif
if (aEnabled)
if (aCallback)
{
SuccessOrExit(error = mSubMac.Enable());
}
@@ -84,7 +83,7 @@ otError LinkRaw::SetEnabled(bool aEnabled)
IgnoreError(mSubMac.Disable());
}
mEnabled = aEnabled;
mReceiveDoneCallback = aCallback;
exit:
return error;
@@ -135,14 +134,13 @@ exit:
return error;
}
otError LinkRaw::Receive(otLinkRawReceiveDone aCallback)
otError LinkRaw::Receive(void)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
SuccessOrExit(error = mSubMac.Receive(mReceiveChannel));
mReceiveDoneCallback = aCallback;
exit:
return error;
+7 -8
View File
@@ -71,19 +71,21 @@ public:
* @returns true if enabled, false otherwise.
*
*/
bool IsEnabled(void) const { return mEnabled; }
bool IsEnabled(void) const { return mReceiveDoneCallback != NULL; }
/**
* This method enables/disables the raw link-layer.
*
* @param[in] aEnabled Whether enable raw link-layer.
* @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame, NULL to disable
* raw link-layer.
*
*
* @retval OT_ERROR_INVALID_STATE Thread stack is enabled.
* @retval OT_ERROR_FAILED The radio could not be enabled.
* @retval OT_ERROR_FAILED The radio could not be enabled/disabled.
* @retval OT_ERROR_NONE Successfully enabled/disabled raw link.
*
*/
otError SetEnabled(bool aEnabled);
otError SetReceiveDone(otLinkRawReceiveDone aCallback);
/**
* This method returns the capabilities of the raw link-layer.
@@ -96,13 +98,11 @@ public:
/**
* This method starts a (recurring) Receive on the link-layer.
*
* @param[in] aCallback A pointer to a function called on receipt of a IEEE 802.15.4 frame.
*
* @retval OT_ERROR_NONE Successfully transitioned to Receive.
* @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
*
*/
otError Receive(otLinkRawReceiveDone aCallback);
otError Receive(void);
/**
* This method invokes the mReceiveDoneCallback, if set.
@@ -302,7 +302,6 @@ public:
#endif
private:
bool mEnabled;
uint8_t mReceiveChannel;
PanId mPanId;
otLinkRawReceiveDone mReceiveDoneCallback;
+2 -2
View File
@@ -1361,7 +1361,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_CHAN>(void)
// stream enabled already
if (otLinkRawIsEnabled(mInstance) && mIsRawStreamEnabled)
{
error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
error = otLinkRawReceive(mInstance);
}
#endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
@@ -1462,7 +1462,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_RAW_STREAM_ENABLE
{
if (enabled)
{
error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
error = otLinkRawReceive(mInstance);
}
else
{
+3 -15
View File
@@ -190,7 +190,7 @@ void NcpBase::LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi)
// Make sure we are back listening on the original receive channel,
// since the energy scan could have been on a different channel.
IgnoreError(otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone));
IgnoreError(otLinkRawReceive(mInstance));
SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_MAC_ENERGY_SCAN_RESULT));
@@ -348,23 +348,11 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_ENABLED>(void)
if (value == false)
{
// If we have raw stream enabled stop receiving
if (mIsRawStreamEnabled)
{
IgnoreError(otLinkRawSleep(mInstance));
}
error = otLinkRawSetEnable(mInstance, false);
error = otLinkRawSetReceiveDone(mInstance, NULL);
}
else
{
error = otLinkRawSetEnable(mInstance, true);
// If we have raw stream enabled already, start receiving
if (error == OT_ERROR_NONE && mIsRawStreamEnabled)
{
error = otLinkRawReceive(mInstance, &NcpBase::LinkRawReceiveDone);
}
error = otLinkRawSetReceiveDone(mInstance, &NcpBase::LinkRawReceiveDone);
}
exit:
+93
View File
@@ -0,0 +1,93 @@
#!/usr/bin/expect -f
#
# Copyright (c) 2020, 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.
#
source "tests/scripts/expect/_common.exp"
set timeout 1
spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?forkpty-arg=--sleep-to-tx 1"
set node_1 $spawn_id
expect_after {
timeout { exit 1 }
}
send "dataset init new\n"
expect "Done"
send "dataset panid 0xface\n"
expect "Done"
send "dataset commit active\n"
expect "Done"
send "ifconfig up\n"
expect "Done"
send "thread start\n"
expect "Done"
wait_for "state" "leader"
send "extaddr\n"
expect "extaddr"
expect -re {([0-9a-f]{16})}
set extaddr $expect_out(1,string)
expect "Done"
send "panid\n"
expect "panid"
expect -re {([0-9a-f]{4})}
set pan $expect_out(1,string)
expect "Done"
send "extpanid\n"
expect "extpanid"
expect -re {([0-9a-f]{16})}
set extpan $expect_out(1,string)
expect "Done"
send "networkname\n"
expect "networkname"
expect -re {[\r\n]([^\r\n]+)[\r\n]}
set network $expect_out(1,string)
expect "Done"
send "channel\n"
expect "channel"
expect -re {(\d+)}
set channel $expect_out(1,string)
expect "Done"
spawn $env(OT_COMMAND) "spinel+hdlc+uart://$env(RCP_COMMAND)?forkpty-arg=--sleep-to-tx 2"
set node_2 $spawn_id
expect_after {
timeout { exit 1 }
}
send "scan\n"
expect "| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm | LQI |"
expect "+---+------------------+------------------+------+------------------+----+-----+-----+"
wait_for "" "\\| \\d \\| $network +\\| $extpan \\| $pan \\| $extaddr \\| +$channel \\| +-?\\d+ \\| +\\d \\|"
wait_for "" "Done"
dispose
set spawn_id $node_1
dispose