Can’t write JSON to peripheral with CoreBluetooth

Published

I have a paired bluetooth peripheral which I have to send some credentials in a JSON like as follows

{"SSID":"WIFI_SSID", "Password": "WIFI_PASSWORD"}

And after the information has been sent the peripheral should connect to the provided WiFi credentials but I’m not completely sure the process is being performed correctly.

As soon the bluetooth peripheral has connected I start the process,

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

    // As soon as the device has connected 
    peripheral.delegate = self
    // Only discover the service I know it's for writing
    peripheral.discoverServices([SERVICE_UUID])
}

The discoverServices will call the peripheral(:didDiscoverServices error)

func peripheral( _ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    for service in peripheral.services! {
        peripheral.discoverCharacteristics(nil, for: service)
    }
}

Calling the following method where I do all the logic

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

    for characteristic in service.characteristics! {
        let characteristic = characteristic as CBCharacteristic

        debugPrint(characteristic.properties)
        // This prints the following properties, reading + writing
        // __C.CBCharacteristicProperties(rawValue: 10)

        if characteristic.uuid.isEqual(RX_UUID) {
            do {
                let msgDictionary = ["SSID": wiFiCredentials.SSID, "Password": wiFiCredentials.Password]
                let jsonData = try JSONSerialization.data(withJSONObject: msgDictionary,options:[])

                peripheral.writeValue(jsonData, for: characteristic, type: CBCharacteristicWriteType.withResponse)

            } catch let error as NSError {
                debugPrint("Error in auth message JSON: (error.description)")
            }
        }
    }
}

Up to this point I think everything it’s correct. After calling writeValue and setting the type to CBCharacteristicWriteType.withResponse I should expect something in the peripheral(:didWriteValueFor characteristic: error) method. What I receive in that method is the next error

Error Domain=CBATTErrorDomain Code=3 "Writing is not permitted." UserInfo={NSLocalizedDescription=Writing is not permitted.}"

What I guess is that when I write the JSON value I shouldn’t use the .withResponse flag and use .withoutResponse. If I do so I get the following log in the console.

[CoreBluetooth] WARNING: Characteristic <CBCharacteristic: 0x28388a040, UUID = 3E9D2532-2F00-11E9-9602-A44CC81C989A, properties = 0xA, value = (null), notifying = NO> does not specify the "Write Without Response" property - ignoring response-less write

Which confirms to me that I have to use the .writeWithResponse.

Is there something I am missing in the process? The JSON has to be sent using GATT and AFAIK this is the correct approach to do it. Are the printed CBCharacteristicProperties correct?

Things I’ve done:

  • The JSON is not the problem. I’ve tried writing a random variable "1".data(using: .ascii) and still receive the same error.

Source: Swift

Published
Categorised as core-bluetooth, swift

Answers

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq