A: What is GATT? B: Let me show

2017-10-08  本文已影响0人  ZafirTab

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;
}

上一篇下一篇

猜你喜欢

热点阅读