Skip to content

Commit a495a22

Browse files
authored
[otns] make various enhancements to Otns (openthread#11643)
This commit contains various enhancements to the `Otns` class: - Makes `Otns` methods non-static. This aligns their use with the clang-tidy `readability-static-accessed-through-instance` check, which disallows accessing static methods through an instance. - Updates the `make-pretty` script to enable OTNS and include it in `clang-tidy` checks. - Adds a stub implementation of `otPlatOtnsStatus()` in the simulation and fake platforms. This allows the OTNS feature to be enabled in `make-pretty` builds and covered by GitHub Action CI checks. - Simplifies the `EmitStatus` methods to use the `String` class for constructing the status string. - Adds a new helper method to construct the CoAP status string, removing duplicated code.
1 parent 0093b9c commit a495a22

7 files changed

Lines changed: 130 additions & 95 deletions

File tree

examples/platforms/simulation/misc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,7 @@ void otPlatAssertFail(const char *aFilename, int aLineNumber)
122122
assert(false);
123123
exit(1);
124124
}
125+
126+
#if OPENTHREAD_CONFIG_OTNS_ENABLE && !OPENTHREAD_SIMULATION_VIRTUAL_TIME
127+
void otPlatOtnsStatus(const char *aStatus) { OT_UNUSED_VARIABLE(aStatus); }
128+
#endif

examples/platforms/simulation/platform-config.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,6 @@
7676
#define OPENTHREAD_CONFIG_NCP_SPI_ENABLE 0
7777
#endif
7878

79-
/**
80-
* Check OTNS configurations
81-
*/
82-
#if OPENTHREAD_CONFIG_OTNS_ENABLE
83-
84-
#if !OPENTHREAD_SIMULATION_VIRTUAL_TIME
85-
#error "OTNS requires virtual time simulations"
86-
#endif
87-
88-
#endif // OPENTHREAD_CONFIG_OTNS_ENABLE
89-
9079
/**
9180
* @def OPENTHREAD_SIMULATION_MAX_NETWORK_SIZE
9281
*

script/make-pretty

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ OT_CLANG_TIDY_BUILD_OPTS=(
129129
'-DOT_NAT64_TRANSLATOR=ON'
130130
'-DOT_NETDATA_PUBLISHER=ON'
131131
'-DOT_NETDIAG_CLIENT=ON'
132+
'-DOT_OTNS=ON'
132133
'-DOT_PING_SENDER=ON'
133134
'-DOT_REFERENCE_DEVICE=ON'
134135
'-DOT_SERVICE=ON'

src/core/utils/otns.cpp

Lines changed: 89 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -42,49 +42,49 @@ namespace Utils {
4242

4343
RegisterLogModule("Otns");
4444

45-
const int kMaxStatusStringLength = 128;
45+
void Otns::EmitShortAddress(uint16_t aShortAddress) const { EmitStatus("rloc16=%d", aShortAddress); }
4646

47-
void Otns::EmitShortAddress(uint16_t aShortAddress) { EmitStatus("rloc16=%d", aShortAddress); }
48-
49-
void Otns::EmitExtendedAddress(const Mac::ExtAddress &aExtAddress)
47+
void Otns::EmitExtendedAddress(const Mac::ExtAddress &aExtAddress) const
5048
{
5149
Mac::ExtAddress revExtAddress;
50+
5251
revExtAddress.Set(aExtAddress.m8, Mac::ExtAddress::kReverseByteOrder);
5352
EmitStatus("extaddr=%s", revExtAddress.ToString().AsCString());
5453
}
5554

5655
void Otns::EmitPingRequest(const Ip6::Address &aPeerAddress,
5756
uint16_t aPingLength,
5857
uint32_t aTimestamp,
59-
uint8_t aHopLimit)
58+
uint8_t aHopLimit) const
6059
{
6160
OT_UNUSED_VARIABLE(aHopLimit);
62-
EmitStatus("ping_request=%s,%d,%lu", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp);
61+
EmitStatus("ping_request=%s,%d,%lu", aPeerAddress.ToString().AsCString(), aPingLength, ToUlong(aTimestamp));
6362
}
6463

65-
void Otns::EmitPingReply(const Ip6::Address &aPeerAddress, uint16_t aPingLength, uint32_t aTimestamp, uint8_t aHopLimit)
64+
void Otns::EmitPingReply(const Ip6::Address &aPeerAddress,
65+
uint16_t aPingLength,
66+
uint32_t aTimestamp,
67+
uint8_t aHopLimit) const
6668
{
67-
EmitStatus("ping_reply=%s,%u,%lu,%d", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp, aHopLimit);
69+
EmitStatus("ping_reply=%s,%u,%lu,%d", aPeerAddress.ToString().AsCString(), aPingLength, ToUlong(aTimestamp),
70+
aHopLimit);
6871
}
6972

70-
void Otns::EmitStatus(const char *aFmt, ...)
73+
void Otns::EmitStatus(const char *aFmt, ...) const
7174
{
72-
char statusStr[kMaxStatusStringLength + 1];
73-
int n;
74-
75-
va_list ap;
76-
va_start(ap, aFmt);
75+
StatusString string;
76+
va_list args;
7777

78-
n = vsnprintf(statusStr, sizeof(statusStr), aFmt, ap);
79-
OT_UNUSED_VARIABLE(n);
80-
OT_ASSERT(n >= 0);
78+
va_start(args, aFmt);
79+
string.AppendVarArgs(aFmt, args);
80+
va_end(args);
8181

82-
va_end(ap);
83-
84-
otPlatOtnsStatus(statusStr);
82+
EmitStatus(string);
8583
}
8684

87-
void Otns::HandleNotifierEvents(Events aEvents)
85+
void Otns::EmitStatus(const StatusString &aString) const { otPlatOtnsStatus(aString.AsCString()); }
86+
87+
void Otns::HandleNotifierEvents(Events aEvents) const
8888
{
8989
if (aEvents.Contains(kEventThreadRoleChanged))
9090
{
@@ -93,7 +93,7 @@ void Otns::HandleNotifierEvents(Events aEvents)
9393

9494
if (aEvents.Contains(kEventThreadPartitionIdChanged))
9595
{
96-
EmitStatus("parid=%x", Get<Mle::Mle>().GetLeaderData().GetPartitionId());
96+
EmitStatus("parid=%lx", ToUlong(Get<Mle::Mle>().GetLeaderData().GetPartitionId()));
9797
}
9898

9999
#if OPENTHREAD_CONFIG_JOINER_ENABLE
@@ -104,95 +104,118 @@ void Otns::HandleNotifierEvents(Events aEvents)
104104
#endif
105105
}
106106

107-
void Otns::EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor)
107+
void Otns::EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor) const
108108
{
109+
StatusString string;
110+
109111
switch (aEvent)
110112
{
111113
case NeighborTable::kRouterAdded:
112-
EmitStatus("router_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
114+
string.Append("router_added");
113115
break;
114116
case NeighborTable::kRouterRemoved:
115-
EmitStatus("router_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
117+
string.Append("router_removed");
116118
break;
117119
case NeighborTable::kChildAdded:
118-
EmitStatus("child_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
120+
string.Append("child_added");
119121
break;
120122
case NeighborTable::kChildRemoved:
121-
EmitStatus("child_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
123+
string.Append("child_removed");
122124
break;
123125
case NeighborTable::kChildModeChanged:
124-
break;
126+
ExitNow();
125127
}
128+
129+
string.Append("=%s", aNeighbor.GetExtAddress().ToString().AsCString());
130+
EmitStatus(string);
131+
132+
exit:
133+
return;
126134
}
127135

128-
void Otns::EmitTransmit(const Mac::TxFrame &aFrame)
136+
void Otns::EmitTransmit(const Mac::TxFrame &aFrame) const
129137
{
138+
StatusString string;
130139
Mac::Address dst;
131-
uint16_t frameControlField = aFrame.GetFrameControlField();
132-
uint8_t channel = aFrame.GetChannel();
133-
uint8_t sequence = aFrame.GetSequence();
134140

135141
IgnoreError(aFrame.GetDstAddr(dst));
136142

143+
string.Append("transmit=%d,%04x,%d", aFrame.GetChannel(), aFrame.GetFrameControlField(), aFrame.GetSequence());
144+
137145
if (dst.IsShort())
138146
{
139-
EmitStatus("transmit=%d,%04x,%d,%04x", channel, frameControlField, sequence, dst.GetShort());
147+
string.Append(",%04x", dst.GetShort());
140148
}
141149
else if (dst.IsExtended())
142150
{
143-
EmitStatus("transmit=%d,%04x,%d,%s", channel, frameControlField, sequence, dst.ToString().AsCString());
151+
string.Append(",%s", dst.ToString().AsCString());
144152
}
145-
else
146-
{
147-
EmitStatus("transmit=%d,%04x,%d", channel, frameControlField, sequence);
148-
}
149-
}
150153

151-
void Otns::EmitDeviceMode(Mle::DeviceMode aMode)
152-
{
153-
EmitStatus("mode=%s%s%s", aMode.IsRxOnWhenIdle() ? "r" : "", aMode.IsFullThreadDevice() ? "d" : "",
154-
(aMode.GetNetworkDataType() == NetworkData::kFullSet) ? "n" : "");
154+
EmitStatus(string);
155155
}
156156

157-
void Otns::EmitCoapSend(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
157+
void Otns::EmitDeviceMode(Mle::DeviceMode aMode) const
158158
{
159-
char uriPath[Coap::Message::kMaxReceivedUriPath + 1];
160-
Error error;
159+
StatusString string;
161160

162-
SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
161+
string.Append("mode=");
162+
163+
if (aMode.IsRxOnWhenIdle())
164+
{
165+
string.Append("r");
166+
}
163167

164-
EmitStatus("coap=send,%d,%d,%d,%s,%s,%d", aMessage.GetMessageId(), aMessage.GetType(), aMessage.GetCode(), uriPath,
165-
aMessageInfo.GetPeerAddr().ToString().AsCString(), aMessageInfo.GetPeerPort());
168+
if (aMode.IsFullThreadDevice())
169+
{
170+
string.Append("d");
171+
}
166172

167-
exit:
168-
LogWarnOnError(error, "EmitCoapSend");
173+
if (aMode.GetNetworkDataType() == NetworkData::kFullSet)
174+
{
175+
string.Append("m");
176+
}
177+
178+
EmitStatus(string);
169179
}
170180

171-
void Otns::EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
181+
void Otns::EmitCoapSend(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
172182
{
173-
char uriPath[Coap::Message::kMaxReceivedUriPath + 1];
174-
Error error = kErrorNone;
183+
EmitCoapStatus("send", aMessage, aMessageInfo);
184+
}
175185

176-
SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
186+
void Otns::EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
187+
{
188+
EmitCoapStatus("recv", aMessage, aMessageInfo);
189+
}
177190

178-
EmitStatus("coap=recv,%d,%d,%d,%s,%s,%d", aMessage.GetMessageId(), aMessage.GetType(), aMessage.GetCode(), uriPath,
179-
aMessageInfo.GetPeerAddr().ToString().AsCString(), aMessageInfo.GetPeerPort());
180-
exit:
181-
LogWarnOnError(error, "EmitCoapReceive");
191+
void Otns::EmitCoapSendFailure(Error aError, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
192+
{
193+
EmitCoapStatus("send_error", aMessage, aMessageInfo, &aError);
182194
}
183195

184-
void Otns::EmitCoapSendFailure(Error aError, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
196+
void Otns::EmitCoapStatus(const char *aAction,
197+
const Coap::Message &aMessage,
198+
const Ip6::MessageInfo &aMessageInfo,
199+
Error *aError) const
185200
{
186-
char uriPath[Coap::Message::kMaxReceivedUriPath + 1];
187-
Error error = kErrorNone;
201+
Error error;
202+
char uriPath[Coap::Message::kMaxReceivedUriPath + 1];
203+
StatusString string;
188204

189205
SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
190206

191-
EmitStatus("coap=send_error,%d,%d,%d,%s,%s,%d,%s", aMessage.GetMessageId(), aMessage.GetType(), aMessage.GetCode(),
192-
uriPath, aMessageInfo.GetPeerAddr().ToString().AsCString(), aMessageInfo.GetPeerPort(),
193-
ErrorToString(aError));
207+
string.Append("coap=%s,%d,%d,%d,%s,%s,%d", aAction, aMessage.GetMessageId(), aMessage.GetType(), aMessage.GetCode(),
208+
uriPath, aMessageInfo.GetPeerAddr().ToString().AsCString(), aMessageInfo.GetPeerPort());
209+
210+
if (aError != nullptr)
211+
{
212+
string.Append(",%s", ErrorToString(*aError));
213+
}
214+
215+
EmitStatus(string);
216+
194217
exit:
195-
LogWarnOnError(error, "EmitCoapSendFailure");
218+
LogWarnOnError(error, "EmitCoapStatus");
196219
}
197220

198221
} // namespace Utils

src/core/utils/otns.hpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "common/locator.hpp"
4747
#include "common/non_copyable.hpp"
4848
#include "common/notifier.hpp"
49+
#include "common/string.hpp"
4950
#include "mac/mac_frame.hpp"
5051
#include "mac/mac_types.hpp"
5152
#include "net/ip6_address.hpp"
@@ -78,14 +79,14 @@ class Otns : public InstanceLocator, private NonCopyable
7879
*
7980
* @param[in] aShortAddress The new short address.
8081
*/
81-
static void EmitShortAddress(uint16_t aShortAddress);
82+
void EmitShortAddress(uint16_t aShortAddress) const;
8283

8384
/**
8485
* Emits radio extended address to OTNS when changed.
8586
*
8687
* @param[in] aExtAddress The new extended address.
8788
*/
88-
static void EmitExtendedAddress(const Mac::ExtAddress &aExtAddress);
89+
void EmitExtendedAddress(const Mac::ExtAddress &aExtAddress) const;
8990

9091
/**
9192
* Emits ping request information to OTNS when sending.
@@ -95,10 +96,10 @@ class Otns : public InstanceLocator, private NonCopyable
9596
* @param[in] aTimestamp The timestamp of the ping request.
9697
* @param[in] aHopLimit The hop limit of the ping request.
9798
*/
98-
static void EmitPingRequest(const Ip6::Address &aPeerAddress,
99-
uint16_t aPingLength,
100-
uint32_t aTimestamp,
101-
uint8_t aHopLimit);
99+
void EmitPingRequest(const Ip6::Address &aPeerAddress,
100+
uint16_t aPingLength,
101+
uint32_t aTimestamp,
102+
uint8_t aHopLimit) const;
102103

103104
/**
104105
* Emits ping reply information to OTNS when received.
@@ -108,40 +109,40 @@ class Otns : public InstanceLocator, private NonCopyable
108109
* @param[in] aTimestamp The timestamp of the ping reply.
109110
* @param[in] aHopLimit The hop limit of the ping reply.
110111
*/
111-
static void EmitPingReply(const Ip6::Address &aPeerAddress,
112-
uint16_t aPingLength,
113-
uint32_t aTimestamp,
114-
uint8_t aHopLimit);
112+
void EmitPingReply(const Ip6::Address &aPeerAddress,
113+
uint16_t aPingLength,
114+
uint32_t aTimestamp,
115+
uint8_t aHopLimit) const;
115116

116117
/**
117118
* Emits a neighbor table event to OTNS when a neighbor is added or removed.
118119
*
119120
* @param[in] aEvent The event type.
120121
* @param[in] aNeighbor The neighbor that is added or removed.
121122
*/
122-
static void EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor);
123+
void EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor) const;
123124

124125
/**
125126
* Emits a transmit event to OTNS.
126127
*
127128
* @param[in] aFrame The frame of the transmission.
128129
*/
129-
static void EmitTransmit(const Mac::TxFrame &aFrame);
130+
void EmitTransmit(const Mac::TxFrame &aFrame) const;
130131

131132
/**
132133
* Emits the device mode to OTNS.
133134
*
134135
* @param[in] aMode The device mode.
135136
*/
136-
static void EmitDeviceMode(Mle::DeviceMode aMode);
137+
void EmitDeviceMode(Mle::DeviceMode aMode) const;
137138

138139
/**
139140
* Emits the sending COAP message info to OTNS.
140141
*
141142
* @param[in] aMessage The sending COAP message.
142143
* @param[in] aMessageInfo The message info.
143144
*/
144-
static void EmitCoapSend(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
145+
void EmitCoapSend(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const;
145146

146147
/**
147148
* Emits the COAP message sending failure to OTNS.
@@ -150,19 +151,29 @@ class Otns : public InstanceLocator, private NonCopyable
150151
* @param[in] aMessage The COAP message failed to send.
151152
* @param[in] aMessageInfo The message info.
152153
*/
153-
static void EmitCoapSendFailure(Error aError, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
154+
void EmitCoapSendFailure(Error aError, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const;
154155

155156
/**
156157
* Emits the received COAP message info to OTNS.
157158
*
158159
* @param[in] aMessage The received COAP message.
159160
* @param[in] aMessageInfo The message info.
160161
*/
161-
static void EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
162+
void EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const;
162163

163164
private:
164-
static void EmitStatus(const char *aFmt, ...);
165-
void HandleNotifierEvents(Events aEvents);
165+
static constexpr uint16_t kStatusStringLength = 128;
166+
167+
using StatusString = String<kStatusStringLength>;
168+
169+
void EmitStatus(const StatusString &aString) const;
170+
void EmitStatus(const char *aFmt, ...) const OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 3);
171+
void EmitCoapStatus(const char *aAction,
172+
const Coap::Message &aMessage,
173+
const Ip6::MessageInfo &aMessageInfo,
174+
Error *aError = nullptr) const;
175+
176+
void HandleNotifierEvents(Events aEvents) const;
166177
};
167178

168179
} // namespace Utils

0 commit comments

Comments
 (0)