在Swift上从kCBAdvDataManufacturerData提取数据 [英] Extract data from kCBAdvDataManufacturerData on Swift

查看:64
本文介绍了在Swift上从kCBAdvDataManufacturerData提取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个TI传感器标签作为外围设备,它以kCBAdvDataManufacturerData的形式广播BLE数据.我想从iOS中的这些数据中提取不同的值.

I have a TI sensor Tag as a peripheral that broadcasts BLE data in the form of kCBAdvDataManufacturerData. I would like to extract different values from this data in iOS.

我正在Swift中执行以下操作:

I am executing the following in Swift:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){     
     for (index, foundPeripheral) in peripherals.enumerated(){
         if foundPeripheral.peripheral?.identifier == peripheral.identifier{
             peripherals[index].lastRSSI = RSSI
             print("AdvertisementData:\(advertisementData)")
             return

         }
     }  

     let isConnectable = advertisementData["kCBAdvDataIsConnectable"] as! Bool
     let displayPeripheral = DisplayPeripheral(peripheral: peripheral, lastRSSI: RSSI, isConnectable: isConnectable)
     peripherals.append(displayPeripheral)
     tableView.reloadData()
    }
}

这就是我在控制台中看到的:

And this is what I see in the console:

AdvertisementData:["kCBAdvDataIsConnectable":0,"kCBAdvDataManufacturerData":< 0d00fe05 0c6f32>,"kCBAdvDataLocalName":CLIMBC]

AdvertisementData:["kCBAdvDataIsConnectable": 0, "kCBAdvDataManufacturerData": <0d00fe05 0c6f32>, "kCBAdvDataLocalName": CLIMBC]

我要解码的数据是kCBAdvDataManufacturerData:< 0d00fe05 0c6f32>,并在屏幕上显示每个字段.具体来说,这就是我所代表的数字:

The data that I am interested in decoding is kCBAdvDataManufacturerData : <0d00fe05 0c6f32> and displaying each field on the screen. Specifically, this is what the numbers represent in my case:

  1. 0d00-TI制造商ID
  2. fe-我提供的节点ID
  3. 05-节点的状态(保持不变的状态
  4. c6f-是传感器标签电池的电压
  5. 32-是BLE数据包计数器.

在Android中,我可以进行以下解码:

In Android I am able to decode as following:

private static String getNodeIdFromRawPacket(byte[] manufSpecField) {
    if(manufSpecField != null && manufSpecField.length > 1) {
        return String.format("%02X", manufSpecField[0]);
    }else{
        return null;
    }
}
private static int getNodeBatteryVoltageFromRawPacket(byte[] manufSpecField){
    if(manufSpecField != null && manufSpecField.length > 4) {
        return (((((int) manufSpecField[manufSpecField.length - 3]) << 24) >>> 24) << 8) + ((((int) manufSpecField[manufSpecField.length - 2]) << 24) >>> 24);
    }else{
        return 0;
    }
}

private byte[] extractManufacturerSpecificData(byte[] scanRecord, int manufacturer_id){

     if(scanRecord != null) {
         int ptr = 0;
         while (ptr < scanRecord.length && scanRecord[ptr] != 0) {
             int field_length = scanRecord[ptr];
             if (scanRecord[ptr + 1] == (byte) (0xFF)) { //this is true when the manufacturer specific data field has been found
                 if (((scanRecord[ptr + 3] << 8) + scanRecord[ptr + 2]) == manufacturer_id) {
                    byte[] manufacturerSpecificData = new byte[field_length - 3];
                     System.arraycopy(scanRecord, ptr + 4, manufacturerSpecificData, 0, field_length - 3);
                     return manufacturerSpecificData;
                 }
             }
             ptr += (field_length + 1);
         }
         return null;
     }else{
        return null;
     }
  }
};

我到底该如何实现?我是Swift的新手,这就是为什么我遇到一些困难.任何代码段都将受到欢迎.

How exactly can I achieve this? I am new to Swift that is why I am finding some difficulties. Any code snippet will be most welcome.

推荐答案

看到控制台的输出, advertisementData ["kCBAdvDataManufacturerData"] 似乎是包含以下内容的 NSData 7个字节.您可以轻松地将其作为Swift Data 进行访问,并且 Data 中的每个字节都可以使用下标进行访问:

Seeing the output of your console, advertisementData["kCBAdvDataManufacturerData"] seems to be an NSData containing 7 bytes. You can easily access it as a Swift Data, and each byte in a Data can be accessed with subscript:

if let manufacturerData = advertisementData["kCBAdvDataManufacturerData"] as? Data {
    assert(manufacturerData.count >= 7)
    //0d00 - TI manufacturer ID
    //Constructing 2-byte data as little endian (as TI's manufacturer ID is 000D)
    let manufactureID = UInt16(manufacturerData[0]) + UInt16(manufacturerData[1]) << 8
    print(String(format: "%04X", manufactureID)) //->000D
    //fe - the node ID that I have given
    let nodeID = manufacturerData[2]
    print(String(format: "%02X", nodeID)) //->FE
    //05 - state of the node (something that remains constant
    let state = manufacturerData[3]
    print(String(format: "%02X", state)) //->05
    //c6f - is the sensor tag battery voltage
    //Constructing 2-byte data as big endian (as shown in the Java code)
    let batteryVoltage = UInt16(manufacturerData[4]) << 8 + UInt16(manufacturerData[5])
    print(String(format: "%04X", batteryVoltage)) //->0C6F
    //32- is the BLE packet counter.
    let packetCounter = manufacturerData[6]
    print(String(format: "%02X", packetCounter)) //->32
}

这篇关于在Swift上从kCBAdvDataManufacturerData提取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆