藍芽4.0 BLE SimpleBLEPeripheral_新增新CHAR值及UUID
UUID, 就是用來唯一識別一個特徵值的ID.
handle,就是對應的attribute 的一個控制代碼。
所有對特徵值的操作,都是通過對UUID 的搜尋得到對應的handle之後,通過handle來操作特徵值的。
新增新的特徵值CHAR6
下面對主要幾個檔案進行修改
simpleGATTprofile.h 檔案新增以下定義
#define SIMPLEPROFILE_CHAR6 5
#define SIMPLEPROFILE_CHAR6_UUID 0xFFF6
#define SIMPLEPROFILE_CHAR6_LEN 5 (單位元組沒這句)
SIMPLEPROFILE_CHAR6 全大寫 case 引數用到 如 case SIMPLEPROFILE_CHAR6:
在simpleGATTprofile.c
1、 新增特徵值UUID
// Characteristic 6 UUID: 0xFFF6
CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), //低八位
HI_UINT16(SIMPLEPROFILE_CHAR6_UUID) }; //高八位
/**************#define HI_UINT16(a) (((a) >> 8) & 0xFF)*******
/**************#define LO_UINT16(a) ((a) & 0xFF)*******
2、 設定屬性
// Simple Profile Characteristic 6 Properties 可讀可寫 (宣告而已,只是能讓lightblue在列表中顯示為可讀可寫或通知,真正要改在屬性表那裡改。Props= Properties,Desp =Description,)
static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;
// Characteristic 6 Value // simpleProfileChar6是個5位陣列,接收資料後存在這
static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0, 0, 0, 0, 0 };
// Simple Profile Characteristic 6 User Description
static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6\0";
3、 屬性表 (Profile Attributes - Table)最重要,添加了這個才會在lightblue中列表出來
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED]
這裡要把陣列改為
#define SERVAPP_NUM_ATTR_SUPPORTED 20 原來是17
(//添加了3組結構體陣列 CHAR6)
simpleProfileAttrTbl表中,可讀可寫屬性都是3個數組,只有char4的通知是4組,多了個// Characteristic 4 configuration
並把 CHAR6 新增進去
// Characteristic 6 Declaration (宣告,沒加這個lightblue屬性表找不到)
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar6Props
},
// Characteristic Value 6 (特徵值)!!!
{
{ ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, //設定可讀可寫
0,
simpleProfileChar6 //由於值是5位陣列,不用&,一個位元組就用
},
// Characteristic 6 User Description //描述
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar6UserDesp
},
能列出來了但是 點進去會報錯,還沒設定讀寫引數simpleProfile_WriteAttrCB, 和
simpleProfile_ReadAttrCB
4、設定引數函式 (SimpleProfile_SetParameter函式)
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )中:
// 即修改SimpleProfile_SetParameter();函式
新增以下程式碼:
case SIMPLEPROFILE_CHAR6:
if ( len == SIMPLEPROFILE_CHAR6_LEN ) //特徵值賦值到陣列
{
VOID osal_memcpy(simpleProfileChar6, value, SIMPLEPROFILE_CHAR6_LEN );
//把要改寫的資料寫到simpleProfileChar6陣列來
}
else
{
ret = bleInvalidRange;
}
break;
4、 獲取引數函式 {SimpleProfile_GetParameter(UUID,獲取到的值)函式}
實際上就是把被新進的值simpleProfileChar6放進value陣列
在bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )中新增:
case SIMPLEPROFILE_CHAR6:
VOID osal_memcpy( value, simpleProfileChar6, SIMPLEPROFILE_CHAR6_LEN );
break;
//讀取simpleProfileChar6的值放到*value 中,char1是單個位元組讀取,為
*((uint8*)value) = simpleProfileChar1;
· 6、讀寫特徵值函式(2個回撥函式
· 這個兩個是註冊到GATT層的回撥函式, 在GATT初始化的時候註冊的. 這部分程式碼封裝在庫裡面.
每當GATT層有資料發過來的時候, 會呼叫simpleProfile_WriteAttrCB,
每當GATT層收到對方讀取資料請求的時候, 會呼叫simpleProfile_ReadAttrCB
這兩個函式包含在gattServiceCBs_t 型別的結構體裡CONST gattServiceCBs_t simpleProfileCBs,
讀simpleProfile_ReadAttrCB
這個設定後就能在lightblue裡讀出值,值為
simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN]={陣列的數值(16進位制顯示)}
寫simpleProfile_WriteAttrCB
讀取被寫進去的值
)
在static uint8 simpleProfile_ReadAttrCB( uint16 connHandle,
gattAttribute_t *pAttr,
uint8 *pValue,
uint8 *pLen,
uint16 offset,
uint8 maxLen )中:
新增 case SIMPLEPROFILE_CHAR6_UUID:
*pLen = SIMPLEPROFILE_CHAR6_LEN;
VOID osal_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR6_LEN );
break; //讀:pAttr->pValue的內容複製到pValue
新增單位元組char7要在接char1或3後面,不能加break
在simpleProfile_WriteAttrCB()中新增(新增後傳送過去就不會提示出錯了)
case SIMPLEPROFILE_CHAR6_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;//不是第一位元組
}
//Write the value 一開始定義了status == SUCCESS,若上述條件不符,不會執行到這裡。osal_memcpy(目的A,源地址B,長度)複製B內容到A
if ( status == SUCCESS )
{
VOID osal_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
notifyApp = SIMPLEPROFILE_CHAR6;
} //寫:pValue的內容複製到pAttr->pValue(別弄反了)
break;
(下面沒用到)osal_memset為字串集體賦同一數值 return目的儲存區地址
void *osal_memset(void *dest, uint8 value , intlen)
{
Return memset(dest,value,len);
}
if ( status == SUCCESS )
{
uint8 *pCurValue = (uint8 *)pAttr->pValue;
osal_memset(pCurValue, 0, SIMPLEPROFILE_CHAR6_LEN );
//為新陣列pCurValue賦值N個0
VOID osal_memcpy(pCurValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
//複製 pValue內容到新陣列pCurValue notifyApp = SIMPLEPROFILE_CHAR6;
}
break;
7 .在simpleBLEperipheral.c新增初始化值
在 void SimpleBLEPeripheral_Init( uint8 task_id )函式中初始化引數
現在可以在手機裝置中讀取CHAR6的值為0x0102030405;
向char6寫進0x3344556677 再讀取值已經改寫為0x3344556677