A: What is GATT? B: Let me show you

  • 导语
    该篇文章,主要讲述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,读者有什么疑惑,可以一起讨论。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容