How can ESL establish periodic sync with the special AP?

Hi,my board is nRF52840,and the demo is periodic_sync_conn within ncs2.7.0, 

I want to establish periodic sync with the  AP whose rssi is better,but i am failed。The ESL will sync with another AP automatically Disappointed

Thanks.

struct _AP_info
{
    int8_t sid;
    int8_t rssi;
    bt_addr_le_t addr;
} __packed;
static struct _AP_info AP_info={.rssi=-80};

static void scan_AP(const struct bt_le_scan_recv_info *info)
{
    if (info->rssi > AP_info.rssi)
    {
        AP_info.sid = info->sid;
        AP_info.rssi = info->rssi;
        bt_addr_le_copy(&(AP_info.addr), info->addr);
        printk("Get better rssi AP:sid=%d,rssi=%i,addr=0x%X\n", AP_info.sid, AP_info.rssi, AP_info.addr.a.val[0]);
    }
}
static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
{
    char name[NAME_LEN] = {0};
    char le_addr[BT_ADDR_LE_STR_LEN];
    struct _AP_info *p_AP_info = NULL;

    (void)memset(name, 0, sizeof(name));
    bt_data_parse(buf, data_cb, name);
    bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));


    if (0 == strstr(name, "PAwR conn sample") || 0 == info->interval){
        return;
    }

    printk("scan_recv:%s,sid:%d,rssi:%i,type:%d,addr:%s\n", name, info->sid, info->rssi, info->addr->type, le_addr);
    scan_AP(info);


    if (!per_adv_found){

        // per_sid = info->sid;
        // bt_addr_le_copy(&per_addr, info->addr);

        per_sid = AP_info.sid;
        bt_addr_le_copy(&per_addr, &(AP_info.addr));

        per_adv_found = true;
        k_sem_give(&sem_per_adv);
    }
}

static struct bt_le_scan_cb scan_callbacks = {
    .recv = scan_recv,
};
  • Hi Tan, 
    From what I can see in your code, what you were trying is to you will sync to the AP which has the RSSI >-80dBm. But I don't see how you reject an advertiser if the RSSI is <-80. 
    You should have another condition in addition to !per_adv_found for example something like this: 

        if ((!per_adv_found)&&(good_rssi)) {

            // per_sid = info->sid;
            // bt_addr_le_copy(&per_addr, info->addr);

            per_sid = AP_info.sid;
            bt_addr_le_copy(&per_addr, &(AP_info.addr));

            per_adv_found = true;
            k_sem_give(&sem_per_adv);
        }
    Where you assign good_rssi=1 when info->rssi > AP_info.rssi . 

    If you want to compare between APs and choose the best one, you would need to have a timeout, and only select the one with highest RSSI after the timeout. 

  • Hi,

    As you can see in the code ,the AP with highest RSSI will be saved at AP_info, and it will be configure as the AP to be synced with.

    You can try the demo, The bug will occurs.

  • Ah I see. I didn't spot that. But you don't have a timeout before you decide on which AP you want to sync to. From what I can see you will call k_sem_give(&sem_per_adv); on the first AP you scanned. 

  • There are 3 APs with different sid(1~3), It synced with sid_1 but not sid_2 .

    Next is the log:

    scan_recv:833_PAwR conn sample,sid:1,rssi:-49,type:1,addr:67:58:8D:2A:FF:03 (random)
    Get better rssi ap:sid=1,rssi=-49,addr=0x3
    Creating Periodic Advertising Sync
    Waiting for periodic sync
    scan_recv:840_PAwR conn sample,sid:2,rssi:-49,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-60,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-45,type:1,addr:7C:15:8E:D0:69:D3 (random)
    Get better rssi ap:sid=2,rssi=-45,addr=0xD3
    scan_recv:833_PAwR conn sample,sid:1,rssi:-47,type:1,addr:67:58:8D:2A:FF:03 (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-49,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-63,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-48,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:833_PAwR conn sample,sid:1,rssi:-52,type:1,addr:67:58:8D:2A:FF:03 (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-49,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-55,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-47,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-56,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-60,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-49,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-59,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-50,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-61,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-61,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-42,type:1,addr:7C:15:8E:D0:69:D3 (random)
    Get better rssi ap:sid=2,rssi=-42,addr=0xD3
    scan_recv:833_PAwR conn sample,sid:1,rssi:-47,type:1,addr:67:58:8D:2A:FF:03 (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-43,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-62,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-42,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-55,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-56,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-57,type:1,addr:45:59:25:CC:E7:0C (random)
    scan_recv:840_PAwR conn sample,sid:2,rssi:-43,type:1,addr:7C:15:8E:D0:69:D3 (random)
    scan_recv:841_PAwR conn sample,sid:3,rssi:-61,type:1,addr:45:59:25:CC:E7:0C (random)
    Synced to sid=1,addr_info_67:58:8D:2A:FF:03 (random),service_data_0 has 128 subevents,phy=2,reassembly.len=0:0 0 0.
    Periodic sync established.
    Stopped scanning

  • Hi Tan, 

    What I can see in the log is that it will sync to the first one it find (you can see Creating Periodic Advertising Sync is printed). If you do what you do right now, it will give the semaphore after any AP has RSSI > the default RSSI = -80. 
    That's why I suggested that you need to use a timer. You need to run for a certain time before you decide which AP it should connect to. You should not give the semaphore like what you are doing now. 

    The function bt_le_per_adv_sync_create() will not update if you call it again. If you want to change the AP it should try to sync to you need to call bt_le_per_adv_sync_delete() to stop that before you call it again. But anyway, the correct way is to implement a timer so that you only connect to the best AP after you have scanned all of them or scanned for a certain period of time. 

Related