SystemError.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. * @file
  20. * This file contains free functions for mapping OS and LwIP
  21. * stack-specific errors into CHIP System Layer-specific errors
  22. * and for converting those mapped errors into descriptive
  23. * error strings.
  24. */
  25. // Include module header
  26. #include <system/SystemError.h>
  27. // Include common private header
  28. #include "SystemLayerPrivate.h"
  29. #include <support/DLLUtil.h>
  30. #include <support/ErrorStr.h>
  31. #include <core/CHIPConfig.h>
  32. // Include local headers
  33. #if CHIP_SYSTEM_CONFIG_USE_LWIP
  34. #include <lwip/err.h>
  35. #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
  36. #include <limits>
  37. #include <stddef.h>
  38. #include <string.h>
  39. namespace chip {
  40. namespace System {
  41. /**
  42. * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
  43. * underlying POSIX network and OS stack errors into a platform- or system-specific range. Error codes beyond those currently
  44. * defined by POSIX or the ISO C/C++ standards are mapped similar to the standard ones.
  45. *
  46. * @param[in] aError The POSIX network or OS error to map.
  47. *
  48. * @return The mapped POSIX network or OS error.
  49. */
  50. DLL_EXPORT CHIP_ERROR MapErrorPOSIX(int aError)
  51. {
  52. return (aError == 0 ? CHIP_NO_ERROR
  53. : ChipError::Encapsulate(ChipError::Range::kPOSIX, static_cast<ChipError::BaseType>(aError)));
  54. }
  55. /**
  56. * This implements a function to return an NULL-terminated OS-specific descriptive C string, associated with the specified, mapped
  57. * OS error.
  58. *
  59. * @param[in] aError The mapped OS-specific error to describe.
  60. *
  61. * @return A NULL-terminated, OS-specific descriptive C string describing the error.
  62. */
  63. DLL_EXPORT const char * DescribeErrorPOSIX(CHIP_ERROR aError)
  64. {
  65. const int lError = static_cast<int>(ChipError::GetValue(aError));
  66. return strerror(lError);
  67. }
  68. /**
  69. * Register a text error formatter for POSIX errors.
  70. */
  71. void RegisterPOSIXErrorFormatter()
  72. {
  73. static ErrorFormatter sPOSIXErrorFormatter = { FormatPOSIXError, nullptr };
  74. RegisterErrorFormatter(&sPOSIXErrorFormatter);
  75. }
  76. /**
  77. * Given a POSIX error, returns a human-readable NULL-terminated C string
  78. * describing the error.
  79. *
  80. * @param[in] buf Buffer into which the error string will be placed.
  81. * @param[in] bufSize Size of the supplied buffer in bytes.
  82. * @param[in] err The error to be described.
  83. *
  84. * @return true If a description string was written into the supplied buffer.
  85. * @return false If the supplied error was not a POSIX error.
  86. *
  87. */
  88. bool FormatPOSIXError(char * buf, uint16_t bufSize, CHIP_ERROR err)
  89. {
  90. if (ChipError::IsRange(ChipError::Range::kPOSIX, err))
  91. {
  92. const char * desc =
  93. #if CHIP_CONFIG_SHORT_ERROR_STR
  94. NULL;
  95. #else
  96. DescribeErrorPOSIX(err);
  97. #endif
  98. FormatError(buf, bufSize, "OS", err, desc);
  99. return true;
  100. }
  101. return false;
  102. }
  103. /**
  104. * This implements a mapping function for CHIP System Layer errors that allows mapping integers in the number space of the
  105. * Zephyr OS user API stack errors into the POSIX range.
  106. *
  107. * @param[in] aError The native Zephyr API error to map.
  108. *
  109. * @return The mapped POSIX error.
  110. */
  111. DLL_EXPORT CHIP_ERROR MapErrorZephyr(int aError)
  112. {
  113. return MapErrorPOSIX(-aError);
  114. }
  115. #if CHIP_SYSTEM_CONFIG_USE_LWIP
  116. /**
  117. * This implements a mapping function for CHIP System Layer errors that allows mapping underlying LwIP network stack errors into a
  118. * platform- or system-specific range.
  119. *
  120. * @param[in] aError The LwIP error to map.
  121. *
  122. * @return The mapped LwIP network or OS error.
  123. *
  124. */
  125. DLL_EXPORT CHIP_ERROR MapErrorLwIP(err_t aError)
  126. {
  127. static_assert(ChipError::CanEncapsulate(-std::numeric_limits<err_t>::min()), "Can't represent all LWIP errors");
  128. return (aError == ERR_OK ? CHIP_NO_ERROR : ChipError::Encapsulate(ChipError::Range::kLwIP, static_cast<unsigned int>(-aError)));
  129. }
  130. /**
  131. * This implements a function to return an NULL-terminated LwIP-specific descriptive C string, associated with the specified,
  132. * mapped LwIP error.
  133. *
  134. * @param[in] aError The mapped LwIP-specific error to describe.
  135. *
  136. * @return A NULL-terminated, LwIP-specific descriptive C string describing the error.
  137. *
  138. */
  139. DLL_EXPORT const char * DescribeErrorLwIP(CHIP_ERROR aError)
  140. {
  141. if (!ChipError::IsRange(ChipError::Range::kLwIP, aError))
  142. {
  143. return nullptr;
  144. }
  145. const err_t lError = static_cast<err_t>(-static_cast<err_t>(ChipError::GetValue(aError)));
  146. // If we are not compiling with LWIP_DEBUG asserted, the unmapped
  147. // local value may go unused.
  148. (void) lError;
  149. return lwip_strerr(lError);
  150. }
  151. /**
  152. * Register a text error formatter for LwIP errors.
  153. */
  154. void RegisterLwIPErrorFormatter(void)
  155. {
  156. static ErrorFormatter sLwIPErrorFormatter = { FormatLwIPError, NULL };
  157. RegisterErrorFormatter(&sLwIPErrorFormatter);
  158. }
  159. /**
  160. * Given an LwIP error, returns a human-readable NULL-terminated C string
  161. * describing the error.
  162. *
  163. * @param[in] buf Buffer into which the error string will be placed.
  164. * @param[in] bufSize Size of the supplied buffer in bytes.
  165. * @param[in] err The error to be described.
  166. *
  167. * @return true If a description string was written into the supplied buffer.
  168. * @return false If the supplied error was not an LwIP error.
  169. *
  170. */
  171. bool FormatLwIPError(char * buf, uint16_t bufSize, CHIP_ERROR err)
  172. {
  173. if (ChipError::IsRange(ChipError::Range::kLwIP, err))
  174. {
  175. const char * desc =
  176. #if CHIP_CONFIG_SHORT_ERROR_STR
  177. NULL;
  178. #else
  179. DescribeErrorLwIP(err);
  180. #endif
  181. chip::FormatError(buf, bufSize, "LwIP", err, desc);
  182. return true;
  183. }
  184. else
  185. {
  186. return false;
  187. }
  188. }
  189. #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
  190. } // namespace System
  191. } // namespace chip