Android get Nordic nrf52840 nrf connect sdk v2.0.0 extended advertising data

I am working on nrf52840 using nrf connect sdk v2.0.0 example periodic_adv, nrf52840 is prodcasting extended advertising, my app is running on Sony Xperia 1 with bluetooth 5.0 can scan the device, but how can I get the advertising data I print out the scanresult but it shows {}, how can I get the extended advertising data?

Android mainactivity

package com.example.tryble_scanner;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private BluetoothAdapter mBluetoothAdapter  = null;
    private BluetoothLeScanner mBluetoothLeScanner = null;
    public static final int REQUEST_BT_PERMISSIONS = 0;
    public static final int REQUEST_BT_ENABLE = 1;
    private boolean mScanning = false;
    private Handler mHandler = null;

    private ScanCallback mLeScanCallBack1 = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, final ScanResult result) {
                    //super.onScanResult(callbackType, result);
                    String data=ConverttoString(result.getScanRecord().getManufacturerSpecificData());
                    BluetoothDevice btdevice = result.getDevice();
                    Log.d("BLE", btdevice.getAddress());
                    Log.d("BLE",data);

                }
                @Override
                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);
                    Log.d("BLE", "error");
                }
    };

    private  ScanCallback mLeScanCallBack2=new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.d("BLE","scan stop");
        }
        @Override
        public void onScanFailed(int errorCode) {
            Log.d("BLE","stop scan failed");
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btnScan = (Button) findViewById(R.id.btnScan);
        BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
        this.mHandler = new Handler();
    }

    public void stop_scan(View view) {
        Log.d("Ble","scan stop pressed");
//        mBluetoothLeScanner.stopScan(mLeScanCallback2);
        mBluetoothAdapter.getBluetoothLeScanner().stopScan(mLeScanCallBack2);
    }

    public void onBtnScan(View view) {
        Log.i("Btn","get click");
        checkBTPermission();
        String[] names=new String[]{"Auden test"};
        List<ScanFilter> filters=null;
        if(names != null){
            filters=new ArrayList<>();
            for(String name:names){
                ScanFilter filter=new ScanFilter.Builder().setDeviceName(name).build();
                filters.add(filter);
            }
        }
        ScanSettings scanSettings = new ScanSettings.Builder()
                //.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                //.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                //.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
                //.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
                //.setReportDelay(0L)
                  .setLegacy(false)
                  .build();
        if(mBluetoothLeScanner==null){
            Log.i("BLE","could not get scanner");
        }else{
            mBluetoothLeScanner.startScan(filters,scanSettings,mLeScanCallBack1);  //filters,scanSettings,mLeScanCallback
        }
    }

    private void checkBTPermission(){
        if(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){
            int pc=this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
            pc+=this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
            if(pc!=0){
                this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},1001);
            }else {
                Log.d("BLE","checkBT permission");
            }
        }
    }
    public static String ConverttoString (SparseArray<byte[]> array) {
        if (array == null) {
            return "null";
        }
        if (array.size() == 0) {
            return "{}";
        }
        StringBuilder buffer = new StringBuilder();
        buffer.append('{');
        for (int i = 0; i < array.size(); ++i) {
            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
        }
        buffer.append('}');
        Log.d("convert",buffer.toString());
        return buffer.toString();
    }
}



 

nrf52840

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <bluetooth/bluetooth.h>

static uint8_t mfg_data[] = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
							  0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
							  0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,
							  0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10};

static const struct bt_data ad[] = {
	BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 40),
};

void main(void)
{
	struct bt_le_ext_adv *adv;
	int err;

	printk("Starting Periodic Advertising Demo\n");

	/* Initialize the Bluetooth Subsystem */
	err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}

	/* Create a non-connectable non-scannable advertising set */
	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, &adv); //  BT_LE_EXT_ADV_NCONN_NAME  BT_LE_EXT_ADV_SCAN_NAME
	if (err) {
		printk("Failed to create advertising set (err %d)\n", err);
		return;
	}

	/* Set periodic advertising parameters */
	err = bt_le_per_adv_set_param(adv, BT_LE_PER_ADV_DEFAULT);
	if (err) {
		printk("Failed to set periodic advertising parameters"
		       " (err %d)\n", err);
		return;
	}

	/* Enable Periodic Advertising */
	err = bt_le_per_adv_start(adv);
	if (err) {
		printk("Failed to enable periodic advertising (err %d)\n", err);
		return;
	}

	while (true) {
		printk("Start Extended Advertising...");
		err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
		if (err) {
			printk("Failed to start extended advertising "
			       "(err %d)\n", err);
			return;
		}
		printk("done.\n");

		

		k_sleep(K_SECONDS(3000));

		printk("Stop Extended Advertising...");
		err = bt_le_ext_adv_stop(adv);
		if (err) {
			printk("Failed to stop extended advertising "
			       "(err %d)\n", err);
			return;
		}
		printk("done.\n");

		k_sleep(K_SECONDS(1));
	}
}

Parents
  • Hi. 

    Have you verified that your device is advertising with the required data?

    I talked to one of our mobile developers, and he pointed out what seems to be a typo in your code. 

    __________

    static const struct bt_data ad[] = {
    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 40),

    __________

    Here you are defining the data as "ad" but later you are referring to "adv". 

    Maybe you could download nRF Connect and verify that the device actually advertises the data as expected?

    Br, 
    Joakim

Reply
  • Hi. 

    Have you verified that your device is advertising with the required data?

    I talked to one of our mobile developers, and he pointed out what seems to be a typo in your code. 

    __________

    static const struct bt_data ad[] = {
    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 40),

    __________

    Here you are defining the data as "ad" but later you are referring to "adv". 

    Maybe you could download nRF Connect and verify that the device actually advertises the data as expected?

    Br, 
    Joakim

Children
Related