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