Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

NUS Central and Peripheral MAC Filter and Whitelist

Hello everyone,

I developed an application that makes it possible to scan devices and retransmit your advertisements. In addition to enabling the connection with peripheral devices, it also allows the connection to a central device, retransmitting data via the NUS service from the central to the peripherals.

Currently, I filter the devices that I want to retransmit the advertising through the following code in the scan_evt_handler() function.

case NRF_BLE_SCAN_EVT_NOT_FOUND:
            if(memcmp("\xac\x31\x38",&p_scan_evt->params.p_not_found->peer_addr.addr[3],3) == 0){
            ...
            }

As I understand it, I'm actually receiving all the advertising but I only perform the retransmission if the condition of the device starting with MAC 38:31:AC is satisfied, correct? For performance reasons would it be better to use a MAC filter so that this filtering is done in Softdevice or would there be no difference? If there is a difference, I want to carry out this implementation, but I haven't seen any example that the implementation is carried out from a MAC range.

In the filter implementations I found, I see that the filter is applied to a specific MAC, but what I want is to listen to all devices that start with MAC 38:31:AC, is it possible to do this? If yes, could you provide me with an example?

My other doubt would be in relation to retransmission through NUS. Is it possible when retransmitting data from the peripheral or central, choose the device I'm going to connect to and send the data through the MAC of this device? I saw some examples doing this by the connection identifier, but I would like to know who to direct the data to according to the MAC, as I will not maintain a connection with peripherals, I just connect to send data. In short, I would like to establish a connection and send data only if the device has a specific MAC. 

How to do this, can you give me an example?

I'm open to suggestions, I'd like to do this with the best possible performance, either with a whitelist or filters. Thank you very much.

I'm using nRF 52840, Softdevice S140, nRF5 SDK 17.0.2 and my application has a  nus central + nus + beacon.

Parents
  • Hi,

    In the filter implementations I found, I see that the filter is applied to a specific MAC, but what I want is to listen to all devices that start with MAC 38:31:AC, is it possible to do this? If yes, could you provide me with an example?

    That is not possible with the SoftDevice whitelisting, and also whitelisting is about controlling connections, so it does not do what you want in any case. So you need to continue to parse the Bluetooth address on your own, as you are doing.

    In short, I would like to establish a connection and send data only if the device has a specific MAC. 

    Here it sounds like you only want to establish connections with devices with a specific address? If so, that is precisely what whitelisting is for. If you just want to filter a specific address, then I suggest you look at this post. Whitelisting is similar both in central and peripheral roles.

  • Einar, as I said the filter was working, but the filter applied previously was related to the UUID, I tried to add a filter referring to the address, and I'm not successful! I've checked it several times, I've also tried using examples and I can't get the address filter to work!

    Could you take a look at my code to see what's going on? I don't get any error, I find the mac searched for filter through the scan but I never get a match. I've tried running examples and I can never get connection using the address filter, I found several cases with the same problem... is this a bug in sdk 17.0.2?

  • Hi,

    There is in fact a bug in the scan filter module which was fixed in SDK 17.1.0, which prevented filtering on some public Bluetooth addresses (where the two most significant bits were incorrectly assumes to indicate address type). You can work around this by using  nrf_ble_scan.c and  nrf_ble_scan.h from SDK 17.1.0 in your 17.0.2 based application.

    Another typical issue is to mix up endianness if yo manually add address, so if the above does not help that is also worth checking.

  • I made the recommendation, replace nrf_ble_scan.c and nrf_ble_scan.h from SDK 17.1.0 in SDK 17.0.2, not successful, still not getting address match, in relation to address byte order, I can guarantee that it is correct, because using the same filter settings and address identification using an example from SDK 17.1.0 get success.

    Could you try to identify in my code what is happening? I can send you in private!

  • I sent the code to you and to Vidar too, he was handling a similar case, and it looks like the problem was in the SDK. Could you try to run the code and help me identify if it's a bug with SDK 17.0.2? Thank you very much.

  • Hello, i have updates!

    As I had suggested, this is a bug from SDK 17.0.2. I switched my application to SDK 17.1.0 without changing anything in my code, and the address filter started working.

Reply Children
  • The only question that remained for me was to understand the difference between a connection coming from the central to the peripheral and a connection coming from the peripheral to the central.

    Because when I connect through nRF Connect on my central, everything works fine, but when I connect from the central to the peripheral corresponding to the filter, I get an error when I try for stop the scan module to change the MAC.

    Why does this happen when the connection comes from the central to the peripheral, and not when a peripheral (smartphone) is connected to the central?

    As I understand it, when I make a connection with a peripheral through the central, the scan module is automatically paused, but when I make the connection through nRF Connect with the central, the scan is not paused, why does this occur? Can I prevent the scan from being paused when requesting a connection through the central?

  • The central and peripheral plays completely different roles when it comes to establishing a connection in BLE.

    Thabet said:
    but when I connect from the central to the peripheral corresponding to the filter, I get an error when I try for stop the scan module to change the MAC.

    I assume this is the remaining issue you are referring to. Can you explain where you get this error? Which function returns an error, and what is the error code? Perhaps it is related to "NRF_ERROR_INVALID_STATE, when calling the stop scan function inside the beacon function." which you wrote some posts back? That does not really say much though (both as beacon is a advertiser activity and not scan related), and I have no knowledge of the code or where you got this. In sum, please elaborate with detailed references to your code.

    Thabet said:
    As I understand it, when I make a connection with a peripheral through the central, the scan module is automatically paused, but when I make the connection through nRF Connect with the central, the scan is not paused, why does this occur?

    There should not be any dependency on the scan module here. It could be that your application behaves differently depending on which peripheral it has connected to perhaps? That is only speculation.

    In general you need to show your source code and relate the questions and observations to the code as there is not much I can say without such a link.

    Thabet said:
    Can I prevent the scan from being paused when requesting a connection through the central?

    The SoftDevice always stops scanning after providing a scan report to the application, and sd_ble_gap_scan_start() needs to be called again. The scan module does this in most cases, see the last lines in the implementation of nrf_ble_scan_on_adv_report(). However, scanning is stopped when connecting to a peripheral (see implementation of nrf_ble_scan_connect_with_target()). In this case scanning is never automatically started unless the application do that (typically by calling nrf_ble_scan_start()).

  • I assume this is the remaining issue you are referring to. Can you explain where you get this error? Which function returns an error, and what is the error code? Perhaps it is related to "NRF_ERROR_INVALID_STATE, when calling the stop scan function inside the beacon function." which you wrote some posts back? That does not really say much though (both as beacon is a advertiser activity and not scan related), and I have no knowledge of the code or where you got this. In sum, please elaborate with detailed references to your code.

    You're right, the error is this and it occurs where you mentioned, I know the classic beacon has nothing to do with scanning, but my "beacon" repeats the device advertisement, assuming MAC devices, so I need to stop scanning and change the device mac. So I get or error when I stop scan because the scan was already paused inside nrf_ble_scan_connect_with_target(). By the way, thanks for the information, it was very important to know that.

    The SoftDevice always stops scanning after providing a scan report to the application, and sd_ble_gap_scan_start() needs to be called again. The scan module does this in most cases, see the last lines in the implementation of nrf_ble_scan_on_adv_report(). However, scanning is stopped when connecting to a peripheral (see implementation of nrf_ble_scan_connect_with_target()). In this case scanning is never automatically started unless the application do that (typically by calling nrf_ble_scan_start()).

    I actually fixed the problem by calling sd_ble_gap_scan_start(). Is there any flag or variable that I can check to know the status of the scan module? Something to check if scan == start or scan == stop?

  • Hi,

    That makes sense.

    The scan module does not have any state information about if it is scanning or not. You could add this if you like. If so it should be part of nrf_ble_scan_t, and you need to update it whenever it changes. It is normally predictable when this changes though, so it should not be needed. Also, if you get NRF_ERROR_INVALID_STATE when you try to stop scanning you know why, so you could simply ignore that error.

    If you want to ignore specific errors because you know this does not represent an actual error, you typically do something like this:

        if (err_code != NRF_ERROR_INVALID_STATE)
        {
            APP_ERROR_CHECK(err_code);
        }

  • Thanks for the suggestion Einar, I'll do it! I think we can close this topic, because my doubts will now be more related to the exchange of data between devices after establishing the connection, I know you don't like it and it's not organized for users if we change the subject a lot over the tickets.

    So if necessary, I'll open another ticket. Thanks again, you really brought me important information!

Related