nRF Sniffer for Bluetooth LE のセットアップにて、Android端末とnRF52840との間で、Bluetooth5の2Mbpsのフレームが見受けられませんでした。一つの原因は端末仕様でした(詳細はこちら)
上位プロトコルへの自動切換えは何となく怪しい、1Mbps か 2Mbps どちらの状態か把握管理したい。そこで2Mbps( BT用語ではPHY_2Mというようです) 弊方では以下のようにしました。
スレーブAndroid側
STATE_CONNECTEDイベント検出後、setPreferredPhy() をcallし、nRF52840 へ 2Mbps を明示的に要請します。
private final BluetoothGattCallback mGattcallback = new BluetoothGattCallback() {
// 接続状態変更
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
switch (newState ) {
case BluetoothProfile.STATE_CONNECTED : // 接続完了
if ( /* 端末で2Mbpsがサポート済みか?*/ ) {
/* 2MBpsを設定 */
gatt.setPreferredPhy(
BluetoothDevice.PHY_LE_2M_MASK,
BluetoothDevice.PHY_LE_2M_MASK,
0
);
}
}
・・・後 略・・・
これで nRF52840 側の BLE_GAP_EVT_PHY_UPDATE_REQUEST イベントを用意してあれば、速度設定が反映されます。なお大前提として端末が 2Mbps サポートしているかの事前CHECKが必要です。
マスタnRF52840Android側
試したところAndroid側の接続完了が先に到達するようですが、到達順は処理負荷等でずれることも考えられます。nRF52840 側にも仕込んでおきます。こちらは2Mbps サポート有なので無条件に設定します。
static void ble_evt_handler(
ble_evt_t const * p_ble_evt, // [in] Bluetooth stack event.
void * p_context // [in] ハンドラ引数(任意)
) {
uint32_t err_code;
switch( p_ble_evt->header.evt_id )
{
// 通常接続。 Connected to peer.
case BLE_GAP_EVT_CONNECTED:
/* 2MBpsを設定 */
ble_gap_phys_t const phys = {
.rx_phys = BLE_GAP_PHY_2MBPS,
.tx_phys = BLE_GAP_PHY_2MBPS,
};
err_code = sd_ble_gap_phy_update(/*in*/ p_ble_evt->evt.gap_evt.conn_handle,
/*in*/ &phys );
APP_ERROR_CHECK( err_code,902 );
break;
念のためアドバタイズ用の初期値も変更しておきました。
・・・前 略・・・
init.config.ble_adv_secondary_phy = BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_1MBPS ;
// 1Mと2Mを orするようにとどっかに書いてあった。2MBPSだけだと論理エラーが発生。
init.config.ble_adv_primary_phy = BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_1MBPS ;
init.evt_handler = on_adv_evt; // EVENTハンドラ関数
// -BLEアドバタイズ初期化 -
err_code = ble_advertising_init( /*out*/&m_advertising, /*in*/&init );
APP_ERROR_CHECK( err_code,1501 );
Android側も BluetoothGattCallback の onPhyUpdate をオーバライドして、Logcatを仕込んで動きを確認できるようにするとベターです。
実行結果
更新要求のアナライズ結果です。

更新応答のアナライズ結果です。

肝心の転送レートは、あまり変わりません。

PACKET送信部のアナライズ結果は以下の通りでした。まだ課題がありますね。
