bt_gatt_is_subscribed ERROR

Hi,

I am developing the nRF52833 DK with NCS v2.00.

I have implemented a service to display RSSI. I have setup the service according to the instructions provided by Nordic in this tutorial. It works succesfully when I flash the application provided in the tutorial to the DK. I also changed the service so that it send RSSI values. I have now taken this service file and added it to my primary application that I am developing. I am continually getting the following error below. I have also attached the code for the RSSI service.

I undertand that the conn object is causing the error as the assert shows that the conn is an "invalid paramter". Any idea why this could be?

Thanks.

ASSERTION FAIL [conn] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/gatt.c:2891
        invalid parameter

[00:00:06.053,344] <err> os: r0/a1:  0x00000004  r1/a2:  0x00000b4b  r2/a3:  0x00000000
[00:00:06.053,375] <err> os: r3/a4:  0x2000512c r12/ip:  0x00000000 r14/lr:  0x00020027
[00:00:06.053,405] <err> os:  xpsr:  0x61000000
[00:00:06.053,405] <err> os: Faulting instruction address (r15/pc): 0x0002e048
[00:00:06.053,436] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
[00:00:06.053,466] <err> os: Current thread: 0x200022d8 (main)
[00:00:06.317,932] <err> os: Halting system

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <sys/printk.h>
#include <sys/byteorder.h>
#include <zephyr.h>
#include <soc.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>
#include <bluetooth/uuid.h>
#include <bluetooth/addr.h>
#include <bluetooth/gatt.h>

#include "rssi_service.h"

#define BT_UUID_RSSI_SERVICE            BT_UUID_DECLARE_128(RSSI_SERVICE_UUID)
#define BT_UUID_RSSI_CHARACTERISTIC     BT_UUID_DECLARE_128(RSSI_CHARACTERISTIC_UUID)

#define MAX_TRANSMIT_SIZE 240//TODO figure this out
uint8_t data_tx[MAX_TRANSMIT_SIZE]; //Not sure why this is necessary

int rssi_service_init(void)
{
    memset(&data_tx, 0, MAX_TRANSMIT_SIZE); //Not sure why this is necessary
    return 0;
}

/* This function is called whenever a Notification has been sent by the TX Characteristic */
static void on_sent_rssi(struct bt_conn *conn, void *user_data)
{
	ARG_UNUSED(user_data);

    const bt_addr_le_t * addr = bt_conn_get_dst(conn);
        
	/*
    printk("Data sent to Address 0x %02X %02X %02X %02X %02X %02X \n", addr->a.val[0]
                                                                    , addr->a.val[1]
                                                                    , addr->a.val[2]
                                                                    , addr->a.val[3]
                                                                    , addr->a.val[4]
                                                                    , addr->a.val[5]);
    */
}

/* This function is called whenever the CCCD register has been changed by the client*/
void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
    ARG_UNUSED(attr);
    switch(value)
    {
        case BT_GATT_CCC_NOTIFY: 
            // Start sending stuff!
            break;

        case BT_GATT_CCC_INDICATE: 
            // Start sending stuff via indications
            break;

        case 0: 
            // Stop sending stuff
            break;
        
        default: 
            printk("Error, CCCD has been set to an invalid value");     
    }
}
           
/*Service Declaration and Registration */
BT_GATT_SERVICE_DEFINE(rssi_service,
BT_GATT_PRIMARY_SERVICE(BT_UUID_RSSI_SERVICE),
    BT_GATT_CHARACTERISTIC(BT_UUID_RSSI_CHARACTERISTIC,
			        BT_GATT_CHRC_NOTIFY,
                    BT_GATT_PERM_READ,
                    NULL, NULL, NULL),
    BT_GATT_CCC(on_cccd_changed,
                    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);

/* This function sends a notification to a Client with the provided data,
given that the Client Characteristic Control Descripter has been set to Notify (0x1).
It also calls the on_sent_rssi() callback if successful*/
void rssi_service_send(struct bt_conn *conn, const uint8_t *data, uint16_t len)
{
    /* 
    The attribute for the TX characteristic is used with bt_gatt_is_subscribed 
    to check whether notification has been enabled by the peer or not.
    Attribute table: 0 = Service, 1 = Primary service, 2 = TX, 3 = CCC.
    */
    const struct bt_gatt_attr *attr = &rssi_service.attrs[2]; 

    struct bt_gatt_notify_params params = 
    {
        .uuid   = BT_UUID_RSSI_CHARACTERISTIC,
        .attr   = attr,
        .data   = data,
        .len    = len,
        .func   = on_sent_rssi
    };

    	printk("Just BEFORE gatt subsribed is checked\n\n");

    printk("Conn: %d \nAttr: %d \n\n", conn, attr);

    // Check whether notifications are enabled or not
    if(bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY)) 
    {
        printk("Just AFTER gatt subsribed is checked\n\n");
        // Send the notification
        int err = bt_gatt_notify_cb(conn, &params);
        
	    if(err)
        {
            printk("Error, unable to send notification, error: %d\n", err);
        }
    }
    else
    {
        printk("Warning, notification not enabled on the selected attribute\n");
    }


}

Parents
  • Hi,

    You are getting this assert at line 2891 in zephyr\subsys\bluetooth\host\gatt.c:

    	__ASSERT(conn, "invalid parameter\n");

    This is in the implementation of bt_gatt_is_subscribed(). Looking at your code snippet I would think this is from the call to bt_gatt_is_subscribed that you make in rssi_service_send(), and the conn comes from there, but the caller code there I do not see. In any case, that is where you should look. Ensure that the connection object is valid. 

  • Thanks Einar,

    I have already realised that this is where I should look but I am unsure what is wrong with my connection object - please could you suggest how I could further investigate this issue?

    I have attaached a portion of code from my main.c that includes the caller code:

    struct bt_conn *rssi_conn;
    
    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    	int ret;
    
    	rssi_conn = conn;
    
    	if (err) {
    		printk("Connection failed (err 0x%02x)\n", err);
    	} else {
    		default_conn = bt_conn_ref(conn);
    		ret = bt_hci_get_conn_handle(default_conn,
    					     &default_conn_handle);
    		if (ret) {
    			printk("No connection handle (err %d)\n", ret);
    		} else {
    			
    			bt_addr_le_to_str(bt_conn_get_dst(conn),
    							  addr, sizeof(addr));
    			printk("\nConnection established via connection (%d) at %s\n",
    			       default_conn_handle, addr);
    		}
    	}
    }
    
    
    
    void main(void)
    {
    	int err;
    	uint32_t number = 0;
    
    	printk("Starting Temp Application\n");
    	
        /* Initialize the Bluetooth Subsystem */
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	bt_conn_auth_cb_register(&auth_cb_display);
        
    	while (1) {
    		k_sleep(K_SECONDS(1));
    
    		/* Temperature measurements */
    		hts_indicate();
    
    		/* Battery level simulation. */
    		bas_notify();
    
    		/* RSSI notfications 
             * Simulated with uint32_t number
             */
    		rssi_service_send(rssi_conn, (uint8_t *)&number, sizeof(number));
    		number++;
    		
    	}
    }

  • The assert fails only as long as the bt_conn instance (connection handle) is not 0 / NULL, so you are passing 0 for some reason. Looking at the code it looks good, though. Perhaps it gets corrupted at some later point. Can you try to print the value pointer of the conn or inspect with a debugged at different locations and verify that it has the right value, and perhaps you can find where/when it gets set to 0?

  • Thank you.

    I believe this function simply can only be called when there is a connection. I have added an if statement to check for this and it now works.

    For some reason, I did not need this when I manipulated the code from this tutorial...

    Adam

Reply Children
Related