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

问题描述

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

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

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

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

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

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

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

//  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,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 项目(中央和外设)发送/接收指示:https://github.com/alexanderlavrushko/BLEProof-collection

setNotifyValue here 的调用方式与您类似,应该没问题。

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...