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++;
    		
    	}
    }

Reply
  • 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++;
    		
    	}
    }

Children
Related