對於研發和測試BLE來說,經常看到同名的設備,是極為不方便的,一大堆設備同時上電會讓同事不知道哪一個設備才是自己真正想操作的目標。再說一下小米手環,家中有三支小米手環,打開設備搜索全是“MI”,都不知道連接哪一個,所以在開始使用的時候才要求用戶去敲手環幾下,當然這個體驗也還算不錯。但不管怎樣,作為開發者,面對Office里一大堆的BLE設備,能夠方便區分還是不錯的。因此萌生讓設備名稱包含一個唯一的標識——MAC地址。比如筆者的電腦上顯示這么多HXX,在調試時完全不知道該怎么選。
第一步先說如何更改設備名稱
BLE中要更改名稱是極為方便的,只需要更改掃描應答數據和GAP GATT NAME屬性。以TI BLE STACK 1.4.0中的simpleBLEPeripheral工程為例來說,
修改的地方是:
simpleBLEPeripheral.c
static uint8 scanRspData[];
static uint8 advertData[];
第二步再說如何生成一個包含設備MAC地址的名稱
每顆BLE 的芯片都會有一個6字節的MAC地址,讀到它並轉化成ASCII字符,比如0x12 34 56 78 9a bc轉換成“123456789ABC”,如果MAC地址全部寫入設備名稱,則顯得太長,取后2字節地址,即字串“ABCD”即可。將設備名稱的前輟連同地址字串寫入掃描應答數據和GAP GATT NAME屬性,設備運行時,我們再掃描就可以看到它的名稱已經變了。
第三步來說實現
程序可以根據MAC地址生成一個自已唯一的名稱,並在利用初始程序來修改步驟一提到的兩處即可。下文的代碼是生成動態名稱的參考。在simpleBLEPeripheral.c文檔的SimpleBLEPeripheral_Init()函數調用bleTask_BlePara()函數,同時注釋掉該函數中以下調用。
//GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
//GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
// Set the GAP Characteristics
//GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
參考代碼:
/**************************************************************************************************
Filename: simpleBLEOTAPatch.c
Editor: Tome @ Newbit Studio
Revised: $Date: 2015/8/11 11:20:02 +0800 $
Revision: $Revision: 00001 $
Description:
History:
Notes:
**************************************************************************************************/
/**************************************************************************************************
// INCLUDES
**************************************************************************************************/
#include "bcomdef.h"
#include "OSAL.h"
#include "gatt.h"
#include "gatt_profile_uuid.h"
#include "hci.h"
#include "gap.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "peripheral.h"
#include "osal_snv.h"
#include "simpleBLEOTAPatch.h"
/**************************************************************************************************
// TYPEDEF
**************************************************************************************************/
/**************************************************************************************************
// CONSTANTS
**************************************************************************************************/
#define DEVICE_NAME "NB BOOT V3 ----"
#define DEVICE_NAME_WITH_HEADER "xNB BOOT V3 ----*----*----*---"
#define DEVICE_NAME_PLACEHOLDER_IDX 0 //x is placeholder
/**************************************************************************************************
// GLOBAL VARIABLES
**************************************************************************************************/
/**************************************************************************************************
// LOCAL VERIABLE
**************************************************************************************************/
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[31];
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[31];
/**************************************************************************************************
// FUNCTIONS DECLERATION
**************************************************************************************************/
/**************************************************************************************************
// FUNCTIONS
**************************************************************************************************/
/**************************************************************************************************
* @fn BleTask_ScanRspDataInit
*
* @brief
*
* @param uint8 *dat
*
* @return int
**************************************************************************************************/
int BleTask_ScanRspDataInit(uint8 *scanrsp)
{
uint8 dat[5] = {
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
};
int len =
utilSerialization(scanrsp, 0, 5, dat);
dat[0] = GAP_ADTYPE_POWER_LEVEL;
dat[1] = 0;
len = utilSerialization(scanrsp, len, 2, dat);
return len;
}
/**************************************************************************************************
* @fn bleTask_BlePara
*
* @brief
*
* @param void
*
* @return void
**************************************************************************************************/
void bleTask_BlePara(void)
{
int len = 0;
len = BleTask_ScanRspDataInit(scanRspData);
uint8 nvName[20];
uint8 rearNameLen = 4;
uint8 *pName;
if ( SUCCESS == osal_snv_read(NVID_USER_REARNAME, len, nvName) )
{
pName = nvName;
rearNameLen = osal_strlen((char *)nvName);
}
else
{
uint8 mac[6] = {1,2,3,4,5,6};
mac[5]=*(unsigned char *)(0x780E);
mac[4]=*(unsigned char *)(0x780F);
mac[3]=*(unsigned char *)(0x7810);
mac[2]=*(unsigned char *)(0x7811);
mac[1]=*(unsigned char *)(0x7812);
mac[0]=*(unsigned char *)(0x7813);
utilPrintMacAddress(mac, (char*)nvName);
pName = nvName+8;
rearNameLen = 4;
}
uint8 name[] = DEVICE_NAME_WITH_HEADER;
uint8* pFill = utilSearchChar2( name, '-');
uint8* pEnd = osal_memcpy(pFill, pName, rearNameLen);
uint8 length = pEnd-name;
// uint8 length = sizeof(name);
// name[length-5] = macString[8];
// name[length-4] = macString[9];
// name[length-3] = macString[10];
// name[length-2] = macString[11];
name[DEVICE_NAME_PLACEHOLDER_IDX] = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
len = utilSerialization(scanRspData, len, length, name);
// should remove the placeholder! and decrease the length
GGS_SetParameter( GGS_DEVICE_NAME_ATT, length-1, name+1 );
uint8 dat[10];
// advertise data
dat[0] = GAP_ADTYPE_FLAGS;
dat[1] = DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED;
len = utilSerialization(advertData, 0, 2, dat);
dat[0] = GAP_ADTYPE_16BIT_MORE;// some of the UUID's, but not all
dat[1] = LO_UINT16( DEVINFO_SERV_UUID );
dat[2] = HI_UINT16( DEVINFO_SERV_UUID );
dat[3] = LO_UINT16( 0xFEF9 );
dat[4] = HI_UINT16( 0xFEF9 );
len = utilSerialization(advertData, len , 5, dat);
GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
}
/**************************************************************************************************
Copyright 2015 Newbit Studio All rights reserved.
**************************************************************************************************/