Only one character is seen when reading a string as a gatt characteristic

I'm leveraging a fuel_gauge example to pass a version string as part of a Device Information Service. When viewed in Nrf Connect (desktop or mobile) only the first character is seen.

However, the indication sees the whole string. 

To simplify the process (avoiding layers of abstraction), I'm putting the value directly into the gatt characteristic in the service:

// static char *swRev_state = "Rev0_04";
static char swRev_state[10] = "Rev0_04";
BT_GATT_SERVICE_DEFINE(
    my_dis_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_DIS),
    BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SOFTWARE_REVISION, BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE, BT_GATT_PERM_READ, read_swRev, NULL, &swRev_state),
    BT_GATT_CCC(myDisSwRev_ccc_cfg_changedError, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), );
For some reason I needed to declare the string as a fixed array in order to get the 'R' character (which I saw as a win). When declared as a pointer to chars I got a lower case 'b' which I'm pretty sure is garbage.
Why am I able to get the whole string as an indication but only one character on a read? Thank you
Parents
  • Hi Keith, 
    What do you have in read_swRev() ? It's where the application supply to the stack what value it should return to the client when a read request is sent. 
    Can you provide the project here so we can take a look ? 

  • here is the important pieces:

    static ssize_t read_swRev(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset)
    {
        // get a pointer to software revision which is passed in the BT_GATT_CHARACTERISTIC() and stored in attr->user_data
        const char *value = attr->user_data;
    
        if (dis_cb.swRev_cb)
        {
            swRev_state = dis_cb.swRev_cb();                
            return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));         
        }
    
        return 0;
    }
    
    
    static struct my_dis_cb appDis_callbacks =
    {
            .swRev_cb = app_SwRev_cb,
    };
     
    
    #define SW_REVISION  
    static char *app_SwRev_cb(void)
    {
        return "Rev0_04";
    }
Reply
  • here is the important pieces:

    static ssize_t read_swRev(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset)
    {
        // get a pointer to software revision which is passed in the BT_GATT_CHARACTERISTIC() and stored in attr->user_data
        const char *value = attr->user_data;
    
        if (dis_cb.swRev_cb)
        {
            swRev_state = dis_cb.swRev_cb();                
            return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));         
        }
    
        return 0;
    }
    
    
    static struct my_dis_cb appDis_callbacks =
    {
            .swRev_cb = app_SwRev_cb,
    };
     
    
    #define SW_REVISION  
    static char *app_SwRev_cb(void)
    {
        return "Rev0_04";
    }
Children
Related