I'm working on iOS BLE app to charge a mobile phone. I did everything correct up to discover characteristics. First Scanning peripheral and connected to it. Discover the services(FFB0) and characteristics(FFB1, FFB2) which having notify and write without response properties.
I found the Client Characteristic Configuration Descriptor. I want to send the command to PCB to unlock for charging I want write value to FFB2 characteristics but peripheral doesn't respond. Here is my code.
I have searched everything related to this but I didn't find any solution If anybody gives solution to this problem it will be helpful to me.
This is Document Provided by client:
There is a BLE4.0 Bluetooth module on each of the PCB, each Bluetooth module has a solo 12 bytes length address code, The PCB data channel, Service UUID is OxFFBO, including two eigenvalues, it is OxFFBI and OxFFB2, The length of communication data is 1--20 bytes. OxFFB1 is the channel for APP data download.OxFBB2 is the channel for Bluetooth upload the data.
Power-up into idle mode, when in idle mode, the two lights will flash.it will send an ID code(a byte)to the phone, the APP in the phone will get the ID code(a byte). ID code can be set by phone settings. it means sending the corresponding unlock instruction by ID code.
The unlock instruction is 0x55,0xe1,(ID0+1),time,Following is the explain of unlock instruction:
ID0 is a ID code,"time" is the user unlock time(5-120 min), please pay attention to it is binary-to-hexadecimal conversion, time==05 means 5 min, time==6 means 6 min, time ==A means 10 min ,and so on. If the ID0 of the PCB is 0xff, unlock the pcb 60min is:0x55,0xe1,0x00,0x3c; If the ID0 of the PCB is 0x05, unlock the pcb 10 min is :0x55 , 0xe1 ,0x06 , 0x0a
It will start open output and timing when the MCU on the PCB receives the unlock instruction. The system goes into idle mode again when timing time is out. In idle mode, long press the key goes into shut down sleeping time mode.
The baud rate of uart is set at 9,600. The inquiry command that APP send to MCU is 0x55 0x01 MCU should reply to the APP's information format: 0x55, 0x02, bat_level, xH, XL (xH XL represents the current voltage value of the battery, xH - represents the high 8 bits, and XL--- represents the low 8 bits)
import CoreBluetooth
let batteryServiceCBUUID = CBUUID(string: "FFB0")
let batteryServiceRequestCBUUID = CBUUID(string: "FFB1")
let batteryServiceRequestCBUUID2 = CBUUID(string: "FFB2")
class ChargingViewController: UIViewController , CBPeripheralDelegate
,CBCentralManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown:
print("central.state is .unknown")
case .resetting:
print("central.state is .resetting")
case .unsupported:
print("central.state is .unsupported")
case .unauthorised:
print("central.state is .unauthorised")
case .poweredOff:
print("central.state is .poweredOff")
case .poweredOn:
centralManager.scanForPeripherals(withServices: [batteryServiceCBUUID])
print("central.state is .poweredOn")
@unknown default:
fatalError()
}
print("state: \(central.state)")
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral)
batteryServicePeripheral = peripheral
batteryServicePeripheral.delegate = self
centralManager.stopScan()
centralManager.connect(batteryServicePeripheral)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("Connected=======>\(String(describing: batteryServicePeripheral))")
batteryServicePeripheral.delegate = self
batteryServicePeripheral.discoverServices([batteryServiceCBUUID])
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral,
error: Error?) {
print("Fail To Connect=======>\(String(describing: error))")
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral:
CBPeripheral, error: Error?) {
if error == nil {
print("Disconnected========>\(peripheral)")
}else {
print("Disconnected========>\(String(describing: error))")
}
}
// MARK: - CBPeripheral Delegate Methods
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
print("SPAKA:PERIPHERALSERVICES============>\(service)")
peripheral.discoverCharacteristics(nil, for: service)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
//else { return }
for characteristic in characteristics {
print(characteristic)
if characteristic.uuid == batteryServiceCBUUID {
peripheral.setNotifyValue(true, for: characteristic)
}
if characteristic.uuid == batteryServiceRequestCBUUID2 {
batteryCharacteristics = characteristic
let str1 = "55e100"
let data = String(format: "%@%@",str1,hexTimeForChar)
guard let valueString = data.data(using: String.Encoding.utf8) else
{return}
peripheral.writeValue(valueString, for: characteristic , type:
CBCharacteristicWriteType.withoutResponse)
print("Value String===>\(valueString.debugDescription)")
peripheral.setNotifyValue(true, for: characteristic)
}
}
}
peripheral.discoverDescriptors(for: batteryCharacteristics)
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
if error == nil {
print("Message sent=======>\(String(describing: characteristic.value))")
}else{
print("Message Not sent=======>\(String(describing: error))")
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic:
CBCharacteristic, error: Error?) {
if error == nil {
print("SPAKA : IS NOTIFYING UPDATED STATE ======>\(characteristic.isNotifying)")
print("SPAKA : UPDATED DESCRIPTION ======>\(String(describing:
characteristic.description))")
}else{
print("SPAKA : ERRORUPDATEDNOTIFICATION\(String(describing: error))")
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
print("SPAKA: UPDATED VALUE RECEIVED========>\(String(describing: characteristic.value))")
print("characteristic UUID: \(characteristic.uuid), value: \(characteristic.value)")
guard let str = characteristic.value else { return }
if let string = String(bytes: str, encoding: .utf8) {
print("SPAKA==========>:::\(string)")
} else {
print("not a valid UTF-8 sequence")
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
guard let desc = batteryCharacteristics.descriptors else { return }
for des in desc {
print("BEGIN:SPAKA DESCRIPTOR========>\(des)")
discoveredDescriptor = des
print("Descriptor Present Value and uuid: \(des.uuid), value: \(String(describing: des.value))")
peripheral.readValue(for: discoveredDescriptor)
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
if let error = error {
print("Failed… error: \(error)")
return
}
print("Descriptor Write Value uuid: \(descriptor.uuid), value: \(String(describing: descriptor.value))")
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {
if let error = error {
print("Failed… error: \(error)")
return
}
print("Descriptor Updated Value uuid: \(descriptor.uuid), value: \(String(describing: descriptor.value))")
}
}