BLE 2.4G 对接入地址的要求和校验函数


/**
 * @brief 统计从bit0开始 n bits 内相邻位翻转次数
 * @param val 待统计数值
 * @param bits 统计多少位(从bit0起)
 * @return 翻转次数
 */
static uint8_t count_transition(uint32 val, uint8 bits)
{
    if(bits <= 1)
        return 0;
    uint8 cnt = 0;
    uint8 pre = val & 1;
    for(uint8 i = 1; i < bits; i++)
    {
        uint8 curr = (val >> i) & 1;
        if(curr != pre)
        {
            cnt++;
        }
        pre = curr;
    }
    return cnt;
}

 

BOOL ble_address_valid_access (uint32 accessAddr)
{
uint8 num, value, index;
// 1 检测地址是否重复
// 2  24 次位翻转
num = 0;
index = 0;
do {
value = (uint8)( (accessAddr >> index) & 1);
index ++;
if ( (uint8)((accessAddr >> index) & 1) != value ){
num ++;
if ( num >= 25 ){  // 地址无效
return FALSE;
}
}
} while ( index < 31 );
// 3  6 个连续的 0 或 1
index = 0;
do {
value = (accessAddr>>index)&0x3f;
if ( value == 0 || value == 0x3f ){
return FALSE;
}
index++;
} while ( index <= 26 );
// 4  高 6 bit 少于 2 次位翻转
value = (accessAddr>>26)&0x3f;
if ( value == 0x1f ||  value == 0x3e || value == 0x01 ||  value == 0x20 ){
return FALSE;
}
// 5  与广播地址相同
if ( accessAddr == ADV_ACCESS_ADDRESS ){
return FALSE;
}
// 6  与广播地址只有 1bit 差异
uint32 aa;
aa = accessAddr ^ ADV_ACCESS_ADDRESS; if ( !(aa & (aa -1)) ){ return FALSE; } // 7 四字节都相等 value = (uint8) accessAddr; if (value == (uint8)(accessAddr>>8 ) && value == (uint8)(accessAddr>>16) && value == (uint8)(accessAddr>>24) ){ return FALSE; } // ========= 新增规则8:低8位大于等于3个1 =========
uint8 low8_ones=0;

 uint8 i;
 value=accessAddr & 0xFF;
 for(i=0;i<8;i++)
 {
  if(value&(1<<i) low8_ones ++;
 }

 if(low8_ones < 3) { return FALSE; }
 // ========= 新增规则9:低16位不超过11次翻转 =========
uint8 low16_trans = count_transition(accessAddr & 0x0000FFFF, 16);
if(low16_trans > 11) { return FALSE; }
return TRUE;
}

协议强制要求(LL 校验,共 8 条核心规则)

  1. 不能出现连续 6 个 0,也不能出现连续 6 个 1(任意滑动 6bit 窗口,禁止000000/111111
  2. 32bit 相邻位翻转(transition,0↔1 变化)总数 ≤ 24 次;32bit 一共 31 对相邻 bit,翻转≥25 → 无效
  3. 最高 6bit(bit31~bit26)至少 2 次翻转 高 6bit 翻转次数 < 2 无效,也就是 0x01,0x1F,0x20,0x3E 这 4 种 6bit 序列直接被排除
  4. 不能等于广播接入地址 0x8E89BED6
  5. 与广播接入地址不能仅相差 1bit(异或结果只有 1bit 置 1 会被拒绝,防止广播包误判为连接包)
  6. 4 个字节不能全部相等,例如 0xAAAAAAAA0x11111111 无效
  7. 本机所有正在使用的接入地址不能重复:ACL、CIS、周期性广播、BIS、BIG Control 都不能复用同一个 Access Address
  8. CIS 额外约束:新建 CIS 的接入地址,必须和本机其他正在使用的接入地址差异 > 1bit(至少 2bit 不同)

设计目的

接入地址用于接收机帧同步、相关检测

  • 限制长连 0 / 连 1:避免 DC 漂移,时钟恢复丢失;
  • 控制翻转次数:保证符号密度,利于 AGC、位同步;
  • 远离广播地址:防止广播包被误识别成连接数据包,LL 假包;
  • 随机生成:降低多设备同空间下地址碰撞概率。

补充要点

  1. BIS 广播等时流:Seed Access Address(SAA)也遵循同样的校验规则;
  2. 校验是Link Layer 职责,主机 HCI 一般不需要做,但自研 / 芯片 SDK 做接入地址预生成时必须实现这套校验函数;
  3. 位序:规范是bit31 为 MSB,写代码移位时不要搞反高低位。
posted @ 2026-09-23 14:10  debugdabiaoge  阅读(9)  评论(0)    收藏  举报