2021-04-05 11:23 PM
My general understanding is that the BLE standard supports characteristics with a lenght of up to 512 bytes. I'm using the BlueNRG-MS chip from STM but there the function call to add a characteristic has a uint8_t value for the length parameter
tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
uint8_t charUuidType,
const uint8_t* charUuid,
uint8_t charValueLen,
uint8_t charProperties,
uint8_t secPermissions,
uint8_t gattEvtMask,
uint8_t encryKeySize,
uint8_t isVariable,
uint16_t* charHandle);
So this would allow only a maximum characteristic length of 255 bytes. According to this document the stack itself supports 2 bytes with FW 7.2 or higher. I have 7.23 so this should be fine but I cannot find any reference or example of a BlueNRG-MS middleware that would support a call with
charValueLen
of type
uint16_t
. I also downloaded the latest STSW-BLUENRG-DK and the examples also only support
uint8_t charValueLen
.
2021-04-07 10:21 PM
Please manually modify the parameter accordingly.
in bluenrg_gatt_aci.h:
tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
uint8_t charUuidType,
const uint8_t* charUuid,
uint16_t charValueLen,
uint8_t charProperties,
uint8_t secPermissions,
uint8_t gattEvtMask,
uint8_t encryKeySize,
uint8_t isVariable,
uint16_t* charHandle);
in bluenrg_gatt_aci.c:
tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
uint8_t charUuidType,
const uint8_t* charUuid,
uint16_t charValueLen,
uint8_t charProperties,
uint8_t secPermissions,
uint8_t gattEvtMask,
uint8_t encryKeySize,
uint8_t isVariable,
uint16_t* charHandle)
{
struct hci_request rq;
gatt_add_serv_rp resp;
uint8_t buffer[26];
uint8_t uuid_len;
uint8_t indx = 0;
serviceHandle = htobs(serviceHandle);
Osal_MemCpy(buffer + indx, &serviceHandle, 2);
indx += 2;
buffer[indx] = charUuidType;
indx++;
if(charUuidType == UUID_TYPE_16){
uuid_len = 2;
}
else {
uuid_len = 16;
}
Osal_MemCpy(buffer + indx, charUuid, uuid_len);
indx += uuid_len;
charValueLen = htobs(charValueLen);
Osal_MemCpy(buffer + indx, &charValueLen, 2);
indx += 2;
buffer[indx] = charProperties;
indx++;
buffer[indx] = secPermissions;
indx++;
buffer[indx] = gattEvtMask;
indx++;
buffer[indx] = encryKeySize;
indx++;
buffer[indx] = isVariable;
indx++;
Osal_MemSet(&resp, 0, sizeof(resp));
Osal_MemSet(&rq, 0, sizeof(rq));
rq.ogf = OGF_VENDOR_CMD;
rq.ocf = OCF_GATT_ADD_CHAR;
rq.cparam = (void *)buffer;
rq.clen = indx;
rq.rparam = &resp;
rq.rlen = GATT_ADD_CHAR_RP_SIZE;
if (hci_send_req(&rq, FALSE) < 0)
return BLE_STATUS_TIMEOUT;
if (resp.status) {
return resp.status;
}
*charHandle = btohs(resp.handle);
return 0;
}
2021-04-08 06:42 AM
Thanks, I'll give it a try! I assume the same modification applies for aci_gatt_update_char_value()?
What confuses me a bit though is that if this is the fix, then I assume the buffer content would have been incorrect so far right? Or does it distinguish between buffer of size 25 and size 26 to determine whether I have 1 or 2 byte charValueLen?
2021-04-09 05:51 AM
I did the modification but when I do
ret = aci_gatt_add_char(serviceHandle, UUID_TYPE_128, uuid, 470, CHAR_PROP_READ, ATTR_PERMISSION_NONE, GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP, 16, 0 , &charHandle);
I get return value 0x1F, so it fails to add the characteristic.
Did I miss something? What is the origin of this Osal_MemSet? My code uses BLUENRG_memcpy instead, is that a problem?
2021-04-11 07:16 PM
0x1F would be out of memory.
Please check the the "Max_Attribute_Records" value in your previous call to aci_gatt_add_serv().
2021-04-11 11:18 PM
Thanks for your reply. That was my initial thought as well, but I already have it set to 30 with only 2 characteristics added. If I reduce the size of the characteristic to 250, it works. Any other idea how to fix that? Regarding the "max_attribute_records", is there a clarification how to get the number of attributes of a service?
2021-04-12 08:12 PM
A characteristic needs at least 2 attributes (1 for declaration and 1 for value).
It requires 1 additional attribute if the characteristic has the Notify (/Indicate) property, and 1 additional attribute for each descriptor.
In your service, normally the number of attributes you are going to need = 1 for service + 2 for *2 characteristics = 5 attributes
If you only need 1 connection in the application, please use "MODE 2" for the stack, as it reserves more memory (700 bytes) for characteristics records array size.
Please modify IFR to change the mode.
2021-04-13 12:41 AM
But as it works with characteristic size of 250 I assume it's not an issue with the "max_attribute_records"? Any other Idea how I can troubleshoot this? This is a rather urgent project and I either need to solve this issue or reduce my characteristic size - I prefer the first one... :)
2021-04-15 07:14 PM
>But as it works with characteristic size of 250 I assume it's not an issue with the "max_attribute_records"?
No. I was just clarifying the minimum requirement on the number of attributes parameter. And it looks you've configured a number more than enough.
>I either need to solve this issue or reduce my characteristic size - I prefer the first one
Your customized service and characteristics consume memory = 4 + (4 + 250) + (4 + 250) = 512 bytes (in case of no descriptors)
This seems to be a reasonable limit for stack MODE4, which reserves 590 bytes the characteristics records array.
You will need to configure the stack to MODE2 instead to have a larger memory for your characteristics.
Please modify IFR.
Release Notes for BlueNRG, BlueNRG-MS Stacks:
file:///C:/Program%20Files%20(x86)/STMicroelectronics/BlueNRG%20DK%202.0.2/Docs/bluenrg_fw_stack_release_notes_html/_blue_n_r_g-_m_s__stack_v7_2_c.html
2021-04-16 03:16 AM
Actually the IFR is already set to MODE2