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

  • 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,

    I have made these modification on the peripheral uart file which are in red coloured text.


    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 set_tx_power(uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl)
    {
        struct bt_hci_cp_vs_write_tx_power_level *cp;
        struct bt_hci_rp_vs_write_tx_power_level *rp;
        struct net_buf *buf, *rsp = NULL;
        int err;

        buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_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;
        cp->tx_power_level = tx_pwr_lvl;

        err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL,
                       buf, &rsp);
        if (err) {
            uint8_t reason = rsp ?
                ((struct bt_hci_rp_vs_write_tx_power_level *)
                  rsp->data)->status : 0;
            printk("Set Tx power err: %d reason 0x%02x\n", err, reason);
            return;
        }

        rp = (void *)rsp->data;
        printk("Actual Tx Power: %d\n", rp->selected_tx_power);

        net_buf_unref(rsp);
    }


    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;
        int8_t txp;
        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;
        }

        /*bt_addr_le_to_str(bt_conn_foreach(conn), addr, sizeof(addr));*/
            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;
            get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,
                         NULL, &txp);
            LOG_INF("Connected: %s, tx_phy %u, rx_phy %u ,Initial Tx Power = %d",
                   log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy, txp);

            printk("Coded PHY Connected: %s, tx_phy %u, rx_phy %u, Initial Tx Power = %d\n",
                   log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy, txp);
                   //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));
        /*bt_addr_le_to_str(bt_conn_foreach(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 (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);
        }
    }

    void main(void)
    {
        int blink_status = 0;
        int err = 0;
        int8_t txp_get = 0xFF;
        int8_t txp = -30;
        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;
        }
        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;
          

            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);
    In the end I'm sending a sample data d which is passed to central which i want to time stamp and rssi stamp every time it sends but thats not happening. 
    can you help with that.
    Regards
    Karthik Kumar
  • Hello

    I'm going to need more details about your problem to be able to help you.

    What parts of your code have you been able to verify as working? Exactly what is not working as expected right now?

    What is the expected behavior of your code and how does this differ from the observed behavior?

    Are you getting any error codes when you're trying to stamp your data?

    -Einar

  • Hi,

    I'm able to verify the connection made via ble, also the data been sent is confirmed.

    Below attached is the modified peripheral_uart code, have modified the below part of the code as,

    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");
    }

    instead of 

    for (;;) {
            /* Wait indefinitely for data to be sent over Bluetooth */
            struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
                                 K_FOREVER);
            err = bt_nus_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);
            }

    here I'm sending the sensor_data via bt_nus_send().

    All I want to do is every time the d is sent to central. i want central to get its rssi value tx power and time stamp it as shown below.

    00:12:09    d    RSSI: -30  Channel: 37 tx_power: 

    /** @file
     *  @brief Nordic UART Bridge Service (NUS) sample
     */
    #include "uart_async_adapter.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 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 set_tx_power(uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl)
    {
    	struct bt_hci_cp_vs_write_tx_power_level *cp;
    	struct bt_hci_rp_vs_write_tx_power_level *rp;
    	struct net_buf *buf, *rsp = NULL;
    	int err;
    
    	buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_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;
    	cp->tx_power_level = tx_pwr_lvl;
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL,
    				   buf, &rsp);
    	if (err) {
    		uint8_t reason = rsp ?
    			((struct bt_hci_rp_vs_write_tx_power_level *)
    			  rsp->data)->status : 0;
    		printk("Set Tx power err: %d reason 0x%02x\n", err, reason);
    		return;
    	}
    
    	rp = (void *)rsp->data;
    	printk("Actual Tx Power: %d\n", rp->selected_tx_power);
    
    	net_buf_unref(rsp);
    }
    
    
    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;
    	int8_t txp;
    	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;
    	}
    
    	/*bt_addr_le_to_str(bt_conn_foreach(conn), addr, sizeof(addr));*/
    		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;
    		get_tx_power(BT_HCI_VS_LL_HANDLE_TYPE_CONN,
    				     NULL, &txp);
    		LOG_INF("Connected: %s, tx_phy %u, rx_phy %u ,Initial Tx Power = %d",
    		       log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy, txp);
    
    		printk("Coded PHY Connected: %s, tx_phy %u, rx_phy %u, Initial Tx Power = %d\n",
    		       log_strdup(addr), phy_info->tx_phy, phy_info->rx_phy, txp);
    			   //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));
    	/*bt_addr_le_to_str(bt_conn_foreach(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 (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);
    	}
    }
    
    void modulate_tx_power(void *p1, void *p2, void *p3)
    {
    	int8_t txp_get = 0;
    	int8_t txp = -30;
    	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));
    		}
    	}
    }
    
    void main(void)
    {
    	int blink_status = 0;
    	int err = 0;
    	int8_t txp_get = 0xFF;
    	int8_t txp = -30;
    	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));
    		k_thread_create(&pwr_thread_data, pwr_thread_stack,
    			K_THREAD_STACK_SIZEOF(pwr_thread_stack),
    			modulate_tx_power, NULL, NULL, NULL,
    			K_PRIO_COOP(10),
    			0, K_NO_WAIT);
    	k_thread_name_set(&pwr_thread_data, "DYN TX");
    		/*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);
    

    I haven't changed the central_uart code. I'm getting to see on putty the below attached output,

    instead i wanted to see,

    00:12:09    d    RSSI: -30  Channel: 37 tx_power: 

    on the output terminal. How can I do this.

    I'm using 2 nRF5340-DK boards, SDK v1.8.0.

    Regards

    Karthik Kumar

  • OK so you're able to send data over BLE, and it looks like you're also able to measure tx_power?

    That's a good start.

    There's still a lot going on in your code though, and it's not easy for me to tell what's working for you and where you are stuck.

    Are you able to read rssi values at all?

    If not, what are you having problems with? Are you getting any error messages hinting at what isn't working?

    Or is your problem only related to printing your values?

    It's much easier for me to help you if I know exactly where you are stuck.

    Best regards,

    Einar

Related