diff --git a/src/lib/version/version.c b/src/lib/version/version.c index a56fa50281..ccb284c819 100644 --- a/src/lib/version/version.c +++ b/src/lib/version/version.c @@ -58,149 +58,146 @@ enum FIRMWARE_TYPE { FIRMWARE_TYPE_RELEASE = 255 }; -typedef enum { - PATCH = 0, - MINOR = 8, - MAJOR = 16 -} version_type_t; - -/** - * Convert a version number from string to int - * @param version tag - * @param start index of the fist char - * @param end index of the last char - * @return version number as int - */ -static uint32_t string_to_int(const char *tag, int start, int end) +uint32_t version_tag_to_number(const char *tag) { - const char *curr = &tag[start]; - uint32_t temp_ver = 0; + uint32_t version_number = 0; - while (curr <= &tag[end]) { - temp_ver = (temp_ver * 10) + (*curr - '0'); + int16_t buffer = -1; + size_t buffer_counter = 0; + size_t dash_count = 0; + size_t point_count = 0; + char version[3] = {0, 0, 0}; + int firmware_type = FIRMWARE_TYPE_RELEASE; - curr++; + for (size_t i = 0; i < strlen(tag); i++) { + if (tag[i] == '-') { + dash_count++; + + } else if (tag[i] == '.') { + point_count++; + } + + if (tag[i] == 'r' && i < strlen(tag) - 1 && tag[i + 1] == 'c') { + firmware_type = FIRMWARE_TYPE_RC; + + } else if (tag[i] == 'p') { + firmware_type = FIRMWARE_TYPE_ALPHA; + + } else if (tag[i] == 't') { + firmware_type = FIRMWARE_TYPE_BETA; + + } else if (tag[i] == 'v' && i > 0) { + firmware_type = FIRMWARE_TYPE_DEV; + } } - return temp_ver; -} + if ((dash_count == 1 && point_count == 2 && firmware_type == FIRMWARE_TYPE_RELEASE) || + (dash_count == 2 && point_count == 2) || + (dash_count == 3 && point_count == 4)) { + firmware_type = FIRMWARE_TYPE_DEV; + } -/** - * Convert a version tag string to a number - * @param tag version tag in one of the following forms: - * - dev: v1.4.0rc3-7-g7e282f57 - * - dev: v1.4.0rc3-7-g7e282f57-dirty - * - dev: v1.4.0-dirty - * - rc: v1.4.0rc4 - * - release: v1.4.0 - * - linux: 7.9.3 - * @return version in the form 0xAABBCCTT (AA: Major, BB: Minor, CC: Patch, TT Type @see FIRMWARE_TYPE) - */ -static uint32_t version_tag_to_number(const char *tag) -{ - uint32_t ver = 0; - unsigned len = strlen(tag); - int end = 0; - int32_t type = -1; - unsigned dashcount = 0; - version_type_t v_type = PATCH; - - for (int i = len - 1; i >= 0; i--) { - - if (tag[i] == '-') { - dashcount++; + for (size_t i = 0; i < strlen(tag); i++) { + if (buffer_counter > 2) { + continue; } if (tag[i] >= '0' && tag[i] <= '9') { - if (!end) { - end = i; + buffer = (buffer == -1) ? 0 : buffer; + buffer = buffer * 10 + (tag[i] - '0'); + + } else { + if (buffer >= 0) { + version[buffer_counter] = buffer; + buffer_counter++; } - if (i == 0) { - uint32_t temp_ver = string_to_int(tag, i, end); - ver = (temp_ver << v_type) + ver; - } - - } else if ((tag[i] == '.') || (i == 0)) { - uint32_t temp_ver = string_to_int(tag, (i + 1), end); - ver = (temp_ver << v_type) + ver; - - end = 0; - - switch (v_type) { - case PATCH: - v_type = MINOR; - break; - - case MINOR: - v_type = MAJOR; - break; - - case MAJOR: - default: - break; - } - - } else if (i > 3 && type == -1) { - /* scan and look for signature characters for each type */ - const char *curr = &tag[i - 1]; - - while (curr > &tag[0]) { - if (*curr == 'v') { - type = FIRMWARE_TYPE_DEV; - break; - - } else if (*curr == 'p') { - type = FIRMWARE_TYPE_ALPHA; - break; - - } else if (*curr == 't') { - type = FIRMWARE_TYPE_BETA; - break; - - } else if (*curr == 'r') { - type = FIRMWARE_TYPE_RC; - break; - } - - curr--; - } - - /* looks like a release */ - if (type == -1) { - type = FIRMWARE_TYPE_RELEASE; - } - - } else if (tag[i] != 'v') { - /* reset, because we don't have a full tag but - * are seeing non-numeric characters (eg. '-') - */ - ver = 0; - end = 0; + buffer = -1; } } - /* if git describe contains dashes this is not a real tag */ - if (dashcount > 0) { - type = FIRMWARE_TYPE_DEV; + if (buffer >= 0) { + version[buffer_counter] = buffer; + buffer_counter++; } - /* looks like a release */ - if (type == -1) { - type = FIRMWARE_TYPE_RELEASE; - } + version_number = ((uint8_t)version[0] << 8 * 3) | + ((uint8_t)version[1] << 8 * 2) | + ((uint8_t)version[2] << 8 * 1) | firmware_type; - ver = (ver << 8); - - return ver | type; + return version_number; } - uint32_t px4_firmware_version(void) { return version_tag_to_number(PX4_GIT_TAG_STR); } +uint32_t version_tag_to_vendor_version_number(const char *tag) +{ + uint32_t version_number = 0; + + int16_t buffer = -1; + size_t buffer_counter = 0; + char version[6] = {0, 0, 0, 0, 0, 0}; + + size_t dash_count = 0; + size_t point_count = 0; + + for (size_t i = 0; i < strlen(tag); i++) { + if (tag[i] == '-') { + dash_count++; + + } else if (tag[i] == '.') { + point_count++; + } + } + + for (size_t i = 0; i < strlen(tag); i++) { + if (buffer_counter > 5) { + continue; + } + + if (tag[i] >= '0' && tag[i] <= '9') { + buffer = (buffer == -1) ? 0 : buffer; + buffer = buffer * 10 + (tag[i] - '0'); + + } else { + if (buffer >= 0) { + if (buffer_counter + 1 == 4 && tag[i] == '-') { + break; + } + + version[buffer_counter] = buffer; + buffer_counter++; + } + + buffer = -1; + } + } + + if (buffer >= 0 && (buffer_counter + 1 == 3 || buffer_counter + 1 == 6)) { + version[buffer_counter] = buffer; + buffer_counter++; + } + + if (buffer_counter == 6) { + version_number = ((uint8_t)version[3] << 8 * 2) | + ((uint8_t)version[4] << 8 * 1) | + ((uint8_t)version[5] << 8 * 0); + + } else { + version_number = 0; + } + + return version_number; +} + +uint32_t px4_firmware_vendor_version(void) +{ + return version_tag_to_vendor_version_number(PX4_GIT_TAG_STR); +} + const char *px4_firmware_git_branch(void) { return PX4_GIT_BRANCH_NAME; diff --git a/src/lib/version/version.h b/src/lib/version/version.h index 9cc91e93e8..eeb3f8586a 100644 --- a/src/lib/version/version.h +++ b/src/lib/version/version.h @@ -98,12 +98,41 @@ static inline const char *px4_build_uri(void) return STRINGIFY(BUILD_URI); } +/** + * Convert a version tag string to a number + * @param tag version tag in one of the following forms: + * - dev: v1.4.0rc3-7-g7e282f57 + * - rc: v1.4.0rc4 + * - release: v1.4.0 + * - linux: 7.9.3 + * @return version in the form 0xAABBCCTT (AA: Major, BB: Minor, CC: Patch, TT Type @see FIRMWARE_TYPE) + */ +__EXPORT uint32_t version_tag_to_number(const char *tag); + /** * get the PX4 Firmware version * @return version in the form 0xAABBCCTT (AA: Major, BB: Minor, CC: Patch, TT Type @see FIRMWARE_TYPE) */ __EXPORT uint32_t px4_firmware_version(void); +/** + * Convert a version tag string to a vendor version number + * @param tag version tag in one of the following forms: + * - vendor: v1.4.0-0.2.0 + * - dev: v1.4.0rc3-7-g7e282f57 + * - rc: v1.4.0rc4 + * - release: v1.4.0 + * - linux: 7.9.3 + * @return version in the form 0xAABBCC (AA: Major, BB: Minor, CC: Patch) + */ +__EXPORT uint32_t version_tag_to_vendor_version_number(const char *tag); + +/** + * get the PX4 Firmware vendor version + * @return version in the form 0xAABBCC (AA: Major, BB: Minor, CC: Patch) + */ +__EXPORT uint32_t px4_firmware_vendor_version(void); + /** * get the board version (last 8 bytes should be silicon ID, if any) */