2017-02-09 50 views
0

私は、kCBAdvDataManufacturerDataの形式でBLEデータをブロードキャストする周辺機器としてTIセンサータグを持っています。私はiOSでこのデータから異なる値を抽出したいと思います。SwiftのkCBAdvDataManufacturerDataからのデータの抽出

私はスウィフトで次のコマンドを実行しています:

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() 
    } 
} 

そして、これは私がコンソールに表示するものである。

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

デコードに興味があるデータは、kCBAdvDataManufacturerData:< 0d00fe05 0c6f32>で、各フィールドは画面に表示されます。 具体的には、この数字は、私の場合には何を表しているかである:

  1. 0d00 - TIメーカーのID
  2. FE - 私は
  3. 05を与えているノードID - ノードの状態(一定のまま何か
  4. c6f - 。
  5. 32は、BLEパケットカウンタであるセンサータグのバッテリ電圧であるアンドロイドで

私がすることができますよ次のようにデコードしてください:

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; 
    } 
    } 
}; 

どのようにこれを達成できますか?私はスウィフトには新しいので、私はいくつかの困難を見つけるのです。すべてのコードスニペットが大歓迎です。ここで

+1

擬似コード 'VAR manData = AdvertisementData [「kCBAdvDataManufacturerData」]でData'としてその後、あなたは'サブデータを呼び出すことができます(範囲:NSRange) 'を使って' manData'をあなたが望む各部分に分割し、それらを読むことができます。 – Larme

答えて

1

は、あなたが戻って文字列に変換することができますバイトに出て分割し、データに変換した文字列の例で3迅速なデータ方法subdataの実装であり、:

コンソールの出力を見て
let input = "505450578" 
let data = input.data(using: .utf8) 

let manufacturerId:Range<Int> = 0..<2 
let nodeId:Range<Int> = 2..<4 
let nodeState:Range<Int> = 4..<5 
let voltage:Range<Int> = 5..<6 
let packetCounter:Range<Int> = 6..<9 

let subdata1 = data?.subdata(in: manufacturerId) 
let subdata2 = data?.subdata(in: nodeId) 
let subdata3 = data?.subdata(in: nodeState) 
let subdata4 = data?.subdata(in: voltage) 
let subdata5 = data?.subdata(in: packetCounter) 

//Results from original given string 
let str1 = String(data: subdata1!, encoding:.utf8) //50 
let str2 = String(data: subdata2!, encoding:.utf8) //54 
let str3 = String(data: subdata3!, encoding:.utf8) //5 
let str4 = String(data: subdata4!, encoding:.utf8) //0 
let str5 = String(data: subdata5!, encoding:.utf8) //578 
+0

@ Prientus。これは非常に役に立ちました。乾杯。 – user3315702

2

advertisementData["kCBAdvDataManufacturerData"]は、7バイトを含むNSDataと思われます。あなたは簡単にスウィフトDataとしてそれにアクセスすることができ、かつDataの各バイトは、添字でアクセスすることができます。

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 
} 
+0

コード化され、すでにテスト済みです。できます。すばらしいです :) – user3315702

関連する問題