藍(lán)牙廣播數(shù)據(jù)解析
從上一篇我們提到的那樣我們從系統(tǒng)的接收到了 關(guān)于藍(lán)牙數(shù)據(jù)的相關(guān)信息搏明,藍(lán)牙的設(shè)備對象、藍(lán)牙信號、標(biāo)準(zhǔn)藍(lán)牙廣播數(shù)據(jù)包等數(shù)據(jù)颁股。
==================================================================================================================
作為我們開發(fā)的場景來說,我們需要對我們的設(shè)備進(jìn)行必要的過濾傻丝,但是這個(gè)過濾的數(shù)據(jù)來源除了廣播數(shù)據(jù)包甘有,好像是沒有其他辦法的。當(dāng)然名字也還是那么靠譜的葡缰,會有系統(tǒng)的緩存的亏掀。
所以我們需要做一些藍(lán)牙廣播的數(shù)據(jù)的解析忱反。說到藍(lán)牙的數(shù)據(jù)的數(shù)據(jù)解析的問題,就不得不提關(guān)于藍(lán)牙的數(shù)據(jù)結(jié)構(gòu)滤愕,不過這個(gè)網(wǎng)上有很多温算,百度一下,出來的結(jié)果能嚇?biāo)滥慵溆埃渍摺.吘苟饶锸菂柡Φ摹?------言歸正傳:
藍(lán)牙的數(shù)據(jù)結(jié)構(gòu)采用的方式。這有一篇文章還不錯(cuò)的推薦給大家
http://blog.chinaunix.net/uid-28852942-id-5176579.html
其實(shí)在我們android 開發(fā)的數(shù)據(jù)解析中 倒是沒有說的那么復(fù)雜宇智,比方來說蔓搞,
0201060303f1fe03190000020a080aff0000000000000000041509efbbbfe5beaee699ba426561636f6ee6a0bc5a690
上方是一個(gè)藍(lán)牙數(shù)據(jù)(這個(gè)數(shù)據(jù)是我隨便弄得只是做為示范)
對于我們開發(fā)來說
我們知道這樣的數(shù)據(jù)構(gòu)成就OK了
- 020106
- 這是一個(gè)完全的“最小單元有意義的藍(lán)牙廣播數(shù)據(jù)”了吧。
- 02表示這個(gè)數(shù)據(jù)的長度,也就是Length.
- 01表示這個(gè)信息的標(biāo)識随橘,也就是Tag.
- 01后面開始就是這個(gè)數(shù)據(jù)含有真正的數(shù)據(jù)喂分,
- 此時(shí)需要注意的是02表示長度是除去自身以外的長度, 如果你要數(shù)字節(jié)個(gè)數(shù)的話 你需要加1
0303f1fe
03190000
020a08
0a ff 00 00 00 00 00 00 00 00 04
15 09 efbbbfe5beaee699ba426561636
其他的都是一樣的 我就不做一一解析了机蔗。
所以我們解析這個(gè)數(shù)據(jù)的時(shí)候都是解析相關(guān)的TAG蒲祈,然后可以拿到我們需要的數(shù)據(jù),我記得剛剛開始的時(shí)候萝嘁,我是拿著這個(gè)數(shù)據(jù)直姐用索引取值梆掸,結(jié)果我們的固件版本一升級,索引值變了牙言。我那個(gè)寫死的數(shù)據(jù)就完蛋了酸钦。結(jié)果當(dāng)然是教育了啦。
提一些的是關(guān)于常見的Tag,01一般表示是否可連接的狀態(tài)咱枉。08卑硫、09一般都是可以表示設(shè)備的名稱。但是也有很多是不廣播名稱的蚕断。
好吧BB那么多貼上源碼才是關(guān)鍵以下是源碼:
public static class BTScanInfo {
//數(shù)據(jù)庫
public BleDevice dev;
public byte[] advt;
public double rssi = -10000.0;
public static final int
BT_ADVT_FIELD_SHORT_SVC_UUID_MORE = 0x02,
BT_ADVT_FIELD_SHORT_SVC_UUID_COMP = 0x03,
BT_ADVT_FIELD_MANU_INFO = 0xFF,
BT_ADVT_FIEFD_NAME_INFO = 0x09,
BT_ADVT_FIEFD_SUPPROTS_INFO = 0xFF;
public int svcMoreOffset = -1, svcMoreLen = -1,
svcOffset = -1, svcLen = -1, isSupprots = 14,
manuOffset = -1, manuLen = -1,
nameOffset = -1, nameLen = -1,
lightOffset = -1, lightLen = -1;
public BTScanInfo(BleDevice dev_, byte[] advt_, double rssi_) {
Log.i(dev_.getAddress(), "BtScanInfo==" + dev_.getAddress());
dev = dev_;
advt = advt_;
rssi = rssi_;
ParseAdvt();
}
public void ParseAdvt() {
if (advt == null)
return;
for (int offset = 0 ; offset < advt.length ; ) {
int fieldLen = (advt[ offset ] & 0xFF);
if (fieldLen < 1) {
offset += fieldLen + 1;
// Log.v(TAG, "Find a invalid scan advert field length: " + fieldLen );
continue;
}
// a valid field.
if (offset + fieldLen <= advt.length) {
int fieldType = advt[ offset + 1 ] & 0xFF;
if (fieldType == BT_ADVT_FIELD_SHORT_SVC_UUID_MORE) {
svcMoreOffset = offset;
svcMoreLen = fieldLen;
} else if (fieldType == BT_ADVT_FIELD_SHORT_SVC_UUID_COMP) {
svcOffset = offset;
svcLen = fieldLen;
} else if (fieldType == BT_ADVT_FIELD_MANU_INFO & fieldLen == BT_ADVT_FIEFD_NAME_INFO) {
manuOffset = offset;
manuLen = fieldLen;
} else if (fieldType == BT_ADVT_FIEFD_NAME_INFO) {
//獲取到名字信息
nameOffset = offset;
nameLen = fieldLen;
}
}
offset += fieldLen + 1;
}
}