[英]Read advertisement packet in Android
我正在研究一個 BLE 傳感器,它是廣告制造商特定的數據。 是否有任何示例代碼演示如何在 Android 中接收廣告數據包並解析其有效負載?
這就是我要找的:
BLE 掃描 API BluetoothAdapter.startLeScan(ScanCallback) 需要掃描結果的回調函數。 該方法需要如下所示:
private BluetoothAdapter.LeScanCallback ScanCallback =
new BluetoothAdapter.LeScanCallback()onLeScan(final BluetoothDevice device,
int rssi,
final byte[] scanRecord)
{...}
scanRecord 變量是一個字節數組,其中包含廣告數據包負載。
根據 BLE 規范,有效載荷的結構非常簡單,如下所示:
數據包最長可達 47 個字節,包括:
對於廣告通信通道,訪問地址始終為 0x8E89BED6。
PDU 又具有自己的標頭(2 個字節:有效載荷的大小及其類型——設備是否支持連接等)和實際有效載荷(最多 37 個字節)。
最后,payload的前6個字節是設備的MAC地址,實際信息最多可以有31個字節。
實際信息的格式如下:
第一個字節是數據的長度,第二個字節是后跟數據的類型。
這是允許任何應用程序在不關心內容的情況下跳過整個數據記錄的巧妙方法。
以下是確定廣告數據包內容的示例代碼:
parseAdvertisementPacket(final byte[] scanRecord) {
byte[] advertisedData = Arrays.copyOf(scanRecord, scanRecord.length);
int offset = 0;
while (offset < (advertisedData.length - 2)) {
int len = advertisedData[offset++];
if (len == 0)
break;
int type = advertisedData[offset++];
switch (type) {
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
while (len > 1) {
int uuid16 = advertisedData[offset++] & 0xFF;
uuid16 |= (advertisedData[offset++] << 8);
len -= 2;
uuids.add(UUID.fromString(String.format(
"%08x-0000-1000-8000-00805f9b34fb", uuid16)));
}
break;
case 0x06:// Partial list of 128-bit UUIDs
case 0x07:// Complete list of 128-bit UUIDs
// Loop through the advertised 128-bit UUID's.
while (len >= 16) {
try {
// Wrap the advertised bits and order them.
ByteBuffer buffer = ByteBuffer.wrap(advertisedData,
offset++, 16).order(ByteOrder.LITTLE_ENDIAN);
long mostSignificantBit = buffer.getLong();
long leastSignificantBit = buffer.getLong();
uuids.add(new UUID(leastSignificantBit,
mostSignificantBit));
} catch (IndexOutOfBoundsException e) {
// Defensive programming.
Log.e("BlueToothDeviceFilter.parseUUID", e.toString());
continue;
} finally {
// Move the offset to read the next uuid.
offset += 15;
len -= 16;
}
}
break;
case 0xFF: // Manufacturer Specific Data
Log.d(TAG, "Manufacturer Specific Data size:" + len +" bytes" );
while (len > 1) {
if(i < 32) {
MfgData[i++] = advertisedData[offset++];
}
len -= 1;
}
Log.d(TAG, "Manufacturer Specific Data saved." + MfgData.toString());
break;
default:
offset += (len - 1);
break;
}
}
謝謝
質量讓我朝着正確的方向前進!
nv-bluetooth 中的ADPayloadParser解析廣告數據包的負載並返回 AD 結構列表。 AD結構格式在“Bluetooth Core Specification 4.2”的“11 ADVERTISING AND SCAN RESPONSE DATA FORMAT”中有描述。
以下代碼片段是onLeScan方法的實現示例。
public void onLeScan(
BluetoothDevice device, int rssi, byte[] scanRecord)
{
// Parse the payload of the advertising packet.
List<ADStructure> structures =
ADPayloadParser.getInstance().parse(scanRecord);
// For each AD structure contained in the advertising packet.
for (ADStructure structure : structures)
{
if (structure instanceof IBeacon)
{
// iBeacon packet was found.
handleIBeacon((IBeacon)structure);
}
......
}
}
您可以為您的制造商特定格式注冊您自己的解析器到 ADPayloadParser。 有關詳細信息,請參閱以下鏈接。
博客: http : //darutk-oboegaki.blogspot.jp/2015/03/ibeacon-as-kind-of-ad-structures.html
GitHub: https://github.com/TakahikoKawasaki/nv-bluetooth
JavaDoc: http : //takahikokawasaki.github.io/nv-bluetooth/
Maven: http : //search.maven.org/#search| ga|1|a%3A%22nv- bluetooth%22
編輯 21.02.2016
我在下面鏈接的圖書館似乎已被移動; 見https://github.com/AltBeacon/android-beacon-library
您可以先使用 Android iBeacon 庫。
有一個參考應用程序,您可以將其用於基礎知識和模擬數據。 ~ https://github.com/RadiusNetworks/ibeacon-reference-android~
啟動並運行后,您可能希望導入庫並將其用於您的真實設備,站點上還有一些示例代碼: http : //developer.radiusnetworks.com/ibeacon/android/samples.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.