1 /* 2 * Copyright (c) 2016, 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 contains definitions for the diagnostics module. 32 */ 33 34 #ifndef FACTORY_DIAGS_HPP_ 35 #define FACTORY_DIAGS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_DIAG_ENABLE 40 41 #include <string.h> 42 43 #include <openthread/diag.h> 44 #include <openthread/platform/radio.h> 45 46 #include "common/clearable.hpp" 47 #include "common/error.hpp" 48 #include "common/locator.hpp" 49 #include "common/non_copyable.hpp" 50 #include "common/string.hpp" 51 52 namespace ot { 53 namespace FactoryDiags { 54 55 class Diags : public InstanceLocator, private NonCopyable 56 { 57 public: 58 /** 59 * Constructor. 60 * 61 * @param[in] aInstance The OpenThread instance. 62 * 63 */ 64 explicit Diags(Instance &aInstance); 65 66 /** 67 * Processes a factory diagnostics command line. 68 * 69 * @param[in] aString A null-terminated input string. 70 * 71 */ 72 Error ProcessLine(const char *aString); 73 74 /** 75 * Processes a factory diagnostics command line. 76 * 77 * @param[in] aArgsLength The number of args in @p aArgs. 78 * @param[in] aArgs The arguments of diagnostics command line. 79 * 80 * @retval kErrorInvalidArgs The command is supported but invalid arguments provided. 81 * @retval kErrorNone The command is successfully process. 82 * @retval kErrorNotImplemented The command is not supported. 83 * 84 */ 85 Error ProcessCmd(uint8_t aArgsLength, char *aArgs[]); 86 87 /** 88 * Indicates whether or not the factory diagnostics mode is enabled. 89 * 90 * @retval TRUE if factory diagnostics mode is enabled 91 * @retval FALSE if factory diagnostics mode is disabled. 92 * 93 */ 94 bool IsEnabled(void); 95 96 /** 97 * The platform driver calls this method to notify OpenThread diagnostics module that the alarm has fired. 98 * 99 */ 100 void AlarmFired(void); 101 102 /** 103 * The radio driver calls this method to notify OpenThread diagnostics module of a received frame. 104 * 105 * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed. 106 * @param[in] aError kErrorNone when successfully received a frame, 107 * kErrorAbort when reception was aborted and a frame was not received, 108 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space. 109 * 110 */ 111 void ReceiveDone(otRadioFrame *aFrame, Error aError); 112 113 /** 114 * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed. 115 * 116 * @param[in] aError kErrorNone when the frame was transmitted, 117 * kErrorChannelAccessFailure tx could not take place due to activity on channel, 118 * kErrorAbort when transmission was aborted for other reasons. 119 * 120 */ 121 void TransmitDone(Error aError); 122 123 /** 124 * Sets the diag output callback. 125 * 126 * @param[in] aCallback A callback method called to output diag messages. 127 * @param[in] aContext A user context pointer. 128 * 129 */ 130 void SetOutputCallback(otDiagOutputCallback aCallback, void *aContext); 131 132 private: 133 static constexpr uint8_t kMaxArgs = OPENTHREAD_CONFIG_DIAG_CMD_LINE_ARGS_MAX; 134 135 struct Command 136 { 137 const char *mName; 138 Error (Diags::*mCommand)(uint8_t aArgsLength, char *aArgs[]); 139 }; 140 141 struct Stats : public Clearable<Stats> 142 { 143 uint32_t mReceivedPackets; 144 uint32_t mSentPackets; 145 int8_t mFirstRssi; 146 uint8_t mFirstLqi; 147 int8_t mLastRssi; 148 uint8_t mLastLqi; 149 }; 150 151 struct RawPowerSetting 152 { 153 static constexpr uint16_t kMaxDataSize = OPENTHREAD_CONFIG_POWER_CALIBRATION_RAW_POWER_SETTING_SIZE; 154 static constexpr uint16_t kInfoStringSize = kMaxDataSize * 2 + 1; 155 typedef String<kInfoStringSize> InfoString; 156 ToStringot::FactoryDiags::Diags::RawPowerSetting157 InfoString ToString(void) const 158 { 159 InfoString string; 160 161 string.AppendHexBytes(mData, mLength); 162 163 return string; 164 } 165 operator !=ot::FactoryDiags::Diags::RawPowerSetting166 bool operator!=(const RawPowerSetting &aOther) const 167 { 168 return (mLength != aOther.mLength) || (memcmp(mData, aOther.mData, mLength) != 0); 169 } 170 171 uint8_t mData[kMaxDataSize]; 172 uint16_t mLength; 173 }; 174 175 struct PowerSettings 176 { operator !=ot::FactoryDiags::Diags::PowerSettings177 bool operator!=(const PowerSettings &aOther) const 178 { 179 return (mTargetPower != aOther.mTargetPower) || (mActualPower != aOther.mActualPower) || 180 (mRawPowerSetting != aOther.mRawPowerSetting); 181 } 182 183 int16_t mTargetPower; 184 int16_t mActualPower; 185 RawPowerSetting mRawPowerSetting; 186 }; 187 188 Error ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]); 189 Error ProcessChannel(uint8_t aArgsLength, char *aArgs[]); 190 Error ProcessFrame(uint8_t aArgsLength, char *aArgs[]); 191 Error ProcessContinuousWave(uint8_t aArgsLength, char *aArgs[]); 192 Error ProcessGpio(uint8_t aArgsLength, char *aArgs[]); 193 Error ProcessPower(uint8_t aArgsLength, char *aArgs[]); 194 Error ProcessRadio(uint8_t aArgsLength, char *aArgs[]); 195 Error ProcessRepeat(uint8_t aArgsLength, char *aArgs[]); 196 Error ProcessPowerSettings(uint8_t aArgsLength, char *aArgs[]); 197 Error ProcessRawPowerSetting(uint8_t aArgsLength, char *aArgs[]); 198 Error ProcessSend(uint8_t aArgsLength, char *aArgs[]); 199 Error ProcessStart(uint8_t aArgsLength, char *aArgs[]); 200 Error ProcessStats(uint8_t aArgsLength, char *aArgs[]); 201 Error ProcessStop(uint8_t aArgsLength, char *aArgs[]); 202 Error ProcessStream(uint8_t aArgsLength, char *aArgs[]); 203 #if OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI 204 Error ProcessEcho(uint8_t aArgsLength, char *aArgs[]); 205 #endif 206 207 Error GetRawPowerSetting(RawPowerSetting &aRawPowerSetting); 208 Error GetPowerSettings(uint8_t aChannel, PowerSettings &aPowerSettings); 209 210 void TransmitPacket(void); 211 void Output(const char *aFormat, ...); 212 void AppendErrorResult(Error aError); 213 void ResetTxPacket(void); 214 215 static Error ParseLong(char *aString, long &aLong); 216 static Error ParseBool(char *aString, bool &aBool); 217 218 static const struct Command sCommands[]; 219 220 #if OPENTHREAD_FTD || OPENTHREAD_MTD || (OPENTHREAD_RADIO && OPENTHREAD_RADIO_CLI) 221 Stats mStats; 222 223 otRadioFrame *mTxPacket; 224 uint32_t mTxPeriod; 225 uint32_t mTxPackets; 226 uint8_t mChannel; 227 int8_t mTxPower; 228 uint8_t mTxLen; 229 bool mIsTxPacketSet; 230 bool mRepeatActive; 231 bool mDiagSendOn; 232 #endif 233 234 otDiagOutputCallback mOutputCallback; 235 void *mOutputContext; 236 }; 237 238 } // namespace FactoryDiags 239 } // namespace ot 240 241 #endif // #if OPENTHREAD_CONFIG_DIAG_ENABLE 242 243 #endif // FACTORY_DIAGS_HPP_ 244