3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2018 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * General utility functions available on all platforms.
25 #include <platform/internal/CHIPDeviceLayerInternal.h>
26 #include <support/CodeUtils.h>
29 namespace DeviceLayer {
31 CHIP_ERROR ParseCompilerDateStr(const char * dateStr, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth)
33 CHIP_ERROR err = CHIP_NO_ERROR;
38 static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
40 VerifyOrExit(strlen(dateStr) == 11, err = CHIP_ERROR_INVALID_ARGUMENT);
42 memcpy(monthStr, dateStr, 3);
45 p = strstr(months, monthStr);
46 VerifyOrExit(p != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
48 // Safe to cast because "months" is not too long.
49 static_assert(sizeof(months) < UINT8_MAX, "Too many months");
50 month = static_cast<uint8_t>(((p - months) / 3) + 1);
52 // Cast does not lose information, because we then check that we only parsed
53 // 2 digits, so our number can't be bigger than 99.
54 dayOfMonth = static_cast<uint8_t>(strtoul(dateStr + 4, &endptr, 10));
55 VerifyOrExit(endptr == dateStr + 6, err = CHIP_ERROR_INVALID_ARGUMENT);
57 // Cast does not lose information, because we then check that we only parsed
58 // 4 digits, so our number can't be bigger than 9999.
59 year = static_cast<uint16_t>(strtoul(dateStr + 7, &endptr, 10));
60 VerifyOrExit(endptr == dateStr + 11, err = CHIP_ERROR_INVALID_ARGUMENT);
66 CHIP_ERROR Parse24HourTimeStr(const char * timeStr, uint8_t & hour, uint8_t & minute, uint8_t & second)
68 CHIP_ERROR err = CHIP_NO_ERROR;
71 VerifyOrExit(strlen(timeStr) == 8, err = CHIP_ERROR_INVALID_ARGUMENT);
73 // Cast does not lose information, because we then check that we only parsed
74 // 2 digits, so our number can't be bigger than 99.
75 hour = static_cast<uint8_t>(strtoul(timeStr, &p, 10));
76 VerifyOrExit(p == timeStr + 2, err = CHIP_ERROR_INVALID_ARGUMENT);
78 // Cast does not lose information, because we then check that we only parsed
79 // 2 digits, so our number can't be bigger than 99.
80 minute = static_cast<uint8_t>(strtoul(timeStr + 3, &p, 10));
81 VerifyOrExit(p == timeStr + 5, err = CHIP_ERROR_INVALID_ARGUMENT);
83 // Cast does not lose information, because we then check that we only parsed
84 // 2 digits, so our number can't be bigger than 99.
85 second = static_cast<uint8_t>(strtoul(timeStr + 6, &p, 10));
86 VerifyOrExit(p == timeStr + 8, err = CHIP_ERROR_INVALID_ARGUMENT);
93 * Register a text error formatter for Device Layer errors.
95 void RegisterDeviceLayerErrorFormatter()
97 static ErrorFormatter sDeviceLayerErrorFormatter = { FormatDeviceLayerError, nullptr };
99 RegisterErrorFormatter(&sDeviceLayerErrorFormatter);
103 * Given Device Layer error, returns a human-readable NULL-terminated C string
104 * describing the error.
106 * @param[in] buf Buffer into which the error string will be placed.
107 * @param[in] bufSize Size of the supplied buffer in bytes.
108 * @param[in] err The error to be described.
110 * @return true If a descriptions string was written into the supplied buffer.
111 * @return false If the supplied error was not a Device Layer error.
114 bool FormatDeviceLayerError(char * buf, uint16_t bufSize, int32_t err)
116 const char * desc = nullptr;
118 if (err < CHIP_DEVICE_ERROR_MIN || err > CHIP_DEVICE_ERROR_MAX)
123 #if !CHIP_CONFIG_SHORT_ERROR_STR
126 case CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND:
127 desc = "Config not found";
129 case CHIP_DEVICE_ERROR_NOT_SERVICE_PROVISIONED:
130 desc = "Not service provisioned";
133 #endif // !CHIP_CONFIG_SHORT_ERROR_STR
135 FormatError(buf, bufSize, "Device Layer", err, desc);
140 const char * CharacterizeIPv6Address(const chip::Inet::IPAddress & ipAddr)
142 if (ipAddr.IsIPv6LinkLocal())
144 return "IPv6 link-local address";
147 if (ipAddr.IsIPv6ULA())
149 return "IPv6 unique local address";
152 if (ipAddr.IsIPv6GlobalUnicast())
154 return "IPv6 global unicast address";
157 return "IPv6 address";
160 } // namespace DeviceLayer