After Input passkey, Pairing Completing is so late(nRF54L15)

Hello,

Im trying to security connecting but i'm getting this bug.

After auth_passkey_display(), Next step is so late(more then 3min).

Tool : VS code

SDK : nRF Connect SDK v2.8.0

Board : AN54L15Q-DB(nRF54L15)

4784.prj.conf

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/** @file
 *  @brief Nordic UART Bridge Service (NUS) sample
 */
#include <uart_async_adapter.h>

#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/usb/usb_device.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <soc.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>

#include <bluetooth/services/nus.h>

#include <dk_buttons_and_leds.h>

#include <zephyr/settings/settings.h>

#include <stdio.h>
#include <string.h>

#include <zephyr/logging/log.h>

/*BMS*/
#include <bluetooth/services/bms.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/bluetooth/conn.h>

/*Random Number Generate*/
#include <zephyr/syscalls/random.h>

static uint16_t crc_16_table[] = {
    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
};

#define LOG_MODULE_NAME peripheral_uart 
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#define STACKSIZE CONFIG_BT_NUS_THREAD_STACK_SIZE
#define PRIORITY 7

#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN	(sizeof(DEVICE_NAME) - 1)

/*Test Btn*/
#define PAIRING_BUTTON             DK_BTN3_MSK
#define BOND_DELETE_BUTTON         DK_BTN2_MSK

#define RUN_STATUS_LED DK_LED1
#define RUN_LED_BLINK_INTERVAL 1000

#define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
#define KEY_PASSKEY_REJECT DK_BTN2_MSK

#define UART_BUF_SIZE CONFIG_BT_NUS_UART_BUFFER_SIZE
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
#define UART_WAIT_FOR_RX CONFIG_BT_NUS_UART_RX_WAIT_TIME

static K_SEM_DEFINE(ble_init_ok, 0, 1);

static struct bt_conn *current_conn;
static struct bt_conn *auth_conn;
static struct bt_conn *my_conn;

static const struct device *uart = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uart));
static struct k_work_delayable uart_work;

struct uart_data_t {
	void *fifo_reserved;
	uint8_t data[UART_BUF_SIZE];
	uint16_t len;
};

static K_FIFO_DEFINE(fifo_uart_tx_data);
static K_FIFO_DEFINE(fifo_uart_rx_data);

static const uint8_t bms_auth_code[] = {'A', 'B', 'C', 'D'};

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 bool connectFlag = false;
static uint8_t uartIndex = 0;
static bool uartFlag = false;
static uint8_t uartBuffer[256];
static int uartState = 0;

static uint8_t backupLength = 0;
static uint8_t backupBuffer[256];

static uint8_t copyIndex = 0;
static uint8_t copyBuffer[256];

static uint8_t uart_packet[20];
static uint8_t uart_passkey[6];

static uint8_t ble_buffer[20];

static int responseState = 0;

uint8_t LO_crc;
uint8_t HI_crc;

static bool parsingFlag = false;

#ifdef CONFIG_UART_ASYNC_ADAPTER
UART_ASYNC_ADAPTER_INST_DEFINE(async_adapter);
#else
#define async_adapter NULL
#endif

/*white list*/
#define BT_LE_ADV_CONN_ACCEPT_LIST BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE|BT_LE_ADV_OPT_FILTER_CONN|BT_LE_ADV_OPT_ONE_TIME, \
	BT_GAP_ADV_FAST_INT_MIN_2, \
	BT_GAP_ADV_FAST_INT_MAX_2, NULL)

#define BT_LE_ADV_CONN_NO_ACCEPT_LIST  BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, \
	BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL)

uint16_t crc16_modbus(uint16_t init_crc, uint8_t* dat, uint16_t len) {
	uint8_t crc[2];
	uint16_t tmp;
	crc[0] = init_crc >> 8;
	crc[1] = init_crc & 0xFF;
	for (uint16_t i = 0; i < len; i++) {
		tmp = crc_16_table[crc[0] ^ dat[i]];
		crc[0] = (tmp & 0xFF) ^ crc[1];
		crc[1] = tmp >> 8;
	}

	LO_crc = crc[0];
	HI_crc = crc[1];
}

static unsigned int random_Generate(void)
{
	
	unsigned int result = 0;
	uint8_t temp;
	uint8_t cal_num[6];

	for(int i=0; i<6; i++){
		sys_rand_get(&temp, sizeof(temp));
		cal_num[i] = temp;
		cal_num[i] %= 10;
	}

	while(cal_num[0] <= 0)
	{
		sys_rand_get(&temp, sizeof(temp));
		cal_num[0] = temp;
		cal_num[0] %= 10;
	}

	result = cal_num[5] + (cal_num[4]*10) + (cal_num[3]*100) + (cal_num[2]*1000) + (cal_num[1]*10000) + (cal_num[0]*100000);
	
	for(int j=0; j<6; j++){
		uart_passkey[j] = cal_num[j];
	}

	return result;
}

static void response_send(void)
{
	switch(responseState)
	{
		case 1:
			unsigned int passkey = random_Generate();
			bt_passkey_set(passkey);

			LOG_INF("Passkey Changed : %06u", passkey);

			uart_packet[0] = 0x02;
			uart_packet[1] = 0xAA;
			uart_packet[2] = 0x07;
			uart_packet[3] = 0xA2;
			
			uart_packet[4] = uart_passkey[0];
			uart_packet[5] = uart_passkey[1];
			uart_packet[6] = uart_passkey[2];
			uart_packet[7] = uart_passkey[3];
			uart_packet[8] = uart_passkey[4];
			uart_packet[9] = uart_passkey[5];

			crc16_modbus(0xFFFF, uart_packet, 10);

			uart_packet[10] = LO_crc;
			uart_packet[11] = HI_crc;
			uart_packet[12] = 0x03;
			
			for(int i=0; i<13; i++){
				uart_poll_out(uart, uart_packet[i]);
			}	
			// uart_tx(uart, uart_packet, 13, SYS_FOREVER_MS);
			responseState = 0;
	
			break;
		case 2:
			uart_packet[0] = 0x02;
			uart_packet[1] = 0xAB;
			uart_packet[2] = 0x01;
			uart_packet[3] = 0x01;
			
			crc16_modbus(0xFFFF, uart_packet, 4);

			uart_packet[4] = LO_crc;
			uart_packet[5] = HI_crc;
			uart_packet[6] = 0x03;
			
			for(int i=0; i<7; i++){
				uart_poll_out(uart, uart_packet[i]);
			}	

			// uart_tx(uart, uart_packet, 7, SYS_FOREVER_MS);
			responseState = 0;

			break;
		case 3:
			uart_packet[0] = 0x02;
			uart_packet[1] = 0xAB;
			uart_packet[2] = 0x01;
			uart_packet[3] = 0x00;
			
			crc16_modbus(0xFFFF, uart_packet, 4);

			uart_packet[4] = LO_crc;
			uart_packet[5] = HI_crc;
			uart_packet[6] = 0x03;

			for(int i=0; i<7; i++){
				uart_poll_out(uart, uart_packet[i]);
			}	

			// uart_tx(uart, uart_packet, 7, SYS_FOREVER_MS);
			responseState = 0;

			break;
		case 4:
			ble_buffer[0] = 0x02;
			ble_buffer[1] = 0xCB;
			ble_buffer[2] = 0x02;
			ble_buffer[3] = 0x03;
			ble_buffer[4] = 0xF0;

			crc16_modbus(0xFFFF, ble_buffer, 5);

			ble_buffer[5] = LO_crc;
			ble_buffer[6] = HI_crc;
			ble_buffer[7] = 0x03;

			
			if(connectFlag == true){
				bt_nus_send(NULL, ble_buffer, 8);
			}
			responseState = 0;
			break;

		case 5:
			ble_buffer[0] = 0x02;
			ble_buffer[1] = 0xCB;
			ble_buffer[2] = 0x02;
			ble_buffer[3] = 0x04;
			ble_buffer[4] = 0xF0;

			crc16_modbus(0xFFFF, ble_buffer, 5);

			ble_buffer[5] = LO_crc;
			ble_buffer[6] = HI_crc;
			ble_buffer[7] = 0x03;

			if(connectFlag == true){
				bt_nus_send(NULL, ble_buffer, 8);
			}
			responseState = 0;
			break;
		case 6:
			uart_packet[0] = 0x02;
			uart_packet[1] = 0xAB;
			uart_packet[2] = 0x01;
			uart_packet[3] = 0x05;
			
			crc16_modbus(0xFFFF, uart_packet, 4);

			uart_packet[4] = LO_crc;
			uart_packet[5] = HI_crc;
			uart_packet[6] = 0x03;
			
			for(int i=0; i<7; i++){
				uart_poll_out(uart, uart_packet[i]);
			}	
			responseState = 0;

			break;
		case 10:
			if(connectFlag == true){
				bt_nus_send(NULL, copyBuffer, copyIndex);
			
				for (int i=0; i<copyIndex; i++)
				{
					copyBuffer[i] = 0x00;
				}
				copyIndex = 0;
			}
			responseState = 0;
		default:
			break;
	}
}

void parsingTask(void)
{
	if(parsingFlag == true){
		for(int i=0; i<backupLength; i++){
 			uart_poll_out(uart, backupBuffer[i]);
		}	

		backupLength = 0;
		parsingFlag = false;
	}
	if(uartFlag == true){  
		if (uartBuffer[0] == 0x02 && uartBuffer[uartBuffer[2]+5] == 0x03){
				
			crc16_modbus(0xFFFF, uartBuffer, ((int)uartBuffer[2])+3);

			if(LO_crc == uartBuffer[((int)uartBuffer[2])+3] && HI_crc == uartBuffer[((int)uartBuffer[2])+4]){
				if(uartBuffer[1] == 0xAA){
					if(uartBuffer[4] == 0x00){
						uartState = 1;
					}
					else if(uartBuffer[4] == 0x02){
						uartState = 4;
					}
				}
				else{
					if(connectFlag == true){
						for (int i=0; i<uartIndex-2; i++){
							copyBuffer[i] = uartBuffer[i];
						}
						copyIndex = uartIndex;
				
						responseState = 10;
					}
				}
			}
		}
		uartFlag = false;
	}
}

static void setup_accept_list_cb(const struct bt_bond_info *info, void *user_data)
{
	int *bond_cnt = user_data;
	if ((*bond_cnt) < 0) {
		return;
	}
	int err = bt_le_filter_accept_list_add(&info->addr);
	LOG_DBG("Added following peer to whitelist: %x %x \n",info->addr.a.val[0],info->addr.a.val[1]);
	if (err) {
		LOG_DBG("Cannot add peer to Filter Accept List (err: %d)\n", err);
		(*bond_cnt) = -EIO;
	} else {
		(*bond_cnt)++;
	}
}

static int setup_accept_list(uint8_t local_id)
{
	int err = bt_le_filter_accept_list_clear();
	if (err) {
		LOG_DBG("Cannot clear Filter Accept List (err: %d)\n", err);
		return err;
	}
	int bond_cnt = 0;
	bt_foreach_bond(local_id, setup_accept_list_cb, &bond_cnt);
	return bond_cnt;
}

void advertise_with_acceptlist(struct k_work *work)
{
	int err=0;
	int allowed_cnt= setup_accept_list(BT_ID_DEFAULT);
	if (allowed_cnt<0){
		LOG_DBG("Acceptlist setup failed (err:%d)\n", allowed_cnt);
	} else {
		if (allowed_cnt==0){
			LOG_DBG("Advertising with no Filter Accept list\n"); 
			err = bt_le_adv_start(BT_LE_ADV_CONN_NO_ACCEPT_LIST, ad, ARRAY_SIZE(ad),
					sd, ARRAY_SIZE(sd));
		}
		else {
			LOG_DBG("Acceptlist setup number  = %d \n",allowed_cnt);
			err = bt_le_adv_start(BT_LE_ADV_CONN_ACCEPT_LIST, ad, ARRAY_SIZE(ad),
				sd, ARRAY_SIZE(sd));	
		}
		if (err) {
			LOG_DBG("Advertising failed to start (err %d)\n", err);
			return;
		}
		LOG_DBG("Advertising successfully started\n");
	}
}

static void delete_bond(void)
{
	int err= bt_unpair(BT_ID_DEFAULT,BT_ADDR_LE_ANY);
	if (err) {
		LOG_DBG("Cannot delete bond (err: %d)\n", err);
	} else	{
		LOG_DBG("Bond deleted succesfully \n");
	}				
	bt_le_adv_stop();

}

static void pairing_mode(void)
{
	int err_code = bt_le_adv_stop();
	if (err_code) {
		LOG_DBG("Cannot stop advertising err= %d \n", err_code);
		return;
	}				
	err_code = bt_le_adv_start(BT_LE_ADV_CONN_NO_ACCEPT_LIST, ad, ARRAY_SIZE(ad),	sd, ARRAY_SIZE(sd));
	if (err_code) {
		LOG_DBG("Cannot start open advertising (err: %d)\n", err_code);
	} else	{
		LOG_DBG("Advertising in pairing mode started");
	}
}

static void update_phy(struct bt_conn *conn)
{
    int err;
    const struct bt_conn_le_phy_param preferred_phy = {
        .options = BT_CONN_LE_PHY_OPT_NONE,
        .pref_rx_phy = BT_GAP_LE_PHY_1M,
        .pref_tx_phy = BT_GAP_LE_PHY_1M,
    };
    err = bt_conn_le_phy_update(conn, &preferred_phy);
    if (err) {
        LOG_ERR("bt_conn_le_phy_update() returned %d", err);
    }
}


static void uart_state_handler(void)
{    
    switch(uartState)
    {
        case 1: // Nomal Adv
			pairing_mode();
            responseState = 1;
            uartState = 0;
            break;
        case 2: // Adv with Whitelist
			uartState = 0;
            break;
        case 3: // Adv Stop
			int err_code = bt_le_adv_stop();
			if (err_code) {
				LOG_DBG("Cannot stop advertising err= %d \n", err_code);
				return;
			}	
            responseState = 2;
            uartState = 0;
            break;
        case 4: // bond & whitelist clear
			delete_bond();
            responseState = 2;
            uartState = 0;
            break;
        default:
            break;
    }

} 

static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	ARG_UNUSED(dev);

	static size_t aborted_len;
	struct uart_data_t *buf;
	static uint8_t *aborted_buf;
	static bool disable_req;

	switch (evt->type) {
	case UART_TX_DONE:
		LOG_DBG("UART_TX_DONE");
		if ((evt->data.tx.len == 0) ||
		    (!evt->data.tx.buf)) {
			return;
		}

		if (aborted_buf) {
			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
					   data[0]);
			aborted_buf = NULL;
			aborted_len = 0;
		} else {
			buf = CONTAINER_OF(evt->data.tx.buf, struct uart_data_t,
					   data[0]);
		}

		k_free(buf);

		buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
		if (!buf) {
			return;
		}
		
		for(int i=0; i<buf->len; i++){
			uart_poll_out(uart, buf->data[i]);
		}	
		break;

	case UART_RX_RDY:
		LOG_DBG("UART_RX_RDY");
		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data[0]);
		buf->len += evt->data.rx.len;

		if (disable_req) {
			return;
		}

		if ((evt->data.rx.buf[0] == 0x02) && (evt->data.rx.buf[buf->len - 1] == 0x03) && (evt->data.rx.buf[2]+6 == buf->len))
		{
			memcpy(uartBuffer, evt->data.rx.buf, buf->len);
			uartIndex = buf->len;
			uartFlag = true;

			disable_req = true;
			uart_rx_disable(uart);
		}
		break;

	case UART_RX_DISABLED:
		LOG_DBG("UART_RX_DISABLED");
		disable_req = false;

		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf->len = 0;
		} else {
			LOG_WRN("Not able to allocate UART receive buffer");
			k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
			return;
		}

		uart_rx_enable(uart, buf->data, sizeof(buf->data),
			       UART_WAIT_FOR_RX);

		break;

	case UART_RX_BUF_REQUEST:
		LOG_DBG("UART_RX_BUF_REQUEST");
		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf->len = 0;
			uart_rx_buf_rsp(uart, buf->data, sizeof(buf->data));
		} else {
			LOG_WRN("Not able to allocate UART receive buffer");
		}

		break;

	case UART_RX_BUF_RELEASED:
		LOG_DBG("UART_RX_BUF_RELEASED");
		buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
				   data[0]);

		if (buf->len > 0) {
			k_fifo_put(&fifo_uart_rx_data, buf);
		} else {
			k_free(buf);
		}

		break;

	case UART_TX_ABORTED:
		LOG_DBG("UART_TX_ABORTED");
		if (!aborted_buf) {
			aborted_buf = (uint8_t *)evt->data.tx.buf;
		}

		aborted_len += evt->data.tx.len;
		buf = CONTAINER_OF((void *)aborted_buf, struct uart_data_t,
				   data);

		for(int i=0; i<buf->len-aborted_len; i++){
			uart_poll_out(uart, buf->data[aborted_len+i]);
		}	
		break;

	default:
		break;
	}
}

static void uart_work_handler(struct k_work *item)
{
	struct uart_data_t *buf;

	buf = k_malloc(sizeof(*buf));
	if (buf) {
		buf->len = 0;
	} else {
		LOG_WRN("Not able to allocate UART receive buffer");
		k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
		return;
	}

	uart_rx_enable(uart, buf->data, sizeof(buf->data), UART_WAIT_FOR_RX);
}

static bool uart_test_async_api(const struct device *dev)
{
	const struct uart_driver_api *api =
			(const struct uart_driver_api *)dev->api;

	return (api->callback_set != NULL);
}

static int uart_init(void)
{
	int err;
	int pos;
	struct uart_data_t *rx;
	struct uart_data_t *tx;

	if (!device_is_ready(uart)) {
		return -ENODEV;
	}

	if (IS_ENABLED(CONFIG_USB_DEVICE_STACK)) {
		err = usb_enable(NULL);
		if (err && (err != -EALREADY)) {
			LOG_ERR("Failed to enable USB");
			return err;
		}
	}

	rx = k_malloc(sizeof(*rx));
	if (rx) {
		rx->len = 0;
	} else {
		return -ENOMEM;
	}

	k_work_init_delayable(&uart_work, uart_work_handler);


	if (IS_ENABLED(CONFIG_UART_ASYNC_ADAPTER) && !uart_test_async_api(uart)) {
		/* Implement API adapter */
		uart_async_adapter_init(async_adapter, uart);
		uart = async_adapter;
	}

	err = uart_callback_set(uart, uart_cb, NULL);
	if (err) {
		k_free(rx);
		LOG_ERR("Cannot initialize UART callback");
		return err;
	}

	if (IS_ENABLED(CONFIG_UART_LINE_CTRL)) {
		LOG_INF("Wait for DTR");
		while (true) {
			uint32_t dtr = 0;

			uart_line_ctrl_get(uart, UART_LINE_CTRL_DTR, &dtr);
			if (dtr) {
				break;
			}
			/* Give CPU resources to low priority threads. */
			k_sleep(K_MSEC(100));
		}
		LOG_INF("DTR set");
		err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DCD, 1);
		if (err) {
			LOG_WRN("Failed to set DCD, ret code %d", err);
		}
		err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DSR, 1);
		if (err) {
			LOG_WRN("Failed to set DSR, ret code %d", err);
		}
	}

	tx = k_malloc(sizeof(*tx));

	if (tx) {
		pos = snprintf(tx->data, sizeof(tx->data),
			       "Starting Nordic UART service example\r\n");

		if ((pos < 0) || (pos >= sizeof(tx->data))) {
			k_free(rx);
			k_free(tx);
			LOG_ERR("snprintf returned %d", pos);
			return -ENOMEM;
		}

		tx->len = pos;
	} else {
		k_free(rx);
		return -ENOMEM;
	}

	err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
	if (err) {
		k_free(rx);
		k_free(tx);
		LOG_ERR("Cannot display welcome message (err: %d)", err);
		return err;
	}

	err = uart_rx_enable(uart, rx->data, sizeof(rx->data), UART_WAIT_FOR_RX);
	if (err) {
		LOG_ERR("Cannot enable uart reception (err: %d)", err);
		/* Free the rx buffer only because the tx buffer will be handled in the callback */
		k_free(rx);
	}

	return err;
}



static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (err) {
		LOG_ERR("Connection failed, err 0x%02x %s", err, bt_hci_err_to_str(err));
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	LOG_INF("Connected %s", addr);

	if (bt_conn_set_security(conn, BT_SECURITY_L3)) {
		LOG_ERR("Failed to set security\n");
	}
#ifdef CONFIG_BT_USER_PHY_UPDATE
	update_phy(my_conn);
#endif
}
#ifdef CONFIG_BT_USER_PHY_UPDATE
void le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param)
{
    // PHY Updated
    if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_1M) {
        LOG_INF("PHY updated. New PHY: 1M");
    }
    else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_2M) {
        LOG_INF("PHY updated. New PHY: 2M");
    }
    else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S8) {
        LOG_INF("PHY updated. New PHY: Long Range");
    }
}
#endif
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("Disconnected: %s, reason 0x%02x %s", addr, reason, bt_hci_err_to_str(reason));

	dk_set_led_off(RUN_STATUS_LED);
	connectFlag = false;

	if (auth_conn) {
		bt_conn_unref(auth_conn);
		auth_conn = NULL;
	}

	if (current_conn) {
		bt_conn_unref(current_conn);
		current_conn = NULL;
	}
}

static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa, const bt_addr_le_t *identity)
{
	char addr_identity[BT_ADDR_LE_STR_LEN];
	char addr_rpa[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity));
	bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa));

	LOG_INF("Identity resolved %s -> %s\n", addr_rpa, addr_identity);
}

#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
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));

	if (!err) {
		LOG_INF("Security changed: %s level %u", addr, level);
	} else {
		LOG_WRN("Security failed: %s level %u err %d %s", addr, level, err,
			bt_security_err_to_str(err));
	}
}
#endif

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected    = connected,
#ifdef CONFIG_BT_USER_PHY_UPDATE
	.le_phy_updated = le_phy_updated,
#endif
	.disconnected = disconnected,
	.identity_resolved = identity_resolved,
#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
	.security_changed = security_changed,
#endif
};

#if defined(CONFIG_BT_NUS_SECURITY_ENABLED)
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_INF("Passkey for %s: %06u", addr, passkey);
}

static void auth_cancel(struct bt_conn *conn)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_INF("Pairing cancelled: %s", addr);

	dk_set_led_off(RUN_STATUS_LED);
	connectFlag = false;
}


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("Pairing completed: %s, bonded: %d", addr, bonded);

	connectFlag = true;
	dk_set_led_on(RUN_STATUS_LED);

	responseState = 6;
}


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("Pairing failed conn: %s, reason %d %s", addr, reason,
	bt_security_err_to_str(reason));

	dk_set_led_off(RUN_STATUS_LED);
	connectFlag = false;
}

static struct bt_conn_auth_cb auth_cb_display = {
	.passkey_display = auth_passkey_display,
	.passkey_entry = NULL,
	.cancel = auth_cancel,
};

static struct bt_conn_auth_info_cb auth_cb_info = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};
#else
static struct bt_conn_auth_cb conn_auth_callbacks;
static struct bt_conn_auth_info_cb conn_auth_info_callbacks;
#endif

static bool bms_authorize(struct bt_conn *conn,
	struct bt_bms_authorize_params *params)
{
	if ((params->code_len == sizeof(bms_auth_code)) &&
	(memcmp(bms_auth_code, params->code, sizeof(bms_auth_code)) == 0)) {
		LOG_INF("Authorization of BMS operation is successful\n");
		return true;
	}

	LOG_ERR("Authorization of BMS operation has failed\n");
	return false;
}

static struct bt_bms_cb bms_callbacks = {
	.authorize = bms_authorize,
};

static int bms_init(void)
{
	struct bt_bms_init_params init_params = {0};

	/* Enable all possible operation codes */
	init_params.features.delete_requesting.supported = true;
	init_params.features.delete_rest.supported = true;
	init_params.features.delete_all.supported = true;

	/* Require authorization code for operations that
	* also delete bonding information for other devices
	* than the requesting client.
	*/
	init_params.features.delete_rest.authorize = true;
	init_params.features.delete_all.authorize = true;

	init_params.cbs = &bms_callbacks;

	return bt_bms_init(&init_params);
}

static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data,
			  uint16_t len)
{
	int err;
	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);

	for (uint16_t pos = 0; pos != len;) {
		struct uart_data_t *tx = k_malloc(sizeof(*tx));

		if (!tx) {
			LOG_WRN("Not able to allocate UART send data buffer");
			return;
		}

		/* Keep the last byte of TX buffer for potential LF char. */
		size_t tx_data_size = sizeof(tx->data) - 1;

		if ((len - pos) > tx_data_size) {
			tx->len = tx_data_size;
		} else {
			tx->len = (len - pos);
		}

		memcpy(tx->data, &data[pos], tx->len);

		pos += tx->len;

		/* Append the LF character when the CR character triggered
		 * transmission from the peer.
		 */
		if ((pos == len) && (data[len - 1] == '\r')) {
			tx->data[tx->len] = '\n';
			tx->len++;
		}

		memcpy(backupBuffer, tx->data, tx->len);
		backupLength = tx->len;
	
		parsingFlag = true;
	}
}

static struct bt_nus_cb nus_cb = {
	.received = bt_receive_cb,
};

void error(void)
{
	dk_set_leds_state(DK_ALL_LEDS_MSK, DK_NO_LEDS_MSK);

	while (true) {
		/* Spin for ever */
		k_sleep(K_MSEC(1000));
	}
}

#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
static void num_comp_reply(bool accept)
{
	if (accept) {
		bt_conn_auth_passkey_confirm(auth_conn);
		LOG_INF("Numeric Match, conn %p", (void *)auth_conn);
	} else {
		bt_conn_auth_cancel(auth_conn);
		LOG_INF("Numeric Reject, conn %p", (void *)auth_conn);
	}

	bt_conn_unref(auth_conn);
	auth_conn = NULL;
}

#endif /* CONFIG_BT_NUS_SECURITY_ENABLED */

static void configure_gpio(void)
{
	int err = dk_leds_init();
	if (err) {
		LOG_ERR("LEDs init failed (err %d)\n", err);
		return 0;
	}
}

static void Advertising_Start(const struct bt_bond_info *info, void *user_data)
{
	int *bond_cnt = user_data;
	if ((*bond_cnt) < 0) {
		bt_le_adv_start(BT_LE_ADV_CONN_ONE_TIME, ad, ARRAY_SIZE(ad), sd,
			      ARRAY_SIZE(sd));
		return 0;
	} else {
		bt_le_adv_start(BT_LE_ADV_CONN_ACCEPT_LIST, ad, ARRAY_SIZE(ad), sd,
			      ARRAY_SIZE(sd));
	}
}

int main(void)
{
	int blink_status = 0;
	int err = 0;

	configure_gpio();

	err = uart_init();
	if (err) {
		error();
	}

	if (IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
		err = bt_conn_auth_cb_register(&auth_cb_display);
		if (err) {
			LOG_ERR("Failed to register authorization callbacks.\n");
			return 0;
		}

		err = bt_conn_auth_info_cb_register(&auth_cb_info);
		if (err) {
			LOG_ERR("Failed to register authorization info callbacks.\n");
			return 0;
		}
	}

	err = bt_enable(NULL);
	if (err) {
		error();
	}

	LOG_INF("Bluetooth initialized");

	
	
	k_sem_give(&ble_init_ok);

	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = bt_nus_init(&nus_cb);
	if (err) {
		LOG_ERR("Failed to initialize UART service (err: %d)", err);
		return 0;
	}
	err = bms_init();
	if (err) {
		LOG_ERR("Failed to init BMS (err:%d)\n", err);
		return 0;
	}

	unsigned int passkey = 123456;
	bt_passkey_set(passkey);

	err = bt_le_adv_start(BT_LE_ADV_CONN_ONE_TIME, ad, ARRAY_SIZE(ad), sd,
			      ARRAY_SIZE(sd));
	if (err) {
		LOG_ERR("Advertising failed to start (err %d)", err);
		return 0;
	}

	for (;;) {
		if(!connectFlag){
			dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
			k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
		}
		parsingTask();
		uart_state_handler();
		response_send();
	}
}

void ble_write_thread(void)
{
	/* Don't go any further until BLE is initialized */
	k_sem_take(&ble_init_ok, K_FOREVER);
	struct uart_data_t nus_data = {
		.len = 0,
	};

	for (;;) {
		/* Wait indefinitely for data to be sent over bluetooth */
		struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
						     K_FOREVER);

		int plen = MIN(sizeof(nus_data.data) - nus_data.len, buf->len);
		int loc = 0;

		while (plen > 0) {
			memcpy(&nus_data.data[nus_data.len], &buf->data[loc], plen);
			nus_data.len += plen;
			loc += plen;
			
			if (nus_data.len >= sizeof(nus_data.data)) {
				if (connectFlag == true){
					if (bt_nus_send(NULL, nus_data.data, nus_data.len)) {
						LOG_WRN("Failed to send data over BLE connection");
					}
				}
				nus_data.len = 0;
			}

			plen = MIN(sizeof(nus_data.data), buf->len - loc);
		}

		k_free(buf);
	}
}

K_THREAD_DEFINE(ble_write_thread_id, STACKSIZE, ble_write_thread, NULL, NULL,
		NULL, PRIORITY, 0, 0);

Thanks for help.

Parents
  • Hi

    Are you connecting the nRF54L15 to a phone here or to another BLE device? And just to clarify, you do in fact input the passkey on the other device and press okay during this 1minute 50 second delay between the passkey log message and security changed log message, correct?

    It's hard to tell from this log what exactly is wrong, and I think the best would be either if you could upload a BLE sniffer log so we can see what's going on over the air, or if you can let me know what sample you used as a base so I can try reproducing this on my end.

    Best regards,

    Simon

  • Hi Simonr.

    I answer your questions as follows:

    1. Are you connecting the nRF54L15 to a phone here or to another BLE device?

     - phone

    2. you do in fact input the passkey on the other device and press okay during this 1minute 50 second delay between the passkey log message and security changed log message, correct?

    - yes 

    3.  you could upload a BLE sniffer log

    - please check the BLE sniffer log file

    4. what sample you used as a base

     - peripharl_uart

    nrF54L15_Sniffer Log.csv

    5852.11_nRF54L15_Sniffer Log.pcapng


Reply Children
No Data
Related