写操作不会更新 xamarin 表单中 iOS 的特征值

The write operation doesn't update the characteristic value for iOS in xamarin forms

我正在使用 xamarin 表单创建 BLE 应用程序在 Android 中一切正常,我能够读写 GATT 特性。在 iOS 中,我能够成功读取,但 写入操作不会更新特征值 写操作没有错误,它也在执行,但特征值没有改变。我尝试了 iOS 名为 light blue 的本机应用程序,它工作正常,特征值已更新 我只在 Xamarin 表单应用程序中遇到问题。这是我的代码

 private async Task<string> ProcessDeviceInformationService(IService deviceInfoService)
        {
            try
            {
               await adapter.ConnectToDeviceAsync(device);
                var sb = new StringBuilder("Getting information from Device Information service: \n");
                 var characteristics =  deviceInfoService.GetCharacteristicsAsync();
                var characteristic = await deviceInfoService.GetCharacteristicAsync(Guid.Parse("00002a2b-0000-1000-8000-00805F9B34FB"));
                
                try
                {
                    
                    if (characteristic != null)
                    {
                        var sbnew = new StringBuilder("BLE Characteristics\n");
                        byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty(SendMessageLabel.Text) ? "12" : SendMessageLabel.Text);

 

                       
                    
                                                    
                                                 
                        
                        characteristic.ValueUpdated += (o, args) =>
                          {
                        
                         var bytes = characteristic.Value;
                                                 };
                                               await characteristic.WriteAsync(senddata);

 

                                                                                                     
                      

 

                        string str = Encoding.UTF8.GetString(senddata);

 

                  

 

                        sbnew.AppendLine($"Characteristics found on this device: {string.Join(", ", str.ToString())}");
                            CharactericsLabel.Text = sbnew.ToString();
                        

 


                    }
                }
                catch (Exception ex)
                {
                    //return ex.Message;
                    DisplayAlert("Notice", ex.Message.ToString(), "OK");

 

                }

我试过延迟,我也试过在没有外围设备响应的情况下写入,但它不起作用。这是我的外设代码

 // Current Time characteristic
BluetoothGattCharacteristic currentTime = new BluetoothGattCharacteristic(CURRENT_TIME,
        //Read-only characteristic, supports notifications
        BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
        BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PROPERTY_WRITE);
BluetoothGattDescriptor configDescriptor = new BluetoothGattDescriptor(CLIENT_CONFIG,
        //Read/write descriptor
        BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);
currentTime.addDescriptor(configDescriptor);
// Local Time Information characteristic
BluetoothGattCharacteristic localTime = new BluetoothGattCharacteristic(LOCAL_TIME_INFO,
        //Read-only characteristic
        BluetoothGattCharacteristic.PROPERTY_READ,
        BluetoothGattCharacteristic.PERMISSION_READ);
BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic sampleText = new BluetoothGattCharacteristic(SAMPLE_TEXT,
        //Read-only characteristic
        BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
        BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);

我不知道如何解决这个问题 suggestions.I 甚至 Semaphore 都试过了,但它没有帮助,正如您在我的代码中看到的那样

private static async Task<string> WriteAndWaitForResponseAsync(
    ICharacteristic characteristic,
    byte[] senddata)
        {
            var semaphore = new SemaphoreSlim(0, 1);
            string result = null;

            characteristic.ValueUpdated += (o, args) =>
            {
                var bytes = characteristic.Value;

                result = Encoding.UTF8.GetString(bytes);  // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
                                                          // Notify a value has been received.
                semaphore.Release();
            };

            await characteristic.WriteAsync(senddata,new CancellationToken(true)).ConfigureAwait(false);

            // Wait until we receive a notification.
            await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.
           
            return result;
        }

我怀疑线程是这里问题的一部分,您订阅了事件,调用了 WriteAsync,但最终在收到 data/event 之前就离开了该方法。我建议您需要在收到数据之前尝试阻止该方法离开。

试试这样的东西:

private static async Task<string> WriteAndWaitForResponseAsync(
    ICharacteristic characteristic,
    byte[] senddata)
{
    var semaphore = new SemaphoreSlim(0, 1);
    string result = null;

    characteristic.ValueUpdated += (o, args) =>
    {
        // Make sure you read from the new value in event not the existing characteristic.
        var bytes = args.Characteristic.Value;

        result = Encoding.UTF8.GetString(bytes);  // Note I don't know if this is your intended behaviour with the values you get back, you can decide what to actually do with the response.
        // Notify a value has been received.
        semaphore.Release();
    };
    
    await characteristic.WriteAsync(senddata);

    // Wait until we receive a notification.
    await semaphore.WaitAsync(); // I strongly suggest you look in to CancellationTokens but I am not going in to that now.

    return result;
}

然后您可以从当前方法中调用此方法,例如:

string str = await WriteAndWaitForResponseAsync(characteristic, senddata);