This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 5b87eb0b62ea1cdf05d6af6a8d96bcc25c2e4b83
Author: Andrzej Kaczmarek <[email protected]>
AuthorDate: Fri Jan 27 00:48:06 2023 +0100

    nimble/ll: Add helper to validate AA
---
 .../controller/include/controller/ble_ll_utils.h   |   1 +
 nimble/controller/src/ble_ll_utils.c               | 162 +++++++++++----------
 2 files changed, 84 insertions(+), 79 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_utils.h 
b/nimble/controller/include/controller/ble_ll_utils.h
index 3e28fcb4..4d7e7e70 100644
--- a/nimble/controller/include/controller/ble_ll_utils.h
+++ b/nimble/controller/include/controller/ble_ll_utils.h
@@ -28,6 +28,7 @@
 #define CLAMP(_n, _min, _max) (MAX(_min, MIN(_n, _max)))
 #define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max)))
 
+int ble_ll_utils_verify_aa(uint32_t aa);
 uint32_t ble_ll_utils_calc_access_addr(void);
 uint32_t ble_ll_utils_calc_seed_aa(void);
 uint32_t ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n);
diff --git a/nimble/controller/src/ble_ll_utils.c 
b/nimble/controller/src/ble_ll_utils.c
index 4f1c679b..1259f94d 100644
--- a/nimble/controller/src/ble_ll_utils.c
+++ b/nimble/controller/src/ble_ll_utils.c
@@ -32,10 +32,9 @@ static const uint16_t g_ble_sca_ppm_tbl[8] = {
     500, 250, 150, 100, 75, 50, 30, 20
 };
 
-uint32_t
-ble_ll_utils_calc_access_addr(void)
+int
+ble_ll_utils_verify_aa(uint32_t aa)
 {
-    uint32_t aa;
     uint16_t aa_low;
     uint16_t aa_high;
     uint32_t temp;
@@ -47,100 +46,105 @@ ble_ll_utils_calc_access_addr(void)
     uint8_t ones;
     int tmp;
 
-    /* Calculate a random access address */
-    aa = 0;
-    while (1) {
-        /* Get two, 16-bit random numbers */
-        aa_low = ble_ll_rand() & 0xFFFF;
-        aa_high = ble_ll_rand() & 0xFFFF;
+    aa_low = aa & 0xffff;
+    aa_high = aa >> 16;
 
-        /* All four bytes cannot be equal */
-        if (aa_low == aa_high) {
-            continue;
-        }
+    /* All four bytes cannot be equal */
+    if (aa_low == aa_high) {
+        return 0;
+    }
 
-        /* Upper 6 bits must have 2 transitions */
-        tmp = (int16_t)aa_high >> 10;
-        if (__builtin_popcount(tmp ^ (tmp >> 1)) < 2) {
-            continue;
-        }
+    /* Upper 6 bits must have 2 transitions */
+    tmp = (int16_t)aa_high >> 10;
+    if (__builtin_popcount(tmp ^ (tmp >> 1)) < 2) {
+        return 0;
+    }
 
-        /* Cannot be access address or be 1 bit different */
-        aa = aa_high;
-        aa = (aa << 16) | aa_low;
-        bits_diff = 0;
-        temp = aa ^ BLE_ACCESS_ADDR_ADV;
-        for (mask = 0x00000001; mask != 0; mask <<= 1) {
-            if (mask & temp) {
-                ++bits_diff;
-                if (bits_diff > 1) {
-                    break;
-                }
+    /* Cannot be access address or be 1 bit different */
+    aa = aa_high;
+    aa = (aa << 16) | aa_low;
+    bits_diff = 0;
+    temp = aa ^ BLE_ACCESS_ADDR_ADV;
+    for (mask = 0x00000001; mask != 0; mask <<= 1) {
+        if (mask & temp) {
+            ++bits_diff;
+            if (bits_diff > 1) {
+                break;
             }
         }
-        if (bits_diff <= 1) {
-            continue;
-        }
+    }
+    if (bits_diff <= 1) {
+        return 0;
+    }
 
-        /* Cannot have more than 24 transitions */
-        transitions = 0;
-        consecutive = 1;
-        ones = 0;
-        mask = 0x00000001;
-        while (mask < 0x80000000) {
-            prev_bit = aa & mask;
-            mask <<= 1;
-            if (mask & aa) {
-                if (prev_bit == 0) {
-                    ++transitions;
-                    consecutive = 1;
-                } else {
-                    ++consecutive;
-                }
+    /* Cannot have more than 24 transitions */
+    transitions = 0;
+    consecutive = 1;
+    ones = 0;
+    mask = 0x00000001;
+    while (mask < 0x80000000) {
+        prev_bit = aa & mask;
+        mask <<= 1;
+        if (mask & aa) {
+            if (prev_bit == 0) {
+                ++transitions;
+                consecutive = 1;
             } else {
-                if (prev_bit == 0) {
-                    ++consecutive;
-                } else {
-                    ++transitions;
-                    consecutive = 1;
-                }
-            }
-
-            if (prev_bit) {
-                ones++;
+                ++consecutive;
             }
-
-            /* 8 lsb should have at least three 1 */
-            if (mask == 0x00000100 && ones < 3) {
-                break;
+        } else {
+            if (prev_bit == 0) {
+                ++consecutive;
+            } else {
+                ++transitions;
+                consecutive = 1;
             }
+        }
 
-            /* 16 lsb should have no more than 11 transitions */
-            if (mask == 0x00010000 && transitions > 11) {
-                break;
-            }
+        if (prev_bit) {
+            ones++;
+        }
 
-            /* This is invalid! */
-            if (consecutive > 6) {
-                /* Make sure we always detect invalid sequence below */
-                mask = 0;
-                break;
-            }
+        /* 8 lsb should have at least three 1 */
+        if (mask == 0x00000100 && ones < 3) {
+            break;
         }
 
-        /* Invalid sequence found */
-        if (mask != 0x80000000) {
-            continue;
+        /* 16 lsb should have no more than 11 transitions */
+        if (mask == 0x00010000 && transitions > 11) {
+            break;
         }
 
-        /* Cannot be more than 24 transitions */
-        if (transitions > 24) {
-            continue;
+        /* This is invalid! */
+        if (consecutive > 6) {
+            /* Make sure we always detect invalid sequence below */
+            mask = 0;
+            break;
         }
+    }
 
-        /* We have a valid access address */
-        break;
+    /* Invalid sequence found */
+    if (mask != 0x80000000) {
+        return 0;
     }
+
+    /* Cannot be more than 24 transitions */
+    if (transitions > 24) {
+        return 0;
+    }
+
+    return 1;
+}
+
+uint32_t
+ble_ll_utils_calc_access_addr(void)
+{
+    uint32_t aa;
+
+    do {
+        aa = ble_ll_rand();
+    } while (!ble_ll_utils_verify_aa(aa));
+
     return aa;
 }
 

Reply via email to