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

sd_ble_gap_scan_start returned 0x9

I am trying some scanning with a parameter setting, code below. The scan start, I am guessing by the call to nrf_ble_scan_start, generates the error sd_ble_gap_scan_start returned 0x9, which is "invalid length" (not sure)? What length should be changed?

static ble_gap_scan_params_t m_scan_param = {
.extended = 1,
.report_incomplete_evts = 1,
.active = 1,
.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
.scan_phys = BLE_GAP_PHY_1MBPS, // or .scan_phys = BLE_GAP_PHY_1MBPS, 2MBPS
.interval = SCAN_INTERVAL, // 180
.window = SCAN_WINDOW, // 90
.timeout = SCAN_TIMEOUT // 0
};

  • You are required to pass two arguments to sd_ble_gap_scan_start(): a pointer to a ble_gap_scaan_params_t structure, *and* a pointer to a ble_data_t structure for the scan buffer. You only showed us how you configured the former. How did you configure the latter?

    The scan buffer is where the SoftDevice will put the advertising data that it receives from other devices. You need to allocate a buffer big enough to hold the max data you expect to receive. Look for BLE_GAP_SCAN_BUFFER_SIZE in ble_gap.h and you'll see some macros with common sizes. You probably want to use either BLE_GAP_SCAN_BUFFER_MAX or BLE_GAP_SCAN_BUFFER_EXTENDED_MAX.

    -Bill

  • Thanks for the suggestion Bill, I may have to try that. The examples of scan_start which I am following do not directly use sd_ble_gap_scan_start(), they use  nrf_ble_scan_start(&m_scan) where the m_scan variable is created by macro:

    NRF_BLE_SCAN_DEF(m_scan);

    According to the SDK documents, that macro defines a nrf_ble_scan instance.

    What's interesting to me is that my test app does scan with this change:

    init_scan.connect_if_match = false;
    init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
    init_scan.p_scan_param = &m_scan_param;
    init_scan.p_scan_param = NULL;

    (the last line gets rid of the scan parameter entirely, just using NULL to initialize the scan instance). 

    Maybe the answer is indeed to directly call sd_ble_gap_scan_start with two arguments, as you suggest. But then why do other program examples I have seen work with the scan_param and the simpler nrf_ble_scan_start(&m_scan)? I must be doing something else wrong.

  • My apologies, it wasn't clear to me that you were the nrf_ble_scan_start() API rather than calling the SoftDevice function directly.

    NRF_BLE_SCAN_DEF() seems to be used to declare an instance of an nrf_ble_scan_t structure, the pointer to which you pass to nrf_ble_scan_start(). The scan buffer is embedded inside the this structure. The size used to declare the buffer is NRF_BLE_SCAN_BUFFER which in most examples seems to be 31. (That agrees with BLE_GAP_SCAN_BUFFER_MAX.)

    Without seeing all of your code it's hard to say what could be going wrong. Is NRF_BLE_SCAN_BUFFER being redefined somewhere?

    I can tell you that error 9 is indeed what sd_ble_gap_scan_start() will report if you give it a bad scan buffer size (from ble_gap.h):

    * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN.

    What I would do us run your code with the debugger attached and set a breakpoint on sd_ble_gap_scan_start(), and when it hits, examine the contents of the ble_gap_scaan_params_t and ble_data_t arguments for any inconsistencies. From there if you look at the stack trace, you should be able to see up the chain to where nrf_ble_scan_start() is invoked and maybe see where things went wrong.

    -Bill

  • Very good suggestions. I did find NRF_BLE_SCAN_BUFFER was 31 in config/sdk_config.h and tried changing that to 255 (which I saw in a couple other scan demo apps). But the result was 

    sd_ble_gap_scan_start returned 0x6

    a NOT SUPPORTED error. Then I put NRF_BLE_SCAN_BUFFER back to 31, since the comments in ble_gap.h say that 255 will be used anyway where extended=1 is specified in the params_t structure. However, it continued to fail. Eventually, I used this as the params setting:

    static ble_gap_scan_params_t m_scan_param = {
    .extended = 0,
    .report_incomplete_evts = 0,
    .active = 1,
    .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
    .scan_phys = BLE_GAP_PHY_1MBPS, // or .scan_phys = BLE_GAP_PHY_1MBPS, 2MBPS
    .interval = SCAN_INTERVAL, // 180
    .window = SCAN_WINDOW, // 90
    .timeout = SCAN_TIMEOUT // 0
    };

    Notice that extended=0, report_incomplete_evts=0 and the others are the same as originally attempted. That works, the program does scan and report beacons. However, I won't suggest this as a definitive answer because I have seen demo programs (on github) using extended=1. I am possibly missing some other things in sdk_config.h.

    Thank you Bill.

  • According to the ble_gap.h file:

    * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length.
    * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN.

    So if you use extended=1, I think you need to increase the scan buffer size. The extended advertising feature allows you to receive more than 31 bytes per packet. It's only supported for BLE 5.0 and later though. If you turn it on, you need to be able to handle either extended or legacy advertisements, but you have to provide a large enough buffer for the largest/worst case.

    So what should work is:

    extended = 1 and NRF_BLE_SCAN_BUFFER = 255

    or

    extended = 0 and  NRF_BLE_SCAN_BUFFER = 31

    I'm not sure what other parameters might need to be changed for extended advertisement support. There are a couple of examples in the SDK which use NRF_BLE_SCAN_BUFFER = 255 (ble_app_rscs_c, ble_app_hrs_rscs_relay), so I would maybe look at one of those.

    -Bill

Related