Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020 Project CHIP Authors 4 : * Copyright (c) 2016-2017 Nest Labs, Inc. 5 : * 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : */ 18 : 19 : /** 20 : * @file 21 : * This file contains free functions for mapping OS and LwIP 22 : * stack-specific errors into CHIP System Layer-specific errors 23 : * and for converting those mapped errors into descriptive 24 : * error strings. 25 : */ 26 : 27 : // Include module header 28 : #include <system/SystemError.h> 29 : 30 : #include <lib/core/ErrorStr.h> 31 : #include <lib/support/DLLUtil.h> 32 : 33 : #include <lib/core/CHIPConfig.h> 34 : 35 : // Include local headers 36 : #if CHIP_SYSTEM_CONFIG_USE_LWIP 37 : #include <lwip/err.h> 38 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP 39 : 40 : #include <limits> 41 : #include <stddef.h> 42 : #include <string.h> 43 : 44 : namespace chip { 45 : namespace System { 46 : 47 : namespace Internal { 48 : /** 49 : * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the 50 : * underlying POSIX network and OS stack errors into a platform- or system-specific range. Error codes beyond those currently 51 : * defined by POSIX or the ISO C/C++ standards are mapped similar to the standard ones. 52 : * 53 : * @param[in] aError The POSIX network or OS error to map. 54 : * 55 : * @return The mapped POSIX network or OS error. 56 : */ 57 0 : DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError) 58 : { 59 0 : return (aError == 0 ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kPOSIX, static_cast<ChipError::ValueType>(aError))); 60 : } 61 : 62 14179 : DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError, const char * file, unsigned int line) 63 : { 64 : return (aError == 0 ? CHIP_NO_ERROR 65 14179 : : CHIP_ERROR(ChipError::Range::kPOSIX, static_cast<ChipError::ValueType>(aError), file, line)); 66 : } 67 : } // namespace Internal 68 : 69 : /** 70 : * This implements a function to return an NULL-terminated OS-specific descriptive C string, associated with the specified, mapped 71 : * OS error. 72 : * 73 : * @param[in] aError The mapped OS-specific error to describe. 74 : * 75 : * @return A NULL-terminated, OS-specific descriptive C string describing the error. 76 : */ 77 2 : DLL_EXPORT const char * DescribeErrorPOSIX(CHIP_ERROR aError) 78 : { 79 2 : const int lError = static_cast<int>(aError.GetValue()); 80 2 : return strerror(lError); 81 : } 82 : 83 : /** 84 : * Register a text error formatter for POSIX errors. 85 : */ 86 80 : void RegisterPOSIXErrorFormatter() 87 : { 88 : static ErrorFormatter sPOSIXErrorFormatter = { FormatPOSIXError, nullptr }; 89 : 90 80 : RegisterErrorFormatter(&sPOSIXErrorFormatter); 91 80 : } 92 : 93 : /** 94 : * Given a POSIX error, returns a human-readable NULL-terminated C string 95 : * describing the error. 96 : * 97 : * @param[in] buf Buffer into which the error string will be placed. 98 : * @param[in] bufSize Size of the supplied buffer in bytes. 99 : * @param[in] err The error to be described. 100 : * 101 : * @return true If a description string was written into the supplied buffer. 102 : * @return false If the supplied error was not a POSIX error. 103 : * 104 : */ 105 41 : bool FormatPOSIXError(char * buf, uint16_t bufSize, CHIP_ERROR err) 106 : { 107 41 : if (err.IsRange(ChipError::Range::kPOSIX)) 108 : { 109 : const char * desc = 110 : #if CHIP_CONFIG_SHORT_ERROR_STR 111 : nullptr; 112 : #else 113 1 : DescribeErrorPOSIX(err); 114 : #endif 115 1 : FormatError(buf, bufSize, "OS", err, desc); 116 1 : return true; 117 : } 118 : 119 40 : return false; 120 : } 121 : 122 : /** 123 : * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the 124 : * Zephyr OS user API stack errors into the POSIX range. 125 : * 126 : * @param[in] aError The native Zephyr API error to map. 127 : * 128 : * @return The mapped POSIX error. 129 : */ 130 0 : DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError) 131 : { 132 0 : return Internal::MapErrorPOSIX(-aError); 133 : } 134 : 135 : #if CHIP_SYSTEM_CONFIG_USE_LWIP 136 : 137 : /** 138 : * This implements a mapping function for CHIP System Layer errors that allows mapping underlying LwIP network stack errors into a 139 : * platform- or system-specific range. 140 : * 141 : * @param[in] aError The LwIP error to map. 142 : * 143 : * @return The mapped LwIP network or OS error. 144 : * 145 : */ 146 : DLL_EXPORT CHIP_ERROR MapErrorLwIP(err_t aError) 147 : { 148 : static_assert(ChipError::CanEncapsulate(-std::numeric_limits<err_t>::min()), "Can't represent all LWIP errors"); 149 : return (aError == ERR_OK ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kLwIP, static_cast<unsigned int>(-aError))); 150 : } 151 : 152 : /** 153 : * This implements a function to return an NULL-terminated LwIP-specific descriptive C string, associated with the specified, 154 : * mapped LwIP error. 155 : * 156 : * @param[in] aError The mapped LwIP-specific error to describe. 157 : * 158 : * @return A NULL-terminated, LwIP-specific descriptive C string describing the error. 159 : * 160 : */ 161 : DLL_EXPORT const char * DescribeErrorLwIP(CHIP_ERROR aError) 162 : { 163 : if (!aError.IsRange(ChipError::Range::kLwIP)) 164 : { 165 : return nullptr; 166 : } 167 : 168 : const err_t lError = static_cast<err_t>(-static_cast<err_t>(aError.GetValue())); 169 : 170 : // If we are not compiling with LWIP_DEBUG asserted, the unmapped 171 : // local value may go unused. 172 : 173 : (void) lError; 174 : 175 : return lwip_strerr(lError); 176 : } 177 : 178 : /** 179 : * Register a text error formatter for LwIP errors. 180 : */ 181 : void RegisterLwIPErrorFormatter() 182 : { 183 : static ErrorFormatter sLwIPErrorFormatter = { FormatLwIPError, nullptr }; 184 : 185 : RegisterErrorFormatter(&sLwIPErrorFormatter); 186 : } 187 : 188 : /** 189 : * Given an LwIP error, returns a human-readable NULL-terminated C string 190 : * describing the error. 191 : * 192 : * @param[in] buf Buffer into which the error string will be placed. 193 : * @param[in] bufSize Size of the supplied buffer in bytes. 194 : * @param[in] err The error to be described. 195 : * 196 : * @return true If a description string was written into the supplied buffer. 197 : * @return false If the supplied error was not an LwIP error. 198 : * 199 : */ 200 : bool FormatLwIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) 201 : { 202 : if (err.IsRange(ChipError::Range::kLwIP)) 203 : { 204 : const char * desc = 205 : #if CHIP_CONFIG_SHORT_ERROR_STR 206 : nullptr; 207 : #else 208 : DescribeErrorLwIP(err); 209 : #endif 210 : chip::FormatError(buf, bufSize, "LwIP", err, desc); 211 : return true; 212 : } 213 : return false; 214 : } 215 : 216 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP 217 : 218 : } // namespace System 219 : } // namespace chip