iOS CoreBluetooth打印CBService和CBCharacteristic

10

我正在使用Swift开发iOS应用程序,将蓝牙打印机集成到其中以打印信息。我已经使用了CoreBluetooth框架,但是不知道可以写入哪个服务和特征来进行打印。

//find CBService
func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) {
    //println("CBPeripheralDelegate didDiscoverServices")

    for service in peripheral.services {

        println("Service: Discover service \(service)")
        println("Service: UUID \(service.UUID) ")

        peripheral.discoverCharacteristics(nil, forService: service as! CBService)

    }
}

//find CBCharacteristics
func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) {

    //if service.UUID == CBUUID(string: "18F0"){
        for characteristic in service.characteristics {

            let chara: CBCharacteristic? = characteristic as? CBCharacteristic
            println("Char: service \(service.UUID) Discover char \(chara)")
            println("Char: UUID \(chara!.UUID)")

            peripheral.readValueForCharacteristic(chara)

            /*
            println("0")

            switch chara!.UUID {

            case CBUUID(string: "2AF1"):
                println("1")

                var rawArray:[UInt8] = [0x01];
                let data = NSData(bytes: &rawArray, length: rawArray.count)

                peripheral.writeValue(data, forCharacteristic: chara, type: CBCharacteristicWriteType.WithoutResponse)

            default: println("")
            }
            */
        }
    //}

}

系统显示以下结果:

服务:发现服务 服务:UUID 电池 服务:发现服务 服务:UUID 1803 服务:发现服务 服务:UUID 1802 服务:发现服务 服务:UUID 1811 服务:发现服务 服务:UUID 1804 服务:发现服务 服务:UUID 18F0 服务:发现服务 服务:UUID 设备信息 服务:发现服务 服务:UUID E7810A71-73AE-499D-8C15-FAA9AEF0C3F2

特征:发现特征 特征:UUID 电池电量 特征:发现特征 特征:UUID 2A06 特征:发现特征 特征:UUID 2A06 特征:发现特征 特征:UUID 2A47 特征:发现特征 特征:UUID 2A46 特征:发现特征 特征:UUID 2A48 特征:发现特征 特征:UUID 2A45 特征:发现特征 特征:UUID 2A44 特征:发现特征 特征:UUID 2A07 特征:发现特征 特征:UUID 2AF1 特征:发现特征 特征:UUID 2AF0 特征:发现特征 特征:UUID 系统ID 特征:发现特征 特征:UUID 制造商名称字符串 特征:发现特征 特征:UUID BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F

有没有蓝牙专家可以指导我,谢谢。


1
你需要从打印机供应商那里获取有关如何与他们的产品进行接口的信息。我猜你需要写入特征BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F,因为这是唯一的非标准特征。 - Paulw11
像Paulw11一样,还要查看您的CBCharacteristicproperties,以确定您是否只能读取它们,还是可以写入、通知等。 - Larme
@Paulw11 我尝试修改使用“BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F”,以及变量rawArray:[UInt8] = [0x01]; let data = NSData(bytes:&rawArray,length:rawArray.count) peripheral.writeValue(data,forCharacteristic:chara,type:CBCharacteristicWriteType.WithoutResponse) - Kevin Chang
@Paulw11 但是,不起作用,有没有可能是我的writeValue使用错误或需要修改任何代码? - Kevin Chang
@KevinChang 你试过Lite Blue应用程序吗?它会引导你了解特性,并向你显示可编写的内容。 - Max Kraev
3个回答

4

简短版 只需向具有属性为WriteWriteWithoutResponse的任何非标准服务编写即可。请确保第一次写入少于20个字节,以避免超过缓冲区限制。

详细版: 我遇到了与蓝牙热敏打印机(QSPrinter 5801 Bluetooth LE)完全相同的服务和特征的设备的问题。 我发现:

服务18F0 的特征2AF1 具有属性WriteWithoutResponse

服务E7810A71-73AE-499D-8C15-FAA9AEF0C3F2 的特征BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F 具有属性Read+Write+Notify+Indicate

(其中Write表示带响应写入)。

这是特征的官方属性列表:

Broadcast = 0x01,
Read = 0x02,
WriteWithoutResponse = 0x04,
Write = 0x08,
Notify = 0x10,
Indicate = 0x20,
AuthenticatedSignedWrites = 0x40,
ExtendedProperties = 0x80

通过使用位字段乘法,属性可以具有多个值。例如,属性0x30在二进制中为00110000,表示Notify+Indicate。您需要获取二进制数(8位),并将二进制位从右到左放置在值列表上,从上到下:


0 Broadcast
0 Read
0 WriteWithoutResponse
0 Write
1 Notify
1 Indicate
0 AuthenticatedSignedWrites
0 ExtendedProperties

最终我发现,我可以使用以下方法成功地写入任意特征值:


let bytesToPrint: [UInt8] = [27, 64, 10, 10, 10, 99, 105, 97, 111, 10, 10, 10]
let data = Data(bytes: bytesToPrint)

//使用特征2AF1并设置为WriteWithoutResponse属性 peripheral.writeValue(data, for: characteristic, type: CBCharacteristicWriteType.withoutResponse)

//使用特征BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F并设置为Write属性 peripheral.writeValue(data, for: characteristic, type: CBCharacteristicWriteType.withResponse)

问题出在我一次性发送了过多的字节数据。每个蓝牙低功耗设备都有不同的缓冲区大小。有人曾经发现某个设备的缓冲区限制是20、40、100或400字节。 在我的情况下,限制是100,所以只要我开始发送小于100字节的数据,蓝牙设备就会正确地响应。 我的建议是尝试先发送少于20字节的数据,一旦它可以正常工作,您可以逐渐增加发送的字节数,直到它不能正常工作,那么您就知道已经达到了缓冲区限制。


0

我在处理蓝牙打印机时,在Github上找到了一个工作正常的项目(BLEDemo),建议你也试一下。

let BLEService = "DFB0"
let BLECharacteristic = "DFB1"

// 标记:CBPeripheralDelegate 方法

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    
    for service in peripheral.services! {
        
        print("Service found with UUID: " + service.uuid.uuidString)
        
        //device information service
        if (service.uuid.uuidString == "180A") {
            peripheral.discoverCharacteristics(nil, for: service)
        }
        
        //GAP (Generic Access Profile) for Device Name
        // This replaces the deprecated CBUUIDGenericAccessProfileString
        if (service.uuid.uuidString == "1800") {
            peripheral.discoverCharacteristics(nil, for: service)
        }
        
        //Bluno Service
        if (service.uuid.uuidString == BLEService) {
            peripheral.discoverCharacteristics(nil, for: service)
        }
        
    }
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

    //get device name
    if (service.uuid.uuidString == "1800") {
        
        for characteristic in service.characteristics! {
            
            if (characteristic.uuid.uuidString == "2A00") {
                peripheral.readValue(for: characteristic)
                print("Found Device Name Characteristic")
            }
            
        }
        
    }
    
    if (service.uuid.uuidString == "180A") {
        
        for characteristic in service.characteristics! {
            
            if (characteristic.uuid.uuidString == "2A29") {
                peripheral.readValue(for: characteristic)
                print("Found a Device Manufacturer Name Characteristic")
            } else if (characteristic.uuid.uuidString == "2A23") {
                peripheral.readValue(for: characteristic)
                print("Found System ID")
            }
            
        }
        
    }
    
    if (service.uuid.uuidString == BLEService) {
        
        for characteristic in service.characteristics! {
            
            if (characteristic.uuid.uuidString == BLECharacteristic) {
                //we'll save the reference, we need it to write data
                mainCharacteristic = characteristic
                
                //Set Notify is useful to read incoming data async
                peripheral.setNotifyValue(true, for: characteristic)
                print("Found Bluno Data Characteristic")
            }
            
        }
        
    }
    
}

0

尝试使用浅蓝色的应用程序(iOS),您将逐个找到正确的特征进行编写。它具有从应用程序编写值的选项。

Light Blue


从问题中可以看出,特征已经通过编程方式找到了。正如我在答案中解释的那样,问题实际上是写入了过多的字节并超出了缓冲区限制。 - Giorgio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接