This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

S132 3.0 MTU exchange not completing

  1. I looked at examples and added identical code to my own app, specifically to a) set the gatt_enable_params.att_mtu to GATT_MTU_SIZE_DEFAULT, and b) to handle BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST in evt dispatch by doing an sd_ble_gatts_exchange_mtu_reply of that same size.

  2. I found that when testing my app, just after an incoming CONNECT succeeds, when I try to do an sd_ble_gatts_hvx, it is returning NRF_ERROR_INVALID_STATE.

  3. I found the doc of the new functionality of Configurable ATT_MTU on P.6 of the S132 migration document, which was great. I also saw this in the Usage section, which was also a relief because it explains the invalid state. This must mean that the exchange is currently still in progress. "HVx and service changed cannot run while a local client initiated ATT_MTU exchange is active. The SV calls sd_ble_gatts_hvx( ) and sd_ble_gatts_service_changed() will return NRF_ERROR_INVALID_STATE if a local client initiated ATT_MTU exchange is ongoing."

  4. I instrumented my app to use NRF_LOG to output all BLE messages to the serial console, and see the following:

a) BLE_GAP_EVT_CONNECTED (which has a good handle)

b) BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (which I handle with the sd_ble_gatts_exchange_mtu_reply as I said above, and as in all the samples)

c) Nothing else. I never receive the BLE_GATTC_EVT_EXCHANGE_MTU_RSP which the doc would imply I should be receiving to indicate the end of the exchange.

  1. I read this doc, and anything else I could find, and I am stumped as to why the RSP isn't coming, and why I'm stuck in the middle of the MTU exchange. I don't even know who is originathing this request, so I can't look at the source code to see what is happening. infocenter.nordicsemi.com/index.jsp

I'm completely blocked in my conversion to SDKV12 at this point because of nonfunctional BT. Guidance would be greatly appreciated. Thank you.

  • So, Hung Bui, thank you for the sniffer recommendation. That said, I am very, very frustrated and I'd love it if you could just give me your intuition about what may be happening.

    I hope that at this point I have impressed upon you that I don't do this debugging carelessly, and so when I say something it is really factually what I experienced.

    The morning after writing my last reply to you, I did indeed validate the error checking. It was fine.

    And so I ordered the sniffer.

    Yesterday the sniffer arrived, and today I sat down to install and try it. (This is quite nice, by the way. I watched your video and it was quite helpful. My only constructive feedback is that trying to use it on a mac is a little frustrating because it doesn't seem to be officially supported in the downloads, and the one that I did end up finding doesn't work with the latest wireshark. But I did manage to install the old version of wireshark, and it's working fine now.)

    As soon as the sniffer was up and running, I connected my device. Note that between the last time it was failing and now,

    • I have NOT updated the firmware on that failing device (the peripheral)
    • I have NOT done anything else to my phone (the controlelr) in terms of changing versions or config of anything.

    And so even before doing a capture, I connected the device and watched the serial console fully expecting to see the bug happen, since my device has NEVER worked properly in this testing.

    Unbelievably, my device worked. Although I still don't seem to receive the BLE_GATTC_EVT_EXCHANGE_MTU_RSP, immediately after my BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST and my calling sd_ble_gatts_exchange_mtu_reply(), I did receive a BLE_GATTS_EVT_WRITE which set up notification parameters properly, and everything in my app proceeded to work perfectly.

    This leaves me in the position at this point of asking three questions:

    1. Why, when I had isolated it earlier in this thread, did the HRS app fail repeatably with the app being "stuck" in the MTU Exchange state, and then one morning (without any changes) it just started working?
    2. Why, when I had never before had my own app working, being "stuck" in the MTU Exchange state, did it suddenly start working today without any changes at all - that is, without even re-burning a new version of my app to the device?
    3. More because I am curious, why does my app not seem to receive a BLE_GATTC_EVT_EXCHANGE_MTU_RSP event, even though the doc says that it should?

    I've never looked at OTA bluetooth so I'm incapable of evaluating a capture, so I'm including one as an attachment here.

    I'm truly nervous about this, Hung Bui, because I can't afford to just switch to SDKv12 and have it randomly succeed and randomly fail in the field. Anything you can do to help ponder this with the engineers would be appreciated.

    Thanks.

  • Hi Ray,

    I'm sorry to hear that you had inconsistent results. From the trace I can see that the MTU request has been sent from the central side, and the MTU response been replied from the peripheral side, as it should. I would assume it's handled some where in the code. You can test this by comment out the code handling sd_ble_gatts_exchange_mtu_reply() and check if it still works.

    You can see the request and response here:

    image description

    If you are using Wireshark v1.10 (as recommended) you can filter out empty packet by using this filter "!(btle.length == 0)" as in the video.

    From now you have the sniffer so you can capture the trace when the issue occurs. It will be clearer of what could go wrong.

    From the trace I assume you used slave latency = 3. Also please put the sniffer closer to your device as I can see some Malformed packet occurred.

  • I'm not sure where the _RSP is handled in the code, but it's not being swallowed in my code. Regardless, it doesn't matter because I have no need to deal with the _RSP message. I was just curious.

    I did indeed validate that by removing the mtu_reply() call, it stopped working again. And by placing the mtu_reply() call back in, it works again.

    Thanks for the tip on wireshark filtering.

    As you sensed, I do have more than a bit of anxiety about this problem's intermittent/inconsistent nature. That said, at this moment there is really nothing I can do but to wait for it to happen again. At least now I am armed with the ability to sniff.

    Thanks for getting me to this point, and I'll talk with you again if/when I can get it to repro. Thx, Hung.

  • No problem, Ray. Please inform me if it comes back :)

Related