Core-bluetooth peripheral doesn't notify the central when data is updated

2.1k Views Asked by At

I'm trying to send big packets of data via BLE. To do this I've created a characteristic that should notify the central when it's data change. The problem is that apparently the peripheral stacks up the data in the characteristic, but obviously once the characteristic reach 552 bytes it can not stocks more data.

The central only receives 552 bytes and call the function didReceiveRead 3 times (I'm transferring 200 bytes at a time, so 3 times are 600 bytes, but only 552 bytes make it trough (which I think is the limit since iOS 10)). This code also print Unhandled Characteristic UUID: 00000000-0000-0000-0000-000000000000 only one time and manage to setNotifyValue of my characteristic to true. Also didUpdateNotificationStateForis only called one time.

I would like to know why is my characteristic is stacking up the data and does not send it 200 bytes at a time like I would like to.

The code use for the peripheral is: (The function chunk just take data and int of the size of the chunk we want and return the chunk and the data minus the chunk taken)

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
    switch peripheral.state {
    case .unknown:
        print("peripheral.state is .unknown")
    case .resetting:
        print("peripheral.state is .resetting")
    case .unsupported:
        print("peripheral.state is .unsupported")
    case .unauthorized:
        print("peripheral.state is .unauthorized")
    case .poweredOff:
        print("peripheral.state is .poweredOff")
    case .poweredOn:
        print("peripheral.state is .poweredOn")

        let myService = CBMutableService(type: serviceUUID, primary: true)

        let uuid: CBUUID
        uuid = CBUUID(string: "00000000-0000-0000-0000-000000000000")
        let myCharacetristic = CBMutableCharacteristic(type: uuid, properties: [CBCharacteristicProperties.read,CBCharacteristicProperties.notify,CBCharacteristicProperties.write], value: nil, permissions: [CBAttributePermissions.readable, CBAttributePermissions.writeable])
        chara = myCharacetristic
        myService.characteristics = [myCharacetristic]
        print(myService)

        myPeripheral.add(myService)

        let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: [serviceUUID]] as [String : Any]
        myPeripheral.startAdvertising(advertisingData)
        print(advertisingData.description)
    }
}

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
    var max = 0
    if (data.count - 200) > 0{
        max = 200
    }else{
        max =  data.count
    }
    var subdata: Data //subdata is what I want to send
    (subdata, data) = chunck(json: data, max: max)
    print(request.value)
    request.value = subdata
    myPeripheral?.respond(to: request, withResult: CBATTError.success)
}

And for the central the code is:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    guard let characteristics = service.characteristics else { return }

    print("Characteristic:")
    for characteristic in characteristics {
        print(characteristic)
        if characteristic.properties.contains(.read) {
            print("\(characteristic.uuid): properties contains .read")
            peripheral.readValue(for: characteristic)
        }
        if characteristic.properties.contains(.notify) {
            print("\(characteristic.uuid): properties contains .notify")
            peripheral.setNotifyValue(true, for: characteristic)
            print("ok for: \(characteristic)")
        }
    }
}

public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

    print("Unhandled Characteristic UUID: \(characteristic.uuid)")
    print(error)
}
public func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {

    print(characteristic)
    print(characteristic.value)
}

Feel free to ask for more code

Thanks.

0

There are 0 best solutions below