How to print RSSI value of all the advertising packets from peripheral to central and print on PuTTy.

Hi,

I'm working on central_uart and peripheral_uart examples. I want to get the rssi value and tx_power of all advertising packets from peripheral to central via bluetooth connection. How can i get these values and print the same on the PuTTy terminal.

Can you please guide me with all the functions i need to involve in the peripheral or central main functions.

Regards

Karthik Kumar

Parents
  • Hello!

    As I suggested in one of your previous cases, there is a sample that demonstrates how to handle these values:

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/bluetooth/hci_pwr_ctrl/README.html

    This sample shows you how to read the values, and once you've done that you can send them to your central which can print them with printk.

    Best regards,

    Einar

  • Hi Einarh,

    Towards left is the central_uart putty terminal and right is peripheral_uart putty terminal.

    from the https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/bluetooth/hci_pwr_ctrl/README.html example, made use of below 2 function for RSSI and TX_Power 

    static void read_conn_rssi(uint16_t handle, int8_t *rssi)

    static void set_tx_power(uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl).
    but as seen on the terminal its prompting and error as follows,
    d Read RSSI err: -5 reason 0x00 // for read rssi.
    Set Tx power err: -5 reason 0x00 // for Tx_power.
    How can this errors be resolved and get the actual rssi and tx power values. Also wanted to time stamp each packet. How can that be done?
    Peripheral_uart modified code
    * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     *  @brief Nordic UART Bridge Service (NUS) sample
     */
    #include "uart_async_adapter.h"
    
    /*********************Coded PHY Files*************************/
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    /*************************************************************/
    #include <zephyr/types.h>
    #include <zephyr.h>
    #include <drivers/uart.h>
    #include <usb/usb_device.h>
    
    #include <device.h>
    #include <soc.h>
    
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/uuid.h>
    #include <bluetooth/gatt.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/conn.h>
    
    #include <bluetooth/services/nus.h>
    
    #include <dk_buttons_and_leds.h>
    
    #include <settings/settings.h>
    
    #include <stdio.h>
    
    #include <logging/log.h>
    
    #include <bluetooth/hci.h>
    #include <bluetooth/hci_vs.h>
    #include <sys/util.h>
    #include <sys/byteorder.h>
    
    
    #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)
    
    #define RUN_STATUS_LED DK_LED1
    #define RUN_LED_BLINK_INTERVAL 1000
    
    #define CON_STATUS_LED DK_LED2
    
    #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
    #define NRF_RADIO      NRF_RADIO_NS
    #define NRF_RADIO_NS  ((uint32_t  RSSISAMPLE )        NRF_RADIO_NS_BASE)
    #define DEVICE_BEACON_TXPOWER_NUM  8
    
    #define BT_CONN_LE_PHY_PARAM_CODED BT_CONN_LE_PHY_PARAM(BT_GAP_LE_PHY_CODED, \
    							BT_GAP_LE_PHY_CODED)
    						
    
    static K_SEM_DEFINE(ble_init_ok, 0, 1);
    
    static struct bt_conn *current_conn;
    static struct bt_conn *auth_conn;
    static struct k_thread pwr_thread_data;
    static K_THREAD_STACK_DEFINE(pwr_thread_stack, 512);
    //static uint16_t default_conn_handle;
    static const int8_t txp[DEVICE_BEACON_TXPOWER_NUM] = {3};
    static const struct bt_le_adv_param *param =
    	BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME,
    			0x0020, 0x0020, NULL);
    
    /*****************************Coded PHY Ad Data**************************************************/			
    //static const struct bt_data ad[] = {
    //	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    //	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HRS_VAL)),
    //};
    static struct k_work start_advertising_worker;
    
    static struct bt_le_ext_adv *adv;
    /***********************************************************************************************/
    
    static const struct device *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 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),
    };
    
    #if CONFIG_BT_NUS_UART_ASYNC_ADAPTER
    UART_ASYNC_ADAPTER_INST_DEFINE(async_adapter);
    #else
    static const struct device *const async_adapter;
    #endif
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	ARG_UNUSED(dev);
    
    	static uint8_t *current_buf;
    	static size_t aborted_len;
    	static bool buf_release;
    	struct uart_data_t *buf;
    	static uint8_t *aborted_buf;
    
    	switch (evt->type) {
    	case UART_TX_DONE:
    		LOG_DBG("tx_done");
    		printk("tx_done\n");
    		if ((evt->data.tx.len == 0) ||
    		    (!evt->data.tx.buf)) {
    			return;
    		}
    
    		if (aborted_buf) {
    			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    					   data);
    			aborted_buf = NULL;
    			aborted_len = 0;
    		} else {
    			buf = CONTAINER_OF(evt->data.tx.buf, struct uart_data_t,
    					   data);
    		}
    
    		k_free(buf);
    
    		buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
    		if (!buf) {
    			return;
    		}
    
    		if (uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) {
    			LOG_WRN("Failed to send data over UART");
    			printk("Failed to send data over UART\n");
    		}
    
    		break;
    
    	case UART_RX_RDY:
    		LOG_DBG("rx_rdy");
    		printk("rx_rdy\n");
    		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		buf->len += evt->data.rx.len;
    		buf_release = false;
    
    		if (buf->len == UART_BUF_SIZE) {
    			k_fifo_put(&fifo_uart_rx_data, buf);
    		} else if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    			  (evt->data.rx.buf[buf->len - 1] == '\r')) {
    			k_fifo_put(&fifo_uart_rx_data, buf);
    			current_buf = evt->data.rx.buf;
    			buf_release = true;
    			uart_rx_disable(uart);
    		}
    
    		break;
    
    	case UART_RX_DISABLED:
    		LOG_DBG("rx_disabled");
    		printk("rx_disabled\n");
    		buf = k_malloc(sizeof(*buf));
    		if (buf) {
    			buf->len = 0;
    		} else {
    			LOG_WRN("Not able to allocate UART receive buffer");
    			printk("Not able to allocate UART receive buffer\n");
    			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("rx_buf_request");
    		printk("rx_buf_request\n");
    		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");
    			printk("Not able to allocate UART receive buffer\n");
    		}
    
    		break;
    
    	case UART_RX_BUF_RELEASED:
    		LOG_DBG("rx_buf_released");
    		printk("rx_buf_released\n");
    		buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
    				   data);
    		if (buf_release && (current_buf != evt->data.rx_buf.buf)) {
    			k_free(buf);
    			buf_release = false;
    			current_buf = NULL;
    		}
    
    		break;
    
    	case UART_TX_ABORTED:
    			LOG_DBG("tx_aborted");
    			printk("tx_aborted\n");
    			if (!aborted_buf) {
    				aborted_buf = (uint8_t *)evt->data.tx.buf;
    			}
    
    			aborted_len += evt->data.tx.len;
    			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    					   data);
    
    			uart_tx(uart, &buf->data[aborted_len],
    				buf->len - aborted_len, SYS_FOREVER_MS);
    
    		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");
    		printk("Not able to allocate UART receive buffer\n");
    		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;
    
    	uart = device_get_binding(CONFIG_BT_NUS_UART_DEV);
    	if (!uart) {
    		return -ENXIO;
    	}
    
    	if (IS_ENABLED(CONFIG_USB_DEVICE_STACK)) {
    		err = usb_enable(NULL);
    		if (err) {
    			LOG_ERR("Failed to enable USB");
    			printk("Failed to enable USB\n");
    			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_BT_NUS_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) {
    		LOG_ERR("Cannot initialize UART callback");
    		printk("Cannot initialize UART callback\n");
    		return err;
    	}
    
    	if (IS_ENABLED(CONFIG_UART_LINE_CTRL)) {
    		LOG_INF("Wait for DTR");
    		printk("Wait for DTR\n");
    		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");
    		printk("DTR set\n");
    		err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DCD, 1);
    		if (err) {
    			LOG_WRN("Failed to set DCD, ret code %d", err);
    			printk("Failed to set DCD, ret code %d\n", err);
    		}
    		err = uart_line_ctrl_set(uart, UART_LINE_CTRL_DSR, 1);
    		if (err) {
    			LOG_WRN("Failed to set DSR, ret code %d", err);
    			printk("Failed to set DSR, ret code %d\n", 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(tx);
    			LOG_ERR("snprintf returned %d", pos);
    			printk("snprintf returned %d\n", pos);
    			return -ENOMEM;
    		}
    
    		tx->len = pos;
    	} else {
    		return -ENOMEM;
    	}
    
    	err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
    	if (err) {
    		LOG_ERR("Cannot display welcome message (err: %d)", err);
    		printk("Cannot display welcome message (err: %d)\n", err);
    		return err;
    	}
    
    	return uart_rx_enable(uart, rx->data, sizeof(rx->data), 50);
    }
    /*
    Reading RSSI Value 
    */
    static void read_conn_rssi(uint16_t handle, int8_t *rssi)
    {
    	struct net_buf *buf, *rsp = NULL;
    	struct bt_hci_cp_read_rssi *cp;
    	struct bt_hci_rp_read_rssi *rp;
    
    	int err;
    
    	buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
    	if (!buf) {
    		printk("Unable to allocate command buffer\n");
    		return;
    	}
    
    	cp = net_buf_add(buf, sizeof(*cp));
    	cp->handle = sys_cpu_to_le16(handle);
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &rsp);
    	if (err) {
    		uint8_t reason = rsp ?
    			((struct bt_hci_rp_read_rssi *)rsp->data)->status : 0;
    		printk("Read RSSI err: %d reason 0x%02x\n", err, reason);
    		return;
    	}
    
    	rp = (void *)rsp->data;
    	*rssi = rp->rssi;
    
    	net_buf_unref(rsp);
    }
    //uint32_t sd_ble_gap_rssi_start	( conn_handle, BLE_GAP_EVT_RSSI_CHANGED, BLE_GAP_EVT_RSSI_CHANGED);
    //uint32_t sd_ble_gap_rssi_get	(conn_handle, BLE_GAP_EVT_RSSI_CHANGED, BLE_GAP_EVT_RSSI_CHANGED);
    
    /******************************************* TX Power*********************************************************************/
    
    
    
    
    /*
    static void get_tx_power(uint8_t handle_type, uint16_t handle, int8_t *tx_pwr_lvl)
    {
    	struct bt_hci_cp_vs_read_tx_power_level *cp;
    	struct bt_hci_rp_vs_read_tx_power_level *rp;
    	struct net_buf *buf, *rsp = NULL;
    	int err;
    
    	*tx_pwr_lvl = 0xFF;
    	buf = bt_hci_cmd_create(BT_HCI_OP_VS_READ_TX_POWER_LEVEL,
    				sizeof(*cp));
    	if (!buf) {
    		printk("Unable to allocate command buffer\n");
    		return;
    	}
    
    	cp = net_buf_add(buf, sizeof(*cp));
    	cp->handle = sys_cpu_to_le16(handle);
    	cp->handle_type = handle_type;
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_TX_POWER_LEVEL,
    				   buf, &rsp);
    	if (err) {
    		uint8_t reason = rsp ?
    			((struct bt_hci_rp_vs_read_tx_power_level *)
    			  rsp->data)->status : 0;
    		printk("Read Tx power (Maximum): %d reason 0x%02x\n", err, reason);
    		return;
    	}
    
    	rp = (void *)rsp->data;
    	*tx_pwr_lvl = rp->tx_power_level;
    
    	net_buf_unref(rsp);
    }
    */
    /*********************************************Connection***************************************************************/
    
    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	int err;
    	struct bt_conn_info info;
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (conn_err) {
    		LOG_ERR("Connection failed (err %u)", conn_err);
    		printk("Connection failed (err %u)\n", conn_err);
    		return;
    	}
    		err = bt_conn_get_info(conn, &info);
    
    	if (err) {
    		printk("Failed to get connection info\n");
    	}
    	 else {
    	    const struct bt_conn_le_phy_info *phy_info;
    		phy_info = BT_CONN_LE_PHY_OPT_CODED_S8;
    		//phy_info = info.le.phy;
    		//get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,
    				    // NULL, &txp);
    		LOG_INF("Connected: %s, tx_phy %u, rx_phy %u ",
    		       log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy );
    
    		printk("Coded PHY Connected: %s, tx_phy %u, rx_phy %u\n",
    		       log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy);
    			   //printk(NRF_RADIO->RSSISAMPLE);
    			   //uint32_t sd_ble_gap_rssi_start	( conn_handle, 0, 0)
    	 }
    
    	current_conn = bt_conn_ref(conn);
    	/*current_conn = bt_conn_foreach(conn);*/
    
    	dk_set_led_on(CON_STATUS_LED);
    	
    
    }
    
    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 %u)", log_strdup(addr), reason);
    	printk("Disconnected: %s (reason %u)\n", log_strdup(addr), reason);
    
    	//k_work_submit(&start_advertising_worker);
    
    	if (auth_conn) {
    		bt_conn_unref(auth_conn);
    		auth_conn = NULL;
    	}
    
    	if (current_conn) {
    		bt_conn_unref(current_conn);
    		current_conn = NULL;
    		dk_set_led_off(CON_STATUS_LED);
    	}
    }
    
    #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", log_strdup(addr),
    			level);
    			printk("Security changed: %s level %u\n", log_strdup(addr),
    			level);
    	} else {
    		LOG_WRN("Security failed: %s level %u err %d", log_strdup(addr),
    			level, err);
    			printk("Security failed: %s level %u err %d\n", log_strdup(addr),
    			level, err);
    	}
    }
    #endif
    
    static struct bt_conn_cb conn_callbacks = {
    	.connected    = connected,
    	.disconnected = disconnected,
    #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", log_strdup(addr), passkey);
    	printk("Passkey for %s: %06u\n", log_strdup(addr), passkey);
    }
    
    static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	auth_conn = bt_conn_ref(conn);
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	LOG_INF("Passkey for %s: %06u", log_strdup(addr), passkey);
    	printk("Passkey for %s: %06u\n", log_strdup(addr), passkey);
    	LOG_INF("Press Button 1 to confirm, Button 2 to reject.");
    	printk("Press Button 1 to confirm, Button 2 to reject.\n");
    }
    
    
    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", log_strdup(addr));
    	printk("Pairing cancelled: %s\n", log_strdup(addr));
    }
    
    
    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", log_strdup(addr),
    		bonded);
    		printk("Pairing completed: %s, bonded: %d\n", log_strdup(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("Pairing failed conn: %s, reason %d", log_strdup(addr),
    		reason);
    		printk("Pairing failed conn: %s, reason %d\n", log_strdup(addr),
    		reason);
    }
    
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.passkey_display = auth_passkey_display,
    	.passkey_confirm = auth_passkey_confirm,
    	.cancel = auth_cancel,
    	.pairing_complete = pairing_complete,
    	.pairing_failed = pairing_failed
    };
    #else
    static struct bt_conn_auth_cb conn_auth_callbacks;
    #endif
    
    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", log_strdup(addr));
    	printk("Received data from: %s\n", log_strdup(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");
    			printk("Not able to allocate UART send data buffer\n");
    			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++;
    		}
    
    		err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
    		if (err) {
    			k_fifo_put(&fifo_uart_tx_data, tx);
    		}
    	}
    }
    
    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);
    		printk("Numeric Match, conn %p\n", (void *)auth_conn);
    	} else {
    		bt_conn_auth_cancel(auth_conn);
    		LOG_INF("Numeric Reject, conn %p", (void *)auth_conn);
    		printk("Numeric Reject, conn %p\n", (void *)auth_conn);
    	}
    
    	bt_conn_unref(auth_conn);
    	auth_conn = NULL;
    }
    
    void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    	uint32_t buttons = button_state & has_changed;
    
    	if (auth_conn) {
    		if (buttons & KEY_PASSKEY_ACCEPT) {
    			num_comp_reply(true);
    		}
    
    		if (buttons & KEY_PASSKEY_REJECT) {
    			num_comp_reply(false);
    		}
    	}
    }
    #endif /* CONFIG_BT_NUS_SECURITY_ENABLED */
    
    static void configure_gpio(void)
    {
    	int err;
    
    #ifdef CONFIG_BT_NUS_SECURITY_ENABLED
    	err = dk_buttons_init(button_changed);
    	if (err) {
    		LOG_ERR("Cannot init buttons (err: %d)", err);
    		printk("Cannot init buttons (err: %d)\n", err);
    	}
    #endif /* CONFIG_BT_NUS_SECURITY_ENABLED */
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("Cannot init LEDs (err: %d)", err);
    		printk("Cannot init LEDs (err: %d)\n", err);
    	}
    }
    
    /***************************************************Modulated TX_Power*****************************************/
    void modulate_tx_power(void *p1, void *p2, void *p3)
    {
    	int8_t txp_get = 0;
    	int8_t txp = 3;
    	uint8_t idx = 0;
    
    	while (1) {
    		if (!NULL) {
    			printk("Set Tx power level to %d\n", txp);
    			set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,
    				     0, txp);
    
    			k_sleep(K_SECONDS(5));
    
    			printk("Get Tx power level -> ");
    			get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,
    				     0, &txp_get);
    			printk("TXP = %d\n", txp_get);
    
    			idx = (idx+1) % DEVICE_BEACON_TXPOWER_NUM;
    		} else {
    			int8_t rssi = 0xFF;
    			int8_t txp_adaptive;
    
    			idx = 0;
    
    			read_conn_rssi(NULL, &rssi);
    			printk("RSSI = %d\n",
    			       NULL, rssi);
    			if (rssi > -70) {
    				txp_adaptive = -20;
    			} else if (rssi > -90) {
    				txp_adaptive = -12;
    			} else {
    				txp_adaptive = -4;
    			}
    			printk("Adaptive Tx power selected = %d\n",
    			       txp_adaptive);
    			set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,
    				     NULL, txp_adaptive);
    			get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,
    				     NULL, &txp_get);
    			printk("Connection (%d) TXP = %d\n",
    			       NULL, txp_get);
    
    			k_sleep(K_SECONDS(1));
    		}
    	}
    }
    
    /*********************************************Coded PHY*************************************************/
    static int create_advertising_coded(void)
    {
    	int err;
    	struct bt_le_adv_param param =
    		BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE |
    				     BT_LE_ADV_OPT_EXT_ADV |
    				     BT_LE_ADV_OPT_CODED,
    				     BT_GAP_ADV_FAST_INT_MIN_2,
    				     BT_GAP_ADV_FAST_INT_MAX_2,
    				     NULL);
    
    	err = bt_le_ext_adv_create(&param, NULL, &adv);
    	if (err) {
    		printk("Failed to create advertiser set (%d)\n", err);
    		return err;
    	}
    
    	printk("Created adv: %p\n", adv);
    
    	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		printk("Failed to set advertising data (%d)\n", err);
    		return err;
    	}
    
    	return 0;
    }
    
    static void start_advertising_coded(struct k_work *item)
    {
    	int err;
    
    	err = bt_le_ext_adv_start(adv, NULL);
    	if (err) {
    		printk("Failed to start advertising set (%d)\n", err);
    		return;
    	}
    
    	printk("Advertiser %p set started\n", adv);
    }
    
    static void bt_ready(void)
    {
    	int err = 0;
    
    	printk("Bluetooth initialized\n");
    
    	k_work_init(&start_advertising_worker, start_advertising_coded);
    
    	err = create_advertising_coded();
    	if (err) {
    		printk("Advertising failed to create (err %d)\n", err);
    		return;
    	}
    
    	k_work_submit(&start_advertising_worker);
    }
    /******************************************* Main *****************************************************/
    void main(void)
    {
    	int blink_status = 0;
    	int err = 0;
    	//int8_t txp_get = 0xFF;
    	int8_t txp = 3;
    	int8_t rssi = 0xFF;
    
    	configure_gpio();
    
    	err = uart_init();
    	if (err) {
    		error();
    	}
    
    	bt_conn_cb_register(&conn_callbacks);
    
    	if (IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
    		bt_conn_auth_cb_register(&conn_auth_callbacks);
    	}
    
    	err = bt_enable(NULL);
    	if (err) {
    		error();
    	}
    	   set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,0,txp);
    
    	LOG_INF("Bluetooth initialized");
    	printk("Bluetooth initialized\n");
    
    	//printk("Get Tx power level ->");
    	//get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV, 0, &txp_get);
    
    	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);
    		printk("Failed to initialize UART service (err: %d)\n", err);
    		return;
    	}
    
    	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd,
    			      ARRAY_SIZE(sd));
    	if (err) {
    		LOG_ERR("Advertising failed to start (err %d)", err);
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    	/*
    	err = sd_ble_gap_rssi_get(BT_LE_ADV_CONN, 0 , 0 );
    	if(err)
    	{
    		printk("RSSI: \n",err);
    	}
    	*/
    	//printk("Get Tx power level ->");
    	//get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV, 0, &txp_get);
    	//printk("-> default TXP = %d\n", txp_get);
    	//read_conn_rssi(NULL, &rssi);
    	//		printk("RSSI = %d\n", rssi);
    	for (;;) {
    		dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
    		k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    
    		/*ran_data();*/
    		const uint8_t sensor_data ='d';
    		uint16_t length = 1;
    		//uint32_t sd_ble_gap_rssi_start	( sd, NULL, NULL)
    		//uint8_tsdc_hci_cmd_sp_read_rssi(constsdc_hci_cmd_sp_read_rssi_t*p_params, sdc_hci_cmd_sp_read_rssi_return_t*p_return);
    
    		if (bt_nus_send(NULL, &sensor_data, length)) {
    			
    			LOG_WRN("Failed to send data over BLE connection");
    			printk("Failed to send data over BLE connectionl\n");
    		}
    	}
    }
    
    void ble_write_thread(void)
    {
    	/* Don't go any further until BLE is initialized */
    	k_sem_take(&ble_init_ok, K_FOREVER);
    
    	for (;;) {
    		/* Wait indefinitely for data to be sent over bluetooth */
    		struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
    						     K_FOREVER);
    
    		//struct uart_user_data *buf ; 
    
    		const uint8_t sensor_data ='d';
    		 uint16_t length = 1;
    		 
    
    		if (bt_nus_send(NULL, &sensor_data, length)) {
    			LOG_WRN("Failed to send data over BLE connection");
    			printk("Failed to send data over BLE connectionl\n");
    		}
    
    		k_free(buf);
    	}
    }
    
    K_THREAD_DEFINE(ble_write_thread_id, STACKSIZE, ble_write_thread, NULL, NULL,
    		NULL, PRIORITY, 0, 0);
    Central_uart modified code
    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     *  @brief Nordic UART Service Client sample
     */
    
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/byteorder.h>
    #include <sys/printk.h>
    
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/conn.h>
    #include <bluetooth/uuid.h>
    #include <bluetooth/gatt.h>
    
    #include <bluetooth/services/nus.h>
    #include <bluetooth/services/nus_client.h>
    #include <bluetooth/gatt_dm.h>
    #include <bluetooth/scan.h>
    
    #include <settings/settings.h>
    
    #include <drivers/uart.h>
    
    #include <logging/log.h>
    
    
    
    #define LOG_MODULE_NAME central_uart
    LOG_MODULE_REGISTER(LOG_MODULE_NAME);
    
    /* UART payload buffer element size. */
    #define UART_BUF_SIZE 20
    
    #define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
    #define KEY_PASSKEY_REJECT DK_BTN2_MSK
    
    #define NUS_WRITE_TIMEOUT K_MSEC(150)
    #define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
    #define UART_RX_TIMEOUT 50
    
    #define BT_CONN_LE_PHY_PARAM_CODED BT_CONN_LE_PHY_PARAM(BT_GAP_LE_PHY_CODED, \
    							BT_GAP_LE_PHY_CODED)
    
    static const struct device *uart;
    static struct k_work_delayable uart_work;
    
    K_SEM_DEFINE(nus_write_sem, 0, 1);
    
    struct uart_data_t {
    	void *fifo_reserved;
    	uint8_t  data[UART_BUF_SIZE];
    	uint16_t len;
    };
    
    struct uart_user_data {
    	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 struct bt_conn *default_conn;
    static struct bt_nus_client nus_client;
    
    static void ble_data_sent(struct bt_nus_client *nus, uint8_t err,
    					const uint8_t *const data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	struct uart_data_t *buf;
    
    	/* Retrieve buffer context. */
    	buf = CONTAINER_OF(data, struct uart_data_t, data);
    	k_free(buf);
    
    	k_sem_give(&nus_write_sem);
    
    	if (err) {
    		LOG_WRN("ATT error code: 0x%02X", err);
    		printk("ATT error code: 0x%02X\n", err);
    	}
    }
    
    /****************************************Reading RSSI Value*************************************/
    static void read_conn_rssi(uint16_t handle, int8_t *rssi)
    {
    	struct net_buf *buf, *rsp = NULL;
    	struct bt_hci_cp_read_rssi *cp;
    	struct bt_hci_rp_read_rssi *rp;
    
    	int err;
    
    	buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
    	if (!buf) {
    		printk("Unable to allocate command buffer\n");
    		return;
    	}
    
    	cp = net_buf_add(buf, sizeof(*cp));
    	cp->handle = sys_cpu_to_le16(handle);
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &rsp);
    	if (err) {
    		uint8_t reason = rsp ?
    			((struct bt_hci_rp_read_rssi *)rsp->data)->status : 0;
    		printk("Read RSSI err: %d reason 0x%02x\n", err, reason);
    		return;
    	}
    
    	rp = (void *)rsp->data;
    	*rssi = rp->rssi;
    
    	net_buf_unref(rsp);
    }
    
    
    /****************************************Receving Data Via BLE*************************************/
    
    static uint8_t ble_data_received(struct bt_nus_client *nus,
    						const uint8_t *data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	int err;
    	int8_t rssi = 0xFF;
    
    	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");
    			printk("Not able to allocate UART send data buffer\n");
    			return BT_GATT_ITER_CONTINUE;
    		}
    
    		/* 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++;
    		}
    		/* modifications*/
    		printk("\n");
    		err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
    		read_conn_rssi(tx->data, rssi);
    		printk("   RSSI: ",tx->data);
    		if (err) {
    			k_fifo_put(&fifo_uart_tx_data, tx);
    		}
    	}
    
    	return BT_GATT_ITER_CONTINUE;
    }
    
    /**********************************************UART FUNCTION********************************************/
    
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	ARG_UNUSED(dev);
    
    	static uint8_t *current_buf;
    	static size_t aborted_len;
    	static bool buf_release;
    	struct uart_data_t *buf;
    	static uint8_t *aborted_buf;
    
    	switch (evt->type) {
    	case 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);
    			aborted_buf = NULL;
    			aborted_len = 0;
    		} else {
    			buf = CONTAINER_OF(evt->data.tx.buf,
    					   struct uart_data_t,
    					   data);
    		}
    
    		k_free(buf);
    
    		buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
    		if (!buf) {
    			return;
    		}
    
    		if (uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) {
    			LOG_WRN("Failed to send data over UART");
    			printk("Failed to send data over UART\n");
    		}
    
    		break;
    
    	case UART_RX_RDY:
    		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		buf->len += evt->data.rx.len;
    		buf_release = false;
    
    		if (buf->len == UART_BUF_SIZE) {
    			k_fifo_put(&fifo_uart_rx_data, buf);
    		} else if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    			  (evt->data.rx.buf[buf->len - 1] == '\r')) {
    			k_fifo_put(&fifo_uart_rx_data, buf);
    			current_buf = evt->data.rx.buf;
    			buf_release = true;
    			uart_rx_disable(uart);
    		}
    
    		break;
    
    	case UART_RX_DISABLED:
    		buf = k_malloc(sizeof(*buf));
    		if (buf) {
    			buf->len = 0;
    		} else {
    			LOG_WRN("Not able to allocate UART receive buffer");
    			printk("Not able to allocate UART receive buffer\n");
    			k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
    			return;
    		}
    
    		uart_rx_enable(uart, buf->data, sizeof(buf->data),
    			       UART_RX_TIMEOUT);
    
    		break;
    
    	case 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");
    			printk("Not able to allocate UART receive buffer\n");
    		}
    
    		break;
    
    	case UART_RX_BUF_RELEASED:
    		buf = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t,
    				   data);
    		if (buf_release && (current_buf != evt->data.rx_buf.buf)) {
    			k_free(buf);
    			buf_release = false;
    			current_buf = NULL;
    		}
    
    		break;
    
    	case UART_TX_ABORTED:
    			if (!aborted_buf) {
    				aborted_buf = (uint8_t *)evt->data.tx.buf;
    			}
    
    			aborted_len += evt->data.tx.len;
    			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
    					   data);
    
    			uart_tx(uart, &buf->data[aborted_len],
    				buf->len - aborted_len, SYS_FOREVER_MS);
    
    		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");
    		printk("Not able to allocate UART receive buffer\n");
    		k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
    		return;
    	}
    
    	uart_rx_enable(uart, buf->data, sizeof(buf->data), UART_RX_TIMEOUT);
    }
    
    static int uart_init(void)
    {
    	int err;
    	struct uart_data_t *rx;
    
    	uart = device_get_binding(DT_LABEL(DT_NODELABEL(uart0)));
    	if (!uart) {
    		LOG_ERR("UART binding failed");
    		printk("UART binding failed\n");
    		return -ENXIO;
    	}
    
    	rx = k_malloc(sizeof(*rx));
    	if (rx) {
    		rx->len = 0;
    	} else {
    		return -ENOMEM;
    	}
    
    	k_work_init_delayable(&uart_work, uart_work_handler);
    
    	err = uart_callback_set(uart, uart_cb, NULL);
    	if (err) {
    		return err;
    	}
    
    	return uart_rx_enable(uart, rx->data, sizeof(rx->data),
    			      UART_RX_TIMEOUT);
    }
    
    static void discovery_complete(struct bt_gatt_dm *dm,
    			       void *context)
    {
    	struct bt_nus_client *nus = context;
    	LOG_INF("Service discovery completed");
    	printk("Service discovery completed\n");
    
    	bt_gatt_dm_data_print(dm);
    	bt_nus_handles_assign(dm, nus);
    	bt_nus_subscribe_receive(nus);
    	bt_gatt_dm_data_release(dm);
    }
    
    static void discovery_service_not_found(struct bt_conn *conn,
    					void *context)
    {
    	LOG_INF("Service not found");
    	printk("Service not found\n");
    }
    
    static void discovery_error(struct bt_conn *conn,
    			    int err,
    			    void *context)
    {
    	LOG_WRN("Error while discovering GATT database: (%d)", err);
    	printk("Error while discovering GATT database: (%d)\n", 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);
    	if (err) {
    		LOG_ERR("could not start the discovery procedure, error "
    			"code: %d", err);
    			printk("could not start the discovery procedure, error "
    			"code: %d\n", err);
    	}
    }
    
    static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params)
    {
    	if (!err) {
    		LOG_INF("MTU exchange done");
    		printk("MTU exchange done\n");
    	} else {
    		LOG_WRN("MTU exchange failed (err %" PRIu8 ")", err);
    		printk("MTU exchange failed (err %" PRIu8 ")\n", err);
    	}
    }
    
    
    
    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	int err;
    	struct bt_conn_info info;
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (conn_err) {
    		LOG_INF("Failed to connect to %s (%d)", log_strdup(addr),
    			conn_err);
    			printk("Failed to connect to %s (%d)\n", log_strdup(addr),
    			conn_err);
    
    		if (default_conn == conn) {
    			bt_conn_unref(default_conn);
    			default_conn = NULL;
    
    			err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    			if (err) {
    				LOG_ERR("Scanning failed to start (err %d)",
    					err);
    					printk("Scanning failed to start (err %d)\n",
    					err);
    			}
    		}
    
    		return;
    	}
    	
    	err = bt_conn_get_info(conn, &info);
    
    	if (err) {
    		printk("Failed to get connection info\n");
    	} else {
    		const struct bt_conn_le_phy_info *phy_info;
    
    		phy_info = BT_CONN_LE_PHY_OPT_CODED_S8;
    		LOG_INF("Connected: %s, tx_phy %u, rx_phy %u",
    		       log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy);
    		printk("Coded PHY Connected: %s, tx_phy %u, rx_phy %u\n",
    				log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy);
    	}
    
    /*
    	LOG_INF("Connected: %s", log_strdup(addr));
    	printk("Connected: %s\n", log_strdup(addr));*/
    	
    	static struct bt_gatt_exchange_params exchange_params;
    
    	exchange_params.func = exchange_func;
    	err = bt_gatt_exchange_mtu(conn, &exchange_params);
    	if (err) {
    		LOG_WRN("MTU exchange failed (err %d)", err);
    		printk("MTU exchange failed (err %d)\n", err);
    	}
    
    	err = bt_conn_set_security(conn, BT_SECURITY_L2);
    	if (err) {
    		LOG_WRN("Failed to set security: %d", err);
    		printk("Failed to set security: %d\n", err);
    
    		gatt_discover(conn);
    	}
    
    	err = bt_scan_stop();
    	if ((!err) && (err != -EALREADY)) {
    		LOG_ERR("Stop LE scan failed (err %d)", err);
    		printk("Stop LE scan failed (err %d)\n", err);
    	}
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	int err;
    	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 %u)", log_strdup(addr),
    		reason);
    		printk("Disconnected: %s (reason %u)\n", log_strdup(addr),
    		reason);
    
    	if (default_conn != conn) {
    		return;
    	}
    
    	bt_conn_unref(default_conn);
    	default_conn = NULL;
    
    	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (err) {
    		LOG_ERR("Scanning failed to start (err %d)",
    			err);
    			printk("Scanning failed to start (err %d)\n",
    			err);
    	}
    }
    
    
    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", log_strdup(addr),
    			level);
    			printk("Security changed: %s level %u\n", log_strdup(addr),
    			level);
    	} else {
    		LOG_WRN("Security failed: %s level %u err %d", log_strdup(addr),
    			level, err);
    			printk("Security failed: %s level %u err %d\n", log_strdup(addr),
    			level, err);
    	}
    
    	gatt_discover(conn);
    }
    
    static struct bt_conn_cb conn_callbacks = {
    	.connected = connected,
    	.disconnected = disconnected,
    	.security_changed = security_changed
    };
    
    /************************************Scanning for Device*******************************************/
    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",
    		log_strdup(addr), connectable);
    		printk("Filters matched. Address: %s connectable: %d\n",
    		log_strdup(addr), connectable);
    }
    
    static void scan_connecting_error(struct bt_scan_device_info *device_info)
    {
    	LOG_WRN("Connecting failed");
    	printk("Connecting failed\n");
    }
    
    static void scan_connecting(struct bt_scan_device_info *device_info,
    			    struct bt_conn *conn)
    {
    	default_conn = bt_conn_ref(conn);
    }
    
    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);
    	if (err) {
    		LOG_ERR("NUS Client initialization failed (err %d)", err);
    		printk("NUS Client initialization failed (err %d)\n", err);
    		return err;
    	}
    
    	LOG_INF("NUS Client module initialized");
    	printk("NUS Client module initialized\n");
    	return err;
    }
    
    BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL,
    		scan_connecting_error, scan_connecting);
    
    static int scan_init(void)
    {
    	int err;
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 1,
    	};
    
    	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);
    	if (err) {
    		LOG_ERR("Scanning filters cannot be set (err %d)", err);
    		printk("Scanning filters cannot be set (err %d)\n", err);
    		return err;
    	}
    
    	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    	if (err) {
    		LOG_ERR("Filters cannot be turned on (err %d)", err);
    		printk("Filters cannot be turned on (err %d)\n", err);
    		return err;
    	}
    
    	LOG_INF("Scan module initialized");
    	printk("Scan module initialized\n");
    	return err;
    }
    
    
    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", log_strdup(addr));
    	printk("Pairing cancelled: %s\n", log_strdup(addr));
    }
    
    
    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", log_strdup(addr),
    		bonded);
    		printk("Pairing completed: %s, bonded: %d\n", log_strdup(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_WRN("Pairing failed conn: %s, reason %d", log_strdup(addr),
    		reason);
    		printk("Pairing failed conn: %s, reason %d\n", log_strdup(addr),
    		reason);
    }
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.cancel = auth_cancel,
    	.pairing_complete = pairing_complete,
    	.pairing_failed = pairing_failed
    };
    
    void main(void)
    {
    	int err;
    
    	err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    	if (err) {
    		LOG_ERR("Failed to register authorization callbacks.");
    		printk("Failed to register authorization callbacks.\n");
    		return;
    	}
    
    	err = bt_enable(NULL);
    	if (err) {
    		LOG_ERR("Bluetooth init failed (err %d)", err);
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    	//set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,0,txp);
    	LOG_INF("Bluetooth initialized");
    	printk("Bluetooth initialized\n");
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	bt_conn_cb_register(&conn_callbacks);
    
    	int (*module_init[])(void) = {uart_init, scan_init, nus_client_init};
    	for (size_t i = 0; i < ARRAY_SIZE(module_init); i++) {
    		err = (*module_init[i])();
    		if (err) {
    			return;
    		}
    	}
    
    	printk("Starting Bluetooth Central UART example\n");
    
        //#define NRF_LOG_INIT	(typedef uint32_t(* nrf_log_timestamp_func_t)(void))	   
    
    	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (err) {
    		LOG_ERR("Scanning failed to start (err %d)", err);
    		printk("Scanning failed to start (err %d)\n", err);
    		return;
    	}
    
    	LOG_INF("Scanning successfully started");
    	printk("Scanning successfully started\n");
    	//printk("Get Tx power level ->");
    	//get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV, 0, &txp_get);
    
    	for (;;) {
    		/* Wait indefinitely for data to be sent over Bluetooth */
    		//printk("received data: \n");
    		struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data, K_FOREVER);
    		//printk("received data: \n", &buf);
    		//struct uart_user_data *buf = ;
    		err = bt_nus_client_send(&nus_client, buf->data, buf->len);
    
    		if (err) {
    			LOG_WRN("Failed to send data over BLE connection"
    				"(err %d)", err);
    				printk("Failed to send data over BLE connection"
    				"(err %d)\n", err);
    		}
    
    		err = k_sem_take(&nus_write_sem, NUS_WRITE_TIMEOUT);
    		if (err) {
    			LOG_WRN("NUS send timeout");
    			printk("NUS send timeout\n");
    		}
    	}
    }
    
    Regards
    Karthik Kumar
  • ok, we're getting somewhere.

    The error code you're getting seems to mean that there is "no buffer space available".

    I'm trying to look through your code to see how you are using the rssi function, but there is a lot of code so it's not easy for me to see precisely what you are doing.

    Can you tell me exactly what input arguments you are giving to the rssi function?

    It is also still not really clear to me how your application is intended to function. Do you wish to measure rssi on the peripheral or central side?

    There are many ways you could make a timestamp, I would probably use Zephyr's Counter API.

    Best regards,

    Einar

  • Hi Einarh,

    I'm calling the rssi function in,

    static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len)

    function.

    static uint8_t ble_data_received(struct bt_nus_client *nus,
    						const uint8_t *data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	int err;
    	int8_t txp = 3;
    	int8_t rssi = 0xFF;
    
    	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");
    			printk("Not able to allocate UART send data buffer\n");
    			return BT_GATT_ITER_CONTINUE;
    		}
    
    		/* 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++;
    		}
    		/* modifications*/
    		printk("\n");
    		
            typedef uint32_t(* nrf_log_timestamp_func_t)(void);
    		err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
    		//set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,0,txp);
    		//printk("   TX_Power: ",txp);
    		read_conn_rssi(tx->data, rssi);
    		printk("   RSSI: ",tx->data);
    	
    		if (err) {
    			k_fifo_put(&fifo_uart_tx_data, tx);
    		}
    	}
    
    	return BT_GATT_ITER_CONTINUE;
    }
    

    read_conn_rssi(tx->data, rssi);
            printk("   RSSI: ",tx->data);
    I want to measure both RSSI and TX_Power at the central end. Also set the TX_Power at peripheral side alone.
    In terms of Zephyr's Counter API. which would be the better function to select.
    regards
    karthik kumar
Reply
  • Hi Einarh,

    I'm calling the rssi function in,

    static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len)

    function.

    static uint8_t ble_data_received(struct bt_nus_client *nus,
    						const uint8_t *data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	int err;
    	int8_t txp = 3;
    	int8_t rssi = 0xFF;
    
    	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");
    			printk("Not able to allocate UART send data buffer\n");
    			return BT_GATT_ITER_CONTINUE;
    		}
    
    		/* 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++;
    		}
    		/* modifications*/
    		printk("\n");
    		
            typedef uint32_t(* nrf_log_timestamp_func_t)(void);
    		err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
    		//set_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_ADV,0,txp);
    		//printk("   TX_Power: ",txp);
    		read_conn_rssi(tx->data, rssi);
    		printk("   RSSI: ",tx->data);
    	
    		if (err) {
    			k_fifo_put(&fifo_uart_tx_data, tx);
    		}
    	}
    
    	return BT_GATT_ITER_CONTINUE;
    }
    

    read_conn_rssi(tx->data, rssi);
            printk("   RSSI: ",tx->data);
    I want to measure both RSSI and TX_Power at the central end. Also set the TX_Power at peripheral side alone.
    In terms of Zephyr's Counter API. which would be the better function to select.
    regards
    karthik kumar
Children
  • ok thank you.

    It looks like you're using the rssi function wrong.

    If you look at how it's used in the sample you got it from, you will see that the first argument is supposed to be a reference to the Bluetooth connection you're interested in, while the second argument is a pointer to where the measurement value shall be stored.

    Please have a look at how the function is used in the sample and adjust your own code accordingly.

    Regarding the Counter API, there aren't that many functions in the API to choose from. A good start would be to start a timer and then read values from it. Please read the documentation and you will figure out how to use it.

    Best regards,

    Einar

Related