This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Failing to advertise Nordic UART Service

S110 v8.0.0

SDK v8.0.0

ble_app_uart example

image description

I first initialize the services and then initialize advertising. Everything works fine when I do NOT advertise the nus. As soon as I comment that code back in, the firmware seems to crash. I've noticed before crashing m_nus.uuid_type is 0x3 which is NOT in ble_types.h:

/** @defgroup BLE_UUID_TYPES Types of UUID
 * @{ */
#define BLE_UUID_TYPE_UNKNOWN       0x00 /**< Invalid UUID type. */
#define BLE_UUID_TYPE_BLE           0x01 /**< Bluetooth SIG UUID (16-bit). */
#define BLE_UUID_TYPE_VENDOR_BEGIN  0x02 /**< Vendor UUID types start at this index (128-bit). */
/** @} */

My functions:

static ble_nus_t m_nus;

static void OnNusDataReceived(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length) {
  ble_nus_string_send(p_nus, p_data, length);
}

static void my_services_init(void) {
  uint32_t err_code;
  ble_nus_init_t nus_init;

  // Initialize the Nordic UART Service
  memset(&nus_init, 0, sizeof(nus_init));
  nus_init.data_handler = OnNusDataReceived;
  err_code = ble_nus_init(&m_nus, &nus_init);
  APP_ERROR_CHECK(err_code);
}

static void my_advertising_init(void) {
  uint32_t err_code;
  ble_advdata_t advdata;
  ble_advdata_t scanrsp;

  ble_uuid_t adv_uuids[] = {
    {BLE_UUID_NUS_SERVICE, m_nus.uuid_type}
    //{BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_UNKNOWN}
    //{BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_BLE}
    //{BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}
  };

  // Build and set advertising data
  memset(&advdata, 0, sizeof(advdata));
  advdata.name_type               = BLE_ADVDATA_FULL_NAME;
  advdata.include_appearance      = true;
  advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
  
  memset(&scanrsp, 0, sizeof(scanrsp));
  scanrsp.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
  scanrsp.uuids_complete.p_uuids  = adv_uuids;
  
  err_code = ble_advdata_set(&advdata, &scanrsp);
  APP_ERROR_CHECK(err_code);
  
  // Initialize advertising parameters (used when starting advertising)
  memset(&m_adv_params, 0, sizeof(ble_gap_adv_params_t));
  m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;
  m_adv_params.p_peer_addr = NULL; // Undirected advertisement.
  m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;
  m_adv_params.interval    = APP_ADV_INTERVAL;
  m_adv_params.timeout     = APP_ADV_TIMEOUT_IN_SECONDS;
}
  • I just answered a very similar question - devzone.nordicsemi.com/.../

    and the firmware doesn't 'seem to crash', I'm quite sure the ble_advdata_set() returns an error code and the APP_ERROR_CHECK() then sends you to the error handler, in which you should always put a breakpoint, or when nothing happened hit 'break' in the debugger to see where you were, and that would have pointed to the line of code which generated the error.

  • Thank you for the debugging advice. I am not able to put a breakpoint in APP_ERROR_CHECK (it's a macro that gets repeated inline many places). I am also not able to put a breakpoint in assert_nrf_callback even if I define DEBUG macro in the project settings and am sure to compile with optimization level 0. How do you place your breakpoint? Example project is still very unreliable even with a one character name on an nrf51822_xxAA.

  • The macro calls a macro which eventually calls an error handling function, normally app_error_handler, which either you defined yourself or a default implementation was used. Put the breakpoint there. Alternatively since the app_error_handler() just spins in a busy loop, hit 'break' and look at the stack trace, it should show how you got there and somewhere have the error code.

    Either way it's going to be data too large, you can't fit a 16 byte UUID + more than a small-sized name + the flags into a 31 byte ad packet. Go stuff it in the scan response instead, or use a very short name.

    It is rather annoying that when you have to use custom service UUIDs you're very restricted to one, and at the outside 2, in the ad data, and only if you remove just about everything else.

  • @RK Thank you. I've updated the OP to only put the uuids in the scan response instead. I'm able to advertise now, just not able to see TX or RX logs with the mobile app (basically advertises just doesn't work with example app).

  • I see you got your response, but I just want to add that BLE_UUID_TYPE_VENDOR_BEGIN is the index of the first vendor-specific UUID you add. Consecutive VS-UUIDs added will continue to count upwards from this number. If you want to send a request, or receive a response with one of the VS-UUIDs you added, the stack will set the type to the value you got earlier. This means you need to store the ID you got from the stack somewhere if you want to know which VS-UUID this response contained.

Related