美文网首页
A: What is GATT? B: Let me show

A: What is GATT? B: Let me show

作者: ZafirTab | 来源:发表于2017-10-08 11:01 被阅读0次
    • 导语
      该篇文章,主要讲述BLE中的GATT profile。

    1、什么是GATT

    GATTgeneric attribute的简称,顾名思义,其描述的是BLE的属性应用规范。所谓的属性,我们可以理解为数据库中的一张表,是一个可以被查找的数据;在BLE中,我们使用handle句柄来进行寻址,handle句柄值是唯一的。

    在实际应用场景中,需要多个service来支持 ,每个service下面同时有多个特性(character),每个特性要有较为详细的描述,如这个特性的值和一些简单的说明等。无论是服务、特性,都要进行区分,BLE中使用UUID进行了区分。除此之外,作为数据,我们肯定是要对其进行访问的,这就要提供相应的访问权限,如可读、可写等。

    属性
    属性由属性句柄、属性类型、属性值等组成。
    属性句柄就是我们来进行数据查找的依据;
    属性类型使用UUID来进行区分,SIG对属性类型进行了分类:
    0x1800 ~ 0x26FF 用作服务类通用唯一识别码
    0x2700 ~ 0x27FF 用于标识计量单位
    0x2800 ~ 0x28FF 用于区分属性类型
    0x2900 ~ 0x29FF 用作特性描述
    0x2A00 ~ 0x2AFF 用于区分特性类型

    特性
    在BLE规范中,特性一般包括声明、数值和描述三个部分,其中前两者是强制实现的。

    2、GATT能干啥


    简单来讲,BLE利用GATT来进行数据的传输。


    3、 怎么来分析GATT

    GATT中的service or characteristic,本质上都是attribute,为了使用的方便,BLE对这些又进行了逻辑上的抽象。

    以电池服务为例:
    一个电池服务(service)包含一个电池电量特性(characteristic),其一般包含以下几个属性:primary service 电池服务、当前电量的特性定义、当前电量的特性值。由于用户通常会希望能够进行低电量提醒,所以在设计的时候,这个电量特性值不仅是可读的,而且是可以通知的。

    Android Bluetooth GATT attribute type

    以下是battery service在Android中的实现。

    /*******************************************************************************
    **
    ** Function         Battery_Instantiate
    **
    ** Description      Instantiate a Battery service
    **
    *******************************************************************************/
    UINT16 Battery_Instantiate (UINT8 app_id, tBA_REG_INFO *p_reg_info)
    {
        tBT_UUID            uuid = {LEN_UUID_16, {UUID_SERVCLASS_BATTERY}};
        UINT16              srvc_hdl;
        tGATT_STATUS        status = GATT_ERROR;
        tBA_INST            *p_inst;
        tGATT_CHAR_PROP     prop = GATT_CHAR_PROP_BIT_READ;
    
        if (battery_cb.inst_id == BA_MAX_INT_NUM)
        {
            GATT_TRACE_ERROR("MAX battery service has been reached");
            return 0;
        }
    
        p_inst = &battery_cb.battery_inst[battery_cb.inst_id];
    
        srvc_hdl = GATTS_CreateService (srvc_eng_cb.gatt_if ,
                                                &uuid,
                                                battery_cb.inst_id ,
                                                BA_MAX_ATTR_NUM,
                                                p_reg_info->is_pri);
    
        if (srvc_hdl == 0)
        {
            GATT_TRACE_ERROR("Can not create service, Battery_Instantiate() failed!");
            return 0;
        }
    
        battery_cb.inst_id ++;
    
        p_inst->app_id  =   app_id;
        p_inst->p_cback =   p_reg_info->p_cback;
    
        /* add battery level
        */
        uuid.uu.uuid16 = GATT_UUID_BATTERY_LEVEL;
    
        if (p_reg_info->ba_level_descr & BA_LEVEL_NOTIFY)
            prop |= GATT_CHAR_PROP_BIT_NOTIFY;
    
        if ((p_inst->ba_level_hdl  = GATTS_AddCharacteristic(srvc_hdl,
                                                    &uuid,
                                                    BATTER_LEVEL_PERM,
                                                    prop)) == 0)
        {
            GATT_TRACE_ERROR("Can not add Battery Level, Battery_Instantiate() failed!");
            status = GATT_ERROR;
        }
        else
        {
            if (p_reg_info->ba_level_descr & BA_LEVEL_NOTIFY)
            {
                uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
                p_inst->clt_cfg_hdl  = GATTS_AddCharDescriptor(srvc_hdl,
                                                               (GATT_PERM_READ|GATT_PERM_WRITE),
                                                               &uuid);
                if (p_inst->clt_cfg_hdl == 0)
                {
                    GATT_TRACE_ERROR("Add battery level client notification FAILED!");
                }
            }
            /* need presentation format descriptor? */
            if (p_reg_info->ba_level_descr & BA_LEVEL_PRE_FMT)
            {
                uuid.uu.uuid16 = GATT_UUID_CHAR_PRESENT_FORMAT;
                if ( (p_inst->pres_fmt_hdl = GATTS_AddCharDescriptor(srvc_hdl,
                                                                     GATT_PERM_READ,
                                                                     &uuid))
                                           == 0)
                {
                    GATT_TRACE_ERROR("Add battery level presentation format descriptor FAILED!");
                }
    
            }
            /* need presentation format descriptor? */
            if (p_reg_info->ba_level_descr & BA_LEVEL_RPT_REF)
            {
                uuid.uu.uuid16 = GATT_UUID_RPT_REF_DESCR;
                if ( (p_inst->rpt_ref_hdl = GATTS_AddCharDescriptor(srvc_hdl,
                                                                    GATT_PERM_READ,
                                                                    &uuid))
                                           == 0)
                {
                    GATT_TRACE_ERROR("Add battery level report reference descriptor FAILED!");
                }
    
            }
            /* start service
            */
            status = GATTS_StartService (srvc_eng_cb.gatt_if, srvc_hdl, p_reg_info->transport);
        }
    
        if (status != GATT_SUCCESS)
        {
            battery_cb.inst_id --;
            uuid.uu.uuid16 = UUID_SERVCLASS_BATTERY;
            GATTS_DeleteService(srvc_eng_cb.gatt_if, &uuid, battery_cb.inst_id);
            srvc_hdl = 0;
        }
    
        return srvc_hdl;
    }
    
    
    • 总结
      本篇文章旨在简明的讲述GATT是什么,能干什么,怎么去使用GATT,读者有什么疑惑,可以一起讨论。

    相关文章

      网友评论

          本文标题:A: What is GATT? B: Let me show

          本文链接:https://www.haomeiwen.com/subject/fchtextx.html