summaryrefslogtreecommitdiff
path: root/Radio/HW/BladeRF/src/helpers/version.c
diff options
context:
space:
mode:
Diffstat (limited to 'Radio/HW/BladeRF/src/helpers/version.c')
-rw-r--r--Radio/HW/BladeRF/src/helpers/version.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/Radio/HW/BladeRF/src/helpers/version.c b/Radio/HW/BladeRF/src/helpers/version.c
new file mode 100644
index 0000000..a378d23
--- /dev/null
+++ b/Radio/HW/BladeRF/src/helpers/version.c
@@ -0,0 +1,177 @@
+/**
+ * This file is part of the bladeRF project:
+ * http://www.github.com/nuand/bladeRF
+ *
+ * Copyright (C) 2014-2015 Nuand LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "log.h"
+#include "rel_assert.h"
+
+#include "helpers/version.h"
+
+bool version_equal(const struct bladerf_version *v1,
+ const struct bladerf_version *v2)
+{
+ return v1->major == v2->major &&
+ v1->minor == v2->minor &&
+ v1->patch == v2->patch;
+}
+
+bool version_greater_or_equal(const struct bladerf_version *v1,
+ const struct bladerf_version *v2)
+{
+ return version_fields_greater_or_equal(v1, v2->major, v2->minor, v2->patch);
+}
+
+bool version_less_than(const struct bladerf_version *v1,
+ const struct bladerf_version *v2)
+{
+ return version_fields_less_than(v1, v2->major, v2->minor, v2->patch);
+}
+
+bool version_fields_greater_or_equal(const struct bladerf_version *version,
+ unsigned int major, unsigned int minor,
+ unsigned int patch)
+{
+ if (version->major > major) {
+ return true;
+ } else if ( (version->major == major) && (version->minor > minor) ) {
+ return true;
+ } else if ((version->major == major) &&
+ (version->minor == minor) &&
+ (version->patch >= patch) ) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool version_fields_less_than(const struct bladerf_version *version,
+ unsigned int major, unsigned int minor,
+ unsigned int patch)
+{
+ return !version_fields_greater_or_equal(version, major, minor, patch);
+}
+
+static const struct compat *find_fw_compat(const struct version_compat_table *fw_compat_table,
+ const struct bladerf_version *fw_version)
+{
+ const struct compat *newest_compat = &fw_compat_table->table[0];
+ size_t i;
+
+ /* Version is newer than what's in our table - complain */
+ if (version_less_than(&newest_compat->ver, fw_version)) {
+ log_info("Firmware version (v%u.%u.%u) is newer than entries in "
+ "libbladeRF's compatibility table. Please update libbladeRF "
+ "if problems arise.\n",
+ fw_version->major, fw_version->minor, fw_version->patch);
+ return newest_compat;
+ }
+
+ for (i = 0; i < fw_compat_table->len; i++) {
+ if (version_equal(fw_version, &fw_compat_table->table[i].ver)) {
+ return &fw_compat_table->table[i];
+ }
+ }
+
+ return NULL;
+}
+
+static const struct compat *find_fpga_compat(const struct version_compat_table *fpga_compat_table,
+ const struct bladerf_version *fpga_version)
+{
+ const struct compat *newest_compat = &fpga_compat_table->table[0];
+ size_t i;
+
+ /* Device's FPGA is newer than what's in our table - complain */
+ if (version_less_than(&newest_compat->ver, fpga_version)) {
+ log_info("FPGA version (v%u.%u.%u) is newer than entries in "
+ "libbladeRF's compatibility table. Please update libbladeRF "
+ "if problems arise.\n",
+ fpga_version->major, fpga_version->minor, fpga_version->patch);
+ return newest_compat;
+ }
+
+ for (i = 0; i < fpga_compat_table->len; i++) {
+ if (version_equal(fpga_version, &fpga_compat_table->table[i].ver)) {
+ return &fpga_compat_table->table[i];
+ }
+ }
+
+ return NULL;
+}
+
+int version_check_fw(const struct version_compat_table *fw_compat_table,
+ const struct bladerf_version *fw_version,
+ struct bladerf_version *required_fw_version)
+{
+ const struct bladerf_version *oldest_version = &fw_compat_table->table[fw_compat_table->len-1].ver;
+
+ if (required_fw_version) {
+ *required_fw_version = *oldest_version;
+ }
+
+ if (version_greater_or_equal(fw_version, oldest_version)) {
+ return 0;
+ }
+
+ return BLADERF_ERR_UPDATE_FW;
+}
+
+int version_check(const struct version_compat_table *fw_compat_table,
+ const struct version_compat_table *fpga_compat_table,
+ const struct bladerf_version *fw_version,
+ const struct bladerf_version *fpga_version,
+ struct bladerf_version *required_fw_version,
+ struct bladerf_version *required_fpga_version)
+{
+ const struct compat *fw_compat = find_fw_compat(fw_compat_table, fw_version);
+ const struct compat *fpga_compat = find_fpga_compat(fpga_compat_table, fpga_version);
+
+ if (fw_compat == NULL) {
+ log_debug("%s is missing FW version compat table entry?\n",
+ __FUNCTION__);
+ return BLADERF_ERR_UPDATE_FW;
+ } else if (fpga_compat == NULL) {
+ log_debug("%s is missing FPGA version compat table entry?\n",
+ __FUNCTION__);
+ return BLADERF_ERR_UPDATE_FPGA;
+ }
+
+ if (required_fw_version) {
+ *required_fw_version = fpga_compat->requires;
+ }
+ if (required_fpga_version) {
+ *required_fpga_version = fw_compat->requires;
+ }
+
+ /* Check if the FPGA meets the minimum requirements dictated by the
+ * firmware version */
+ if (version_less_than(fpga_version, &fw_compat->requires)) {
+ return BLADERF_ERR_UPDATE_FPGA;
+ }
+
+ /* Check if the firmware version meets the minimum requirements dictated
+ * by the FPGA version */
+ if (version_less_than(fw_version, &fpga_compat->requires)) {
+ return BLADERF_ERR_UPDATE_FW;
+ }
+
+ return 0;
+}
+