Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / system / SystemError.cpp
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 common private header
31 #include "SystemLayerPrivate.h"
32
33 #include <support/DLLUtil.h>
34 #include <support/ErrorStr.h>
35
36 #include <core/CHIPConfig.h>
37
38 // Include local headers
39 #if CHIP_SYSTEM_CONFIG_USE_LWIP
40 #include <lwip/err.h>
41 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
42
43 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
44 #include <string.h>
45 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
46
47 #include <stddef.h>
48
49 #include <limits>
50
51 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
52
53 /**
54  *  @def CHIP_SYSTEM_POSIX_ERROR_MIN
55  *
56  *  @brief
57  *      This defines the base or minimum CHIP System Layer error number range, when passing through errors from an underlying
58  *      POSIX layer.
59  */
60 #define CHIP_SYSTEM_POSIX_ERROR_MIN 2000
61
62 /**
63  *  @def CHIP_SYSTEM_POSIX_ERROR_MAX
64  *
65  *  @brief
66  *      This defines the base or maximum CHIP System Layer error number range, when passing through errors from an underlying
67  *      POSIX layer.
68  */
69 #define CHIP_SYSTEM_POSIX_ERROR_MAX 2999
70
71 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
72
73 #if CHIP_SYSTEM_CONFIG_USE_LWIP
74 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
75
76 /**
77  *  @def CHIP_SYSTEM_LWIP_ERROR_MIN
78  *
79  *  @brief
80  *      This defines the base or minimum CHIP System Layer error number range, when passing through errors from an underlying LWIP
81  *      stack.
82  */
83 #ifndef CHIP_SYSTEM_LWIP_ERROR_MIN
84 #define CHIP_SYSTEM_LWIP_ERROR_MIN 3000
85 #endif // CHIP_SYSTEM_LWIP_ERROR_MIN
86
87 /**
88  *  @def CHIP_SYSTEM_LWIP_ERROR_MAX
89  *
90  *  @brief
91  *      This defines the base or maximum CHIP System Layer error number range, when passing through errors from an underlying LWIP
92  *      layer.
93  */
94 #ifndef CHIP_SYSTEM_LWIP_ERROR_MAX
95 #define CHIP_SYSTEM_LWIP_ERROR_MAX 3128
96 #endif // CHIP_SYSTEM_LWIP_ERROR_MAX
97
98 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
99 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
100
101 namespace chip {
102 namespace System {
103
104 /**
105  * Register a text error formatter for System Layer errors.
106  */
107 void RegisterLayerErrorFormatter()
108 {
109     static ErrorFormatter sSystemLayerErrorFormatter = { FormatLayerError, nullptr };
110
111     RegisterErrorFormatter(&sSystemLayerErrorFormatter);
112 }
113
114 /**
115  * Given a System Layer error, returns a human-readable NULL-terminated C string
116  * describing the error.
117  *
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.
121  *
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.
124  *
125  */
126 bool FormatLayerError(char * buf, uint16_t bufSize, int32_t err)
127 {
128     const char * desc = nullptr;
129
130     if (err < CHIP_SYSTEM_ERROR_MIN || err > CHIP_SYSTEM_ERROR_MAX)
131     {
132         return false;
133     }
134
135 #if !CHIP_CONFIG_SHORT_ERROR_STR
136     switch (err)
137     {
138     case CHIP_SYSTEM_ERROR_NOT_IMPLEMENTED:
139         desc = "Not implemented";
140         break;
141     case CHIP_SYSTEM_ERROR_NOT_SUPPORTED:
142         desc = "Not supported";
143         break;
144     case CHIP_SYSTEM_ERROR_BAD_ARGS:
145         desc = "Bad arguments";
146         break;
147     case CHIP_SYSTEM_ERROR_UNEXPECTED_STATE:
148         desc = "Unexpected state";
149         break;
150     case CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT:
151         desc = "Unexpected event";
152         break;
153     case CHIP_SYSTEM_ERROR_NO_MEMORY:
154         desc = "No memory";
155         break;
156     case CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED:
157         desc = "Real time not synchronized";
158         break;
159     case CHIP_SYSTEM_ERROR_ACCESS_DENIED:
160         desc = "Access denied";
161         break;
162     }
163 #endif // !CHIP_CONFIG_SHORT_ERROR_STR
164
165     chip::FormatError(buf, bufSize, "Sys", err, desc);
166
167     return true;
168 }
169
170 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
171 /**
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.
175  *
176  *  @param[in] aError  The POSIX network or OS error to map.
177  *
178  *  @return The mapped POSIX network or OS error.
179  */
180 DLL_EXPORT Error MapErrorPOSIX(int aError)
181 {
182     return (aError == 0 ? CHIP_SYSTEM_NO_ERROR : CHIP_SYSTEM_POSIX_ERROR_MIN + aError);
183 }
184
185 /**
186  * This implements a function to return an NULL-terminated OS-specific descriptive C string, associated with the specified, mapped
187  * OS error.
188  *
189  *  @param[in] aError  The mapped OS-specific error to describe.
190  *
191  *  @return A NULL-terminated, OS-specific descriptive C string describing the error.
192  */
193 DLL_EXPORT const char * DescribeErrorPOSIX(Error aError)
194 {
195     const int lError = (aError - CHIP_SYSTEM_POSIX_ERROR_MIN);
196     return strerror(lError);
197 }
198
199 /**
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.
202  *
203  *  @param[in] aError  The mapped error to determine whether it is an OS error.
204  *
205  *  @return True if the specified error is an OS error; otherwise, false.
206  */
207 DLL_EXPORT bool IsErrorPOSIX(Error aError)
208 {
209     return (aError >= CHIP_SYSTEM_POSIX_ERROR_MIN && aError <= CHIP_SYSTEM_POSIX_ERROR_MAX);
210 }
211
212 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_POSIX_ERROR_FUNCTIONS
213
214 /**
215  * Register a text error formatter for POSIX errors.
216  */
217 void RegisterPOSIXErrorFormatter()
218 {
219     static ErrorFormatter sPOSIXErrorFormatter = { FormatPOSIXError, nullptr };
220
221     RegisterErrorFormatter(&sPOSIXErrorFormatter);
222 }
223
224 /**
225  * Given a POSIX error, returns a human-readable NULL-terminated C string
226  * describing the error.
227  *
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.
231  *
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.
234  *
235  */
236 bool FormatPOSIXError(char * buf, uint16_t bufSize, int32_t err)
237 {
238     const Error sysErr = static_cast<Error>(err);
239
240     if (IsErrorPOSIX(sysErr))
241     {
242         const char * desc =
243 #if CHIP_CONFIG_SHORT_ERROR_STR
244             NULL;
245 #else
246             DescribeErrorPOSIX(sysErr);
247 #endif
248         FormatError(buf, bufSize, "OS", err, desc);
249         return true;
250     }
251
252     return false;
253 }
254
255 /**
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.
258  *
259  *  @param[in] aError  The native Zephyr API error to map.
260  *
261  *  @return The mapped POSIX error.
262  */
263 DLL_EXPORT Error MapErrorZephyr(int aError)
264 {
265     return MapErrorPOSIX(-aError);
266 }
267
268 #if CHIP_SYSTEM_CONFIG_USE_LWIP
269 #if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
270
271 /**
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.
274  *
275  *  @param[in] aError  The LwIP error to map.
276  *
277  *  @return The mapped LwIP network or OS error.
278  *
279  */
280 DLL_EXPORT Error MapErrorLwIP(err_t aError)
281 {
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);
285 }
286
287 /**
288  * This implements a function to return an NULL-terminated LwIP-specific descriptive C string, associated with the specified,
289  * mapped LwIP error.
290  *
291  *  @param[in] aError  The mapped LwIP-specific error to describe.
292  *
293  *  @return A NULL-terminated, LwIP-specific descriptive C string describing the error.
294  *
295  */
296 DLL_EXPORT const char * DescribeErrorLwIP(Error aError)
297 {
298     if (!IsErrorLwIP(aError))
299     {
300         return nullptr;
301     }
302
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
305     // store in int.
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
310     // MapErrorLwIP.
311     const err_t lError = static_cast<err_t>(-lErrorWithoutOffset);
312
313     // If we are not compiling with LWIP_DEBUG asserted, the unmapped
314     // local value may go unused.
315
316     (void) lError;
317
318     return lwip_strerr(lError);
319 }
320
321 /**
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.
325  *
326  *  @param[in] aError  The mapped error to determine whether it is a LwIP error.
327  *
328  *  @return True if the specified error is a LwIP error; otherwise, false.
329  *
330  */
331 DLL_EXPORT bool IsErrorLwIP(Error aError)
332 {
333     return (aError >= CHIP_SYSTEM_LWIP_ERROR_MIN && aError <= CHIP_SYSTEM_LWIP_ERROR_MAX);
334 }
335
336 #endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_LWIP_ERROR_FUNCTIONS
337
338 /**
339  * Register a text error formatter for LwIP errors.
340  */
341 void RegisterLwIPErrorFormatter(void)
342 {
343     static ErrorFormatter sLwIPErrorFormatter = { FormatLwIPError, NULL };
344
345     RegisterErrorFormatter(&sLwIPErrorFormatter);
346 }
347
348 /**
349  * Given an LwIP error, returns a human-readable NULL-terminated C string
350  * describing the error.
351  *
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.
355  *
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.
358  *
359  */
360 bool FormatLwIPError(char * buf, uint16_t bufSize, int32_t err)
361 {
362     const chip::System::Error sysErr = static_cast<chip::System::Error>(err);
363
364     if (IsErrorLwIP(sysErr))
365     {
366         const char * desc =
367 #if CHIP_CONFIG_SHORT_ERROR_STR
368             NULL;
369 #else
370             DescribeErrorLwIP(sysErr);
371 #endif
372         chip::FormatError(buf, bufSize, "LwIP", err, desc);
373         return true;
374     }
375     else
376     {
377         return false;
378     }
379 }
380
381 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
382
383 } // namespace System
384 } // namespace chip