我正在尝试通过 BLE 连接接收指示,但我无法接收任何数据

I'm trying to receive indicate via BLE connection, but I can't receive any data

我正在为 iOS 创建一个 BLE 连接应用程序。 我可以从中央连接到外围设备(iPhone6:iOS12.9)并发送命令 我可以发送带有 writevalue 的命令。

https://developer.apple.com/documentation/corebluetooth/cbperipheral/1518949-setnotifyvalue

在上面的setNotifyValue中,有一个描述似乎被indicate接受了。 didUpdateValueFor 的以下方法不 return.

    /// When changing the characteristic
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

https://developer.apple.com/documentation/corebluetooth/cbperipheraldelegate/1518708-peripheral

如果你知道如何在indicate中实现接收数据,请告诉我。

示例代码如下所示。 我还在努力,所以可能会有一些垃圾代码,抱歉。

//  ViewController.swift

import UIKit
import CoreBluetooth
import os

class ViewController: UIViewController {

    /// https://qiita.com/eKushida/items/def628e0eff6c106d467

    var serviceUUID : CBUUID!
    var characteristicUUID : CBUUID!
    var responseCharacteristicUUID : CBUUID!

    var centralManager: CBCentralManager!
    var peripheral: CBPeripheral!
    
    var writeCharacteristic: CBCharacteristic!
    var responsCharacteristic: CBCharacteristic!

    var data = Data()
        
    @IBOutlet weak var dispLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
        dispLabel.text = "Startup"
    }
    /// Initialize the central manager and UUID
    private func setup() {
        // Create an object representing the UUID.
        self.serviceUUID = CBUUID(string: "XXXXX0000-XXXX-XXXX-XXXX-XXXXXXXXXX")
        self.characteristicUUID = CBUUID(string: "XXXX2001-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
        self.responseCharacteristicUUID = CBUUID(string: "XXXX2000-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
     }

    /// Pairing process
    @IBAction func scan(_ sender: UIButton) {
        print("Pairing process")
        dispLabel.text = "Pairing process pressed"
        
        self.centralManager = CBCentralManager(delegate: self, queue: nil)
    }
    
    /// Communication connection
    @IBAction func connect(_ sender: UIButton) {
        print("Communication connection")
        
        /// https://qiita.com/MashMorgan/items/32500f158cb08d565786
        /// https://knkomko.hatenablog.com/entry/2019/07/16/013443
        let message = "**COMMAND**"
        let command = message + "\r"
        let writeData = Data(command.utf8)
        print("writeData:" + String(data: writeData, encoding: .utf8)!)
        
        peripheral.writeValue(writeData, for: writeCharacteristic, type: CBCharacteristicWriteType.withResponse)
    }
    

}

//MARK : - CBCentralManagerDelegate
extension ViewController: CBCentralManagerDelegate {
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {

        switch central.state {

        //wait for power on and scan
        case CBManagerState.poweredOn:
            let services: [CBUUID] = [serviceUUID] ///serviceUUID
            centralManager.scanForPeripherals(withServices: nil, options: nil)
            // centralManager.scanForPeripherals(withServices: services, options: nil)
            print("isScanning:" + String(centralManager.isScanning))
        default:
            break
        }
    }
    
    /// Called when a peripheral is discovered
    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any],
                        rssi RSSI: NSNumber) {

        self.peripheral = peripheral
        
        print("peripheral.name:" + String(peripheral.name ? "") + " peripheral.id:" + peripheral.identifier.uuidString)
        
        if "XXXXXXX" == peripheral.name {
            //start connection
            self.centralManager.connect(self.peripheral, options: nil)
            //peripheral is found, stop scanning
            centralManager.stopScan()
        }
    }
    
    /// called when connected
    func centralManager(_ central: CBCentralManager,
                        didConnect peripheral: CBPeripheral) {
        print("Connection successful serviceUUID:" + serviceUUID.uuidString)
        peripheral.delegate = self
        peripheral.discoverServices([serviceUUID])
        dispLabel.text = "Peripheral connection successful"
    }
    
    /// Called when the connection fails
    func centralManager(_ central: CBCentralManager,
                        didFailToConnect peripheral: CBPeripheral,
                        error: Error?) {
        print("Connection failed")
    }
    
    /// When disconnected
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("Disconnection: \(String(describing: error))")
    }
}

//MARK : - CBPeripheralDelegate
extension ViewController: CBPeripheralDelegate {

    /// Called when the characteristic is found
    func peripheral(_ peripheral: CBPeripheral,
                    DidDiscoverCharacteristicsFor service: CBService,
                    error: Error?) {

        if error ! = nil {
            print(error.debugDescription)
            return
        }
        
        guard let serviceCharacteristics = service.characteristics else {
           // error handling
           return
       }
        // Processing by characteristic
        for characreristic in serviceCharacteristics {
            if characreristic.uuid == characteristicUUID
            {
            // keep the characteristic for writing data
                self.writeCharacteristic = characreristic
                print("Write characreristic / UUID:" + characreristic.uuid.uuidString)
                print("Write characreristic / properties: \(self.writeCharacteristic.properties)")
                continue
            }
            if characreristic.uuid == responseCharacteristicUUID {
                peripheral.setNotifyValue(true, for: characreristic)
                self.responsesCharacteristic = characreristic
                print("Responses characreristic / UUID:" + characreristic.uuid.uuidString)
                print("Responses characreristic / properties: \(self.responsesCharacteristic.properties)")
                continue
            }
            print("Other characreristic / UUID:" + characreristic.uuid.uuidString)
        }
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverIncludedServicesFor: CBService, error: Error?){
        print("peripheral didDiscoverIncludedServicesFor")
    }

    /// When writing data to the characteristic (called when sending a command)
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        print("peripheral didWriteValueFor")
        guard error == nil else {
            print("Error when writing characteristic data: \(String(describing: error))")
            // failure handling
            return
        }
        print(characteristic.value)
        
    }
    
    func peripheral(peripheral: CBPeripheral,
        didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic,
        error: NSError?)
    {
        print("peripheral didUpdateNotificationStateForCharacteristic")
        if let error = error {
            print("Notify state update failed.... .error: \(error)")
        } else {
            print("Notify state update succeeded! isNotifying: \(characteristic.isNotifying)")
        }
    }
    
    func peripheral(peripheral: CBPeripheral,
        didUpdateValueForCharacteristic characteristic: CBCharacteristic,
        error: NSError?)
    {
        print("peripheral didUpdateValueForCharacteristic")
        if let error = error {
            print("Data update notification error: \(error)")
            return
        }
        print("Data update! value: \(characteristic.value)")
    }
    
    /// When changing the characteristic
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        print("peripheral didUpdateValueFor")
        guard error == nil else {
            print("Error getting/changing characteristic value: \(String(describing: error))")
            // failure handling
            return
        }
        guard let data = characteristic.value else {
            print("characteristic.value")
            // failure process
            return
        }
        // data will be passed to us
        print(data)
    }
}

我有 示例 iOS 项目(中央和外围)send/receive 适应症:https://github.com/alexanderlavrushko/BLEProof-collection

setNotifyValue here 跟你叫法差不多,应该没问题。

我建议检查在外设端如何创建和更新特征的方式,iOS example link

还有一个很棒的 iOS 应用程序 LightBlue,它可以模拟 BLE 设备,参见 this guide:

  • 中央 - “订阅特征”主题可能有用
  • 外设 - “添加新的虚拟外设”,但使用空白设备并配置 services/characteristics 您需要