title: Android 6.0 Marshmallow BLE : Connection Parameters
body: <p>The Bluetooth Low Energy connection parameters management seems to have changed in Android 6.</p>
  
  <p>I have a BLE Peripheral device who needs to use some specific connection parameters (notably, the connection interval), and I want to use the minimum connection interval allowed by the BLE specification (i.e. 7,5ms).</p>
  
  <p>The Android SDK doesn't allow to choose it from the BLE GAP Central (the smartphone) side, so the proper way to do it is to make my GAP Peripheral device send a <code>L2CAP Connection Parameter Update Request</code> after the GAP connection is made.</p>
  
  <p>The parameters I request are: </p>
  
  <ul>
  <li>conn interval min : 7,5ms</li>
  <li>conn interval max : 7,5ms</li>
  <li>slave latency : 0</li>
  <li>supervision timeout : 2000ms</li>
  </ul>
  
  <p>This worked as expected with all Android devices I've been testing, from 4.3 to 5.x : after sending the <code>L2CAP Connection Parameter Update Request</code>, my device receives a <code>L2CAP Connection Parameter Update Response</code> with 0x0000 (accepted), followed by a <code>LE Connection Update Complete event</code> where I can see that the requested connection parameters have well been taken into account.</p>
  
  <p>Now, with a Nexus 9 tablet or with 2 different Nexus 5 devices, all having Android 6.0.1, I can see that the the <code>L2CAP Connection Parameter Update Request</code> is always rejected (I receive a <code>L2CAP Connection Parameter Update Response</code> with 0x0001 (rejected)). Then I receive a <code>LE Connection Update Complete event</code> where I can see that the requested connection parameters have NOT been taken into account.</p>
  
  <p>I've been trying this with 2 different implementations on the Peripheral side (one with ST Microelectronics' BlueNRG, one with Nordic Semiconductor's nRF52), both with the exact same result.</p>
  
  <p>Then, after more testing : I have tried different parameter sets, changing the conn interval max (I kept other parameters the same). Here is what I found : </p>
  
  <ul>
  <li>with conn interval max = 18.75ms, update request was accepted with interval set to 18.75ms</li>
  <li>with conn interval max = 17.50ms, update request was accepted with interval set to 15.00ms</li>
  <li>with conn interval max = 15.00ms, update request was accepted with interval set to 15.00ms</li>
  <li>with conn interval max = 13.75ms, update request was accepted with interval set to 11.25ms</li>
  <li>with conn interval max = 11.25ms, update request was accepted with interval set to 11.25ms</li>
  <li>with any other conn interval max value below 11.25ms, I get rejected.</li>
  </ul>
  
  <p>So the observation is that something has clearly changed with the way Android 6's BLE stack handles the connection parameters. But there doesn't seem to be any kind of information or documentation to confirm that.</p>
  
  <p>My observations lead to a conclusion that the minimum connection interval allowed is now 11.25ms (which actually fits my needs) instead of 7.5ms in earlier Android versions. But having found it empirically, I'd want to be sure that I'm not missing some other constraints/rules or if that minimum would not be dynamic, depending for example on the current battery level...</p>
  
  <p>What would be great would be to have the equivalent of <a href="https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf" rel="noreferrer">Apple's Bluetooth Design Guidelines</a> (cf. §3.6) to set things clear on how an LE Peripheral should deal with this topic.</p>
  
  <p>Is anyone having the same issue or is aware of some more helpful information from Google ?  </p>