日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > BLE添加特征值

BLE添加特征值 時間:2018-08-16      來源:未知

一、 什么是特征值

特征值就是BLE協議棧向外提供的一個數據接口,藍牙之間的數據傳輸終落實在特征值上。在BLE協議棧的GATT層中封裝了若干服務(service),而在每一個服務中又有若干特征值(characters),特征值可以是任意類型的數據。藍牙之間的數據傳輸靠協議棧提供的write和read函數,而這兩個函數就是在操作特征值

二、UUID

UUID就是通用唯一識別碼。在藍牙協議棧中可能會有多個服務,每個服務會有多個特征值,而這些服務或者特征值都有一個唯一的ID,這樣就可以區分了。這個UUID是其他設備設置藍牙服務和特征值的唯一方法。

三、增加特征值

在BLE協議棧中,GATT層定義了特征值和服務。下面就以SimpleBLEPeripheral為例,增加一個特征值。在simpleGATTprofile.c中,已經有定義好的特征值,參考已有的特征值就可以順利添加自己的特征值

1) 修改頭文件simpleGATTprofile.h

頭文件中定義了特征值的UUID,以及長度和默認值

//特征值UUID

#define SIMPLEPROFILE_CHAR5_UUID            0xFFF5

//特征值長度

#define SIMPLEPROFILE_CHAR5_LEN           5

2)添加特征值相關變量

包括特征值的讀寫權限、變量名、展現給用戶的名字

//特征值初始化

// 特征值屬性,讀或者寫

static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;

// 值,可以向其寫入數據,也可以讀出數據。這里是一個字符數組

static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = {0};

// 用戶描述,展現給用戶的名字

static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6\0";

//提取uuid,uuid定義在頭文件中

CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] =

    LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)

};

3)將特征值加入屬性表

特征值由服務統一管理,所有的特征值都會在一個服務的屬性表中呈現出來,每增加一個特征值,它的相關變量就要在添加到屬性表中

//特征值初始化

static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = 

{

    // Simple Profile Service

    { 

        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */

        GATT_PERMIT_READ,                         /* permissions */

        0,                                        /* handle */

        (uint8 *)&simpleProfileService            /* pValue */

    },

    // Characteristic 1 Declaration

    { 

        { ATT_BT_UUID_SIZE, characterUUID },

        GATT_PERMIT_READ, 

        0,

        &simpleProfileChar1Props 

    },

    

    // Characteristic Value 1

    { 

        { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },

        GATT_PERMIT_AUTHEN_READ | GATT_PERMIT_AUTHEN_WRITE, 

        0, 

        &simpleProfileChar1 

    },

    

    // Characteristic 1 User Description

    { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar1UserDesp 

    },      

  

。。。。。

    

    // Characteristic 5 Declaration

    { 

        { ATT_BT_UUID_SIZE, characterUUID },

        GATT_PERMIT_READ, 

        0,

        &simpleProfileChar5Props 

    },

    

    // Characteristic Value 5

    { 

        { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },

        GATT_PERMIT_AUTHEN_READ| GATT_PERMIT_AUTHEN_WRITE, 

        0, 

        simpleProfileChar5 

    },

    

    // Characteristic 5 User Description

    { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar5UserDesp 

    },    

4)修改屬性表的長度

每增加一個特征值,屬性表的長度也會增加,因此要修改屬性表的長度。在文件的一開始就聲明了屬性表的長度

#define SERVAPP_NUM_ATTR_SUPPORTED        24

5)修改SimpleProfile_SetParamete和SimpleProfile_GetParamete函數

這是操作特征值的兩個函數,set函數可以用來初始化特征值,get函數可以用來提取特征值。一般我們定義的特征值都是uint8類型的數組,因此無論set還是get,都可以使用copy函數來完成,同時要注意實際的長度

bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )

{

    bStatus_t ret = SUCCESS;

    switch ( param )

    {     

。。。。。。。        

    case SIMPLEPROFILE_CHAR5:

        if ( len <= SIMPLEPROFILE_CHAR5_LEN ) 

        {

           //將value值復制到特征值5,同時注意長度

            VOID osal_memcpy( simpleProfileChar5, value, len );

        }

        else

        {

            ret = bleInvalidRange;

        }

        break;      

    default:

        ret = INVALIDPARAMETER;

        break;

    }

    return ( ret );

}

 

bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )

{

    bStatus_t ret = SUCCESS;

    switch ( param )

    { 

。。。。。。        

case SIMPLEPROFILE_CHAR5:

   //將特征值5復制到value

        VOID osal_memcpy( value, simpleProfileChar5, osal_strlen(simpleProfileChar5));

        break;      

    default:

        ret = INVALIDPARAMETER;

        break;

    }

    

    return ( ret );

}

6)修改simpleProfile_ReadAttrCB和simpleProfile_WriteAttrCB函數

上面已經有了set和get函數,可以實現對特征值的讀寫,那么這里為何又來了一對read和write呢???set和get是用來本地讀寫特征值的,而read和write則是網絡上的讀寫。什么意思呢,當藍牙網絡的另一端想要讀取特征值的時候,協議棧就會自動回調這個read函數,然后將讀取的結果傳輸的網絡的另一端。當然,寫操作也是一樣的。

static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, 

                                      uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )

{

    bStatus_t status = SUCCESS;

    if ( pAttr->type.len == ATT_BT_UUID_SIZE )

    {

        // 16-bit UUID

        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);

        switch ( uuid )

        {

 。。。。。。

            

        case SIMPLEPROFILE_CHAR5_UUID:

            *pLen = osal_strlen(pAttr->pValue);

            VOID osal_memcpy( pValue, pAttr->pValue, osal_strlen(pAttr->pValue) );

            break;            

        default:

            // Should never get here! (characteristics 3 and 4 do not have read permissions)

            *pLen = 0;

            status = ATT_ERR_ATTR_NOT_FOUND;

            break;

        }

    }    

    return ( status );

}

 

static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,

                                           uint8 *pValue, uint8 len, uint16 offset )

{

    bStatus_t status = SUCCESS;

    uint8 notifyApp = 0xFF;  

    if ( pAttr->type.len == ATT_BT_UUID_SIZE )

    {

        // 16-bit UUID

        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);

        switch ( uuid )

        {

。。。。。。

            

        case SIMPLEPROFILE_CHAR5_UUID: 

            //Validate the value 檢測輸入數據是否合法

            // Make sure it's not a blob oper

            if ( offset == 0 ) //是第一字節

            {

                if ( len >= SIMPLEPROFILE_CHAR6_LEN )

                {

                    status = ATT_ERR_INVALID_VALUE_SIZE;

                } //若輸入長度不對,status為

            }

            else

            {

                status = ATT_ERR_ATTR_NOT_LONG;//不是第一字節

            }

            

            if ( status == SUCCESS )

            {  

                //清空緩沖區

                osal_memset(pAttr->pValue, '\0', SIMPLEPROFILE_CHAR6_LEN) ;

                //復制

                VOID osal_memcpy( pAttr->pValue, pValue, len);

                notifyApp = SIMPLEPROFILE_CHAR6;

            }   

           

            break;    

                        

        default:

            // Should never get here! (characteristics 2 and 4 do not have write permissions)

            status = ATT_ERR_ATTR_NOT_FOUND;

            break;

        }

}

 

7)修改simpleBLEPeripheral.c

A、在SimpleBLEPeripheral_Init函數中可以使用set方法對特征值做初始化操作

SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, 5, charValue5 );

B、修改simpleProfileChangeCB

當特征值被網絡的另一端修改之后,協議棧會回調這個函數,通知當前特征值發生變化

static void simpleProfileChangeCB( uint8 paramID )

{

  uint8 newValue;

  uint8 *val;

  switch( paramID )

  {

    。。。。。。

      

    case SIMPLEPROFILE_CHAR5:

      val = osal_msg_allocate(15);

//提取特征值,注意這里使用的是get方式

      SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR5, val );

      break;

    default:

      // should not reach here!

      break;

  }

   SerialPrint(val);

}

 

四、測試

如何驗證特征值已經被成功的添加呢,基于上面的例子,我們需要一個BLE主機設備來讀取特征值。建議使用手機來完成測試,因為你很難確保你的主機代碼是正確的。從網絡上下載BLE調試軟件,可以輕松的操作特征值。

上一篇:BLE 數據接發流程

下一篇:Platform相親之旅

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 浙江卫视网络直播源| 极寒之城在线观看高清完整 | 妈妈的脊背简谱| 左航个人资料| 护航 电影| 北国之恋| 女演员佟欣简介| 永恒传说图文详细攻略| 寡妇 电影| 吃大米饭是增肥还是减肥| 刘思维| 我想成为影之强者| 马文的战争电影完整视频观看| 二年级上册音乐教案全册| 情侣视频| 心经般若波罗蜜多心经全文 | 马修| 我的丁香结| av电影网| 格什温| 绫濑天| 韩国电影诱惑| 乔治桑| 红灯区免费看| 电影田螺姑娘| 美女网站视频免费| 吴添豪| 电影世界冒险记| 《欲望中的女人》| 五上语文第7课笔记| 未删减版电视剧在线观看| 杯弓蛇影读后感| 廖凡演的电影| 叶子楣作品| 大学生国防论文2000字| 陈若| 播放凯登克罗斯演的全部影片| 膨腹爱好者撑肚子视频| 黄网站免费在线观看| 情人电影网| 文王一支笔的功效与作用 |