iosswiftbluetoothbluetooth-lowenergycore-bluetooth

The peripheral does not respond to the central in writeRequest (bluetooth)


I set up a function to read a feature, and it works correctly, I send the request from central:

func readCharacteristicValue() {
        if let peripheral = connectedPeripheral, let characteristic = targetCharacteristic {
            peripheral.readValue(for: characteristic)
        }
    }

And I process the answer from peripheral:

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
        
        //Richiamo comportamenti differenti in base al servizio
        switch request.characteristic.uuid {
            
        case Constants.uuid.AuthService:
                let authenticationInstance = PAuthentication.pAuthentication
                authenticationInstance.responseToReadRequest(request: request, peripheralManager: peripheralManager, clearServiceCharacteristic: clearServiceCharacteristic)
            
            case Constants.uuid.OtherService: print("Other implementation")
            
            default: print("Nothing")
        }
        
    }

this is then captured by this function from central:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
        //Se qualcosa va storto
        if let error = error {
            print("Error reading characteristic value: \(error)")
        }

        //In base alla caratteristica che sta rispondendo gestisco in maniera differente le risposte
        switch characteristic.uuid {
            
        case Constants.uuid.AuthService:
                let authenticationInstance = CAuthentication.cAuthentication
                authenticationInstance.responceFromReadRequest(characteristic: characteristic, disconnect: disconnect)
            
            default:
                print("Nothing")
        }
    }

But when I try to make a write request, I can get to the peripheral, but when it responds I can't see the response, but I don't understand why. This is the function that sends the write request by central:

    func writeStringToCharacteristic(_ string: String) {
        if let data = string.data(using: .utf8), let peripheral = connectedPeripheral, let characteristic = targetCharacteristic {
            peripheral.writeValue(data, for: characteristic, type: .withResponse)
        }
    }

This is the function in peripheral than handle the message:

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
         for request in requests {
             if request.characteristic == characteristic {
                 if let value = request.value {
                     // Esempio: Processa i dati scritti dal Central
                     let receivedString = String(data: value, encoding: .utf8)
                     print("Received data from Central: \(receivedString ?? "")")
                     if (receivedString == "Auth"){
                         
                         var dataToSend:Data?
                         if let name = SharedData.shared.AuthData["name"],
                            let surname = SharedData.shared.AuthData["surname"],
                            let date = SharedData.shared.AuthData["date"] {
                            dataToSend = "\(name), \(surname), \(date)".data(using: .utf8)
                             // Ora puoi utilizzare 'dataToSend' per inviare i dati alla caratteristica Bluetooth
                         } else {
                             print("One or more values are missing")
                         }
                         
                         request.value = dataToSend
                         peripheralManager.respond(to: request, withResult: .success)
                         //NON RIESCO A RECAPITARE LA RISPOSTA DAL CENTRALE
                     }
                 }
             }
         }
     }

From the latter function of the peripheral, I cannot see the message sent to the central. So the central transmits the data to the peripheral but I can't then see the response from the central.


Solution

  • The peripheral cannot send data to the central in the response to a write request.

    The withResponse write type requires that the peripheral send a response that the write has been received successfully (the withResult:.success), but that is all. The response does not include any additional data.

    For the peripheral to send unsolicited data to the central, it must use Indicate/Notify.

    After you respond to the write, you need to use updateValue to deliver an updated value to your central. Your central must have previously used setNotifyValue in order to receive the notification that there is a new value for the characteristic.