Hello!
I am programming BLE with the nRF52840-DK. [Toolchain Manager: v1.3.0, IDE: Visual Studio Code (VSCode), SDK: ncs v2.6.0, window11 pro]
I am using two nRF52840-DK devices to communicate via Bluetooth(NUS).
I am adding modifications to the NUS example to adjust PHY, data length, and connection parameters (connection interval, timeout, delay).
Since my search didn't resolve my questions, I decided to create a ticket.
<my questions>
1. Can you explain the conditions and situations under which the Discovery completed callback in the struct bt_gatt_dm_cb (in 'gatt_dm.h') is triggered?
2. In my central debugging, the le_param_updated
callback was triggered even though I didn't use 'bt_conn_le_param_update'. Additionally, I observed that the connection parameters were set to 'interval: 40, latency: 0, timeout: 42' despite setting them to 'BT_LE_CONN_PARAM(80, 80, 0, 400)'. I suspect this is due to 'connection interval negotiation'. Can you provide the cause and a solution for this issue?
[00:00:13.889,343] <inf> cho: CALLBACK - LE PHY updated: TX PHY LE 2M, RX PHY LE 2M
[00:00:14.289,794] <inf> cho: CALLBACK - Service discovery completed
[00:00:14.296,752] <inf> cho: discovery_complete - MTU exchange pending
[00:00:14.689,788] <inf> cho: CALLBACK - MTU exchange done
[00:00:17.889,770] <inf> cho: CALLBACK - Connection parameters updated. >> interval: 40, latency: 0, timeout: 42
< additional materials >
- Blow is 'main.c' of central_uart
#include <errno.h> #include <zephyr/kernel.h> #include <zephyr/bluetooth/conn.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/gatt.h> #include <zephyr/bluetooth/uuid.h> #include <bluetooth/scan.h> #include <bluetooth/gatt_dm.h> #include <bluetooth/services/nus.h> #include <bluetooth/services/nus_client.h> #include <zephyr/settings/settings.h> #include <zephyr/logging/log.h> #include <zephyr/settings/settings.h> #include <zephyr/sys/printk.h> #define LOG_MODULE_NAME cho LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG); static struct bt_conn *default_conn; static struct bt_nus_client nus_client; static struct bt_gatt_exchange_params exchange_params; #define INTERVAL_MIN 0x50 #define INTERVAL_MAX 0x50 static struct bt_le_conn_param *conn_param = BT_LE_CONN_PARAM(INTERVAL_MIN, INTERVAL_MAX, 0, 400); uint8_t data_from_central[16384]; int data_received_count = 0; uint64_t stamp; int64_t delta; static const char *phy2str(uint8_t phy){ switch (phy) { case 0: return "No packets"; case BT_GAP_LE_PHY_1M: return "LE 1M"; case BT_GAP_LE_PHY_2M: return "LE 2M"; case BT_GAP_LE_PHY_CODED: return "LE Coded"; default: return "Unknown"; } } /////////////////////////////////////////////////////////////////////////// static void ble_data_sent(struct bt_nus_client *nus, uint8_t err, const uint8_t *const data, uint16_t len){ LOG_INF("ble_data_sent"); } static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len){ ARG_UNUSED(nus); if(data_received_count == 0){ stamp = k_uptime_get_32(); } memcpy(&data_from_central[data_received_count * len], data, len); data_received_count++; if (data_received_count >= 60) { delta = k_uptime_delta(&stamp); LOG_INF("time: %llu ms", delta); bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); /* for (int i = 0; i < data_received_count * len; i++) { LOG_INF("data_from_central[%d]: %d ",i,data_from_central[i]); } */ LOG_INF("[local] sent %u bytes (%u KB) in %lld ms at %llu kbps", 244*60, 244 * 60 / 1024, delta, ((uint64_t)244 * 60 * 8 / delta)); data_received_count = 0; LOG_INF("\n"); } return BT_GATT_ITER_CONTINUE; } static int nus_client_init(void){ int err; struct bt_nus_client_init_param init = { .cb = { .received = ble_data_received, .sent = ble_data_sent, } }; err = bt_nus_client_init(&nus_client, &init); LOG_INF("bt_nus_client_init >>> err:%d", err); return err; } /////////////////////////////////////////////////////////////////////////// static void scan_filter_match(struct bt_scan_device_info *device_info, struct bt_scan_filter_match *filter_match, bool connectable){ char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr)); LOG_INF("Filters matched. Address: %s connectable: %d ", addr, connectable); } static void scan_connecting_error(struct bt_scan_device_info *device_info){ LOG_INF("Connecting failed"); } void scan_filter_no_match(struct bt_scan_device_info *device_info, bool connectable){ //char addr[BT_ADDR_LE_STR_LEN]; //bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr)); //LOG_INF("Filter not match. Address: %s connectable: %d", addr, connectable); } static void scan_connecting(struct bt_scan_device_info *device_info, struct bt_conn *conn){ default_conn = bt_conn_ref(conn); LOG_INF("<<< scan_connecting >>>>"); } BT_SCAN_CB_INIT(scan_cb, scan_filter_match, scan_filter_no_match, scan_connecting_error, scan_connecting); static int scan_init(void){ int err; struct bt_le_scan_param scan_param = { .type = 0x01, // 1: active, 0: passive .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = 0x0010, // 10ms .window = 0x0010, // 10ms }; struct bt_scan_init_param scan_init = { .connect_if_match = 1, .scan_param = &scan_param, //type, options, interval, window, timeout, interval_coded, window_coded; .conn_param = conn_param // interval_min, interval_max, latency, timeout }; bt_scan_init(&scan_init); bt_scan_cb_register(&scan_cb); err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE); err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false); return err; } ////////////////////////////////////////////////////////////////////////// static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout){ LOG_INF("CALLBACK - Connection parameters updated. >> interval: %d, latency: %d, timeout: %d", interval, latency, timeout); } static void le_data_length_updated(struct bt_conn *conn, struct bt_conn_le_data_len_info *info){ LOG_INF("CALLBACK - LE data len updated: TX (len: %d time: %d) RX (len: %d time: %d)", info->tx_max_len, info->tx_max_time, info->rx_max_len, info->rx_max_time); default_conn = bt_conn_ref(conn); } static void le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param){ LOG_INF("CALLBACK - LE PHY updated: TX PHY %s, RX PHY %s", phy2str(param->tx_phy), phy2str(param->rx_phy)); default_conn = bt_conn_ref(conn); } static void connected(struct bt_conn *conn, uint8_t conn_err){ char addr[BT_ADDR_LE_STR_LEN]; int err; struct bt_conn_info info = {0}; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if(conn_err){ LOG_INF("Failed to connect to %s (%d)", addr, conn_err); if (default_conn == conn) { bt_conn_unref(default_conn); default_conn = NULL; err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); LOG_INF("Scanning failed to start (err %d)",err); } return; } default_conn = bt_conn_ref(conn); err = bt_conn_get_info(conn, &info); LOG_INF("connected - GET_INFO >>> err:%d", err); LOG_INF("connected - Connected as %s", info.role == BT_CONN_ROLE_CENTRAL ? "central" : "peripheral"); LOG_INF("connected - Conn. interval is %u units", info.le.interval); err = bt_conn_set_security(conn, BT_SECURITY_L2); LOG_INF("connected - Set_Security >>> err:%d", err); err = bt_conn_le_phy_update(conn, BT_CONN_LE_PHY_PARAM_2M); LOG_INF("connected - PHY >>> err:%d", err); err = bt_conn_le_data_len_update(conn, BT_LE_DATA_LEN_PARAM_MAX); LOG_INF("connected - data_length >>> err:%d", err); err = bt_scan_stop(); // success: 0 or -120 LOG_INF("connected - SCAN_STOP (err %d)", err); err = bt_conn_get_info(conn, &info); LOG_INF("connected - GET_INFO >>> err:%d", err); LOG_INF("connected - Conn. interval is %u units", info.le.interval); } static void disconnected(struct bt_conn *conn, uint8_t reason){ char addr[BT_ADDR_LE_STR_LEN]; int err; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("disconnected"); if (default_conn != conn) { return; } bt_conn_unref(default_conn); default_conn = NULL; err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); LOG_INF("bt_scan_restart: %d",err); } static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params){ if (!err) { LOG_INF("CALLBACK - MTU exchange done"); } else { LOG_INF("CALLBACK - MTU exchange failed >>> err : PRIu8 ", err); } } static void discovery_complete(struct bt_gatt_dm *dm, void *context){ int err; struct bt_nus_client *nus = context; LOG_INF("CALLBACK - Service discovery completed"); bt_gatt_dm_data_print(dm); bt_nus_handles_assign(dm, nus); bt_nus_subscribe_receive(nus); bt_gatt_dm_data_release(dm); exchange_params.func = exchange_func; err = bt_gatt_exchange_mtu(default_conn, &exchange_params); if (err) { LOG_INF("discovery_complete - MTU exchange failed (err %d)", err); } else { LOG_INF("discovery_complete - MTU exchange pending");} } static void discovery_service_not_found(struct bt_conn *conn, void *context){ LOG_INF("CALLBACK - Service not found"); } static void discovery_error(struct bt_conn *conn, int err, void *context){ LOG_INF("CALLBACK - Error while discovering GATT database: (%d)", err); } struct bt_gatt_dm_cb discovery_cb = { .completed = discovery_complete, .service_not_found = discovery_service_not_found, .error_found = discovery_error, }; static void gatt_discover(struct bt_conn *conn){ int err; if (conn != default_conn) { return; } err = bt_gatt_dm_start(conn, BT_UUID_NUS_SERVICE, &discovery_cb, &nus_client); LOG_INF("gatt_discover - GATT_dm_start: %d", err); } static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err){ if (!err) { LOG_INF("CALLBACK - Security level changed: %u", level); } else { LOG_INF("CALLBACK - Security change failed: %d", err); } gatt_discover(conn); } static struct bt_conn_cb conn_callbacks = { .connected = connected, .disconnected = disconnected, .security_changed = security_changed, .le_param_updated = le_param_updated, .le_data_len_updated = le_data_length_updated, .le_phy_updated = le_phy_updated, }; static void pairing_complete(struct bt_conn *conn, bool bonded){ char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("CALLBACK - Pairing completed: %s, bonded: %d", addr, bonded); } static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason){ char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("CALLBACK - Pairing failed conn: %s, reason %d", addr, reason); } static struct bt_conn_auth_info_cb conn_auth_info_callbacks = { .pairing_complete = pairing_complete, .pairing_failed = pairing_failed }; int main(void){ int main_err; LOG_INF("cho >> 240711_central //////////////////////////////////////////////////////"); bt_conn_cb_register(&conn_callbacks); main_err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks); main_err = bt_enable(NULL); //LOG_INF("bt_enable: %d",main_err); if (IS_ENABLED(CONFIG_SETTINGS)) { settings_load(); } scan_init(); nus_client_init(); bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); for (;;) { k_sleep(K_MSEC(1000)); } return 0; }
- Blow is 'prj.conf' of central_uart
# UART and Console Settings
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
# System and Memory Settings
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=1536
# Bluetooth Settings Storage
CONFIG_BT_SETTINGS=y
# Flash and Non-Volatile Storage (NVS) Settings
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y
# Logging Settings
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=n
CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_PRINTK=y
CONFIG_LOG_MODE_IMMEDIATE=y
#CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
CONFIG_ASSERT=y
# Bluetooth Basic Settings
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
# Pre-connection settings
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_SCAN_NAME_CNT=5
CONFIG_BT_SCAN_NAME_MAX_LEN=20
# Post-connection settings
CONFIG_BT_SMP=y
CONFIG_BT_GATT_DM=y
CONFIG_BT_NUS_CLIENT=y
CONFIG_BT_GATT_CLIENT=y
# Bluetooth Memory and Buffer Settings
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_CONN_TX_MAX=10
CONFIG_BT_L2CAP_TX_BUF_COUNT=10
CONFIG_BT_BUF_ACL_TX_COUNT=10
# Bluetooth Physical Layer (PHY) Settings
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_CTLR_PHY_2M=y
# Bluetooth Data Length Settings
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
# Bluetooth Maximum Transmission Unit (MTU) Settings
CONFIG_BT_L2CAP_TX_MTU=247
- Blow is 'debugging' of central_uart
*** Booting nRF Connect SDK v3.5.99-ncs1 ***
[00:00:00.004,486] <inf> cho: cho >> 240711_central //////////////////////////////////////////////////////
[00:00:00.022,277] <inf> fs_nvs: 8 Sectors of 4096 bytes
[00:00:00.027,954] <inf> fs_nvs: alloc wra: 0, f90
[00:00:00.033,142] <inf> fs_nvs: data wra: 0, 9c
[00:00:00.038,360] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision:
36 f0 e5 0e 87 68 48 fb 02 fd 9f 82 cc 32 e5 7b |6....hH. .....2.{
91 b1 5c ed |..\.
[00:00:00.068,756] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.076,538] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:00:00.083,038] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 54.58864 Build 1214809870
[00:00:00.094,818] <inf> bt_hci_core: No ID address. App must call settings_load()
[00:00:00.103,424] <inf> bt_hci_core: Identity: C2:82:F6:94:03:85 (random)
[00:00:00.110,687] <inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x118f, manufacturer 0x0059
[00:00:00.120,056] <inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0x118f
[00:00:00.128,570] <inf> cho: bt_nus_client_init >>> err:0
[00:00:12.078,948] <inf> cho: Filters matched. Address: EE:3E:4D:30:14:7D (random) connectable: 0
[00:00:12.089,385] <inf> cho: <<< scan_connecting >>>>
[00:00:12.188,415] <inf> cho: connected - GET_INFO >>> err:0
[00:00:12.194,580] <inf> cho: connected - Connected as central
[00:00:12.200,805] <inf> cho: connected - Conn. interval is 80 units
[00:00:12.207,824] <inf> cho: connected - Set_Security >>> err:0
[00:00:12.214,508] <inf> cho: connected - PHY >>> err:0
[00:00:12.220,397] <inf> cho: connected - data_length >>> err:0
[00:00:12.226,684] <inf> cho: connected - SCAN_STOP (err -120)
[00:00:12.232,940] <inf> cho: connected - GET_INFO >>> err:0
[00:00:12.239,013] <inf> cho: connected - Conn. interval is 80 units
[00:00:12.489,959] <err> bt_smp: pairing failed (peer reason 0x3)
[00:00:12.496,826] <inf> cho: CALLBACK - Security change failed: 4
[00:00:12.503,448] <inf> cho: gatt_discover - GATT_dm_start: 0
[00:00:12.509,735] <inf> cho: CALLBACK - Pairing failed conn: EE:3E:4D:30:14:7D (random), reason 4
[00:00:12.889,923] <inf> cho: CALLBACK - LE data len updated: TX (len: 251 time: 2120) RX (len: 251 time: 2120)
[00:00:13.889,343] <inf> cho: CALLBACK - LE PHY updated: TX PHY LE 2M, RX PHY LE 2M
[00:00:14.289,794] <inf> cho: CALLBACK - Service discovery completed
[00:00:14.296,752] <inf> cho: discovery_complete - MTU exchange pending
[00:00:14.689,788] <inf> cho: CALLBACK - MTU exchange done
[00:00:17.889,770] <inf> cho: CALLBACK - Connection parameters updated. >> interval: 40, latency: 0, timeout: 42
[00:00:19.025,604] <inf> cho: time: 85 ms
[00:00:19.030,639] <inf> cho: [local] sent 14640 bytes (14 KB) in 85 ms at 1377 kbps
[00:00:19.038,757] <inf> cho:
[00:00:19.091,156] <inf> cho: disconnected
[00:00:19.096,618] <inf> cho: bt_scan_restart: 0
- Blow is 'main.c' of peripheral_uart
#include <bluetooth/services/nus.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/settings/settings.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/printk.h>
#define STACKSIZE CONFIG_BT_NUS_THREAD_STACK_SIZE
#define PRIORITY 7
#define LOG_MODULE_NAME cho
LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG);
#define DEVICE_NAME "SEONGMIN"
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
#define MTU_SIZE 244
uint8_t data_to_central[MTU_SIZE][2];
static struct bt_conn *current_conn;
//static K_SEM_DEFINE(ble_init_ok, 0, 1);
static K_SEM_DEFINE(disconnect_sem, 0, 1);
static K_SEM_DEFINE(param_ok, 0, 1);
static K_SEM_DEFINE(data_length_ok, 0, 1);
static K_SEM_DEFINE(phy_ok, 0, 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 const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
};
static const char *phy2str(uint8_t phy){
switch (phy) {
case 0: return "No packets";
case BT_GAP_LE_PHY_1M: return "LE 1M";
case BT_GAP_LE_PHY_2M: return "LE 2M";
case BT_GAP_LE_PHY_CODED: return "LE Coded";
default: return "Unknown";
}
}
static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data, uint16_t len)
{
char addr[BT_ADDR_LE_STR_LEN] = {0};
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, ARRAY_SIZE(addr));
LOG_INF("Received data from: %s", addr);
/*
DATA PROCESS STEP
*/
}
static void bt_sent_cb(struct bt_conn *conn){
LOG_INF("bt_sent_cb");
}
static struct bt_nus_cb nus_cb = {
.received = bt_receive_cb,
//.sent = bt_sent_cb,
};
///////////////////////////////////////////////////////////////////////////////////
static void pairing_complete(struct bt_conn *conn, bool bonded){
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("CALLBACK - Pairing completed: %s, bonded: %d", addr, bonded);
}
static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason){
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("CALLBACK - Pairing failed conn: %s, reason %d", addr, reason);
}
static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
.pairing_complete = pairing_complete,
.pairing_failed = pairing_failed
};
//////////////////////////////////////////////////////////////////////////////////
static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout){
LOG_INF("CALLBACK - Connection parameters updated. >> interval: %d, latency: %d, timeout: %d", interval, latency, timeout);
k_sem_give(¶m_ok);
}
static void le_data_length_updated(struct bt_conn *conn, struct bt_conn_le_data_len_info *info){
LOG_INF("CALLBACK - len updated: TX (len: %d time: %d) RX (len: %d time: %d)", info->tx_max_len, info->tx_max_time, info->rx_max_len, info->rx_max_time);
k_sem_give(&data_length_ok);
}
static void le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param){
LOG_INF("CALLBACK - TX PHY %s, RX PHY %s", phy2str(param->tx_phy), phy2str(param->rx_phy));
k_sem_give(&phy_ok);
}
static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err){
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("CALLBACK - security_changed: %s, level: %u, err: %d", addr, level, err);
}
static void disconnected(struct bt_conn *conn, uint8_t reason){
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("CALLBACK - Disconnected: %s (reason %u)", addr, reason);
k_sem_give(&disconnect_sem);
}
static void connected(struct bt_conn *conn, uint8_t err){
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (err) {
LOG_INF("connected - connected: Connection failed (err %u)", err);
return;
}
LOG_INF("connected - Connected %s", addr);
current_conn = bt_conn_ref(conn);
struct bt_conn_info info = {0};
err = bt_conn_get_info(conn, &info);
LOG_INF("connected - bt_conn_get_info >>> err:%d", err);
LOG_INF("connected - Connected as %s", info.role == BT_CONN_ROLE_CENTRAL ? "central" : "peripheral");
LOG_INF("connected - Conn. interval is %u units", info.le.interval);
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
.security_changed = security_changed,
.le_param_updated = le_param_updated,
.le_data_len_updated = le_data_length_updated,
.le_phy_updated = le_phy_updated,
};
int main(void){
int err;
for(int x=0; x<MTU_SIZE; x++){
data_to_central[x][0] = x;
data_to_central[x][1] = x;
}
LOG_INF("cho >> 240712_peripheral //////////////////////////////////////////////////////");
bt_conn_cb_register(&conn_callbacks);
err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
err = bt_enable(NULL);
LOG_INF("bt_enable: %d",err);
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
err = bt_nus_init(&nus_cb); //LOG_INF("bt_nus_init: %d",err);
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
LOG_INF("bt_le_adv_start: %d",err);
while(1){ k_sleep(K_MSEC(1000)); }
return 0;
}
void ble_write_thread(void){
int ret;
k_sem_take(¶m_ok, K_FOREVER);
k_sem_take(&data_length_ok, K_FOREVER);
k_sem_take(&phy_ok, K_FOREVER);
k_sleep(K_MSEC(1000));
LOG_INF("Starting BLE Write Thread");
while (1) {
ret = bt_nus_send(current_conn, data_to_central, MTU_SIZE);
if (k_sem_take(&disconnect_sem, K_NO_WAIT) == 0) {
LOG_INF("Disconnected, exiting BLE Write Thread");
return;
}
}
}
K_THREAD_DEFINE(ble_write_thread_id, 1024, ble_write_thread, NULL, NULL, NULL, PRIORITY, 0, 0);
- Blow is 'prj.conf' of peripheral_uart
# UART and Console Settings
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
# Flash and Non-Volatile Storage (NVS) Settings
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y
# System and Memory Settings
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=1536
# Logging Settings
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=n
CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_PRINTK=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_ASSERT=y
# Bluetooth Settings Storage
CONFIG_BT_SETTINGS=y
# Bluetooth Basic Settings
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="SEONGMIN"
CONFIG_BT_NUS=y
CONFIG_BT_SMP=y
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1
#CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
# Bluetooth Memory and Buffer Settings
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_CONN_TX_MAX=10
CONFIG_BT_L2CAP_TX_BUF_COUNT=10
CONFIG_BT_BUF_ACL_TX_COUNT=10
# Bluetooth Physical Layer (PHY) Settings
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_CTLR_PHY_2M=y
# Bluetooth Data Length Settings
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
# Bluetooth Maximum Transmission Unit (MTU) Settings
CONFIG_BT_L2CAP_TX_MTU=247
- Blow is 'debugging' of peripheral_uart
*** Booting nRF Connect SDK v3.5.99-ncs1 ***
[00:00:00.004,486] <inf> cho: cho >> 240712_peripheral //////////////////////////////////////////////////////
[00:00:00.021,362] <inf> fs_nvs: 8 Sectors of 4096 bytes
[00:00:00.027,008] <inf> fs_nvs: alloc wra: 0, f30
[00:00:00.032,196] <inf> fs_nvs: data wra: 0, 184
[00:00:00.037,475] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision:
36 f0 e5 0e 87 68 48 fb 02 fd 9f 82 cc 32 e5 7b |6....hH. .....2.{
91 b1 5c ed |..\.
[00:00:00.067,687] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.075,408] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:00:00.081,909] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 54.58864 Build 1214809870
[00:00:00.093,597] <inf> bt_hci_core: No ID address. App must call settings_load()
[00:00:00.101,501] <inf> cho: bt_enable: 0
[00:00:00.107,208] <inf> bt_hci_core: Identity: EE:3E:4D:30:14:7D (random)
[00:00:00.114,440] <inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x118f, manufacturer 0x0059
[00:00:00.123,748] <inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0x118f
[00:00:00.134,613] <inf> cho: bt_le_adv_start: 0
[00:00:00.257,202] <inf> cho: connected - Connected C2:82:F6:94:03:85 (random)
[00:00:00.264,831] <inf> cho: connected - bt_conn_get_info >>> err:0
[00:00:00.271,545] <inf> cho: connected - Connected as peripheral
[00:00:00.278,045] <inf> cho: connected - Conn. interval is 80 units
[00:00:00.357,788] <inf> cho: CALLBACK - security_changed: C2:82:F6:94:03:85 (random), level: 1, err: 4
[00:00:00.367,645] <inf> cho: CALLBACK - Pairing failed conn: C2:82:F6:94:03:85 (random), reason 4
[00:00:00.857,940] <inf> cho: CALLBACK - len updated: TX (len: 251 time: 2120) RX (len: 251 time: 2120)
[00:00:01.957,092] <inf> cho: CALLBACK - TX PHY LE 2M, RX PHY LE 2M
[00:00:05.957,550] <inf> cho: CALLBACK - Connection parameters updated. >> interval: 40, latency: 0, timeout: 42
[00:00:06.968,170] <inf> cho: Starting BLE Write Thread
[00:00:07.159,149] <inf> cho: CALLBACK - Disconnected: C2:82:F6:94:03:85 (random) (reason 19)