/* * SPDX-License-Identifier: LicenseRef-CSSL-1.0 */ #include #include #include #include #include #include #include #include "utils.h" /**************************************************************************** ** ** ** Name: hex_char_to_hex_value() ** ** ** ** Description: Converts an hexadecimal ASCII coded digit into its value. ** ** ** ** Inputs: c: A char holding the ASCII coded value ** ** Others: None ** ** ** ** Outputs: None ** ** Return: Converted value (-1 on error) ** ** Others: None ** ** ** ***************************************************************************/ int hex_char_to_hex_value (char c) { if (!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'))) return -1; if (c >= 'A') { /* Remove case bit */ c &= ~('a' ^ 'A'); return (c - 'A' + 10); } else { return (c - '0'); } } /**************************************************************************** ** ** ** Name: hex_string_to_hex_value() ** ** ** ** Description: Converts an hexadecimal ASCII coded string into its value.** ** ** ** Inputs: hex_value: A pointer to the location to store the ** ** conversion result ** ** size: The size of hex_value in bytes ** ** Others: None ** ** ** ** Outputs: hex_value: Converted value ** ** Return: 0 on success, -1 on error ** ** Others: None ** ** ** ***************************************************************************/ int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) { int i; if (strlen(hex_string) != size*2) { fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2); return -1; } for (i=0; i < size; i++) { int a = hex_char_to_hex_value(hex_string[2 * i]); int b = hex_char_to_hex_value(hex_string[2 * i + 1]); if (a == -1 || b == -1) goto error; hex_value[i] = (a << 4) | b; } return 0; error: fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string); for (i=0; i < size; i++) hex_value[i] = 0; return -1; } char *itoa(int i) { char buffer[64]; int ret; ret = snprintf(buffer, sizeof(buffer), "%d",i); if ( ret <= 0 ) { return NULL; } return strdup(buffer); } /**************************************************************************** ** ** ** Name: digit_string_to_bcd_value() ** ** ** ** Description: Converts a decimal ASCII coded string into its BCD encoded** ** value. ** ** ** ** Inputs: bcd_value: Output buffer ** ** digit_string: Input digit string ** ** size: Size of bcd_value in bytes ** ** ** ** Outputs: bcd_value: Converted BCD value ** ** Return: 0 on success, -1 on error ** ** ** ***************************************************************************/ int digit_string_to_bcd_value(uint8_t *bcd_value, const char *digit_string, int size) { int i; uint8_t len = strlen(digit_string); /* Accept even (size*2) or odd (size*2 - 1) digit counts */ if (len < size * 2 - 1 || len > size * 2) { fprintf(stderr, "the string '%s' should be of length %d or %d\n", digit_string, size * 2 - 1, size * 2); return -1; } for (i = 0; i < size; i++) { uint8_t low = digit_string[2 * i] - '0'; uint8_t high = (2 * i + 1 < len) ? digit_string[2 * i + 1] - '0' : 0xF; if (low > 9 || (high > 9 && high != 0xF)) goto error; bcd_value[i] = (high << 4) | low; } return 0; error: fprintf(stderr, "the string '%s' is not a valid digit string\n", digit_string); for (i = 0; i < size; i++) bcd_value[i] = 0; return -1; } /** * @brief Convert a version string x.y.z into numbers. * * The function takes a version string of format "x.y.z" where x is the major * version number, y minor, z patch. It tries to match version, and outputs the * numbers in the correspondingly named variables. * * @return The number of version parts matched (should be three on x.y.z). */ int read_version(const char *version, uint8_t *major, uint8_t *minor, uint8_t *patch) { int ret = sscanf(version, "%hhu.%hhu.%hhu", major, minor, patch); // EOF means "end of input reached or matching failure" if (ret == EOF) return 3; return ret; // ret has number of items matched }