mirror of
https://github.com/espressif/openthread.git
synced 2026-09-07 17:50:09 +00:00
[mesh-forwarder] add logs for forwarded MeshHeader messages (#2783)
This commit adds a new method `MeshForwarder::LogMeshMessage()` to log info about messages with `MeshHeader` (messages that are forwarded by device). The new logs indicate when a message is received/sent or possibly dropped. The immediate source and destination for the received or sent frame is logged. The new logs include info from `MeshHeader` such as mesh source, mesh destination, number of hops left. If the message is fragmented, info from fragment header such as datagram tag and offset is included in the logs. For a non-fragmented or a first fragment, `LogMeshMessage()` will also decompress the IPv6 and transport (UDP/TCP) headers and provide info from them such as IPv6 source/destination addresses, UDP/TCP checksum, source/destination port numbers. In addition to the new logs, this commit add the following changes: - Adds `\t` to log lines which are grouped (make it easier to read). - Adds `const` qualifiers to some methods in `Lowpan::MeshHeader`. - Adds new method in `FragmentHeader` to init it from a `Message`. - Refactors/updates some methods in `Lowpan` class (e.g., adding new public method to decompress LOWPAN_NHC UDP header).
This commit is contained in:
committed by
Jonathan Hui
parent
403723dc82
commit
9e2d7181ae
+63
-20
@@ -598,6 +598,7 @@ exit:
|
||||
}
|
||||
|
||||
int Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
bool & aCompressedNextHeader,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
const uint8_t * aBuf,
|
||||
@@ -685,6 +686,11 @@ int Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
aIp6Header.SetNextHeader(static_cast<Ip6::IpProto>(cur[0]));
|
||||
cur++;
|
||||
remaining--;
|
||||
aCompressedNextHeader = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
aCompressedNextHeader = true;
|
||||
}
|
||||
|
||||
// Hop Limit
|
||||
@@ -963,12 +969,11 @@ exit:
|
||||
return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
|
||||
}
|
||||
|
||||
int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength)
|
||||
int Lowpan::DecompressUdpHeader(Ip6::UdpHeader &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
otError error = OT_ERROR_PARSE;
|
||||
const uint8_t *cur = aBuf;
|
||||
uint16_t remaining = aBufLength;
|
||||
Ip6::UdpHeader udpHeader;
|
||||
uint8_t udpCtl;
|
||||
|
||||
VerifyOrExit(remaining >= 1);
|
||||
@@ -976,39 +981,41 @@ int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t
|
||||
cur++;
|
||||
remaining--;
|
||||
|
||||
memset(&udpHeader, 0, sizeof(udpHeader));
|
||||
VerifyOrExit((udpCtl & kUdpDispatchMask) == kUdpDispatch);
|
||||
|
||||
memset(&aUdpHeader, 0, sizeof(aUdpHeader));
|
||||
|
||||
// source and dest ports
|
||||
switch (udpCtl & kUdpPortMask)
|
||||
{
|
||||
case 0:
|
||||
VerifyOrExit(remaining >= 4);
|
||||
udpHeader.SetSourcePort(ReadUint16(cur));
|
||||
udpHeader.SetDestinationPort(ReadUint16(cur + 2));
|
||||
aUdpHeader.SetSourcePort(ReadUint16(cur));
|
||||
aUdpHeader.SetDestinationPort(ReadUint16(cur + 2));
|
||||
cur += 4;
|
||||
remaining -= 4;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
VerifyOrExit(remaining >= 3);
|
||||
udpHeader.SetSourcePort(ReadUint16(cur));
|
||||
udpHeader.SetDestinationPort(0xf000 | cur[2]);
|
||||
aUdpHeader.SetSourcePort(ReadUint16(cur));
|
||||
aUdpHeader.SetDestinationPort(0xf000 | cur[2]);
|
||||
cur += 3;
|
||||
remaining -= 3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
VerifyOrExit(remaining >= 3);
|
||||
udpHeader.SetSourcePort(0xf000 | cur[0]);
|
||||
udpHeader.SetDestinationPort(ReadUint16(cur + 1));
|
||||
aUdpHeader.SetSourcePort(0xf000 | cur[0]);
|
||||
aUdpHeader.SetDestinationPort(ReadUint16(cur + 1));
|
||||
cur += 3;
|
||||
remaining -= 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
VerifyOrExit(remaining >= 1);
|
||||
udpHeader.SetSourcePort(0xf0b0 | (cur[0] >> 4));
|
||||
udpHeader.SetDestinationPort(0xf0b0 | (cur[0] & 0xf));
|
||||
aUdpHeader.SetSourcePort(0xf0b0 | (cur[0] >> 4));
|
||||
aUdpHeader.SetDestinationPort(0xf0b0 | (cur[0] & 0xf));
|
||||
cur += 1;
|
||||
remaining -= 1;
|
||||
break;
|
||||
@@ -1022,27 +1029,39 @@ int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t
|
||||
else
|
||||
{
|
||||
VerifyOrExit(remaining >= 2);
|
||||
udpHeader.SetChecksum(ReadUint16(cur));
|
||||
aUdpHeader.SetChecksum(ReadUint16(cur));
|
||||
cur += 2;
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
|
||||
}
|
||||
|
||||
int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength)
|
||||
{
|
||||
Ip6::UdpHeader udpHeader;
|
||||
int headerLen = -1;
|
||||
|
||||
headerLen = DecompressUdpHeader(udpHeader, aBuf, aBufLength);
|
||||
VerifyOrExit(headerLen >= 0);
|
||||
|
||||
// length
|
||||
if (aDatagramLength == 0)
|
||||
{
|
||||
udpHeader.SetLength(sizeof(udpHeader) + static_cast<uint16_t>(aBufLength - (cur - aBuf)));
|
||||
udpHeader.SetLength(sizeof(udpHeader) + static_cast<uint16_t>(aBufLength - headerLen));
|
||||
}
|
||||
else
|
||||
{
|
||||
udpHeader.SetLength(aDatagramLength - aMessage.GetOffset());
|
||||
}
|
||||
|
||||
SuccessOrExit(aMessage.Append(&udpHeader, sizeof(udpHeader)));
|
||||
VerifyOrExit(aMessage.Append(&udpHeader, sizeof(udpHeader)) == OT_ERROR_NONE, headerLen = -1);
|
||||
aMessage.MoveOffset(sizeof(udpHeader));
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
|
||||
return headerLen;
|
||||
}
|
||||
|
||||
int Lowpan::Decompress(Message & aMessage,
|
||||
@@ -1063,9 +1082,7 @@ int Lowpan::Decompress(Message & aMessage,
|
||||
uint16_t currentOffset = aMessage.GetOffset();
|
||||
|
||||
VerifyOrExit(remaining >= 2);
|
||||
compressed = ((ReadUint16(cur) & kHcNextHeader) != 0);
|
||||
|
||||
VerifyOrExit((rval = DecompressBaseHeader(ip6Header, aMacSource, aMacDest, cur, remaining)) >= 0);
|
||||
VerifyOrExit((rval = DecompressBaseHeader(ip6Header, compressed, aMacSource, aMacDest, cur, remaining)) >= 0);
|
||||
|
||||
cur += rval;
|
||||
remaining -= rval;
|
||||
@@ -1204,5 +1221,31 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError FragmentHeader::Init(const Message &aMessage, uint16_t aOffset)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t bytesRead;
|
||||
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mDispatchSize), &mDispatchSize);
|
||||
VerifyOrExit(bytesRead == sizeof(mDispatchSize), error = OT_ERROR_PARSE);
|
||||
aOffset += bytesRead;
|
||||
|
||||
VerifyOrExit(IsFragmentHeader(), error = OT_ERROR_PARSE);
|
||||
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mTag), &mTag);
|
||||
VerifyOrExit(bytesRead == sizeof(mTag), error = OT_ERROR_PARSE);
|
||||
aOffset += bytesRead;
|
||||
|
||||
if (IsOffsetPresent())
|
||||
{
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mOffset), &mOffset);
|
||||
VerifyOrExit(bytesRead == sizeof(mOffset), error = OT_ERROR_PARSE);
|
||||
aOffset += bytesRead;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Lowpan
|
||||
} // namespace ot
|
||||
|
||||
+43
-14
@@ -138,21 +138,35 @@ public:
|
||||
/**
|
||||
* This method decompresses a LOWPAN_IPHC header.
|
||||
*
|
||||
* @param[out] aHeader A reference where the IPv6 header will be placed.
|
||||
* @param[in] aMacSource The MAC source address.
|
||||
* @param[in] aMacDest The MAC destination address.
|
||||
* @param[in] aBuf A pointer to the LOWPAN_IPHC header.
|
||||
* @param[in] aBufLength The number of bytes in @p aBuf.
|
||||
* @param[out] aHeader A reference where the IPv6 header will be placed.
|
||||
* @param[out] aCommpressedNextHeader A boolean reference to output whether next header is compressed or not.
|
||||
* @param[in] aMacSource The MAC source address.
|
||||
* @param[in] aMacDest The MAC destination address.
|
||||
* @param[in] aBuf A pointer to the LOWPAN_IPHC header.
|
||||
* @param[in] aBufLength The number of bytes in @p aBuf.
|
||||
*
|
||||
* @returns The size of the compressed header in bytes.
|
||||
* @returns The size of the compressed header in bytes or -1 if decompression fails.
|
||||
*
|
||||
*/
|
||||
int DecompressBaseHeader(Ip6::Header & aHeader,
|
||||
bool & aCompressedNextHeader,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
const uint8_t * aBuf,
|
||||
uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method decompresses a LOWPAN_NHC UDP header.
|
||||
*
|
||||
* @param[out] aUdpHeader A reference where the UDP header will be placed.
|
||||
* @param[in] aBuf A pointer to the LOWPAN_NHC header.
|
||||
* @param[in] aBufLength The number of bytes in @p aBuf.
|
||||
*
|
||||
* @returns The size of the compressed header in bytes or -1 if decompression fails.
|
||||
*
|
||||
*/
|
||||
int DecompressUdpHeader(Ip6::UdpHeader &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -279,7 +293,7 @@ public:
|
||||
* @retval FALSE If the header does not match the Mesh Header dispatch value.
|
||||
*
|
||||
*/
|
||||
bool IsMeshHeader(void) { return (mDispatchHopsLeft & kDispatchMask) == kDispatch; }
|
||||
bool IsMeshHeader(void) const { return (mDispatchHopsLeft & kDispatchMask) == kDispatch; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Mesh Header appears to be well-formed.
|
||||
@@ -288,7 +302,7 @@ public:
|
||||
* @retval FALSE If the header does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) { return (mDispatchHopsLeft & kSourceShort) && (mDispatchHopsLeft & kDestinationShort); }
|
||||
bool IsValid(void) const { return (mDispatchHopsLeft & kSourceShort) && (mDispatchHopsLeft & kDestinationShort); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the header contains Deep Hops Left field.
|
||||
@@ -297,7 +311,7 @@ public:
|
||||
* @retval FALSE If the header does not contain Deep Hops Left field.
|
||||
*
|
||||
*/
|
||||
bool IsDeepHopsLeftField(void) { return (mDispatchHopsLeft & kHopsLeftMask) == kDeepHopsLeft; }
|
||||
bool IsDeepHopsLeftField(void) const { return (mDispatchHopsLeft & kHopsLeftMask) == kDeepHopsLeft; }
|
||||
|
||||
/**
|
||||
* This static method returns the size of the Mesh Header in bytes.
|
||||
@@ -305,7 +319,7 @@ public:
|
||||
* @returns The size of the Mesh Header in bytes.
|
||||
*
|
||||
*/
|
||||
uint8_t GetHeaderLength(void) { return sizeof(*this) - (IsDeepHopsLeftField() ? 0 : sizeof(mDeepHopsLeft)); }
|
||||
uint8_t GetHeaderLength(void) const { return sizeof(*this) - (IsDeepHopsLeftField() ? 0 : sizeof(mDeepHopsLeft)); }
|
||||
|
||||
/**
|
||||
* This method returns the Hops Left value.
|
||||
@@ -313,7 +327,10 @@ public:
|
||||
* @returns The Hops Left value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetHopsLeft(void) { return IsDeepHopsLeftField() ? mDeepHopsLeft : mDispatchHopsLeft & kHopsLeftMask; }
|
||||
uint8_t GetHopsLeft(void) const
|
||||
{
|
||||
return IsDeepHopsLeftField() ? mDeepHopsLeft : mDispatchHopsLeft & kHopsLeftMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Hops Left value.
|
||||
@@ -340,7 +357,7 @@ public:
|
||||
* @returns The Mesh Source address.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSource(void) { return HostSwap16(mAddress.mSource); }
|
||||
uint16_t GetSource(void) const { return HostSwap16(mAddress.mSource); }
|
||||
|
||||
/**
|
||||
* This method sets the Mesh Source address.
|
||||
@@ -356,7 +373,7 @@ public:
|
||||
* @returns The Mesh Destination address.
|
||||
*
|
||||
*/
|
||||
uint16_t GetDestination(void) { return HostSwap16(mAddress.mDestination); }
|
||||
uint16_t GetDestination(void) const { return HostSwap16(mAddress.mDestination); }
|
||||
|
||||
/**
|
||||
* This method sets the Mesh Destination address.
|
||||
@@ -372,7 +389,7 @@ public:
|
||||
* @param[in] aFrame The pointer to the frame.
|
||||
*
|
||||
*/
|
||||
void AppendTo(uint8_t *aFrame)
|
||||
void AppendTo(uint8_t *aFrame) const
|
||||
{
|
||||
*aFrame++ = mDispatchHopsLeft;
|
||||
|
||||
@@ -441,6 +458,18 @@ public:
|
||||
*/
|
||||
otError Init(const uint8_t *aFrame, uint8_t aFrameLength);
|
||||
|
||||
/**
|
||||
* This method initializes the fragment header from a message @p aMessage.
|
||||
*
|
||||
* @param[in] aMessage The message object.
|
||||
* @param[in] aOffset An offset into the message to read the header.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Fragment Header initialized successfully.
|
||||
* @retval OT_ERROR_PARSE Fragment header could not be initialized (e.g., no frag header or message too short).
|
||||
*
|
||||
*/
|
||||
otError Init(const Message &aMessage, uint16_t aOffset);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the header is a Fragment Header.
|
||||
*
|
||||
|
||||
@@ -157,7 +157,7 @@ void MeshForwarder::RemoveMessage(Message &aMessage)
|
||||
}
|
||||
|
||||
mSendQueue.Dequeue(aMessage);
|
||||
LogIp6Message(kMessageEvict, aMessage, NULL, OT_ERROR_NO_BUFS);
|
||||
LogMessage(kMessageEvict, aMessage, NULL, OT_ERROR_NO_BUFS);
|
||||
aMessage.Free();
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ Message *MeshForwarder::GetDirectTransmission(void)
|
||||
case OT_ERROR_DROP:
|
||||
case OT_ERROR_NO_BUFS:
|
||||
mSendQueue.Dequeue(*curMessage);
|
||||
LogIp6Message(kMessageDrop, *curMessage, NULL, error);
|
||||
LogMessage(kMessageDrop, *curMessage, NULL, error);
|
||||
curMessage->Free();
|
||||
continue;
|
||||
|
||||
@@ -1001,7 +1001,7 @@ void MeshForwarder::HandleSentFrame(Mac::Frame &aFrame, otError aError)
|
||||
|
||||
if (mMessageNextOffset >= mSendMessage->GetLength())
|
||||
{
|
||||
LogIp6Message(kMessageTransmit, *mSendMessage, &macDest, aError);
|
||||
LogMessage(kMessageTransmit, *mSendMessage, &macDest, aError);
|
||||
|
||||
if (aError == OT_ERROR_NONE)
|
||||
{
|
||||
@@ -1309,7 +1309,7 @@ void MeshForwarder::ClearReassemblyList(void)
|
||||
next = message->GetNext();
|
||||
mReassemblyList.Dequeue(*message);
|
||||
|
||||
LogIp6Message(kMessageReassemblyDrop, *message, NULL, OT_ERROR_NO_FRAME_RECEIVED);
|
||||
LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_NO_FRAME_RECEIVED);
|
||||
mIpCounters.mRxFailure++;
|
||||
|
||||
message->Free();
|
||||
@@ -1339,7 +1339,7 @@ void MeshForwarder::HandleReassemblyTimer(void)
|
||||
{
|
||||
mReassemblyList.Dequeue(*message);
|
||||
|
||||
LogIp6Message(kMessageReassemblyDrop, *message, NULL, OT_ERROR_REASSEMBLY_TIMEOUT);
|
||||
LogMessage(kMessageReassemblyDrop, *message, NULL, OT_ERROR_REASSEMBLY_TIMEOUT);
|
||||
mIpCounters.mRxFailure++;
|
||||
|
||||
message->Free();
|
||||
@@ -1408,7 +1408,7 @@ otError MeshForwarder::HandleDatagram(Message & aMessage,
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
|
||||
LogIp6Message(kMessageReceive, aMessage, &aMacSource, OT_ERROR_NONE);
|
||||
LogMessage(kMessageReceive, aMessage, &aMacSource, OT_ERROR_NONE);
|
||||
mIpCounters.mRxSuccess++;
|
||||
|
||||
return netif.GetIp6().HandleDatagram(aMessage, &netif, netif.GetInterfaceId(), &aLinkInfo, false);
|
||||
@@ -1421,78 +1421,68 @@ void MeshForwarder::HandleDataPollTimeout(Mac::Receiver &aReceiver)
|
||||
|
||||
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||
|
||||
void MeshForwarder::LogIp6Message(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError)
|
||||
otError MeshForwarder::ParseIp6UdpTcpHeader(const Message &aMessage,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint16_t & aChecksum,
|
||||
uint16_t & aSourcePort,
|
||||
uint16_t & aDestPort)
|
||||
{
|
||||
uint16_t checksum = 0;
|
||||
Ip6::Header ip6Header;
|
||||
Ip6::IpProto protocol;
|
||||
const char * actionText;
|
||||
const char * priorityText;
|
||||
bool shouldLogRss = false;
|
||||
bool shouldLogSrcDstAddresses = (OPENTHREAD_CONFIG_LOG_SRC_DST_IP_ADDRESSES != 0);
|
||||
otError error = OT_ERROR_PARSE;
|
||||
union
|
||||
{
|
||||
Ip6::UdpHeader udp;
|
||||
Ip6::TcpHeader tcp;
|
||||
} header;
|
||||
|
||||
VerifyOrExit(aMessage.GetType() == Message::kTypeIp6);
|
||||
aChecksum = 0;
|
||||
aSourcePort = 0;
|
||||
aDestPort = 0;
|
||||
|
||||
VerifyOrExit(sizeof(ip6Header) == aMessage.Read(0, sizeof(ip6Header), &ip6Header));
|
||||
VerifyOrExit(ip6Header.IsVersion6());
|
||||
VerifyOrExit(sizeof(Ip6::Header) == aMessage.Read(0, sizeof(Ip6::Header), &aIp6Header));
|
||||
VerifyOrExit(aIp6Header.IsVersion6());
|
||||
|
||||
protocol = ip6Header.GetNextHeader();
|
||||
|
||||
switch (protocol)
|
||||
switch (aIp6Header.GetNextHeader())
|
||||
{
|
||||
case Ip6::kProtoUdp:
|
||||
{
|
||||
Ip6::UdpHeader udpHeader;
|
||||
|
||||
if (sizeof(udpHeader) == aMessage.Read(sizeof(ip6Header), sizeof(udpHeader), &udpHeader))
|
||||
{
|
||||
checksum = udpHeader.GetChecksum();
|
||||
}
|
||||
|
||||
VerifyOrExit(sizeof(Ip6::UdpHeader) == aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::UdpHeader), &header.udp));
|
||||
aChecksum = header.udp.GetChecksum();
|
||||
aSourcePort = header.udp.GetSourcePort();
|
||||
aDestPort = header.udp.GetDestinationPort();
|
||||
break;
|
||||
}
|
||||
|
||||
case Ip6::kProtoTcp:
|
||||
{
|
||||
Ip6::TcpHeader tcpHeader;
|
||||
|
||||
if (sizeof(tcpHeader) == aMessage.Read(sizeof(ip6Header), sizeof(tcpHeader), &tcpHeader))
|
||||
{
|
||||
checksum = tcpHeader.GetChecksum();
|
||||
}
|
||||
|
||||
VerifyOrExit(sizeof(Ip6::TcpHeader) == aMessage.Read(sizeof(Ip6::Header), sizeof(Ip6::TcpHeader), &header.tcp));
|
||||
aChecksum = header.tcp.GetChecksum();
|
||||
aSourcePort = header.tcp.GetSourcePort();
|
||||
aDestPort = header.tcp.GetDestinationPort();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *MeshForwarder::MessageActionToString(MessageAction aAction, otError aError)
|
||||
{
|
||||
const char *actionText = "";
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kMessageReceive:
|
||||
actionText = "Received";
|
||||
shouldLogRss = true;
|
||||
actionText = "Received";
|
||||
break;
|
||||
|
||||
case kMessageTransmit:
|
||||
if (aError == OT_ERROR_NONE)
|
||||
{
|
||||
actionText = "Sent";
|
||||
}
|
||||
else
|
||||
{
|
||||
actionText = "Failed to send";
|
||||
}
|
||||
|
||||
actionText = (aError == OT_ERROR_NONE) ? "Sent" : "Failed to send";
|
||||
break;
|
||||
|
||||
case kMessagePrepareIndirect:
|
||||
actionText = "Prepping indir tx";
|
||||
shouldLogSrcDstAddresses = false;
|
||||
actionText = "Prepping indir tx";
|
||||
break;
|
||||
|
||||
case kMessageDrop:
|
||||
@@ -1500,19 +1490,21 @@ void MeshForwarder::LogIp6Message(MessageAction aAction,
|
||||
break;
|
||||
|
||||
case kMessageReassemblyDrop:
|
||||
actionText = "Dropping (reassembly queue)";
|
||||
shouldLogRss = true;
|
||||
actionText = "Dropping (reassembly queue)";
|
||||
break;
|
||||
|
||||
case kMessageEvict:
|
||||
actionText = "Evicting";
|
||||
break;
|
||||
|
||||
default:
|
||||
actionText = "";
|
||||
break;
|
||||
}
|
||||
|
||||
return actionText;
|
||||
}
|
||||
|
||||
const char *MeshForwarder::MessagePriorityToString(const Message &aMessage)
|
||||
{
|
||||
const char *priorityText = "unknown";
|
||||
|
||||
switch (aMessage.GetPriority())
|
||||
{
|
||||
case Message::kPriorityHigh:
|
||||
@@ -1530,30 +1522,264 @@ void MeshForwarder::LogIp6Message(MessageAction aAction,
|
||||
case Message::kPriorityVeryLow:
|
||||
priorityText = "verylow";
|
||||
break;
|
||||
|
||||
default:
|
||||
priorityText = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
otLogInfoMac(GetInstance(), "%s IPv6 %s msg, len:%d, chksum:%04x%s%s, sec:%s%s%s, prio:%s%s%s", actionText,
|
||||
Ip6::Ip6::IpProtoToString(protocol), aMessage.GetLength(), checksum,
|
||||
return priorityText;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_SRC_DST_IP_ADDRESSES
|
||||
void MeshForwarder::LogIp6SourceDestAddresses(Ip6::Header &aIp6Header, uint16_t aSourcePort, uint16_t aDestPort)
|
||||
{
|
||||
if (aSourcePort != 0)
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "\tsrc:[%s]:%d", aIp6Header.GetSource().ToString().AsCString(), aSourcePort);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "\tsrc:[%s]", aIp6Header.GetSource().ToString().AsCString());
|
||||
}
|
||||
|
||||
if (aDestPort != 0)
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "\tdst:[%s]:%d", aIp6Header.GetDestination().ToString().AsCString(), aDestPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "\tdst:[%s]", aIp6Header.GetDestination().ToString().AsCString());
|
||||
}
|
||||
}
|
||||
#else
|
||||
void MeshForwarder::LogIp6SourceDestAddresses(Ip6::Header &, uint16_t, uint16_t)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void MeshForwarder::LogIp6Message(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError)
|
||||
{
|
||||
Ip6::Header ip6Header;
|
||||
uint16_t checksum;
|
||||
uint16_t sourcePort;
|
||||
uint16_t destPort;
|
||||
bool shouldLogRss;
|
||||
|
||||
SuccessOrExit(ParseIp6UdpTcpHeader(aMessage, ip6Header, checksum, sourcePort, destPort));
|
||||
|
||||
shouldLogRss = (aAction == kMessageReceive) || (aAction == kMessageReassemblyDrop);
|
||||
|
||||
otLogInfoMac(GetInstance(), "%s IPv6 %s msg, len:%d, chksum:%04x%s%s, sec:%s%s%s, prio:%s%s%s",
|
||||
MessageActionToString(aAction, aError), Ip6::Ip6::IpProtoToString(ip6Header.GetNextHeader()),
|
||||
aMessage.GetLength(), checksum,
|
||||
(aMacAddress == NULL) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
|
||||
(aMacAddress == NULL) ? "" : aMacAddress->ToString().AsCString(),
|
||||
aMessage.IsLinkSecurityEnabled() ? "yes" : "no", (aError == OT_ERROR_NONE) ? "" : ", error:",
|
||||
(aError == OT_ERROR_NONE) ? "" : otThreadErrorToString(aError), priorityText,
|
||||
(aError == OT_ERROR_NONE) ? "" : otThreadErrorToString(aError), MessagePriorityToString(aMessage),
|
||||
shouldLogRss ? ", rss:" : "", shouldLogRss ? aMessage.GetRssAverager().ToString().AsCString() : "");
|
||||
|
||||
if (shouldLogSrcDstAddresses)
|
||||
if (aAction != kMessagePrepareIndirect)
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "src: %s", ip6Header.GetSource().ToString().AsCString());
|
||||
otLogInfoMac(GetInstance(), "dst: %s", ip6Header.GetDestination().ToString().AsCString());
|
||||
LogIp6SourceDestAddresses(ip6Header, sourcePort, destPort);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError MeshForwarder::LogMeshFragmentHeader(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError,
|
||||
uint16_t & aOffset,
|
||||
Mac::Address & aMeshSource,
|
||||
Mac::Address & aMeshDest)
|
||||
{
|
||||
otError error = OT_ERROR_FAILED;
|
||||
bool hasFragmentHeader = false;
|
||||
bool shouldLogRss;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
|
||||
SuccessOrExit(meshHeader.Init(aMessage));
|
||||
VerifyOrExit(meshHeader.IsMeshHeader());
|
||||
|
||||
aMeshSource.SetShort(meshHeader.GetSource());
|
||||
aMeshDest.SetShort(meshHeader.GetDestination());
|
||||
|
||||
aOffset = meshHeader.GetHeaderLength();
|
||||
|
||||
if (fragmentHeader.Init(aMessage, aOffset) == OT_ERROR_NONE)
|
||||
{
|
||||
hasFragmentHeader = true;
|
||||
aOffset += fragmentHeader.GetHeaderLength();
|
||||
}
|
||||
|
||||
shouldLogRss = (aAction == kMessageReceive) || (aAction == kMessageReassemblyDrop);
|
||||
|
||||
otLogInfoMac(
|
||||
GetInstance(), "%s mesh frame, len:%d%s%s, msrc:%s, mdst:%s, hops:%d, frag:%s, sec:%s%s%s%s%s",
|
||||
MessageActionToString(aAction, aError), aMessage.GetLength(),
|
||||
(aMacAddress == NULL) ? "" : ((aAction == kMessageReceive) ? ", from:" : ", to:"),
|
||||
(aMacAddress == NULL) ? "" : aMacAddress->ToString().AsCString(), aMeshSource.ToString().AsCString(),
|
||||
aMeshDest.ToString().AsCString(), meshHeader.GetHopsLeft() + ((aAction == kMessageReceive) ? 1 : 0),
|
||||
hasFragmentHeader ? "yes" : "no", aMessage.IsLinkSecurityEnabled() ? "yes" : "no",
|
||||
(aError == OT_ERROR_NONE) ? "" : ", error:", (aError == OT_ERROR_NONE) ? "" : otThreadErrorToString(aError),
|
||||
shouldLogRss ? ", rss:" : "", shouldLogRss ? aMessage.GetRssAverager().ToString().AsCString() : "");
|
||||
|
||||
if (hasFragmentHeader)
|
||||
{
|
||||
otLogInfoMac(GetInstance(), "\tFrag tag:%04x, offset:%d, size:%d", fragmentHeader.GetDatagramTag(),
|
||||
fragmentHeader.GetDatagramOffset(), fragmentHeader.GetDatagramSize());
|
||||
|
||||
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0);
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::DecompressIp6UdpTcpHeader(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint16_t & aChecksum,
|
||||
uint16_t & aSourcePort,
|
||||
uint16_t & aDestPort)
|
||||
{
|
||||
otError error = OT_ERROR_PARSE;
|
||||
Lowpan::Lowpan &lowpan = GetNetif().GetLowpan();
|
||||
int headerLength;
|
||||
bool nextHeaderCompressed;
|
||||
uint8_t frameBuffer[sizeof(Ip6::Header)];
|
||||
uint16_t frameLength;
|
||||
union
|
||||
{
|
||||
Ip6::UdpHeader udp;
|
||||
Ip6::TcpHeader tcp;
|
||||
} header;
|
||||
|
||||
aChecksum = 0;
|
||||
aSourcePort = 0;
|
||||
aDestPort = 0;
|
||||
|
||||
// Read and decompress the IPv6 header
|
||||
|
||||
frameLength = aMessage.Read(aOffset, sizeof(frameBuffer), frameBuffer);
|
||||
|
||||
headerLength =
|
||||
lowpan.DecompressBaseHeader(aIp6Header, nextHeaderCompressed, aMeshSource, aMeshDest, frameBuffer, frameLength);
|
||||
VerifyOrExit(headerLength >= 0);
|
||||
|
||||
aOffset += headerLength;
|
||||
|
||||
// Read and decompress UDP or TCP header
|
||||
|
||||
switch (aIp6Header.GetNextHeader())
|
||||
{
|
||||
case Ip6::kProtoUdp:
|
||||
if (nextHeaderCompressed)
|
||||
{
|
||||
frameLength = aMessage.Read(aOffset, sizeof(Ip6::UdpHeader), frameBuffer);
|
||||
headerLength = lowpan.DecompressUdpHeader(header.udp, frameBuffer, frameLength);
|
||||
VerifyOrExit(headerLength >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(sizeof(Ip6::UdpHeader) == aMessage.Read(aOffset, sizeof(Ip6::UdpHeader), &header.udp));
|
||||
}
|
||||
|
||||
aChecksum = header.udp.GetChecksum();
|
||||
aSourcePort = header.udp.GetSourcePort();
|
||||
aDestPort = header.udp.GetDestinationPort();
|
||||
break;
|
||||
|
||||
case Ip6::kProtoTcp:
|
||||
VerifyOrExit(sizeof(Ip6::TcpHeader) == aMessage.Read(aOffset, sizeof(Ip6::TcpHeader), &header.tcp));
|
||||
aChecksum = header.tcp.GetChecksum();
|
||||
aSourcePort = header.tcp.GetSourcePort();
|
||||
aDestPort = header.tcp.GetDestinationPort();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MeshForwarder::LogMeshIpHeader(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest)
|
||||
{
|
||||
uint16_t checksum;
|
||||
uint16_t sourcePort;
|
||||
uint16_t destPort;
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
SuccessOrExit(DecompressIp6UdpTcpHeader(aMessage, aOffset, aMeshSource, aMeshDest, ip6Header, checksum, sourcePort,
|
||||
destPort));
|
||||
|
||||
otLogInfoMac(GetInstance(), "\tIPv6 %s msg, chksum:%04x, prio:%s",
|
||||
Ip6::Ip6::IpProtoToString(ip6Header.GetNextHeader()), checksum, MessagePriorityToString(aMessage));
|
||||
|
||||
LogIp6SourceDestAddresses(ip6Header, sourcePort, destPort);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void MeshForwarder::LogMeshMessage(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError)
|
||||
{
|
||||
uint16_t offset;
|
||||
Mac::Address meshSource;
|
||||
Mac::Address meshDest;
|
||||
|
||||
SuccessOrExit(LogMeshFragmentHeader(aAction, aMessage, aMacAddress, aError, offset, meshSource, meshDest));
|
||||
|
||||
// When log action is `kMessageTransmit` we do not include
|
||||
// the IPv6 header info in the logs, as the same info is
|
||||
// logged when the same Mesh Header message was received
|
||||
// and info about it was logged.
|
||||
|
||||
VerifyOrExit(aAction != kMessageTransmit);
|
||||
|
||||
LogMeshIpHeader(aMessage, offset, meshSource, meshDest);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void MeshForwarder::LogMessage(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError)
|
||||
{
|
||||
switch (aMessage.GetType())
|
||||
{
|
||||
case Message::kTypeIp6:
|
||||
LogIp6Message(aAction, aMessage, aMacAddress, aError);
|
||||
break;
|
||||
|
||||
case Message::kType6lowpan:
|
||||
LogMeshMessage(aAction, aMessage, aMacAddress, aError);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::LogFrame(const char *aActionText, const Mac::Frame &aFrame, otError aError)
|
||||
{
|
||||
if (aError != OT_ERROR_NONE)
|
||||
@@ -1594,7 +1820,7 @@ void MeshForwarder::LogLowpanHcFrameDrop(otError aError,
|
||||
|
||||
#else // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||
|
||||
void MeshForwarder::LogIp6Message(MessageAction, const Message &, const Mac::Address *, otError)
|
||||
void MeshForwarder::LogMessage(MessageAction, const Message &, const Mac::Address *, otError)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ private:
|
||||
|
||||
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
|
||||
|
||||
void LogIp6Message(MessageAction aAction, const Message &aMessage, const Mac::Address *aMacAddress, otError aError);
|
||||
void LogMessage(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
|
||||
void LogFrame(const char *aActionText, const Mac::Frame &aFrame, otError aError);
|
||||
void LogFragmentFrameDrop(otError aError,
|
||||
uint8_t aFrameLength,
|
||||
@@ -340,6 +340,40 @@ private:
|
||||
const Mac::Address &aMacDest,
|
||||
bool aIsSecure);
|
||||
|
||||
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||
const char *MessageActionToString(MessageAction aAction, otError aError);
|
||||
const char *MessagePriorityToString(const Message &aMessage);
|
||||
|
||||
otError ParseIp6UdpTcpHeader(const Message &aMessage,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint16_t & aChecksum,
|
||||
uint16_t & aSourcePort,
|
||||
uint16_t & aDestPort);
|
||||
otError DecompressIp6UdpTcpHeader(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest,
|
||||
Ip6::Header & aIp6Header,
|
||||
uint16_t & aChecksum,
|
||||
uint16_t & aSourcePort,
|
||||
uint16_t & aDestPort);
|
||||
otError LogMeshFragmentHeader(MessageAction aAction,
|
||||
const Message & aMessage,
|
||||
const Mac::Address *aMacAddress,
|
||||
otError aError,
|
||||
uint16_t & aOffset,
|
||||
Mac::Address & aMeshSource,
|
||||
Mac::Address & aMeshDest);
|
||||
|
||||
void LogIp6SourceDestAddresses(Ip6::Header &aIp6Header, uint16_t aSourcePort, uint16_t aDestPort);
|
||||
void LogMeshIpHeader(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
const Mac::Address &aMeshSource,
|
||||
const Mac::Address &aMeshDest);
|
||||
void LogMeshMessage(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
|
||||
void LogIp6Message(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
|
||||
#endif
|
||||
|
||||
Mac::Receiver mMacReceiver;
|
||||
Mac::Sender mMacSender;
|
||||
TimerMilli mDiscoverTimer;
|
||||
|
||||
@@ -174,7 +174,7 @@ void MeshForwarder::HandleResolved(const Ip6::Address &aEid, otError aError)
|
||||
}
|
||||
else
|
||||
{
|
||||
LogIp6Message(kMessageDrop, *cur, NULL, aError);
|
||||
LogMessage(kMessageDrop, *cur, NULL, aError);
|
||||
cur->Free();
|
||||
}
|
||||
}
|
||||
@@ -361,7 +361,7 @@ void MeshForwarder::RemoveDataResponseMessages(void)
|
||||
}
|
||||
|
||||
mSendQueue.Dequeue(*message);
|
||||
LogIp6Message(kMessageDrop, *message, NULL, OT_ERROR_NONE);
|
||||
LogMessage(kMessageDrop, *message, NULL, OT_ERROR_NONE);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ Message *MeshForwarder::GetIndirectTransmission(Child &aChild)
|
||||
{
|
||||
Mac::Address macAddr;
|
||||
|
||||
LogIp6Message(kMessagePrepareIndirect, *message, &aChild.GetMacAddress(macAddr), OT_ERROR_NONE);
|
||||
LogMessage(kMessagePrepareIndirect, *message, &aChild.GetMacAddress(macAddr), OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
return message;
|
||||
@@ -830,6 +830,7 @@ otError MeshForwarder::CheckReachability(uint8_t * aFrame,
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE, error = OT_ERROR_DROP);
|
||||
|
||||
@@ -850,7 +851,8 @@ otError MeshForwarder::CheckReachability(uint8_t * aFrame,
|
||||
// only process IPv6 packets
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame));
|
||||
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, aMeshSource, aMeshDest, aFrame, aFrameLength) > 0,
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, nextHeaderCompressed, aMeshSource, aMeshDest, aFrame,
|
||||
aFrameLength) > 0,
|
||||
error = OT_ERROR_DROP);
|
||||
|
||||
error = netif.GetMle().CheckReachability(aMeshSource.GetShort(), aMeshDest.GetShort(), ip6Header);
|
||||
@@ -915,6 +917,9 @@ void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
||||
message->Write(0, aFrameLength, aFrame);
|
||||
message->SetLinkSecurityEnabled(aLinkInfo.mLinkSecurity);
|
||||
message->SetPanId(aLinkInfo.mPanId);
|
||||
message->AddRss(aLinkInfo.mRss);
|
||||
|
||||
LogMessage(kMessageReceive, *message, &aMacSource, OT_ERROR_NONE);
|
||||
|
||||
SendMessage(*message);
|
||||
}
|
||||
@@ -942,6 +947,7 @@ void MeshForwarder::UpdateRoutes(uint8_t * aFrame,
|
||||
ThreadNetif &netif = GetNetif();
|
||||
Ip6::Header ip6Header;
|
||||
Neighbor * neighbor;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
VerifyOrExit(!aMeshDest.IsBroadcast() && aMeshSource.IsShort());
|
||||
|
||||
@@ -965,7 +971,8 @@ void MeshForwarder::UpdateRoutes(uint8_t * aFrame,
|
||||
// only process IPv6 packets
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame));
|
||||
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, aMeshSource, aMeshDest, aFrame, aFrameLength) > 0);
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, nextHeaderCompressed, aMeshSource, aMeshDest, aFrame,
|
||||
aFrameLength) > 0);
|
||||
|
||||
netif.GetAddressResolver().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user