boot: replace boot_is_version_sufficient() function

Replace the boot_is_version_sufficient() function with a new,
boot_version_cmp() function which is more straightforward and
distinguishes the 3 possible results of the comparison.
Update the error handling accordingly.

Change-Id: Ie7d4f892dc3df2c6ef82769c4d0676965b75b7b8
Signed-off-by: David Vincze <david.vincze@linaro.org>
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 1094ff2..60815df 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -519,33 +519,39 @@
 #if (BOOT_IMAGE_NUMBER > 1) || \
     (defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION))
 /**
- * Check if the version of the image is not older than required.
+ * Compare image version numbers not including the build number
  *
- * @param req         Required minimal image version.
- * @param ver         Version of the image to be checked.
+ * @param ver1           Pointer to the first image version to compare.
+ * @param ver2           Pointer to the second image version to compare.
  *
- * @return            0 if the version is sufficient, nonzero otherwise.
+ * @retval -1           If ver1 is strictly less than ver2.
+ * @retval 0            If the image version numbers are equal,
+ *                      (not including the build number).
+ * @retval 1            If ver1 is strictly greater than ver2.
  */
 static int
-boot_is_version_sufficient(struct image_version *req,
-                           struct image_version *ver)
+boot_version_cmp(const struct image_version *ver1,
+                 const struct image_version *ver2)
 {
-    if (ver->iv_major > req->iv_major) {
-        return 0;
+    if (ver1->iv_major > ver2->iv_major) {
+        return 1;
     }
-    if (ver->iv_major < req->iv_major) {
-        return BOOT_EBADVERSION;
+    if (ver1->iv_major < ver2->iv_major) {
+        return -1;
     }
-    /* The major version numbers are equal. */
-    if (ver->iv_minor > req->iv_minor) {
-        return 0;
+    /* The major version numbers are equal, continue comparison. */
+    if (ver1->iv_minor > ver2->iv_minor) {
+        return 1;
     }
-    if (ver->iv_minor < req->iv_minor) {
-        return BOOT_EBADVERSION;
+    if (ver1->iv_minor < ver2->iv_minor) {
+        return -1;
     }
-    /* The minor version numbers are equal. */
-    if (ver->iv_revision < req->iv_revision) {
-        return BOOT_EBADVERSION;
+    /* The minor version numbers are equal, continue comparison. */
+    if (ver1->iv_revision > ver2->iv_revision) {
+        return 1;
+    }
+    if (ver1->iv_revision < ver2->iv_revision) {
+        return -1;
     }
 
     return 0;
@@ -603,10 +609,10 @@
 #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION)
     if (slot != BOOT_PRIMARY_SLOT) {
         /* Check if version of secondary slot is sufficient */
-        rc = boot_is_version_sufficient(
-                &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver,
-                &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver);
-        if (rc != 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
+        rc = boot_version_cmp(
+                &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
+                &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
+        if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
             BOOT_LOG_ERR("insufficient version in secondary slot");
             flash_area_erase(fap, 0, fap->fa_size);
             /* Image in the secondary slot does not satisfy version requirement.
@@ -1126,8 +1132,8 @@
                                           : BOOT_PRIMARY_SLOT;
     dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
 
-    rc = boot_is_version_sufficient(&dep->image_min_version, dep_version);
-    if (rc != 0) {
+    rc = boot_version_cmp(dep_version, &dep->image_min_version);
+    if (rc < 0) {
         /* Dependency not satisfied.
          * Modify the swap type to decrease the version number of the image
          * (which will be located in the primary slot after the boot process),
@@ -1145,6 +1151,9 @@
         default:
             break;
         }
+    } else {
+        /* Dependency satisfied. */
+        rc = 0;
     }
 
     return rc;
@@ -1243,7 +1252,7 @@
         if (rc == 0) {
             /* All dependencies've been satisfied, continue with next image. */
             BOOT_CURR_IMG(state)++;
-        } else if (rc == BOOT_EBADVERSION) {
+        } else {
             /* Cannot upgrade due to non-met dependencies, so disable all
              * image upgrades.
              */
@@ -1252,9 +1261,6 @@
                 BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
             }
             break;
-        } else {
-            /* Other error happened, images are inconsistent */
-            return rc;
         }
     }
     return rc;
@@ -1675,7 +1681,7 @@
          * are all satisfied and update swap type if necessary.
          */
         rc = boot_verify_dependencies(state);
-        if (rc == BOOT_EBADVERSION) {
+        if (rc != 0) {
             /*
              * It was impossible to upgrade because the expected dependency version
              * was not available. Here we already changed the swap_type so that