• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file implements OTNS utilities.
32  */
33 
34 #include "otns.hpp"
35 
36 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
37 
38 #include "instance/instance.hpp"
39 
40 namespace ot {
41 namespace Utils {
42 
43 RegisterLogModule("Otns");
44 
45 const int kMaxStatusStringLength = 128;
46 
EmitShortAddress(uint16_t aShortAddress)47 void Otns::EmitShortAddress(uint16_t aShortAddress) { EmitStatus("rloc16=%d", aShortAddress); }
48 
EmitExtendedAddress(const Mac::ExtAddress & aExtAddress)49 void Otns::EmitExtendedAddress(const Mac::ExtAddress &aExtAddress)
50 {
51     Mac::ExtAddress revExtAddress;
52     revExtAddress.Set(aExtAddress.m8, Mac::ExtAddress::kReverseByteOrder);
53     EmitStatus("extaddr=%s", revExtAddress.ToString().AsCString());
54 }
55 
EmitPingRequest(const Ip6::Address & aPeerAddress,uint16_t aPingLength,uint32_t aTimestamp,uint8_t aHopLimit)56 void Otns::EmitPingRequest(const Ip6::Address &aPeerAddress,
57                            uint16_t            aPingLength,
58                            uint32_t            aTimestamp,
59                            uint8_t             aHopLimit)
60 {
61     OT_UNUSED_VARIABLE(aHopLimit);
62     EmitStatus("ping_request=%s,%d,%lu", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp);
63 }
64 
EmitPingReply(const Ip6::Address & aPeerAddress,uint16_t aPingLength,uint32_t aTimestamp,uint8_t aHopLimit)65 void Otns::EmitPingReply(const Ip6::Address &aPeerAddress, uint16_t aPingLength, uint32_t aTimestamp, uint8_t aHopLimit)
66 {
67     EmitStatus("ping_reply=%s,%u,%lu,%d", aPeerAddress.ToString().AsCString(), aPingLength, aTimestamp, aHopLimit);
68 }
69 
EmitStatus(const char * aFmt,...)70 void Otns::EmitStatus(const char *aFmt, ...)
71 {
72     char statusStr[kMaxStatusStringLength + 1];
73     int  n;
74 
75     va_list ap;
76     va_start(ap, aFmt);
77 
78     n = vsnprintf(statusStr, sizeof(statusStr), aFmt, ap);
79     OT_UNUSED_VARIABLE(n);
80     OT_ASSERT(n >= 0);
81 
82     va_end(ap);
83 
84     otPlatOtnsStatus(statusStr);
85 }
86 
HandleNotifierEvents(Events aEvents)87 void Otns::HandleNotifierEvents(Events aEvents)
88 {
89     if (aEvents.Contains(kEventThreadRoleChanged))
90     {
91         EmitStatus("role=%d", Get<Mle::Mle>().GetRole());
92     }
93 
94     if (aEvents.Contains(kEventThreadPartitionIdChanged))
95     {
96         EmitStatus("parid=%x", Get<Mle::Mle>().GetLeaderData().GetPartitionId());
97     }
98 
99 #if OPENTHREAD_CONFIG_JOINER_ENABLE
100     if (aEvents.Contains(kEventJoinerStateChanged))
101     {
102         EmitStatus("joiner_state=%d", Get<MeshCoP::Joiner>().GetState());
103     }
104 #endif
105 }
106 
EmitNeighborChange(NeighborTable::Event aEvent,const Neighbor & aNeighbor)107 void Otns::EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor)
108 {
109     switch (aEvent)
110     {
111     case NeighborTable::kRouterAdded:
112         EmitStatus("router_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
113         break;
114     case NeighborTable::kRouterRemoved:
115         EmitStatus("router_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
116         break;
117     case NeighborTable::kChildAdded:
118         EmitStatus("child_added=%s", aNeighbor.GetExtAddress().ToString().AsCString());
119         break;
120     case NeighborTable::kChildRemoved:
121         EmitStatus("child_removed=%s", aNeighbor.GetExtAddress().ToString().AsCString());
122         break;
123     case NeighborTable::kChildModeChanged:
124         break;
125     }
126 }
127 
EmitTransmit(const Mac::TxFrame & aFrame)128 void Otns::EmitTransmit(const Mac::TxFrame &aFrame)
129 {
130     Mac::Address dst;
131     uint16_t     frameControlField = aFrame.GetFrameControlField();
132     uint8_t      channel           = aFrame.GetChannel();
133     uint8_t      sequence          = aFrame.GetSequence();
134 
135     IgnoreError(aFrame.GetDstAddr(dst));
136 
137     if (dst.IsShort())
138     {
139         EmitStatus("transmit=%d,%04x,%d,%04x", channel, frameControlField, sequence, dst.GetShort());
140     }
141     else if (dst.IsExtended())
142     {
143         EmitStatus("transmit=%d,%04x,%d,%s", channel, frameControlField, sequence, dst.ToString().AsCString());
144     }
145     else
146     {
147         EmitStatus("transmit=%d,%04x,%d", channel, frameControlField, sequence);
148     }
149 }
150 
EmitDeviceMode(Mle::DeviceMode aMode)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" : "");
155 }
156 
EmitCoapSend(const Coap::Message & aMessage,const Ip6::MessageInfo & aMessageInfo)157 void Otns::EmitCoapSend(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
158 {
159     char  uriPath[Coap::Message::kMaxReceivedUriPath + 1];
160     Error error;
161 
162     SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
163 
164     EmitStatus("coap=send,%d,%d,%d,%s,%s,%d", aMessage.GetMessageId(), aMessage.GetType(), aMessage.GetCode(), uriPath,
165                aMessageInfo.GetPeerAddr().ToString().AsCString(), aMessageInfo.GetPeerPort());
166 
167 exit:
168     LogWarnOnError(error, "EmitCoapSend");
169 }
170 
EmitCoapReceive(const Coap::Message & aMessage,const Ip6::MessageInfo & aMessageInfo)171 void Otns::EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
172 {
173     char  uriPath[Coap::Message::kMaxReceivedUriPath + 1];
174     Error error = kErrorNone;
175 
176     SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
177 
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");
182 }
183 
EmitCoapSendFailure(Error aError,Coap::Message & aMessage,const Ip6::MessageInfo & aMessageInfo)184 void Otns::EmitCoapSendFailure(Error aError, Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
185 {
186     char  uriPath[Coap::Message::kMaxReceivedUriPath + 1];
187     Error error = kErrorNone;
188 
189     SuccessOrExit(error = aMessage.ReadUriPathOptions(uriPath));
190 
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));
194 exit:
195     LogWarnOnError(error, "EmitCoapSendFailure");
196 }
197 
198 } // namespace Utils
199 } // namespace ot
200 
201 #endif // (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE
202