基本のアドバタイズ
nRF SDKにはble_app_templateという基本的な設定とアドバタイズのみを行うプロジェクトが用意されていてそれをベースに組み立てていくことができたのですが、nRF connect SDKには同様のものが現時点(SDK 1.7.0)では存在していません。ただ、いくつかのサンプルプロジェクトには当然アドバタイズを使ったものがありますので、それを分解していきたいと思います。
まず、最低限のアドバタイズを行うためには以下のソースコードで実現できます。
main
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
# include <zephyr.h>
# include <sys/printk.h>
# include <bluetooth/bluetooth.h>
# define DEVICE_NAME CONFIG_BT_DEVICE_NAME
# define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
void main(void)
{
int err = 0;
err = bt_enable(NULL);
if (err) {
printk("Blutooth failed to start (err %d)\n", err);
}
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) {
printk("Advertising failed to start (err %d)\n", err);
}
}
prj.conf
# Use bluetooth
CONFIG_BT=y
CONFIG_BT_DEVICE_NAME="nRF connect SDK"
確認
コンパイルして実行した後にnRF connect for mobileで見てみるとちゃんとアドバタイズを拾えています。
BLEイベント
nRF SDKのサンプルプロジェクトにはBLEの各種イベントが発生したときに処理をする機能がありました。
nRF SDK時代のイベントハンドラ
/**@brief Function for handling BLE events.
*
* @param[in] p_ble_evt Bluetooth stack event.
* @param[in] p_context Unused.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code = NRF_SUCCESS;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
break;
case BLE_GAP_EVT_DISCONNECTED:
break;
・・・
}
}
nRF connect SDKのイベントハンドラ
同様の機能がもちろんnRF connect SDKにも用意されています。ただし、用意されているイベントにはいくつか変更があるようです。(未確認)
詳細についてはこちらを参照してください。
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
# include <zephyr.h>
# include <sys/printk.h>
# include <bluetooth/bluetooth.h>
# include <bluetooth/gatt.h>
# define DEVICE_NAME CONFIG_BT_DEVICE_NAME
# define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
static void connected(struct bt_conn *conn, uint8_t err)
{
printk("Connected\n");
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printk("Disconnected\n");
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
};
void main(void)
{
int err = 0;
err = bt_enable(NULL);
if (err) {
printk("Blutooth failed to start (err %d)\n", err);
}
bt_conn_cb_register(&conn_callbacks);
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) {
printk("Advertising failed to start (err %d)\n", err);
}
}
先ほどのソースコードにbt_conn_cb_register関数でコールバック関数を追加します。これで接続時と切断時にそれぞれメッセージが出るようになりました。
拡張アドバタイズ
Bluetooth 5からは拡張アドバタイズを使用できるようになりました。アドバタイズで送信できるデータ量が従来の31バイトから254バイトと大幅に増え、アドバタイズ時の情報量を増やすことができます。
ただ、nRF connect SDK 1.7.0時点では拡張アドバタイズ設定はExperimental扱いになっており、設定しても拡張アドバタイズを使用することはできません。まだまだnRF SDKの代わりには使えなさそうです。
SDKがアップデートされてちゃんと使えるようになったら更新したいと思います。