It was not a phone I was using. I think it was a Nexus 6P. And yeah, I shouldnt’t have said “Android” when I was mentioning the bug. I have used other Android phones and they dont have this issue. Well, I have used one other Android Phone (I think it was a Nexus 5x) and there was no issue.
Regarding the proposed fix. I agree that the spec does not mention what to do when a LL_REJECT_IND (or REJECT_IND_EXT) is received (outside of the control procedures where use of REJECT_IND is expected). The spec is quite clear in other areas though; for example, a Data Length Update procedure ends only when a LL_LENGTH_RSP is received or LL_UNKNOWN_RSP is received. This might just be me, but I really dislike adding work-arounds to what are pretty clearly bugs and that also clearly violate the spec in other areas. I also "worry" that there might be other unintended consequences by doing this. For example, the nimble controller issues a connection update and the peer responds with LL_REJECT_IND. We cancel the procedure but the peer accepts the connection update (which would cause a supervision timeout). I wonder if there is a work-around that would fix this particular issue with this controller that would not violate the spec in other areas? Dont get me wrong; I think your idea is very reasonable and makes sense. Especially if you have encountered this with other devices. > On Jan 17, 2017, at 2:12 AM, Andrzej Kaczmarek > <[email protected]> wrote: > > Hi Will, > > On Tue, Jan 17, 2017 at 5:48 AM, will sanfilippo <[email protected]> wrote: > >> Hello: >> >> Was wondering if there were any folks out there that could comment on >> something regarding a disconnect issue with an Android Phone running 7.1.1 >> and our bluetooth stack (the controller). >> > > Which phone do you use? Android has only host stack (Bluedroid) to this is > likely specific to controller used in particular phone - I've seen similar > problems when testing other controller and some "generic" Chinese phones. > > >> >> What appears to be happening is this: >> >> * Nimble wants to do Data Length Extension and enqueues a LL_LENGTH_REQ >> when a connection gets created. Nimble is a peripheral btw. >> * The Android controller wants to do a feature exchange so it enqueues a >> LL_FEATURE_REQ. >> * Android controller sends the LL_FEATURE_REQ. >> * Nimble controller sends a LL_LENGTH_REQ. >> * Once the nimble controller succeeds in sending the LL_LENGTH_REQ, it >> sends the LL_FEATURE_RSP. >> * Android responds with a LL_REJECT_IND with error code 0x24 LMP PDU not >> allowed. >> > > IIRC this is the same as I've seen (even the error code is the same) - > don't have logs now though... > > >> * Android resends the LL_FEATURE_REQ. >> * Nimble responds with LL_FEATURE_RSP. >> * Android sends LL_LENGTH_REQ >> * Nimble controller sends LL_LENGTH_RSP. >> * All goes fine until nimble controller times out due to a failed LL >> control procedure: the nimble stack never received a LL_LENGTH_RSP. >> >> NOTE: from the above it is hard to say why the Android controller sent the >> LL_REJECT_IND. Basically, it appears that the LL_LENGTH_REQ messed up the >> Android controller as the Android controller was expecting a LL_FEATURE_RSP. >> >> My questions are the following: >> * I think this is a bug on the part of the Android controller. The >> specification allows for non-real time response to control PDU’s and it is >> quite possible that a controller starts a procedure “at the same time” that >> the remote controller starts a procedure. What I would have expected is >> that the Android controller should have responded to the LL_LENGTH_REQ with >> a LL_LENGTH_RSP. Eventually, the Android controller gets the LL_FEATURE_RSP >> and all should have been fine. Do folks agree with this? >> * A controller should not use a LL_REJECT_IND as a generic response when a >> controller sends something unexpected. The LL_REJECT_IND is only used >> during encryption procedures, connection parameter request update >> procedures and in a couple of cases where there are Control Procedure >> collisions. Note that the scenario described above is NOT one of the >> Control Procedure collisions mentioned in the specification. >> > > I agree, this is clearly issue on peer side - there is no procedure > collision here since both length update and feature request can be handled > at the same time. However, I think what Nimble should do here is to remove > transaction once LL_REJECT_IND is received. > > I know specification does use LL_REJECT_IND explicitly only in case of > certain scenarios, but it does not seem to specify what to do if > LL_REJECT_IND is received as response in other procedures. It makes sense > to me that if peer indicated explicitly that it will not handle request, we > should not expect response. I think it is better to have such workaround > rather that strictly follow the spec and timeout connection. > > BTW, I made small modification in Nimble so it replies LL_REJECT_IND on > LL_LENGTH_REQ and checked how other device (here: LG G5 with Android 7.0, > Broadcom controller) handle this and it just seem to do as I described, > i.e. the connection was not terminated due to transaction timeout. > > BR, > Andrzej
