combine scan and adv function with uart, nrf 52840

I have written the code to test the RSSI signal, and the segger shows the result on the debug terminal, However, the debug terminal can only show first 500 data, the first 500 will be erased as the time goes by. I want to save more than 10 thousands data via Tera term. Then I combine the uart with my code. I have add the directories of UART header files. The header files  regarding UART are added to my RSSI code. Here are output results.

It shows somethings are wrong with log.h, and I am afraid of changing anything in log.h. There is one thing wrong in main.c, shown as follows, please help me? I have been stuck in this for a month. How is the problem fixed?  thank you

#include <stdio.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "ble.h"
#include "boards.h"
#include "simple_hal.h"
#include "nrf_mesh.h"
#include "log.h"
#include "advertiser.h"
#include "mesh_app_utils.h"
#include "mesh_stack.h"
#include "ble_softdevice_support.h"
#include "mesh_provisionee.h"
#include "nrf_mesh_config_examples.h"
#include "app_timer.h"
#include "example_common.h"
#include "nrf_mesh_configure.h"
#include "ad_type_filter.h"
#include "app_uart.h"
#include <stdint.h>//below is uart header files
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "app_timer.h"
#include "ble_nus.h"
#include "app_util_platform.h"
#include "nrf_uart.h"
#include "nrf_atflags.h"
#define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256    
#define NRF_LOG_DEBUG(...)
#define NRF_LOG_HEXDUMP_DEBUG(p_data, len)
BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);  
static uint16_t   m_conn_handle          = BLE_CONN_HANDLE_INVALID; 
#if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
#include "stack_depth.h"
#endif

/*****************************************************************************
 * Definitions
 *****************************************************************************/
#define ADVERTISER_BUFFER_SIZE  (64)


/*****************************************************************************
 * Forward declaration of static functions
 *****************************************************************************/


/*****************************************************************************
 * Static variables
 *****************************************************************************/
/** Single advertiser instance. May periodically transmit one packet at a time. */
static advertiser_t m_advertiser;
static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;

static uint8_t      m_adv_buffer[ADVERTISER_BUFFER_SIZE];
static bool         m_device_provisioned;

//modify
uint8_t adv_addr[BLE_GAP_ADDR_LEN];
static uint8_t scan_rssi;

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t       err_code;

    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;

            if ((data_array[index - 1] == '\n') ||
                (data_array[index - 1] == '\r') ||
                (index >= m_ble_nus_max_data_len))
            {
                if (index > 1)
                {
                    NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                    NRF_LOG_HEXDUMP_DEBUG(data_array, index);

                    do
                    {
                        uint16_t length = (uint16_t)index;
                        err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                        if ((err_code != NRF_ERROR_INVALID_STATE) &&
                            (err_code != NRF_ERROR_RESOURCES) &&
                            (err_code != NRF_ERROR_NOT_FOUND))
                        {
                            APP_ERROR_CHECK(err_code);
                        }
                    } while (err_code == NRF_ERROR_RESOURCES);
                }

                index = 0;
            }
            break;

        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}
static void adv_start(void)
{
    /* Let scanner accept Complete Local Name AD Type. */
    bearer_adtype_add(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);

    advertiser_enable(&m_advertiser);
//    static const uint8_t adv_data[] =
//    {
//        0x11, /* AD data length (including type, but not itself) */
//        BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, /* AD data type (Complete local name) */
//        'N',  /* AD data payload (Name of device) */
//        'o',
//        'r',
//        'd',
//        'i',
//        'c',
//        ' ',
//        'S',
//        'e',
//        'm',
//        'i',
//        ' ',
//        'M',
//        'e',
//        's',
//        'h'
//   };
    uint8_t adv_data[]=
    {
      0x02, /* AD data length (including type, but not itself) */
      BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, /* AD data type (Complete local name) */
      scan_rssi,
    };
  
    adv_data[2]=scan_rssi;
    /* Allocate packet */
    adv_packet_t * p_packet = advertiser_packet_alloc(&m_advertiser, sizeof(adv_data));
    
   
    if(p_packet)
    {
        /* Construct packet contents */
        memcpy(p_packet->packet.payload, adv_data, sizeof(adv_data));
        /* Repeat forever */
        p_packet->config.repeats = ADVERTISER_REPEAT_INFINITE;
   
        advertiser_packet_send(&m_advertiser, p_packet);
        
        //modify
        //advertiser_packet_discard(&m_advertiser,p_packet);
//        
//        char advdata[128];
//
//        (void) sprintf(advdata, "adv %d",adv_data[2]);
//        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, advdata);
        for(int i=0;i<BLE_GAP_ADDR_LEN;i++)
          adv_addr[i]= p_packet->packet.addr[i];
    }

}
static void rx_cb(const nrf_mesh_adv_packet_rx_data_t * p_rx_data)
{
    LEDS_OFF(BSP_LED_0_MASK);  /* @c LED_RGB_RED_MASK on pca10031 */
    char msg[128];
    char data[128];
//    (void) sprintf(msg, "RX [@%u]: RSSI: %3d ADV TYPE: %x ADDR: [%02x:%02x:%02x:%02x:%02x:%02x]",
//                   p_rx_data->p_metadata->params.scanner.timestamp,
//                   p_rx_data->p_metadata->params.scanner.rssi,
//                   p_rx_data->adv_type,
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[0],
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[1],
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[2],
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[3],
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[4],
//                   p_rx_data->p_metadata->params.scanner.adv_addr.addr[5]);
      scan_rssi=(uint8_t)abs( p_rx_data->p_metadata->params.scanner.rssi);   
     (void) sprintf(data, "adv:[%02x:%02x] scan:[%02x:%02x] ch:%d rssi=%3d",
                    adv_addr[0],
                    adv_addr[1],
                    p_rx_data->p_metadata->params.scanner.adv_addr.addr[0],
                    p_rx_data->p_metadata->params.scanner.adv_addr.addr[1],
                    p_rx_data->p_metadata->params.scanner.channel,
                    p_rx_data->p_metadata->params.scanner.rssi
                   );
 
    //printf("adv ADDR: [%02x:%02x:%02x:%02x:%02x:%02x] ",adv_addr[0],adv_addr[1],adv_addr[2],adv_addr[3],adv_addr[4],adv_addr[5]);
    __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, data, p_rx_data->p_payload, p_rx_data->length);
    
    //__LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, msg, p_rx_data->p_payload, p_rx_data->length);
    LEDS_ON(BSP_LED_0_MASK);  /* @c LED_RGB_RED_MASK on pca10031 */
}

static void adv_init(void)
{   
    ret_code_t err_code;
    advertiser_instance_init(&m_advertiser, NULL, m_adv_buffer, ADVERTISER_BUFFER_SIZE);
    //modify tx power
    //err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertiser.handle, 4);
    //APP_ERROR_CHECK(err_code);
   
}



static void node_reset(void)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
    /* This function may return if there are ongoing flash operations. */
    mesh_stack_device_reset();
}

static void config_server_evt_cb(const config_server_evt_t * p_evt)
{
    if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
    {
        node_reset();
    }
}

static void device_identification_start_cb(uint8_t attention_duration_s)
{
    hal_led_mask_set(LEDS_MASK, false);
    hal_led_blink_ms(BSP_LED_2_MASK  | BSP_LED_3_MASK,
                     LED_BLINK_ATTENTION_INTERVAL_MS,
                     LED_BLINK_ATTENTION_COUNT(attention_duration_s));
}

static void provisioning_aborted_cb(void)
{
    hal_led_blink_stop();
}

static void unicast_address_print(void)
{
    dsm_local_unicast_address_t node_address;
    dsm_local_unicast_addresses_get(&node_address);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);
}

static void provisioning_complete_cb(void)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");

    unicast_address_print();
    hal_led_blink_stop();
    hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
}

static void mesh_init(void)
{
    mesh_stack_init_params_t init_params =
    {
        .core.irq_priority = NRF_MESH_IRQ_PRIORITY_LOWEST,
        .core.lfclksrc     = DEV_BOARD_LF_CLK_CFG,
        .models.config_server_cb = config_server_evt_cb
    };

    uint32_t status = mesh_stack_init(&init_params, &m_device_provisioned);
    switch (status)
    {
        case NRF_ERROR_INVALID_DATA:
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Data in the persistent memory was corrupted. Device starts as unprovisioned.\n");
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Reset device before starting of the provisioning process.\n");
            break;
        case NRF_SUCCESS:
            break;
        default:
            ERROR_CHECK(status);
    }

    /* Start listening for incoming packets */
    nrf_mesh_rx_cb_set(rx_cb);

    /* Initialize the advertiser */
    adv_init();
}

static void initialize(void)
{
#if defined(NRF51) && defined(NRF_MESH_STACK_DEPTH)
    stack_depth_paint_stack();
#endif

    ERROR_CHECK(app_timer_init());
    hal_leds_init();

    __LOG_INIT(LOG_SRC_APP, LOG_LEVEL_INFO, log_callback_rtt);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Bluetooth Mesh Beacon Example -----\n");

    ble_stack_init();

    mesh_init();

    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initialization complete!\n");
}

static void start(void)
{   
  
    if (!m_device_provisioned)
    {
        static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
        mesh_provisionee_start_params_t prov_start_params =
        {
            .p_static_data    = static_auth_data,
            .prov_complete_cb = provisioning_complete_cb,
            .prov_device_identification_start_cb = device_identification_start_cb,
            .prov_device_identification_stop_cb = NULL,
            .prov_abort_cb = provisioning_aborted_cb,
            .p_device_uri = EX_URI_BEACON
        };
        ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
    }
    else
    {
        unicast_address_print();
    }

    /* Start advertising own beacon */
    /* Note: If application wants to start beacons at later time, adv_start() API must be called
     * from the same IRQ priority context same as that of the Mesh Stack. */
    adv_start();

    mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());

    ERROR_CHECK(mesh_stack_start());

    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Bluetooth Mesh Beacon example started!\n");

    hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
}

static void uart_init(void)
{
    ret_code_t err_code;

    app_uart_comm_params_t const comm_params =
    {
        .rx_pin_no    = RX_PIN_NUMBER,
        .tx_pin_no    = TX_PIN_NUMBER,
        .rts_pin_no   = RTS_PIN_NUMBER,
        .cts_pin_no   = CTS_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity   = false,
        .baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
    };

    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_event_handle,
                       APP_IRQ_PRIORITY_LOWEST,
                       err_code);

    APP_ERROR_CHECK(err_code);
}


int main(void)
{
    uart_init();
    printf("hello");
    initialize();
    start();
    for (;;)
    {   
      (void)sd_app_evt_wait();
    }
}

  • Hi

    What steps exactly did you take to add UART functionality to your sample exactly and what are you planning on using UART for in your application? I think what is happening here is that you have configured the UART incorrectly when adding it to your own project. Did you for example add mentions to the header file and the necessary files to the preprocessor definitions, etc.?

    Best regards,

    Simon

  • I add the UART code to my main function to save RSSI signal on Tera term.Then, I include the header files and reset the directory, making sure all the ".h" files related to the UART are included in the local folders. and the path of these UART headers are added in the segger preprocessor directories. The uart code is from nRF5SDK160098a08e2, as follows

    /**
     * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include "nordic_common.h"
    #include "app_error.h"
    #include "app_uart.h"
    #include "ble_db_discovery.h"
    #include "app_timer.h"
    #include "app_util.h"
    #include "bsp_btn_ble.h"
    #include "ble.h"
    #include "ble_gap.h"
    #include "ble_hci.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_sdh_soc.h"
    #include "ble_nus_c.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_pwr_mgmt.h"
    #include "nrf_ble_scan.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    #define APP_BLE_CONN_CFG_TAG    1                                       /**< Tag that refers to the BLE stack configuration set with @ref sd_ble_cfg_set. The default tag is @ref BLE_CONN_CFG_TAG_DEFAULT. */
    #define APP_BLE_OBSERVER_PRIO   3                                       /**< BLE observer priority of the application. There is no need to modify this value. */
    
    #define UART_TX_BUF_SIZE        256                                     /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE        256                                     /**< UART RX buffer size. */
    
    #define NUS_SERVICE_UUID_TYPE   BLE_UUID_TYPE_VENDOR_BEGIN              /**< UUID type for the Nordic UART Service (vendor specific). */
    
    #define ECHOBACK_BLE_UART_DATA  1                                       /**< Echo the UART data that is received over the Nordic UART Service (NUS) back to the sender. */
    
    
    BLE_NUS_C_DEF(m_ble_nus_c);                                             /**< BLE Nordic UART Service (NUS) client instance. */
    NRF_BLE_GATT_DEF(m_gatt);                                               /**< GATT module instance. */
    BLE_DB_DISCOVERY_DEF(m_db_disc);                                        /**< Database discovery module instance. */
    NRF_BLE_SCAN_DEF(m_scan);                                               /**< Scanning Module instance. */
    NRF_BLE_GQ_DEF(m_ble_gatt_queue,                                        /**< BLE GATT Queue instance. */
                   NRF_SDH_BLE_CENTRAL_LINK_COUNT,
                   NRF_BLE_GQ_QUEUE_SIZE);
    
    static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
    
    /**@brief NUS UUID. */
    static ble_uuid_t const m_nus_uuid =
    {
        .uuid = BLE_UUID_NUS_SERVICE,
        .type = NUS_SERVICE_UUID_TYPE
    };
    
    
    /**@brief Function for handling asserts in the SoftDevice.
     *
     * @details This function is called in case of an assert in the SoftDevice.
     *
     * @warning This handler is only an example and is not meant for the final product. You need to analyze
     *          how your product is supposed to react in case of assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in] line_num     Line number of the failing assert call.
     * @param[in] p_file_name  File name of the failing assert call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(0xDEADBEEF, line_num, p_file_name);
    }
    
    
    /**@brief Function for handling the Nordic UART Service Client errors.
     *
     * @param[in]   nrf_error   Error code containing information about what went wrong.
     */
    static void nus_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    
    /**@brief Function to start scanning. */
    static void scan_start(void)
    {
        ret_code_t ret;
    
        ret = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(ret);
    
        ret = bsp_indication_set(BSP_INDICATE_SCANNING);
        APP_ERROR_CHECK(ret);
    }
    
    
    /**@brief Function for handling Scanning Module events.
     */
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        ret_code_t err_code;
    
        switch(p_scan_evt->scan_evt_id)
        {
             case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
             {
                  err_code = p_scan_evt->params.connecting_err.err_code;
                  APP_ERROR_CHECK(err_code);
             } break;
    
             case NRF_BLE_SCAN_EVT_CONNECTED:
             {
                  ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
                 NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                          p_connected->peer_addr.addr[0],
                          p_connected->peer_addr.addr[1],
                          p_connected->peer_addr.addr[2],
                          p_connected->peer_addr.addr[3],
                          p_connected->peer_addr.addr[4],
                          p_connected->peer_addr.addr[5]
                          );
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 NRF_LOG_INFO("Scan timed out.");
                 scan_start();
             } break;
    
             default:
                 break;
        }
    }
    
    
    /**@brief Function for initializing the scanning and setting the filters.
     */
    static void scan_init(void)
    {
        ret_code_t          err_code;
        nrf_ble_scan_init_t init_scan;
    
        memset(&init_scan, 0, sizeof(init_scan));
    
        init_scan.connect_if_match = true;
        init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
    
        err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling database discovery events.
     *
     * @details This function is a callback function to handle events from the database discovery module.
     *          Depending on the UUIDs that are discovered, this function forwards the events
     *          to their respective services.
     *
     * @param[in] p_event  Pointer to the database discovery event.
     */
    static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
    {
        ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);
    }
    
    
    /**@brief Function for handling characters received by the Nordic UART Service (NUS).
     *
     * @details This function takes a list of characters of length data_len and prints the characters out on UART.
     *          If @ref ECHOBACK_BLE_UART_DATA is set, the data is sent back to sender.
     */
    static void ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len)
    {
        ret_code_t ret_val;
    
        NRF_LOG_DEBUG("Receiving data.");
        NRF_LOG_HEXDUMP_DEBUG(p_data, data_len);
    
        for (uint32_t i = 0; i < data_len; i++)
        {
            do
            {
                ret_val = app_uart_put(p_data[i]);
                if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("app_uart_put failed for index 0x%04x.", i);
                    APP_ERROR_CHECK(ret_val);
                }
            } while (ret_val == NRF_ERROR_BUSY);
        }
        if (p_data[data_len-1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
        if (ECHOBACK_BLE_UART_DATA)
        {
            // Send data back to the peripheral.
            do
            {
                ret_val = ble_nus_c_string_send(&m_ble_nus_c, p_data, data_len);
                if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed sending NUS message. Error 0x%x. ", ret_val);
                    APP_ERROR_CHECK(ret_val);
                }
            } while (ret_val == NRF_ERROR_BUSY);
        }
    }
    
    
    /**@brief   Function for handling app_uart events.
     *
     * @details This function receives a single character from the app_uart module and appends it to
     *          a string. The string is sent over BLE when the last character received is a
     *          'new line' '\n' (hex 0x0A) or if the string reaches the maximum data length.
     */
    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        switch (p_event->evt_type)
        {
            /**@snippet [Handling data from UART] */
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
    
                if ((data_array[index - 1] == '\n') ||
                    (data_array[index - 1] == '\r') ||
                    (index >= (m_ble_nus_max_data_len)))
                {
                    NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                    NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                    do
                    {
                        ret_val = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
                        if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                        {
                            APP_ERROR_CHECK(ret_val);
                        }
                    } while (ret_val == NRF_ERROR_RESOURCES);
    
                    index = 0;
                }
                break;
    
            /**@snippet [Handling data from UART] */
            case APP_UART_COMMUNICATION_ERROR:
                NRF_LOG_ERROR("Communication error occurred while handling UART.");
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:
                NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief Callback handling Nordic UART Service (NUS) client events.
     *
     * @details This function is called to notify the application of NUS client events.
     *
     * @param[in]   p_ble_nus_c   NUS client handle. This identifies the NUS client.
     * @param[in]   p_ble_nus_evt Pointer to the NUS client event.
     */
    
    /**@snippet [Handling events from the ble_nus_c module] */
    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
    {
        ret_code_t err_code;
    
        switch (p_ble_nus_evt->evt_type)
        {
            case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
                NRF_LOG_INFO("Discovery complete.");
                err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
                APP_ERROR_CHECK(err_code);
    
                err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
                NRF_LOG_INFO("Connected to device with Nordic UART Service.");
                break;
    
            case BLE_NUS_C_EVT_NUS_TX_EVT:
                ble_nus_chars_received_uart_print(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
                break;
    
            case BLE_NUS_C_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                scan_start();
                break;
        }
    }
    /**@snippet [Handling events from the ble_nus_c module] */
    
    
    /**
     * @brief Function for handling shutdown events.
     *
     * @param[in]   event       Shutdown type.
     */
    static bool shutdown_handler(nrf_pwr_mgmt_evt_t event)
    {
        ret_code_t err_code;
    
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
        switch (event)
        {
            case NRF_PWR_MGMT_EVT_PREPARE_WAKEUP:
                // Prepare wakeup buttons.
                err_code = bsp_btn_ble_sleep_mode_prepare();
                APP_ERROR_CHECK(err_code);
                break;
    
            default:
                break;
        }
    
        return true;
    }
    
    NRF_PWR_MGMT_HANDLER_REGISTER(shutdown_handler, APP_SHUTDOWN_HANDLER_PRIORITY);
    
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t            err_code;
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
    
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
    
                // start discovery of services. The NUS Client waits for a discovery result
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
    
                NRF_LOG_INFO("Disconnected. conn_handle: 0x%x, reason: 0x%x",
                             p_gap_evt->conn_handle,
                             p_gap_evt->params.disconnected.reason);
                break;
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    NRF_LOG_INFO("Connection Request timed out.");
                }
                break;
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported.
                err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@brief Function for handling events from the GATT library. */
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
        {
            NRF_LOG_INFO("ATT MTU exchange completed.");
    
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Ble NUS max data length set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
    }
    
    
    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the BSP module.
     *
     * @param[in] event  Event generated by button press.
     */
    void bsp_event_handler(bsp_event_t event)
    {
        ret_code_t err_code;
    
        switch (event)
        {
            case BSP_EVENT_SLEEP:
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
                break;
    
            case BSP_EVENT_DISCONNECT:
                err_code = sd_ble_gap_disconnect(m_ble_nus_c.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;
    
            default:
                break;
        }
    }
    
    /**@brief Function for initializing the UART. */
    static void uart_init(void)
    {
        ret_code_t err_code;
    
        app_uart_comm_params_t const comm_params =
        {
            .rx_pin_no    = RX_PIN_NUMBER,
            .tx_pin_no    = TX_PIN_NUMBER,
            .rts_pin_no   = RTS_PIN_NUMBER,
            .cts_pin_no   = CTS_PIN_NUMBER,
            .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
            .use_parity   = false,
            .baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
    
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the Nordic UART Service (NUS) client. */
    static void nus_c_init(void)
    {
        ret_code_t       err_code;
        ble_nus_c_init_t init;
    
        init.evt_handler   = ble_nus_c_evt_handler;
        init.error_handler = nus_error_handler;
        init.p_gatt_queue  = &m_ble_gatt_queue;
    
        err_code = ble_nus_c_init(&m_ble_nus_c, &init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing buttons and leds. */
    static void buttons_leds_init(void)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the timer. */
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the nrf log module. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /** @brief Function for initializing the database discovery module. */
    static void db_discovery_init(void)
    {
        ble_db_discovery_init_t db_init;
    
        memset(&db_init, 0, sizeof(ble_db_discovery_init_t));
    
        db_init.evt_handler  = db_disc_handler;
        db_init.p_gatt_queue = &m_ble_gatt_queue;
    
        ret_code_t err_code = ble_db_discovery_init(&db_init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details Handles any pending log operations, then sleeps until the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    int main(void)
    {
        // Initialize.
        log_init();
        timer_init();
        uart_init();
        buttons_leds_init();
        db_discovery_init();
        power_management_init();
        ble_stack_init();
        gatt_init();
        nus_c_init();
        scan_init();
    
        // Start execution.
        printf("jack lin BLE UART central example started.\r\n");
        NRF_LOG_INFO("BLE UART central example started.");
        scan_start();
    
        // Enter main loop.
        for (;;)
        {
          printf("jack lin BLE UART central example started.\r\n");
            idle_state_handle();
        }
    }
    

    Finally, when compiling the codes, the log.h has errors, as follows

    /* Copyright (c) 2010 - 2020, Nordic Semiconductor ASA
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     * list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    #ifndef MESH_LOG_H__
    #define MESH_LOG_H__
    
    #include <stdarg.h>
    #include <stddef.h>
    #include <stdint.h>
    
    #include "nrf_mesh_defines.h"
    #include "nrf_mesh_config_core.h"
    #include "nordic_common.h"
    
    
    #if defined(HOST)
        #ifdef __linux__
            #include <time.h>
        #endif /* __linux__ */
    #else /* HOST */
        #include "nrf.h"
    #endif /* HOST */
    
    /**
     * @defgroup LOG Logging functions
     * @ingroup MESH_CORE
     * This module provides a common logging interface for the stack.
     * The module allows the user to choose what backend to use for logging.
     *
     * The following backends are supported:
     * * [**RTT**](https://www.segger.com/products/debug-probes/j-link/technology/real-time-transfer/general-information/):
     *   provides fast logging when using SEGGER's J-Link debuggers. This is used when
     *   `log_callback_rtt()` is passed to `__LOG_INIT()`.
     * * **Logview compatible RTT**: provides logs over RTT that can be viewed using the
     *   [Python Log Viewer](https://pythonhosted.org/logview).
     * * **Standard output**: Provides output to `stdout` when running on host. This is
     *   used when `log_callback_stdout` is passed to `__LOG_INIT()`.
     * @{
     */
    
    /** Maximum number of array elements to print in the @ref __LOG_XB macro. */
    #define LOG_ARRAY_LEN_MAX   128
    
    /**
     * @defgroup LOG_SOURCES Log sources
     * Defines various sources for logging messages. This can be used in __LOG_INIT() to
     * filter events from different modules.
     * @{
     */
    
    #define LOG_SRC_BEARER          (1 <<  0) /**< Receive logs from the bearer layer. */
    #define LOG_SRC_NETWORK         (1 <<  1) /**< Receive logs from the network layer. */
    #define LOG_SRC_TRANSPORT       (1 <<  2) /**< Receive logs from the transport layer. */
    #define LOG_SRC_PROV            (1 <<  3) /**< Receive logs from the provisioning module. */
    #define LOG_SRC_PACMAN          (1 <<  4) /**< Receive logs from the packet manager. */
    #define LOG_SRC_INTERNAL        (1 <<  5) /**< Receive logs from the internal event module. */
    #define LOG_SRC_API             (1 <<  6) /**< Receive logs from the nRF Mesh API. */
    #define LOG_SRC_DFU             (1 <<  7) /**< Receive logs from the DFU module. */
    #define LOG_SRC_BEACON          (1 <<  8) /**< Receive logs from the beacon module. */
    #define LOG_SRC_TEST            (1 <<  9) /**< Receive logs from unit tests. */
    #define LOG_SRC_ENC             (1 << 10) /**< Receive logs from the encryption module. */
    #define LOG_SRC_TIMER_SCHEDULER (1 << 11) /**< Receive logs from the timer scheduler. */
    #define LOG_SRC_CCM             (1 << 12) /**< Receive logs from the CCM module. */
    #define LOG_SRC_ACCESS          (1 << 13) /**< Receive logs from the access layer. */
    #define LOG_SRC_APP             (1 << 14) /**< Receive logs from the application. */
    #define LOG_SRC_SERIAL          (1 << 15) /**< Receive logs from the serial module. */
    #define LOG_SRC_FSM             (1 << 16) /**< Receive logs from the FSM module. */
    #define LOG_SRC_FRIEND          (1 << 17) /**< Receive logs from the Friend node. */
    #define LOG_SRC_DSM             (1 << 18) /**< Receive logs from the DSM module. */
    #define LOG_SRC_CORE            (1 << 19) /**< Receive logs from the other core modules. */
    #define LOG_SRC_FM              (1 << 20) /**< Receive logs from the flash management modules. */
    
    /** Group for receiving logs from the core stack. */
    #define LOG_GROUP_STACK (LOG_SRC_BEARER | LOG_SRC_NETWORK | LOG_SRC_TRANSPORT)
    
    /** @} */
    
    /**
     * @defgroup LOG_LEVELS Log levels
     * Defines possible criticality levels for logged messages. This can be used in
     * __LOG_INIT() to filter events by criticality.
     * @{
     */
    
    #define LOG_LEVEL_ASSERT ( 0) /**< Log level for assertions */
    #define LOG_LEVEL_ERROR  ( 1) /**< Log level for error messages. */
    #define LOG_LEVEL_WARN   ( 2) /**< Log level for warning messages. */
    #define LOG_LEVEL_REPORT ( 3) /**< Log level for report messages. */
    #define LOG_LEVEL_INFO   ( 4) /**< Log level for information messages. */
    #define LOG_LEVEL_DBG1   ( 5) /**< Log level for debug messages (debug level 1). */
    #define LOG_LEVEL_DBG2   ( 6) /**< Log level for debug messages (debug level 2). */
    #define LOG_LEVEL_DBG3   ( 7) /**< Log level for debug messages (debug level 3). */
    #define EVT_LEVEL_BASE   ( 8) /**< Base level for event logging. For internal use only. */
    #define EVT_LEVEL_ERROR  ( 9) /**< Critical error event logging level. For internal use only. */
    #define EVT_LEVEL_INFO   (10) /**< Normal event logging level. For internal use only. */
    #define EVT_LEVEL_DATA   (11) /**< Event data logging level. For internal use only. */
    
    /** @} */
    
    /** Filename macro used when printing. Provides the filename of the input file without any directory prefix. */
    #ifdef __CC_ARM
    #define __FILENAME__ __MODULE__
    #else
    #include <string.h>
    #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
    #endif
    
    #if NRF_MESH_LOG_ENABLE > 0
    
    /** Global debug mask. The value of this variable is used to filter the log messages being printed. */
    extern uint32_t g_log_dbg_msk;
    /** Global log level. The value of this variable is used to filter the log messages being printed. */
    extern int32_t g_log_dbg_lvl;
    
    /** Callback function used for printing log strings. */
    typedef void (*log_callback_t)(uint32_t dbg_level, const char * p_filename, uint16_t line,
                                       uint32_t timestamp, const char * format, va_list arguments);
    
    #if (LOG_ENABLE_RTT && !defined(HOST))
    /** Callback function for printing debug information over RTT. */
    void log_callback_rtt(uint32_t dbg_level, const char * p_filename, uint16_t line,
        uint32_t timestamp, const char * format, va_list arguments);
    
    /** Callback function for printing debug information over RTT in the format required by LogViewer. */
    void log_callback_logview(uint32_t dbg_level, const char * p_filename, uint16_t line,
        uint32_t timestamp, const char * format, va_list arguments);
    #endif
    
    #if defined(HOST)
    /** Callback function for printing debug information on stdout. */
    void log_callback_stdout(uint32_t dbg_level, const char * p_filename, uint16_t line,
        uint32_t timestamp, const char * format, va_list arguments);
    #endif
    
    /**
     * Initializes the logging module.
     *
     * @param[in] mask     Mask specifying which modules to log information from.
     * @param[in] level    Maximum log level to print messages from.
     * @param[in] callback Callback function for printing log strings.
     */
    void log_init(uint32_t mask, uint32_t level, log_callback_t callback);
    
    /**
     * Sets the log callback function.
     *
     * The callback function is called to print strings from the logging module.
     * An application that is interested in internal logging can set this function
     * in order to print the log information in an application-specific way.
     *
     * @param[in] callback The callback function to use for printing log information.
     */
    void log_set_callback(log_callback_t callback);
    
    /**
     * Gets a timestamp to use with the log functions.
     *
     * When compiling for target, the timestamp is the current value of the RTC1 counter. If
     * compiling for a Linux host, the timestamp is the value of the system real-time clock in 繕s.
     *
     * On Windows hosts, this function returns 0.
     *
     * @return A timestamp to use with the log functions.
     */
    static inline uint32_t log_timestamp_get(void)
    {
    #if defined(HOST)
        #if defined(__linux__)
            struct timespec now;
            clock_gettime(CLOCK_REALTIME, &now);
            return (now.tv_sec * 1000000UL) + (now.tv_nsec / 1000UL);
        #else
            return 0;
        #endif
    #else
        return NRF_RTC1->COUNTER;
    #endif
    }
    
    /**
     * Prints log data.
     * This function is used by the logging macros, but can also be called directly
     * if desired.
     *
     * @param[in] dbg_level    The debugging level to print the message as.
     * @param[in] p_filename   Name of the file in which the log call originated.
     * @param[in] line         Line number where the function was called.
     * @param[in] timestamp    Timestamp for when the log function was called.
     * @param[in] format       Format string, printf()-compatible.
     *
     * @see log_vprintf()
     */
    void __attribute((format(printf, 5, 6))) log_printf(
        uint32_t dbg_level, const char * p_filename, uint16_t line, uint32_t timestamp, const char * format, ...);
    
    /**
     * Prints log data.
     * This function is used by the logging macros, but can also be called directly
     * if desired.
     *
     * @param[in] dbg_level    The debugging level to print the message as.
     * @param[in] p_filename   Name of the file in which the log call originated.
     * @param[in] line         Line number for where the log function was called.
     * @param[in] timestamp    Timestamp for when the log function was called.
     * @param[in] format       Format string, printf()-compatible.
     * @param[in] arguments    Arguments according to the @c format string.
     *
     * @see log_printf()
     */
    void log_vprintf(uint32_t dbg_level, const char * p_filename, uint16_t line, uint32_t timestamp,
        const char * format, va_list arguments);
    
    /**
     * Initializes the logging framework.
     * @param[in] msk      Log mask
     * @param[in] level    Log level
     * @param[in] callback Log callback
     */
    #define __LOG_INIT(msk, level, callback) log_init(msk, level, callback)
    
    /**
     * Prints a log message.
     * @param[in] source Log source
     * @param[in] level  Log level
     * @param[in] ...    Arguments passed on to the callback (similar to @c printf)
     */
    #define __LOG(source, level, ...)                                 
     if((source & g_log_dbg_msk) && level <= g_log_dbg_lvl)            
     {                                                                   
      log_printf(level, __FILENAME__, __LINE__, log_timestamp_get(), __VA_ARGS__); 
     }
    
    /**
     * Prints an array with a message.
     * @param[in] source Log source
     * @param[in] level  Log level
     * @param[in] msg    Message string
     * @param[in] array  Pointer to array
     * @param[in] len    Length of array (in bytes)
     */
    #define __LOG_XB(source, level, msg, array, array_len)                  
     if ((source & g_log_dbg_msk) && (level <= g_log_dbg_lvl))              
     {                                                                       
      unsigned _array_len = array_len;                                   
      _array_len = MIN(_array_len, LOG_ARRAY_LEN_MAX);                   
      char array_text[LOG_ARRAY_LEN_MAX * 2 + 1];                      
      for(unsigned _i = 0; _i < _array_len; ++_i)                      
      {                                                               
        extern const char * g_log_hex_digits;                           
        const uint8_t array_elem = (array)[_i];                         
        array_text[_i * 2] = g_log_hex_digits[(array_elem >> 4) & 0xf]; 
        array_text[_i * 2 + 1] = g_log_hex_digits[array_elem & 0xf];    
      }                                                                   
        array_text[_array_len * 2] = 0;                                     
         log_printf(level, __FILENAME__, __LINE__, log_timestamp_get(), "%s: %s\n", msg, ' ');    
     }
     //log_printf(level, __FILENAME__, __LINE__, log_timestamp_get(), "%s: %s\n", msg, array_text); 
    #else
    #define __LOG_INIT(...)
    #define __LOG(...)
    #define __LOG_XB(...)
    
    #ifndef LOG_CALLBACK_DEFAULT
    /** Default log callback. */
    #define LOG_CALLBACK_DEFAULT NULL
    #endif
    
    #endif  /* NRF_MESH_LOG_ENABLE */
    
    /** @} */
    #endif  /* LOG_H__ */
    

    This is the error message from "log.h" after compiling

    Building ‘beaconing_nrf52840_xxAA_s140_7.0.1’ from solution ‘beaconing_nrf52840_xxAA_s140_7.0.1’ in configuration ‘Debug’
    1> Compiling ‘main.c’
    2> Compiling ‘mesh_provisionee.c’
    4> Compiling ‘mesh_app_utils.c’
    3> Compiling ‘ble_softdevice_support.c’
    4> In file included from C:\nrf5_SDK_for_Mesh_v4.2.0_src\examples\beaconing_t\mesh_app_utils.c:42:
    4> ../../mesh/core/include/log.h:261:2: error: expected identifier or '(' before 'if'
    4> ../../mesh/core/include/log.h:263:66: warning: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro
    4> ../../mesh/core/include/log.h:275:2: error: expected identifier or '(' before 'if'
    1> In file included from C:\nrf5_SDK_for_Mesh_v4.2.0_src\examples\beaconing_t\main.c:8:
    1> ../../mesh/core/include/log.h:261:2: error: expected identifier or '(' before 'if'
    1> ../../mesh/core/include/log.h:263:66: warning: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro
    1> ../../mesh/core/include/log.h:275:2: error: expected identifier or '(' before 'if'
    2> In file included from ../../mesh/core/include/packet.h:48,
    2>                  from ../../mesh/core/include/heartbeat.h:43,
    2>                  from ../../models/foundation/config/include/config_server_events.h:44,
    2>                  from ../../mesh/stack/api/mesh_stack.h:42,
    2>                  from C:\nrf5_SDK_for_Mesh_v4.2.0_src\examples\beaconing_t\mesh_provisionee.c:41:
    2> ../../mesh/core/include/log.h:261:2: error: expected identifier or '(' before 'if'
    2> ../../mesh/core/include/log.h:263:66: warning: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro
    2> ../../mesh/core/include/log.h:275:2: error: expected identifier or '(' before 'if'
    3> In file included from C:\nrf5_SDK_for_Mesh_v4.2.0_src\examples\beaconing_t\ble_softdevice_support.c:61:
    3> ../../mesh/core/include/log.h:261:2: error: expected identifier or '(' before 'if'
    3> ../../mesh/core/include/log.h:263:66: warning: __VA_ARGS__ can only appear in the expansion of a C99 variadic macro
    3> ../../mesh/core/include/log.h:275:2: error: expected identifier or '(' before 'if'
    1> C:\nrf5_SDK_for_Mesh_v4.2.0_src\examples\beaconing_t\main.c:198:26: warning: implicit declaration of function 'abs' [-Wimplicit-function-declaration]
    Build failed
    

  • Hi

    Have you followed the getting started documentation of the nRF5 SDK for Mesh to make sure your toolchain and stack is set up correctly? https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.meshsdk.v5.0.0/md_doc_getting_started_how_to_toolchain.html 

    The errors you're getting seem to be related to syntax errors, but I assume you haven't made changes to the log.h file in question, so that doesn't make much sense. My guess is that the Mesh SDK isn't set up correctly. What Bluetooth Mesh functionality is it that you're trying to include exactly, and does it build correctly before adding the UART functionality?

    Best regards,

    Simon

Related