Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS CoreBluetooth print CBService and CBCharacteristic

I am using Swift to develop a iOS application to integrate bluetooth printer to print out information. I have used CoreBluetooth framework but can't know which service, characteristic I can writevalue to print out

//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("")
            }
            */
        }
    //}

}

and the system display result like below:

Service: Discover service Service: UUID Battery Service: Discover service Service: UUID 1803 Service: Discover service Service: UUID 1802 Service: Discover service Service: UUID 1811 Service: Discover service Service: UUID 1804 Service: Discover service Service: UUID 18F0 Service: Discover service Service: UUID Device Information Service: Discover service Service: UUID E7810A71-73AE-499D-8C15-FAA9AEF0C3F2

Char: Discover char Char: UUID Battery Level Char: Discover char Char: UUID 2A06 Char: Discover char Char: UUID 2A06 Char: Discover char Char: UUID 2A47 Char: Discover char Char: UUID 2A46 Char: Discover char Char: UUID 2A48 Char: Discover char Char: UUID 2A45 Char: Discover char Char: UUID 2A44 Char: Discover char Char: UUID 2A07 Char: Discover char Char: UUID 2AF1 Char: Discover char Char: UUID 2AF0 Char: Discover char Char: UUID System ID Char: Discover char Char: UUID Manufacturer Name String Char: Discover char Char: UUID BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F

can any bluetooth expert can guide me, thanks

like image 496
Kevin Chang Avatar asked Jul 11 '15 03:07

Kevin Chang


1 Answers

Short version Just write to any non-standard Service with a Characteristic with Properties Write or WriteWithoutResponse. Be sure to write less than 20 bytes the first time to avoid passing the buffer limit.

Long version: I had the same problem with a bluetooth thermal printer (QSPrinter 5801 Bluetooth LE) that had exactly the same services and characteristics of the device from this question. I found out that the:

Service 18F0 with characteristic 2AF1 had property WriteWithoutResponse

Service E7810A71-73AE-499D-8C15-FAA9AEF0C3F2 with characteristic BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F had properties Read+Write+Notify+Indicate

(where Write means Write with response).

This is the official list of properties of a Characteristic:

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

A property can have multiple values by using bit field multiplication. For example properties 0x30 is 00110000 in binary which means Notify+Indicate. You need to get the binary number (8 bits) and place the binary bits from right to left on the values list from top to bottom:


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

In the end I discovered I could write to either of characteristic successfully by using:


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

//Using Characteristic 2AF1 with Properties WriteWithoutResponse peripheral.writeValue(data, for: characteristic, type: CBCharacteristicWriteType.withoutResponse)

//Using Characteristic BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F with Properties Write peripheral.writeValue(data, for: characteristic, type: CBCharacteristicWriteType.withResponse)

The problem was that I was sending too many bytes of data at the same time. Each bluetooth low energy device has a different buffer size. I heard of people finding the buffer limit of a device to be 20, 40, 100, 400 bytes. In my case the limit was 100 so as soon as I started to send less than 100 bytes the bluetooth device reacted correctly. My advice is to try to send less than 20 bytes to start with and once it works you can increment the bytes sent until it stops working and you'll know you've reached the buffer limit.

like image 107
Giorgio Avatar answered Oct 24 '22 00:10

Giorgio