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 contains header for exit code utilities. 32 */ 33 34 #ifndef PLATFORM_EXIT_CODE_H_ 35 #define PLATFORM_EXIT_CODE_H_ 36 37 #include <stdint.h> 38 #include <stdlib.h> 39 #include <string.h> 40 41 #include <openthread/logging.h> 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 /** 47 * Represents exit codes used when OpenThread exits. 48 * 49 */ 50 enum 51 { 52 /** 53 * Success. 54 */ 55 OT_EXIT_SUCCESS = 0, 56 57 /** 58 * Generic failure. 59 */ 60 OT_EXIT_FAILURE = 1, 61 62 /** 63 * Invalid arguments. 64 */ 65 OT_EXIT_INVALID_ARGUMENTS = 2, 66 67 /** 68 * Incompatible radio spinel. 69 */ 70 OT_EXIT_RADIO_SPINEL_INCOMPATIBLE = 3, 71 72 /** 73 * Unexpected radio spinel reset. 74 */ 75 OT_EXIT_RADIO_SPINEL_RESET = 4, 76 77 /** 78 * System call or library function error. 79 */ 80 OT_EXIT_ERROR_ERRNO = 5, 81 82 /** 83 * No response from radio spinel. 84 */ 85 OT_EXIT_RADIO_SPINEL_NO_RESPONSE = 6, 86 87 /** 88 * Invalid state. 89 */ 90 OT_EXIT_INVALID_STATE = 7, 91 92 }; 93 94 /** 95 * Converts an exit code into a string. 96 * 97 * @param[in] aExitCode An exit code. 98 * 99 * @returns A string representation of an exit code. 100 * 101 */ 102 const char *otExitCodeToString(uint8_t aExitCode); 103 104 /** 105 * Checks for the specified condition, which is expected to commonly be true, 106 * and both records exit status and terminates the program if the condition is false. 107 * 108 * @param[in] aCondition The condition to verify 109 * @param[in] aExitCode The exit code. 110 * 111 */ 112 #define VerifyOrDie(aCondition, aExitCode) \ 113 do \ 114 { \ 115 if (!(aCondition)) \ 116 { \ 117 const char *start = strrchr(__FILE__, '/'); \ 118 OT_UNUSED_VARIABLE(start); \ 119 otLogCritPlat("%s() at %s:%d: %s", __func__, (start ? start + 1 : __FILE__), __LINE__, \ 120 otExitCodeToString(aExitCode)); \ 121 exit(aExitCode); \ 122 } \ 123 } while (false) 124 125 /** 126 * Checks for the specified error code, which is expected to commonly be successful, 127 * and both records exit status and terminates the program if the error code is unsuccessful. 128 * 129 * @param[in] aError An error code to be evaluated against OT_ERROR_NONE. 130 * 131 */ 132 #define SuccessOrDie(aError) \ 133 VerifyOrDie(aError == OT_ERROR_NONE, \ 134 (aError == OT_ERROR_INVALID_ARGS ? OT_EXIT_INVALID_ARGUMENTS : OT_EXIT_FAILURE)) 135 136 /** 137 * Unconditionally both records exit status and terminates the program. 138 * 139 * @param[in] aExitCode The exit code. 140 * 141 */ 142 #define DieNow(aExitCode) VerifyOrDie(false, aExitCode) 143 144 /** 145 * Unconditionally both records exit status and exit message and terminates the program. 146 * 147 * @param[in] aMessage The exit message. 148 * @param[in] aExitCode The exit code. 149 * 150 */ 151 #define DieNowWithMessage(aMessage, aExitCode) \ 152 do \ 153 { \ 154 otLogCritPlat("exit(%d): %s line %d, %s, %s", aExitCode, __func__, __LINE__, aMessage, \ 155 otExitCodeToString(aExitCode)); \ 156 exit(aExitCode); \ 157 } while (false) 158 159 #ifdef __cplusplus 160 } 161 #endif 162 163 #endif // PLATFORM_EXIT_CODE_H_ 164