Git Product home page Git Product logo

Comments (25)

chipweinberger avatar chipweinberger commented on August 17, 2024 1

fixed: 66655d6

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024 1

odd. at what point does the actual mtu change to a larger value?

Not sure, I'm going to go into the office on Tuesday and debug all of the BT traffic to figure it out.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024 1

Here's the request to our peripheral:
image001

... and the response from our peripheral:
image003

It looks like the value of 23 is coming from this plugin, not the peripheral.

Here's a discussion on the Apple forums about how to get the MTU size, and whether the onMtuChanged callback is actually called.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024 1

I added

[NSTimer scheduledTimerWithTimeInterval:.01
    target:self
    selector:@selector(logMtu:) 
    userInfo:@{@"peripheral":peripheral,}
    repeats:YES];

to didConnectPeripheral, with logMtu of

- (void)logMtu:(NSTimer *)timer {
    CBPeripheral * peripheral = timer.userInfo[@"peripheral"];
    NSLog( @"[FBP-iOS] logMtu %d", [self getMtu:peripheral]);
}

... and it looks like the value is ready in .06s for my phone and peripheral:

[FBP-iOS] didConnectPeripheral
[FBP-iOS] logMtu 23
[FBP-iOS] handleMethodCall: discoverServices
[FBP-iOS] logMtu 23
[FBP-iOS] logMtu 23
[FBP-iOS] logMtu 23
[FBP-iOS] logMtu 23
[FBP-iOS] logMtu 185

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

is "OnMtuChanged" ever seen in your logs?

I did change how the dart mtu code works. you can look at older versions. we used to actively get the mtu from the system, but now we just passively wait for OnMtuChanged. I find it odd if iOS does not report the mtu change.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

something like this (see older code)

/// The current MTU size in bytes
  Stream<int> get mtu {
    // get initial value from our cache
    int? initialValue = FlutterBluePlus._mtuValues[remoteId]?.mtu;
    if (initialValue == null) {
        // invoke getMtu from system
       initialValue = invokeXXX
    }
    return FlutterBluePlus._methodStream.stream
        .where((m) => m.method == "OnMtuChanged")
        .map((m) => m.arguments)
        .map((args) => BmMtuChangedResponse.fromMap(args))
        .where((p) => p.remoteId == remoteId.str)
        .map((p) => p.mtu)
        .newStreamWithInitialValue(initialValue!);
  }

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

yes this looks like a real bug in flutter blue plus.

i'm surprised no one else has noticed this.

in iOS, onMtuChanged is not exposed by iOS. We must actively ask for the mtu from the system.

I can fix this later next week.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

Thank you for the fix, @chipweinberger!

A related question, is there any way to tell the difference between the default value and a reading from the peripheral? I'm planning on listening to the mtu stream until the value isn't 23, but this is awkward... I'd think the stream should only be populated with actual readings, and users of this plugin could implement their own default.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

yes i was thinking about that issue as well.

before i release the next version i'll improve it

i think the solution is to change the order so that onMtuChanged is called before onConnectionStateChanged

then, after connection you can await device.mtu.first and it will always be the correct value


another solution is similar to yours. remove default value and return first result after connection.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

I tried a later patch (a5c2396), and I can see the new code is getting called, but I'm still only getting a single value of 23 from the mtu stream on my iPhone 6s.

... same results, one mtu value of 23, on a newer iPhone running iOS 17 beta.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

odd. at what point does the actual mtu change to a larger value?

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

@chipweinberger

i'm surprised no one else has noticed this.

It looks like the error is relatively new (PlatformException(writeCharacteristic, data is longer than MTU allows. dataLen: 237 > maxDataLen: 182, null, null);); I think this was failing silently before.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

my main question is when will calling getMtu return the correct value?

currently i call it in the onConnected handler. is that too soon?

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

perhaps you can try adding a separate thread that continually calls getMtu

and then we can figure out when it changes on the iOS platform

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

I think this was failing silently before.

on iOS, the platform will silently split your payload into multiple packets.

that is bad for performance, so i've made it an error, and provide a separate function (writeLarge) in the README if you want auto splitting behavior.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

it looks like the value is ready in .06s

Thanks for testing!!

This is tricky. How should we handle this?

perhaps we can

  • add a timer that checks for mtu changes (just like you did), and caches the results

when the mtu changes:

  • push to stream

when flutter blue plus ios code is initialized:

  • create timer

thoughts?

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

I've pushed a fix to master: 5dc29c4

let me know if it works for you.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

I took a quick look at the diff for this change, are you canceling the timer? I think once we get a non-23 value, we should no longer expect any changes, so there's a lot of unnecessary traffic (assuming that this MTU read gets passed along to the peripheral).

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

Is there a similar problem for large reads? We are getting some truncated data on the iPhone 6S; e.g. the length sent with the data says there should be 212 bytes, but we're now only receiving 182 bytes.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

assuming that this MTU read gets passed along to the peripheral

no it does not get passed on. it is just reading a cached value.

canceling the timer could be nice but more complicated to support multiple devices. also a device may only support 23 MTU, so we'd need some timeout (maybe 30 seconds?). Overall kinda complicated to save what i think is a very small amount of perf. But i wish there was a simpler solution than a timer.

Is there a similar problem for large reads? We are getting some truncated data on the iPhone 6S; e.g. the length sent with the data says there should be 212 bytes, but we're now only receiving 182 bytes.

I would think this is a problem with your device firmware.

when you say now what do you mean? did it work on 1.4.0?

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024
Screenshot 2023-09-05 at 6 38 48 PM Screenshot 2023-09-05 at 6 42 15 PM

It seems writeLarge may not be work with subsequent reads if data > mtu.

I could remove these checks for writing larger than MTU. But we need to make sure all supported android versions operate this same way. i.e. support writing larger than MTU & autosplit

But perhaps there is some other way to fix this issue?

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

according to chatGPT, reading a characteristic on Android when data > MTU truncates to MTU length.

There seems to be no way to get the rest of the data.

If this is true, then iOS should be enforced to operate the same way.

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

in android, it seems the maximum write length is 512, hardcoded (note: GATT_MAX_ATTR_LEN == 512)

https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/system/stack/gatt/gatt_sr.cc

Screenshot 2023-09-05 at 7 29 05 PM

from flutter_blue_plus.

chipweinberger avatar chipweinberger commented on August 17, 2024

fixed in 1.14.13.

the length sent with the data says there should be 212 bytes, but we're now only receiving 182 bytes.

try using allowSplits, added in 1.14.13. open a new issue if you still have problems.

from flutter_blue_plus.

sqcsabbey avatar sqcsabbey commented on August 17, 2024

in android, it seems the maximum write length is 512, hardcoded (note: GATT_MAX_ATTR_LEN == 512)

Different Android versions will support different values; I believe Android 14+ have a mtu of 517.

from flutter_blue_plus.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.