ATT层容器结构

1.att容器数据结构需要考虑到的东西

1.1属性类型

UUID

  • 公开的数据有许多不同的类型,数据的类型称为属性类型
  • 为了区分如此多的属性类型,可以用一串128b的通用唯一识别码(UUID)来标识属性的类型。这样识别数据类型需要发送长达16B的数据。
  • 为了提高传输速率,蓝牙技术联盟(SIG)定义了一个称为“蓝牙UUID基数”的128b通用唯一识别码,结合一个较短的16b数使用。在设备间传输常用的UUID时,只发送较短的16b版本,接收后补上蓝牙UUID的基数即可。

    蓝牙UUID基数为:
            00000000 - 000 - 1000 - 800 - 00805F9B34FB


要发送16b识别码xxxx时,完整的128b的UUID为:
        0000xxxx - 000 - 1000 - 800 - 00805F9B34FB 蓝牙基础UUID数组设计的时候要注意是小印第安序来存放的
    // Buetooth Base UUID 00000000-0000-1000-8000-00805F9B34FB in little endian
    static const uint8_t bluetooth_base_uuid[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

小印第安序:数据的低地址上存放的是这个整数的低位字节,在高地址上存放的是整数的高位字节。

地址0x00000x00010x00020x0003
Big endian0x120x340x560x78
little endian0x780x560x340x12

1.2属性句柄

handle

  • 服务器上的所有属性都会分配一个非零的属性句柄。客户端与服务器之间的操作使用句柄来区分属性
  • 新的属性不能被分配一个已使用的句柄,即使曾使用过这个句柄的属性已被删除。这可以保证客户端总是可以获取一个唯一独特的额属性句柄
  • 一旦一个属性被分配了一个句柄,那么任何时候都应该保持这个句柄不变,以使得客户端可以使用同一个句柄持续访问相应的属性
  • 属性服务器的属性按照句柄来排序。句柄0x0000被保留,0xFFFF是最大的属性句柄

1.3属性值

value value_len

  • 属性值是一个包含属性实际值得8b组阵列。属性长度可以是固定的,也可以不定的。固定长度时,长度可以是8b,16b和32b。不定长度时,属性值得长度可以是0B到最长512B。
  • 一个协议数据单元(PDU)只能传输一个属性值,属性值过长可以分拆到多个协议数据单元中传输。

1.4数据结构的设计

采用一种新型的java形态的设计方法

    typedef struct att_iterator{
        //private
        uint8_t  cosnt *att_ptr;//数据的起始
        //public
        uint16_t size;
        uint16_t flags;//用来确定是16位的还是128位的UUID
        uint16_t handle;//属性句柄
        uint8_t  const *uuid;
        uint16_t value_len;
        uint8_t  const *value; 
    }att_iterator_t;

    static void att_iterator_init(att_iterator_t *it){
        it->att_ptr = att_db;
    }    

    static int att_iterator_has_next(att_iterator_t *it){
        return it->att_ptr != NULL;//判断时候有下一个属性
    }

    static void att_iterator_fetch_next(att_iterator_it *it){
        it->size = read_little_endian_16(it->att_ptr, 0);
        if(it->size == 0){
            it->flags = 0;
            it->handle = 0;
            it->uuid = NULL;
            it->value_len = 0;
            it->value = NULL;
            it->att_ptr = NULL;
            return;//读取这个空的属性就可以返回了
        }
        it->flags = read_little_endian_16(it->att_ptr, 2);
        it->handle = read_little_endian_16(it->att_ptr, 4);
        it->uuid = &it->att_ptr[6];
        if(it->flags & ATT_PROPERTY_UUID128){//当flag == 0x02时候成立
            it->value_len = it->size - 22;
            it->value = &it->att_ptr[22];
        }else{
            it->value_len = it->size - 8;
            it->value = &it->att_ptr[8];
        }
        it->att_ptr += it->size;
    }

    #define read_little_endian_16(buffer, pos) (((uint16_t)buffer[pos]) || (((uint16_t)(buffer[(pos) + 1]) << 8))

    #define ATT_PROPERTY_UUID128             0x200

ATT连接

void bt_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){
    buffer[pos++] = value;
    buffer[pos++] = value >> 8;
}

typedef struct att_connection {
    uint16_t con_handle;
    uint16_t mtu;       // initialized to ATT_DEFAULT_MTU (23), negotiated during MTU exchange
    uint16_t max_mtu;   // local maximal L2CAP_MTU, set to l2cap_max_le_mtu()
    uint8_t  encryption_key_size;
    uint8_t  authenticated;
    uint8_t  authorized;
} att_connection_t;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值