mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 02:39:52 +00:00
[qos] handle NCP messages based on the priority of the message (#3318)
This commit is contained in:
committed by
Jonathan Hui
parent
4ed2c8c222
commit
19f2533aff
@@ -256,7 +256,7 @@ OTAPI const otNetifAddress *OTCALL otIp6GetUnicastAddresses(otInstance *aInstanc
|
||||
* @retval OT_ERROR_ALREADY The multicast address is already subscribed.
|
||||
* @retval OT_ERROR_INVALID_ARGS The IP Address indicated by @p aAddress is invalid address.
|
||||
* @retval OT_ERROR_NO_BUFS The Network Interface is already storing the maximum allowed external multicast
|
||||
* addresses.
|
||||
* addresses.
|
||||
*
|
||||
*/
|
||||
otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress);
|
||||
@@ -279,6 +279,7 @@ otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Addre
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to the first Network Interface Multicast Address.
|
||||
*
|
||||
*/
|
||||
const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance);
|
||||
|
||||
@@ -288,6 +289,7 @@ const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @sa otIp6SetMulticastPromiscuousEnabled
|
||||
*
|
||||
*/
|
||||
bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance);
|
||||
|
||||
@@ -298,6 +300,7 @@ bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance);
|
||||
* @param[in] aEnabled TRUE to enable Multicast Promiscuous mode, FALSE otherwise.
|
||||
*
|
||||
* @sa otIp6IsMulticastPromiscuousEnabled
|
||||
*
|
||||
*/
|
||||
void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled);
|
||||
|
||||
@@ -308,7 +311,7 @@ void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled);
|
||||
* @param[inout] aAddress A pointer to structure containing IPv6 address for which IID is being created.
|
||||
* @param[inout] aContext A pointer to creator-specific context.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
|
||||
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
|
||||
* @retval OT_ERROR_IP6_ADDRESS_CREATION_FAILURE Creation of valid IID for given IPv6 address failed.
|
||||
*
|
||||
*/
|
||||
@@ -361,7 +364,7 @@ otError otIp6CreateMacIid(otInstance *aInstance, otNetifAddress *aAddresses, voi
|
||||
* @param[inout] aAddresses A pointer to structure containing IPv6 address for which IID is being created.
|
||||
* @param[inout] aContext A pointer to a otSemanticallyOpaqueIidGeneratorData structure.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
|
||||
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
|
||||
* @retval OT_ERROR_IP6_ADDRESS_CREATION_FAILURE Could not create valid IID for given IPv6 address.
|
||||
*
|
||||
*/
|
||||
@@ -378,10 +381,33 @@ otError otIp6CreateSemanticallyOpaqueIid(otInstance *aInstance, otNetifAddress *
|
||||
*
|
||||
* @returns A pointer to the message buffer or NULL if no message buffers are available or parameters are invalid.
|
||||
*
|
||||
* @sa otFreeMessage
|
||||
* @sa otMessageFree
|
||||
*
|
||||
*/
|
||||
otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings);
|
||||
|
||||
/**
|
||||
* Allocate a new message buffer and write the IPv6 datagram to the message buffer for sending an IPv6 message.
|
||||
*
|
||||
* @note If @p aSettings is NULL, the link layer security is enabled and the message priority is obtained from IPv6
|
||||
* message itself.
|
||||
* If @p aSettings is not NULL, the @p aSetting->mPriority is ignored and obtained from IPv6 message itself.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aData A pointer to the IPv6 datagram buffer.
|
||||
* @param[in] aDataLength The size of the IPv6 datagram buffer pointed by @p aData.
|
||||
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if malformed IPv6 header or insufficient message buffers are available.
|
||||
*
|
||||
* @sa otMessageFree
|
||||
*
|
||||
*/
|
||||
otMessage *otIp6NewMessageFromBuffer(otInstance * aInstance,
|
||||
const uint8_t * aData,
|
||||
uint16_t aDataLength,
|
||||
const otMessageSettings *aSettings);
|
||||
|
||||
/**
|
||||
* This function pointer is called when an IPv6 datagram is received.
|
||||
*
|
||||
@@ -485,8 +511,8 @@ otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort);
|
||||
* This function removes a port from the allowed unsecure port list.
|
||||
*
|
||||
* @note This function removes @p aPort by overwriting @p aPort with the element after @p aPort in the internal port
|
||||
* list. Be careful when calling otIp6GetUnsecurePorts() followed by otIp6RemoveUnsecurePort() to remove unsecure
|
||||
* ports.
|
||||
* list. Be careful when calling otIp6GetUnsecurePorts() followed by otIp6RemoveUnsecurePort() to remove unsecure
|
||||
* ports.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aPort The port value.
|
||||
@@ -526,6 +552,7 @@ const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntrie
|
||||
*
|
||||
* @retval TRUE The two IPv6 addresses are the same.
|
||||
* @retval FALSE The two IPv6 addresses are not the same.
|
||||
*
|
||||
*/
|
||||
OTAPI bool OTCALL otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond);
|
||||
|
||||
@@ -537,6 +564,7 @@ OTAPI bool OTCALL otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Add
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully parsed the string.
|
||||
* @retval OT_ERROR_INVALID_ARGS Failed to parse the string.
|
||||
*
|
||||
*/
|
||||
OTAPI otError OTCALL otIp6AddressFromString(const char *aString, otIp6Address *aAddress);
|
||||
|
||||
|
||||
@@ -217,6 +217,20 @@ exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
otMessage *otIp6NewMessageFromBuffer(otInstance * aInstance,
|
||||
const uint8_t * aData,
|
||||
uint16_t aDataLength,
|
||||
const otMessageSettings *aSettings)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
Message * message;
|
||||
|
||||
VerifyOrExit((message = instance.GetIp6().NewMessage(aData, aDataLength, aSettings)) != NULL);
|
||||
|
||||
exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
@@ -73,6 +73,29 @@ Message *Ip6::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
|
||||
Message::kTypeIp6, sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + aReserved, aSettings);
|
||||
}
|
||||
|
||||
Message *Ip6::NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings)
|
||||
{
|
||||
otMessageSettings settings = {true, OT_MESSAGE_PRIORITY_NORMAL};
|
||||
Message * message = NULL;
|
||||
|
||||
if (aSettings != NULL)
|
||||
{
|
||||
settings = *aSettings;
|
||||
}
|
||||
|
||||
SuccessOrExit(GetDatagramPriority(aData, aDataLength, *reinterpret_cast<uint8_t *>(&settings.mPriority)));
|
||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0, &settings)) != NULL);
|
||||
|
||||
if (message->Append(aData, aDataLength) != OT_ERROR_NONE)
|
||||
{
|
||||
message->Free();
|
||||
message = NULL;
|
||||
}
|
||||
|
||||
exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
uint8_t Ip6::DscpToPriority(uint8_t aDscp)
|
||||
{
|
||||
uint8_t priority;
|
||||
@@ -127,6 +150,23 @@ uint8_t Ip6::PriorityToDscp(uint8_t aPriority)
|
||||
return dscp;
|
||||
}
|
||||
|
||||
otError Ip6::GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const Header *header;
|
||||
|
||||
VerifyOrExit((aData != NULL) && (aDataLen >= sizeof(Header)), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
header = reinterpret_cast<const Header *>(aData);
|
||||
VerifyOrExit(header->IsValid(), error = OT_ERROR_PARSE);
|
||||
VerifyOrExit(sizeof(Header) + header->GetPayloadLength() == aDataLen, error = OT_ERROR_PARSE);
|
||||
|
||||
aPriority = DscpToPriority(header->GetDscp());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
uint16_t Ip6::UpdateChecksum(uint16_t aChecksum, const Address &aAddress)
|
||||
{
|
||||
return Message::UpdateChecksum(aChecksum, aAddress.mFields.m8, sizeof(aAddress));
|
||||
|
||||
+19
-1
@@ -111,7 +111,7 @@ public:
|
||||
* This method allocates a new message buffer from the buffer pool.
|
||||
*
|
||||
* @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
|
||||
* OT_MESSAGE_PRIORITY_NORMAL by default.
|
||||
* OT_MESSAGE_PRIORITY_NORMAL by default.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve following the IPv6 header.
|
||||
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
|
||||
@@ -121,6 +121,22 @@ public:
|
||||
*/
|
||||
Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
|
||||
|
||||
/**
|
||||
* This method allocates a new message buffer from the buffer pool and writes the IPv6 datagram to the message.
|
||||
*
|
||||
* @note If @p aSettings is NULL, the link layer security is enabled and the message priority is obtained from
|
||||
* IPv6 message itself.
|
||||
* If @p aSettings is not NULL, the @p aSetting->mPriority is ignored and obtained from IPv6 message itself.
|
||||
*
|
||||
* @param[in] aData A pointer to the IPv6 datagram buffer.
|
||||
* @param[in] aDataLength The size of the IPV6 datagram buffer pointed by @p aData.
|
||||
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if malformed IPv6 header or insufficient message buffers are available.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings);
|
||||
|
||||
/**
|
||||
* This method converts the message priority level to IPv6 DSCP value.
|
||||
*
|
||||
@@ -411,6 +427,8 @@ private:
|
||||
static void HandleSendQueue(Tasklet &aTasklet);
|
||||
void HandleSendQueue(void);
|
||||
|
||||
static otError GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority);
|
||||
|
||||
otError ProcessReceiveCallback(const Message & aMessage,
|
||||
const MessageInfo &aMessageInfo,
|
||||
uint8_t aIpProto,
|
||||
|
||||
@@ -40,22 +40,31 @@ namespace Ip6 {
|
||||
|
||||
otError Header::Init(const Message &aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t length;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
// check aMessage length
|
||||
VerifyOrExit(aMessage.Read(0, sizeof(*this), this) == sizeof(*this), error = OT_ERROR_PARSE);
|
||||
|
||||
// check Version
|
||||
VerifyOrExit(IsVersion6(), error = OT_ERROR_PARSE);
|
||||
|
||||
// check Payload Length
|
||||
length = sizeof(*this) + GetPayloadLength();
|
||||
VerifyOrExit(length == aMessage.GetLength() && length <= Ip6::kMaxDatagramLength, error = OT_ERROR_PARSE);
|
||||
VerifyOrExit(IsValid(), error = OT_ERROR_PARSE);
|
||||
VerifyOrExit((sizeof(*this) + GetPayloadLength()) == aMessage.GetLength(), error = OT_ERROR_PARSE);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Header::IsValid(void) const
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
// check Version
|
||||
VerifyOrExit(IsVersion6(), ret = false);
|
||||
|
||||
// check Payload Length
|
||||
VerifyOrExit((sizeof(*this) + GetPayloadLength()) <= Ip6::kMaxDatagramLength, ret = false);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Ip6
|
||||
} // namespace ot
|
||||
|
||||
@@ -177,6 +177,15 @@ public:
|
||||
*/
|
||||
otError Init(const Message &aMessage);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the header appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE if the header appears to be well-formed.
|
||||
* @retval FALSE if the header does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the IPv6 Version is set to 6.
|
||||
*
|
||||
@@ -216,7 +225,7 @@ public:
|
||||
* @returns The IPv6 Payload Length value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPayloadLength(void) { return HostSwap16(mPayloadLength); }
|
||||
uint16_t GetPayloadLength(void) const { return HostSwap16(mPayloadLength); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Payload Length value.
|
||||
|
||||
@@ -1744,19 +1744,15 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET>(void)
|
||||
otMessage * message = NULL;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
// STREAM_NET requires layer 2 security.
|
||||
message = otIp6NewMessage(mInstance, NULL);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
|
||||
SuccessOrExit(error = mDecoder.ReadData(metaPtr, metaLen));
|
||||
|
||||
// We ignore metadata for now.
|
||||
// May later include TX power, allow retransmits, etc...
|
||||
OT_UNUSED_VARIABLE(metaPtr);
|
||||
OT_UNUSED_VARIABLE(metaLen);
|
||||
|
||||
SuccessOrExit(error = otMessageAppend(message, framePtr, frameLen));
|
||||
// STREAM_NET requires layer 2 security.
|
||||
message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, NULL);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
error = otIp6Send(mInstance, message);
|
||||
|
||||
@@ -2588,19 +2584,15 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET_INSECURE>(
|
||||
otError error = OT_ERROR_NONE;
|
||||
otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
|
||||
|
||||
// STREAM_NET_INSECURE packets are not secured at layer 2.
|
||||
message = otIp6NewMessage(mInstance, &msgSettings);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
SuccessOrExit(mDecoder.ReadDataWithLen(framePtr, frameLen));
|
||||
SuccessOrExit(mDecoder.ReadData(metaPtr, metaLen));
|
||||
|
||||
// We ignore metadata for now.
|
||||
// May later include TX power, allow retransmits, etc...
|
||||
OT_UNUSED_VARIABLE(metaPtr);
|
||||
OT_UNUSED_VARIABLE(metaLen);
|
||||
|
||||
SuccessOrExit(error = otMessageAppend(message, framePtr, frameLen));
|
||||
// STREAM_NET_INSECURE packets are not secured at layer 2.
|
||||
message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, &msgSettings);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
// Ensure the insecure message is forwarded using direct transmission.
|
||||
otMessageSetDirectTransmission(message, true);
|
||||
|
||||
Reference in New Issue
Block a user