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/error.hpp" 46 #include "common/locator.hpp" 47 #include "common/non_copyable.hpp" 48 49 namespace ot { 50 namespace FactoryDiags { 51 52 class Diags : public InstanceLocator, private NonCopyable 53 { 54 public: 55 /** 56 * Constructor. 57 * 58 * @param[in] aInstance The OpenThread instance. 59 * 60 */ 61 explicit Diags(Instance &aInstance); 62 63 /** 64 * This method processes a factory diagnostics command line. 65 * 66 * @param[in] aString A null-terminated input string. 67 * @param[out] aOutput The diagnostics execution result. 68 * @param[in] aOutputMaxLen The output buffer size. 69 * 70 */ 71 void ProcessLine(const char *aString, char *aOutput, size_t aOutputMaxLen); 72 73 /** 74 * This method processes a factory diagnostics command line. 75 * 76 * @param[in] aArgsLength The number of args in @p aArgs. 77 * @param[in] aArgs The arguments of diagnostics command line. 78 * @param[out] aOutput The diagnostics execution result. 79 * @param[in] aOutputMaxLen The output buffer size. 80 * 81 * @retval kErrorInvalidArgs The command is supported but invalid arguments provided. 82 * @retval kErrorNone The command is successfully process. 83 * @retval kErrorNotImplemented The command is not supported. 84 * 85 */ 86 Error ProcessCmd(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 87 88 /** 89 * This method indicates whether or not the factory diagnostics mode is enabled. 90 * 91 * @retval TRUE if factory diagnostics mode is enabled 92 * @retval FALSE if factory diagnostics mode is disabled. 93 * 94 */ 95 bool IsEnabled(void); 96 97 /** 98 * The platform driver calls this method to notify OpenThread diagnostics module that the alarm has fired. 99 * 100 */ 101 void AlarmFired(void); 102 103 /** 104 * The radio driver calls this method to notify OpenThread diagnostics module of a received frame. 105 * 106 * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed. 107 * @param[in] aError kErrorNone when successfully received a frame, 108 * kErrorAbort when reception was aborted and a frame was not received, 109 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space. 110 * 111 */ 112 void ReceiveDone(otRadioFrame *aFrame, Error aError); 113 114 /** 115 * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed. 116 * 117 * @param[in] aError kErrorNone when the frame was transmitted, 118 * kErrorChannelAccessFailure tx could not take place due to activity on channel, 119 * kErrorAbort when transmission was aborted for other reasons. 120 * 121 */ 122 void TransmitDone(Error aError); 123 124 private: 125 static constexpr uint8_t kMaxArgs = OPENTHREAD_CONFIG_DIAG_CMD_LINE_ARGS_MAX; 126 127 struct Command 128 { 129 const char *mName; 130 Error (Diags::*mCommand)(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 131 }; 132 133 struct Stats 134 { Clearot::FactoryDiags::Diags::Stats135 void Clear(void) { memset(this, 0, sizeof(*this)); } 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 Error ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]); 146 Error ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 147 Error ProcessPower(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 148 Error ProcessRadio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 149 Error ProcessRepeat(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 150 Error ProcessSend(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 151 Error ProcessStart(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 152 Error ProcessStats(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 153 Error ProcessStop(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 154 #if OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI 155 Error ProcessEcho(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); 156 #endif 157 158 void TransmitPacket(void); 159 160 static void AppendErrorResult(Error aError, char *aOutput, size_t aOutputMaxLen); 161 static Error ParseLong(char *aString, long &aLong); 162 163 static const struct Command sCommands[]; 164 165 #if OPENTHREAD_FTD || OPENTHREAD_MTD || (OPENTHREAD_RADIO && OPENTHREAD_RADIO_CLI) 166 Stats mStats; 167 168 otRadioFrame *mTxPacket; 169 uint32_t mTxPeriod; 170 uint32_t mTxPackets; 171 uint8_t mChannel; 172 int8_t mTxPower; 173 uint8_t mTxLen; 174 bool mRepeatActive; 175 bool mDiagSendOn; 176 #endif 177 }; 178 179 } // namespace FactoryDiags 180 } // namespace ot 181 182 #endif // #if OPENTHREAD_CONFIG_DIAG_ENABLE 183 184 #endif // FACTORY_DIAGS_HPP_ 185