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

Device name showing as "n/a"

I've tried to set up my own BLE project as an exercise in understanding what's going on. It's going okay, with the exception that the device isn't advertising the data that I'd expect it to. At the moment I just have the very basics needed to advertise the device.

My main program:

int main(void)
{

  gpio_init();
  ble_stack_init();
  gap_init();
  advertising_init();

  ble_advertising_start(BLE_ADV_MODE_FAST);

  while(1)
  {

  }

}

ble_stack_init():

static void ble_stack_init()
{
	// Initialise the SoftDevice handler module
	SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
	
	/** Enable BLE stack **/
	
	ble_enable_params_t ble_enable_params = {0}; //Instantiate enable params structure
	
	ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;	// GATTs attr. table size
	ble_enable_params.gatts_enable_params.service_changed = 0;	// Don't include the service changed characterstic in the Attr. table
	
	// Enable the BLE stack
	sd_ble_enable(&ble_enable_params);
	
	/** Register the SoftDevice BLE Event handlers **/
	
	softdevice_ble_evt_handler_set(ble_evt_dispatch);
	softdevice_sys_evt_handler_set(sys_evt_dispatch);
	
}

gap_init():

static void gap_init(void)
{
	uint32_t err_msg;
	//ble_gap_addr_t gap_addr; // Use if you want to specifically set the GAP Address

	// Instantiate param structs.
	ble_gap_conn_params_t gap_conn_params = {0};		// GAP connection parameters
	ble_gap_conn_sec_mode_t gap_sec_mode = {0};		// GAP security mode

	/** GAP security mode **/
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&gap_sec_mode);
	
	/** Set GAP name **/
	err_msg = sd_ble_gap_device_name_set(&gap_sec_mode, (uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME));
	check(err_msg);
	
	/** GAP Appearance * Set if required **/ 
	//sd_ble_gap_appearance_set( );
	
	/** GAP connection parameters **/
	gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;		// Connection supervisory timeout
	gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;	// Max acceptable conn. interval
	gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;	// Min ..
	gap_conn_params.slave_latency = SLAVE_LATENCY;				//
	
	/** Set GAP Peripheral Preferred Connection Parameters **/
	sd_ble_gap_ppcp_set(&gap_conn_params);

	
}

advertising_init():

static void advertising_init(void)
{
	
	/** Create UUID object **/
	ble_uuid_t m_adv_uuids[] = {{X_SERVICE_UUID,BLE_UUID_TYPE_VENDOR_BEGIN}}; // Service UUID, UUID type (16 bit, vendor)
	// Add more UUIDs for additional services
	
	ble_advdata_t advdata;	// Instantiate advertising data struct
	memset(&advdata, 0, sizeof(advdata));
	
	/** Advertised Data setup **/
	advdata.name_type 					= BLE_ADVDATA_FULL_NAME;												// Advertise full device name
	advdata.include_appearance			= true;													
	advdata.flags 						= BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;	// BLE General Discoverable mode
	advdata.uuids_complete.uuid_cnt	= sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);	// Number of UUID entries
	advdata.uuids_complete.p_uuids	= m_adv_uuids;                                  // Pointer to UUID array entries

	/** Advertising Advanced config options **/
	ble_adv_modes_config_t adv_options = {0};
	adv_options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
	adv_options.ble_adv_fast_interval = APP_ADV_INTERVAL;	//
	adv_options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;	
	
	/** apply advertising configuration **/
	ble_advertising_init(&advdata, NULL, &adv_options, on_adv_event, NULL);
}

My device name is set at the top, so I don't really understand what I'm missing now.

  • The Bluetooth SIG UUIDs only take 2 bytes whereas a custom UUID will take 16. When included in the advertisement, each will also include a length byte and a type byte, so each advertised Bluetooth SIG Service will take 4 bytes and each advertised custom UUID will take 18 bytes. You also include flags and appearance. Since the advertising packet is only 31 bytes, it doesn't leave much space for a name. (I.e. about <= 7 bytes for a name). As you can see in name_encode(), if there isn't enough space for the complete name it will attempt to use the short name. Did you actually debug the call to name_decode() and step through the if-statements to see which path it is taking?

  • Stepping through it, it appears that it's fine stepping into this whole section of the name_encode() function:

    // Check if device internd to use short name and it can fit available data size.
    if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
    {
        // Complete device name can fit, setting Complete Name in Adv Data.
        adv_data_format  = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
        rem_adv_data_len = actual_length;
    }
    

    EDIT: seems like after using the sd_ble_uuid_vs_add() function I'm able to get the device to show a name while still using the BLE_UUID_TYPE_VENDOR_BEGIN. Like you had anticipated, Bill, I'm fairly limited in the length of the device name but it seems to be showing okay if it's 4 characters or less.

Related