Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

How to do the MTU negotiation so that MTU size is updated to 128 or more on Android #15790

Closed
Priyabaghelgithub opened this issue Aug 1, 2023 · 2 comments
Labels
s/unverified New report that has yet to be verified t/bug 🐛

Comments

@Priyabaghelgithub
Copy link

Priyabaghelgithub commented Aug 1, 2023

###Code
'using Android.App;
using Android.Bluetooth;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

using Plugin.BluetoothLE;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading.Tasks;

using Xam.C.Droid;
using Xamarin.Forms;
using Application = Android.App.Application;

[assembly: Dependency(typeof(AndroidBluetoothLERenderer))]

namespace Xam.C.Droid
{
public class AndroidBluetoothLERenderer : IBluetoothManager

{

public async Task<bool> RequestMtuAsync(Guid? deviceGuid, int mtu)

{
try
{
bool c;
var adapter = BluetoothAdapter.DefaultAdapter;

    string hexString = ConvertGuidToHexString(deviceGuid.Value);
   
     var device = adapter.GetRemoteDevice(hexString);

      
  if (device != null)
      
  {
         
   var callbackHandler = new CustomBluetoothGattCallback();
          
  var gatt = device.ConnectGatt(Application.Context, false, callbackHandler);
      
      //var mtuRequestResult = gatt.RequestMtu(mtu);
  
          int mtuRequestResults = await callbackHandler.RequestMtuAsync(gatt, mtu);
   
         if (mtuRequestResults >0 )
          
  {
           
     c = true;
           
     return c;
           
 }
            
//// Return true if the MTU request was successful.
              
        }

        
return false;
 
   }

      catch (Exception ex)
  
  {
            // Handle any exceptions that may occur during the process.
            Console.WriteLine("Error requesting MTU: " + ex.Message);
        
return false;
   
 }

}

'

Expected Behavior

Currently on Android device data is truncated to 20bytes and the remaining data will not visible so how to update MTU size negotiation so that it can accept MTU size to 128 butes or more

Actual Behavior

MTU is not correctly setting and also not working on Samsung

Basic Information

  • Version with issue: Android 9, Android 11, Samusng devices

  • NuGet Packages:Plugin.BluetoothLE

@jfversluis
@jamesmontemagno

@Priyabaghelgithub Priyabaghelgithub added s/unverified New report that has yet to be verified t/bug 🐛 labels Aug 1, 2023
@jfversluis
Copy link
Member

I don't think this is an issue with Xamarin.Forms. For more how to questions please turn to other forums like Stack Overflow or Microsoft Q&A, thanks!

@jfversluis jfversluis closed this as not planned Won't fix, can't repro, duplicate, stale Aug 7, 2023
@Priyabaghelgithub
Copy link
Author

Priyabaghelgithub commented Aug 26, 2023

I'm implementing BLE in Xamarin forms using Plugin.BluetoothLE package, where I'm trying to send data larger than 20 bytes. So I used

await _Device.RequestMtu(512) but its MTU size is not updating on central device(smartphone device or device inside the app) on Android only

'''
public bool TrySetScanResult(IScanResult result) ///Method responsible for connecting device in mobile app
{
var response = false;
try
{
if (Uuid == Guid.Empty || Device == null)
{
Device = result.Device;
Uuid = Device.Uuid;

                Device.WhenStatusChanged()
                    .ObserveOn(RxApp.MainThreadScheduler)
                    .Subscribe(connstat =>
                    {
                        SetDeviceInfo(connstat);
                       
                    }, onError: ex => ex.WriteLog().UploadLog())
                    .DisposeWith(DeactivateWith);

                Device.WhenDisconnected()
                    .ObserveOn(RxApp.MainThreadScheduler)
                    .Subscribe(device =>
                    {
                        
                        if (this.isFired && device.Uuid == Device.Uuid)
                        {
                            this._watcher?.Dispose();
                            this._watcher = null;
                            this.isFired = false;
                        }
                    }, onError: ex => ex.WriteLog().UploadLog())
                    .DisposeWith(DeactivateWith);

}
System.Diagnostics.Debug.WriteLine(Device.Status);
if (this.Uuid == result.Device.Uuid)
{
if (!Device.IsConnected())
{
response = true;
IsDevicePairedWatcher();
}
if (Device.IsConnected())
{
UpdtaeMtuSize ();
}
}
}
catch (Exception ex)
{
ex.WriteLog().UploadLog();
}
return response;
}

private void IsDevicePairedWatcher() // this method is watching data of hooked characteristic
{
if (!isFired)
{
isFired = true;
if (this._watcher != null)
{
_watcher?.Dispose();
_watcher = null;
}

            this._watcher = Device.ConnectHook(ServiceUUID,
           WriteReadNotify_Results_CharacteristicUUID,
            ReadNotify_Calibration_CharacteristicUUID)
              .ObserveOn(RxApp.MainThreadScheduler)
              .Subscribe(async (result) =>
              {
                  try
                  {                   
                  }
                  catch (Exception er)
                  {
                      er.WriteLog().UploadLog();
                  }

              }, onError: (ex) =>
              {
                  ex.WriteLog().UploadLog();
                  isFired = false;
              });
        }
    }

private async void UpdateMtuSize() //responsible for setting CustomCallback class and requesting Device to request MTU
{
int desiredMtuSize = 128;
DependencyService.Get().GetConnectedBluetoothGatt(_currentDevice.Uuid);
var currentMTU = await Device.RequestMtu(desiredMtuSize);
if (currentMTU >= desiredMtuSize)
{
IsMTUupdate = true;
Console.WriteLine("Successful, current MTU size: " + currentMTU);
}
else Console.WriteLine("Failed, current MTU size: " + currentMTU); // MTU negotiation failed, actualMtu is different from the desired MTU
}

public class AndroidBluetoothLERenderer : IBluetoothManager //rendere setting bluetoothGatt instance
{
private BluetoothGatt GetBluetoothGatt;
public void GetConnectedBluetoothGatt(Guid? deviceGuid)
{
try
{
var adapter = BluetoothAdapter.DefaultAdapter;
string hexString = ConvertGuidToHexString(deviceGuid.Value);
var device = adapter.GetRemoteDevice(hexString);

            if (device != null)
            {
                var customBluetoothGattCallbackhandler = new CustomBluetoothGattCallback();
                var gatt = device.ConnectGatt(Application.Context, false, customBluetoothGattCallbackhandler);
                GetBluetoothGatt = gatt;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error requesting MTU: " + ex.ToString());  // Handle any exceptions that may occur during the process.
        }
    }
    public bool DisconnectBluetoothGatt(bool mtuupdate)
    {
        if (mtuupdate)
        {
            if (GetBluetoothGatt.Device != null)
            {
                GetBluetoothGatt.Close();
                GetBluetoothGatt.Dispose();
                return true;
            }
            else
                return false;
        }
        else return false;
    }

'''
where should I call the method UpdtaeMtuSize so that MTU is updated whenever the device connected instantly
curently I called the method when the device is connected but MTU size is not updating properly on central device(device inside the app) sometimes it set or sometimes not why on Android only

I am using PluginBluetoothLE nuget package in xamarin from

suggest any alternative to set the MTU size properly
@jfversluis @jamesmontemagno

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
s/unverified New report that has yet to be verified t/bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants