3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2016-2017 Nest Labs, Inc.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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
27 // Include module header
28 #include <system/SystemError.h>
30 // Include common private header
31 #include "SystemLayerPrivate.h"
33 #include <support/DLLUtil.h>
34 #include <support/ErrorStr.h>
36 #include <core/CHIPConfig.h>
38 // Include local headers
39 #if CHIP_SYSTEM_CONFIG_USE_LWIP
41 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
43 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
45 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
51 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
54 * @def CHIP_SYSTEM_POSIX_ERROR_MIN
57 * This defines the base or minimum CHIP System Layer error number range, when passing through errors from an underlying
60 #define CHIP_SYSTEM_POSIX_ERROR_MIN 2000
63 * @def CHIP_SYSTEM_POSIX_ERROR_MAX
66 * This defines the base or maximum CHIP System Layer error number range, when passing through errors from an underlying
69 #define CHIP_SYSTEM_POSIX_ERROR_MAX 2999
71 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
73 #if CHIP_SYSTEM_CONFIG_USE_LWIP
74 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
77 * @def CHIP_SYSTEM_LWIP_ERROR_MIN
80 * This defines the base or minimum CHIP System Layer error number range, when passing through errors from an underlying LWIP
83 #ifndef CHIP_SYSTEM_LWIP_ERROR_MIN
84 #define CHIP_SYSTEM_LWIP_ERROR_MIN 3000
85 #endif // CHIP_SYSTEM_LWIP_ERROR_MIN
88 * @def CHIP_SYSTEM_LWIP_ERROR_MAX
91 * This defines the base or maximum CHIP System Layer error number range, when passing through errors from an underlying LWIP
94 #ifndef CHIP_SYSTEM_LWIP_ERROR_MAX
95 #define CHIP_SYSTEM_LWIP_ERROR_MAX 3128
96 #endif // CHIP_SYSTEM_LWIP_ERROR_MAX
98 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
99 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
105 * Register a text error formatter for System Layer errors.
107 void RegisterLayerErrorFormatter()
109 static ErrorFormatter sSystemLayerErrorFormatter = { FormatLayerError, nullptr };
111 RegisterErrorFormatter(&sSystemLayerErrorFormatter);
115 * Given a System Layer error, returns a human-readable NULL-terminated C string
116 * describing the error.
118 * @param[in] buf Buffer into which the error string will be placed.
119 * @param[in] bufSize Size of the supplied buffer in bytes.
120 * @param[in] err The error to be described.
122 * @return true If a description string was written into the supplied buffer.
123 * @return false If the supplied error was not a System Layer error.
126 bool FormatLayerError(char * buf, uint16_t bufSize, int32_t err)
128 const char * desc = nullptr;
130 if (err < CHIP_SYSTEM_ERROR_MIN || err > CHIP_SYSTEM_ERROR_MAX)
135 #if !CHIP_CONFIG_SHORT_ERROR_STR
138 case CHIP_SYSTEM_ERROR_NOT_IMPLEMENTED:
139 desc = "Not implemented";
141 case CHIP_SYSTEM_ERROR_NOT_SUPPORTED:
142 desc = "Not supported";
144 case CHIP_SYSTEM_ERROR_BAD_ARGS:
145 desc = "Bad arguments";
147 case CHIP_SYSTEM_ERROR_UNEXPECTED_STATE:
148 desc = "Unexpected state";
150 case CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT:
151 desc = "Unexpected event";
153 case CHIP_SYSTEM_ERROR_NO_MEMORY:
156 case CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED:
157 desc = "Real time not synchronized";
159 case CHIP_SYSTEM_ERROR_ACCESS_DENIED:
160 desc = "Access denied";
163 #endif // !CHIP_CONFIG_SHORT_ERROR_STR
165 chip::FormatError(buf, bufSize, "Sys", err, desc);
170 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
172 * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
173 * underlying POSIX network and OS stack errors into a platform- or system-specific range. Error codes beyond those currently
174 * defined by POSIX or the ISO C/C++ standards are mapped similar to the standard ones.
176 * @param[in] aError The POSIX network or OS error to map.
178 * @return The mapped POSIX network or OS error.
180 DLL_EXPORT Error MapErrorPOSIX(int aError)
182 return (aError == 0 ? CHIP_SYSTEM_NO_ERROR : CHIP_SYSTEM_POSIX_ERROR_MIN + aError);
186 * This implements a function to return an NULL-terminated OS-specific descriptive C string, associated with the specified, mapped
189 * @param[in] aError The mapped OS-specific error to describe.
191 * @return A NULL-terminated, OS-specific descriptive C string describing the error.
193 DLL_EXPORT const char * DescribeErrorPOSIX(Error aError)
195 const int lError = (aError - CHIP_SYSTEM_POSIX_ERROR_MIN);
196 return strerror(lError);
200 * This implements an introspection function for CHIP System Layer errors that allows the caller to determine whether the
201 * specified error is an internal, underlying OS error.
203 * @param[in] aError The mapped error to determine whether it is an OS error.
205 * @return True if the specified error is an OS error; otherwise, false.
207 DLL_EXPORT bool IsErrorPOSIX(Error aError)
209 return (aError >= CHIP_SYSTEM_POSIX_ERROR_MIN && aError <= CHIP_SYSTEM_POSIX_ERROR_MAX);
212 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
215 * Register a text error formatter for POSIX errors.
217 void RegisterPOSIXErrorFormatter()
219 static ErrorFormatter sPOSIXErrorFormatter = { FormatPOSIXError, nullptr };
221 RegisterErrorFormatter(&sPOSIXErrorFormatter);
225 * Given a POSIX error, returns a human-readable NULL-terminated C string
226 * describing the error.
228 * @param[in] buf Buffer into which the error string will be placed.
229 * @param[in] bufSize Size of the supplied buffer in bytes.
230 * @param[in] err The error to be described.
232 * @return true If a description string was written into the supplied buffer.
233 * @return false If the supplied error was not a POSIX error.
236 bool FormatPOSIXError(char * buf, uint16_t bufSize, int32_t err)
238 const Error sysErr = static_cast<Error>(err);
240 if (IsErrorPOSIX(sysErr))
243 #if CHIP_CONFIG_SHORT_ERROR_STR
246 DescribeErrorPOSIX(sysErr);
248 FormatError(buf, bufSize, "OS", err, desc);
256 * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
257 * Zephyr OS user API stack errors into the POSIX range.
259 * @param[in] aError The native Zephyr API error to map.
261 * @return The mapped POSIX error.
263 DLL_EXPORT Error MapErrorZephyr(int aError)
265 return MapErrorPOSIX(-aError);
268 #if CHIP_SYSTEM_CONFIG_USE_LWIP
269 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
272 * This implements a mapping function for CHIP System Layer errors that allows mapping underlying LwIP network stack errors into a
273 * platform- or system-specific range.
275 * @param[in] aError The LwIP error to map.
277 * @return The mapped LwIP network or OS error.
280 DLL_EXPORT Error MapErrorLwIP(err_t aError)
282 static_assert(std::numeric_limits<err_t>::min() == CHIP_SYSTEM_LWIP_ERROR_MIN - CHIP_SYSTEM_LWIP_ERROR_MAX,
283 "Can't represent all LWIP errors");
284 return (aError == ERR_OK ? CHIP_SYSTEM_NO_ERROR : CHIP_SYSTEM_LWIP_ERROR_MIN - aError);
288 * This implements a function to return an NULL-terminated LwIP-specific descriptive C string, associated with the specified,
291 * @param[in] aError The mapped LwIP-specific error to describe.
293 * @return A NULL-terminated, LwIP-specific descriptive C string describing the error.
296 DLL_EXPORT const char * DescribeErrorLwIP(Error aError)
298 if (!IsErrorLwIP(aError))
303 // Error might be a signed or unsigned type. But we know the value is no
304 // larger than CHIP_SYSTEM_LWIP_ERROR_MAX and that this means it's safe to
306 static_assert(INT_MAX > CHIP_SYSTEM_LWIP_ERROR_MAX, "Our subtraction will fail");
307 const int lErrorWithoutOffset = aError - CHIP_SYSTEM_LWIP_ERROR_MIN;
308 // Cast is safe because the range from CHIP_SYSTEM_LWIP_ERROR_MIN to
309 // CHIP_SYSTEM_LWIP_ERROR_MAX all fits inside err_t. See static_assert in
311 const err_t lError = static_cast<err_t>(-lErrorWithoutOffset);
313 // If we are not compiling with LWIP_DEBUG asserted, the unmapped
314 // local value may go unused.
318 return lwip_strerr(lError);
322 * This implements an introspection function for CHIP System Layer errors that
323 * allows the caller to determine whether the specified error is an
324 * internal, underlying LwIP error.
326 * @param[in] aError The mapped error to determine whether it is a LwIP error.
328 * @return True if the specified error is a LwIP error; otherwise, false.
331 DLL_EXPORT bool IsErrorLwIP(Error aError)
333 return (aError >= CHIP_SYSTEM_LWIP_ERROR_MIN && aError <= CHIP_SYSTEM_LWIP_ERROR_MAX);
336 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
339 * Register a text error formatter for LwIP errors.
341 void RegisterLwIPErrorFormatter(void)
343 static ErrorFormatter sLwIPErrorFormatter = { FormatLwIPError, NULL };
345 RegisterErrorFormatter(&sLwIPErrorFormatter);
349 * Given an LwIP error, returns a human-readable NULL-terminated C string
350 * describing the error.
352 * @param[in] buf Buffer into which the error string will be placed.
353 * @param[in] bufSize Size of the supplied buffer in bytes.
354 * @param[in] err The error to be described.
356 * @return true If a description string was written into the supplied buffer.
357 * @return false If the supplied error was not an LwIP error.
360 bool FormatLwIPError(char * buf, uint16_t bufSize, int32_t err)
362 const chip::System::Error sysErr = static_cast<chip::System::Error>(err);
364 if (IsErrorLwIP(sysErr))
367 #if CHIP_CONFIG_SHORT_ERROR_STR
370 DescribeErrorLwIP(sysErr);
372 chip::FormatError(buf, bufSize, "LwIP", err, desc);
381 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
383 } // namespace System