8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

nRF52によるBLE通信MTUサイズ上限の取得

Last updated at Posted at 2021-02-12

記事の概要

NordicのBLEモジュール nRF52を用いてMTUを取得させます。

MTUとは何か

BLEにおいて、セントラル機器とペリフェラル機器間ではBLE通信(NotifyやWrite)でパケットを送受信します。
このパケットの上限サイズがMTU(Maximum Transmission Unit)です。

MTUのサイズ

BLE 4.0においてMTUは20バイトです。
そして、BLE 4.2においてMTUは257バイトになりました。

ですが、これは飽くまでも規格値の上限であり、実際にはBLE接続機器の性能に依存して150バイト前後にまで下がります。

MTUのサイズを取得する

BLEモジュールがセントラル機器と接続する時、相手のMTUに合わせてパケット分割したい場合があります。

例えば、1000バイトのデータを送信したい時、今回BLE接続したiPhoneはMTUが100バイトだからパケットを10分割して、次にBLE接続したiPhoneはMTUが200バイトだからパケットを5分割する、といったように臨機応変にMTUサイズに合わせて通信したいことがあります。

ただし、MTUサイズを取得した際、オペコードに1バイト、ハンドルに2バイトを使用するので、通信データに使用できるのは、取得値から3バイトを引いた値になります。

MTU に基づいた最大パケットサイズ - KBA203312 - Community Translated (JA)

実装

Q&Aサイトの「negotiating-max-mtu-size」を参照して作成したコードの一部を以下に示します。

#define 	OPCODE_LENGTH   1 
#define 	HANDLE_LENGTH   2

static uint16_t mtu_max_size;

void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
{
    if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
    {
        mtu_max_size = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
    }
}


/**@brief Function for initializing the GATT module.
 */
static void gatt_init(void)
{
    ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); // UPDATE MTU HERE
    APP_ERROR_CHECK(err_code);
}

gatt_init()関数に割り込みハンドラーgatt_evt_handlerを設定します。

割り込みハンドラーでは、p_evt->params.att_mtu_effectiveによりBLE接続したCentral側のMTUを取得できます。
これからオペコードの1バイトとハンドル部の2バイトを引いた値が、1パケットに乗せられるデータサイズの上限になります。

最後にnrf_ble_gatt_att_mtu_periph_set()を実行することで、ペリフェラル側のMTUが更新されます。
ここでは、NRF_SDH_BLE_GATT_MAX_MTU_SIZEをsdk_config.hにおいて247に設定しています。

規格では257バイトなのに247バイトにしている理由は、Data channel PDU headerの2バイト、Data channel PDU MICの4バイト、Basic L2CAP PDU headerの4バイトを除いたのが、257-2-4-4=247バイトだからです。

詳細は以下をご覧ください。
https://devzone.nordicsemi.com/f/nordic-q-a/28640/maximum-att-mtu-for-ble-nus

これを実行すると、BLE接続するたびに、Central機器に依存して、mtu_max_sizeが20、138、152と様々な値に変動し、Central機器のMTUを知ることができます。

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?