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 : #if CHIP_CONFIG_ERROR_SOURCE && CHIP_CONFIG_ERROR_STD_SOURCE_LOCATION
58 : DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError, std::source_location location)
59 : {
60 : return (aError == 0 ? CHIP_NO_ERROR
61 : : CHIP_ERROR(ChipError::Range::kPOSIX, static_cast<ChipError::ValueType>(aError), location));
62 : }
63 : #elif CHIP_CONFIG_ERROR_SOURCE
64 21789 : DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError, const char * file, unsigned int line)
65 : {
66 : return (aError == 0 ? CHIP_NO_ERROR
67 21789 : : CHIP_ERROR(ChipError::Range::kPOSIX, static_cast<ChipError::ValueType>(aError), file, line));
68 : }
69 : #else
70 : DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError)
71 : {
72 : return (aError == 0 ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kPOSIX, static_cast<ChipError::ValueType>(aError)));
73 : }
74 : #endif
75 : } // namespace Internal
76 :
77 : /**
78 : * This implements a function to return an NULL-terminated OS-specific descriptive C string, associated with the specified, mapped
79 : * OS error.
80 : *
81 : * @param[in] aError The mapped OS-specific error to describe.
82 : *
83 : * @return A NULL-terminated, OS-specific descriptive C string describing the error.
84 : */
85 12 : DLL_EXPORT const char * DescribeErrorPOSIX(CHIP_ERROR aError)
86 : {
87 12 : const int lError = static_cast<int>(aError.GetValue());
88 12 : return strerror(lError);
89 : }
90 :
91 : /**
92 : * Register a text error formatter for POSIX errors.
93 : */
94 115 : void RegisterPOSIXErrorFormatter()
95 : {
96 : static ErrorFormatter sPOSIXErrorFormatter = { FormatPOSIXError, nullptr };
97 :
98 115 : RegisterErrorFormatter(&sPOSIXErrorFormatter);
99 115 : }
100 :
101 : /**
102 : * Given a POSIX error, returns a human-readable NULL-terminated C string
103 : * describing the error.
104 : *
105 : * @param[in] buf Buffer into which the error string will be placed.
106 : * @param[in] bufSize Size of the supplied buffer in bytes.
107 : * @param[in] err The error to be described.
108 : *
109 : * @return true If a description string was written into the supplied buffer.
110 : * @return false If the supplied error was not a POSIX error.
111 : *
112 : */
113 59 : bool FormatPOSIXError(char * buf, uint16_t bufSize, CHIP_ERROR err)
114 : {
115 59 : if (err.IsRange(ChipError::Range::kPOSIX))
116 : {
117 : const char * desc =
118 : #if CHIP_CONFIG_SHORT_ERROR_STR
119 : nullptr;
120 : #else
121 11 : DescribeErrorPOSIX(err);
122 : #endif
123 11 : FormatError(buf, bufSize, "OS", err, desc);
124 11 : return true;
125 : }
126 :
127 48 : return false;
128 : }
129 :
130 : /**
131 : * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
132 : * Zephyr OS user API stack errors into the POSIX range.
133 : *
134 : * @param[in] aError The native Zephyr API error to map.
135 : *
136 : * @return The mapped POSIX error.
137 : */
138 0 : DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError)
139 : {
140 0 : return Internal::MapErrorPOSIX(-aError CHIP_ERROR_SOURCE_LOCATION_NULL);
141 : }
142 :
143 : #if CHIP_SYSTEM_CONFIG_USE_LWIP
144 :
145 : /**
146 : * This implements a mapping function for CHIP System Layer errors that allows mapping underlying LwIP network stack errors into a
147 : * platform- or system-specific range.
148 : *
149 : * @param[in] aError The LwIP error to map.
150 : *
151 : * @return The mapped LwIP network or OS error.
152 : *
153 : */
154 : DLL_EXPORT CHIP_ERROR MapErrorLwIP(err_t aError)
155 : {
156 : static_assert(ChipError::CanEncapsulate(-std::numeric_limits<err_t>::min()), "Can't represent all LWIP errors");
157 : return (aError == ERR_OK ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kLwIP, static_cast<unsigned int>(-aError)));
158 : }
159 :
160 : /**
161 : * This implements a function to return an NULL-terminated LwIP-specific descriptive C string, associated with the specified,
162 : * mapped LwIP error.
163 : *
164 : * @param[in] aError The mapped LwIP-specific error to describe.
165 : *
166 : * @return A NULL-terminated, LwIP-specific descriptive C string describing the error.
167 : *
168 : */
169 : DLL_EXPORT const char * DescribeErrorLwIP(CHIP_ERROR aError)
170 : {
171 : if (!aError.IsRange(ChipError::Range::kLwIP))
172 : {
173 : return nullptr;
174 : }
175 :
176 : const err_t lError = static_cast<err_t>(-static_cast<err_t>(aError.GetValue()));
177 :
178 : // If we are not compiling with LWIP_DEBUG asserted, the unmapped
179 : // local value may go unused.
180 :
181 : (void) lError;
182 :
183 : return lwip_strerr(lError);
184 : }
185 :
186 : /**
187 : * Register a text error formatter for LwIP errors.
188 : */
189 : void RegisterLwIPErrorFormatter()
190 : {
191 : static ErrorFormatter sLwIPErrorFormatter = { FormatLwIPError, nullptr };
192 :
193 : RegisterErrorFormatter(&sLwIPErrorFormatter);
194 : }
195 :
196 : /**
197 : * Given an LwIP error, returns a human-readable NULL-terminated C string
198 : * describing the error.
199 : *
200 : * @param[in] buf Buffer into which the error string will be placed.
201 : * @param[in] bufSize Size of the supplied buffer in bytes.
202 : * @param[in] err The error to be described.
203 : *
204 : * @return true If a description string was written into the supplied buffer.
205 : * @return false If the supplied error was not an LwIP error.
206 : *
207 : */
208 : bool FormatLwIPError(char * buf, uint16_t bufSize, CHIP_ERROR err)
209 : {
210 : if (err.IsRange(ChipError::Range::kLwIP))
211 : {
212 : const char * desc =
213 : #if CHIP_CONFIG_SHORT_ERROR_STR
214 : nullptr;
215 : #else
216 : DescribeErrorLwIP(err);
217 : #endif
218 : chip::FormatError(buf, bufSize, "LwIP", err, desc);
219 : return true;
220 : }
221 : return false;
222 : }
223 :
224 : #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
225 :
226 : } // namespace System
227 : } // namespace chip
|