- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have created a simple BLE application called demo, by way of the WICED IDE wizard, with one characteristics, 15 bytes, with notify/read/write properties.
This is the code that the wizard has generated, the following:
<pre>
CHARACTERISTIC_UUID128_WRITABLE (HDLC_DEMO_CHREGISTERHS,
HDLC_DEMO_CHREGISTERHS_VALUE,
__UUID_DEMO_CHREGISTERHS,
LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE,
LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ,
15),
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Characteristic User Description Descriptor */
//<UserDescription>
//<Value>Host To Sensor</Value>
CHAR_DESCRIPTOR_UUID16 (HDLD_DEMO_CHREGISTERHS_USER_DESCRIPTION,
UUID_DESCRIPTOR_CHARACTERISTIC_USER_DESCRIPTION,
LEGATTDB_PERM_READABLE, 14),
//UTF-8 <User Description> Host To Sensor
'H','o','s','t',' ','T','o',' ','S','e','n','s','o','r',
</pre>
The generated code with additions in there commented out for this purpose:
<pre>
BOOL store_in_db_demo_chregisterhs(UINT8* p_value, UINT8 value_len)
{
BLEPROFILE_DB_PDU db_pdu;
// memset(&db_pdu.pdu[0], 0x0, 15); // Ensure we wipe the data first!!!!!
// db_pdu.len = 15;
// bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu);
// Write value to the GATT DB
ble_trace2("write len:%d handle:%02x", value_len, HDLC_DEMO_CHREGISTERHS_VALUE);
memcpy(&db_pdu.pdu[0], p_value, value_len);
db_pdu.len = value_len;
bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu);
return TRUE;
}
</pre>
It was during testing using LightBlue on iOS, I can see, that writing this, 'A','B','C','D','E','F','G','H','I','J', 'K' gets stored good and verified, all 11 bytes.
On the next update of characteristic, I write this, 'Z','Y','X','W','V','U','T','S','R', all 10 bytes.
What surprised me was that the actual value stored was this:
'Z','Y','X','W','V','U','T','S','R','K'
By uncommenting the portion of the code that is in place, one would suspect that the value would be cleanly resetted with zero bytes.
I get the same results.
Can anyone shed light on this?
Solved! Go to Solution.
- Labels:
-
SDK 2.X
-
WICED Sense
- Tags:
- bcm92073x
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello again.
I looked at the code and ran the application myself.
I found out that what you are trying to do is not supported by our stack, and we confirmed it with the developers.
Let me explain.
When LightBlue writes something to the characteristic value, it writes to the GATT database. Then your application gets a callback handled by the write_handle function. The thing is the writing to the GATT database is done by the stack and you don't have any control of it. It supports variable length writes, which means when you write 10 bytes, only the first 10 bytes get changed and the rest stay the same. If you want to change the whole characteristic value, resetting the previous value, you must write the whole max length of the characteristic. That means if you want to overwrite 'A','B','C','D','E','F','G','H','I','J', 'K', you must write 'Z','Y','X','W','V','U','T','S','R',' '.
I also want to comment on the source code.
The two functions generated by the wizard:
store_in_db_demo_chregisterhs and store_in_db_demo_charegisterhs
never get called in the application unless you make the call yourself.
So if you want to use these functions, you must make a function call, probably in the write_handle function.
In the source code that you posted, you've never called these functions, so they were not being used in the app.
However, even if the functions were used, they wouldn't have solved your problem because of the reason I mentioned above.
I hope this helped.
Please let us know if you have any other questions.
Thank you.
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you send a notification or read a characteristic, you read the whole thing no matter what. The 'K' appears at the end of the second read because it was never overwritten after being stored in the characteristic the first time. In order to not see this 'K," you must overwrite with a blank space.
Jacob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From the portion of the code that was commented out, get the same results which is the point I am conveying, it did not matter despite calling memset to scratch the buffer prior to writing it out.
BOOL store_in_db_demo_chregisterhs(UINT8* p_value, UINT8 value_len)
{
BLEPROFILE_DB_PDU db_pdu;
memset(&db_pdu.pdu[0], 0x0, 15); // Ensure we wipe the data first!!!!!
db_pdu.len = 15;
bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu);
// Write value to the GATT DB
ble_trace2("write len:%d handle:%02x", value_len, HDLC_DEMO_CHREGISTERHS_VALUE);
memcpy(&db_pdu.pdu[0], p_value, value_len);
db_pdu.len = value_len;
bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu);
return TRUE;
}
Am I missing something? Why space?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've run into problems with memset() myself. Try running a for loop to zero everything out instead. Let me know how it goes.
Jacob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.
Try to print out what value_len is.
If value_len is 10 bytes then doesn't matter how many bytes you are setting it to 0x0,
because you are only writing the first 10 bytes. In your case, it would be 'Z','Y','X','W','V','U','T','S','R'.
Then the 11th byte and beyond will not be overwritten.
If this is the case, instead of doing
dp_pdu.len = value_len;
try just leaving it alone, because you already changed it to 15 earlier.
* Side notes:
Here is something that you should be familiar in C : Array variable holds pointer to the first element of the array.
So db_pdu.pdu is equal to &db_pdu.pdu[0]. Use the formal instead of the latter.
For example, memcpy(db_pdu.pdu, p_value, value_len);
Revised code:
BOOL store_in_db_demo_chregisterhs(UINT8* p_value, UINT8 value_len)
{
BLEPROFILE_DB_PDU db_pdu;
// Write value to the GATT DB
ble_trace2("write len:%d handle:%02x", value_len, HDLC_DEMO_CHREGISTERHS_VALUE);
db_pdu.len = 15;
memset(db_pdu.pdu, 0x0, 15); // Ensure we wipe the data first!!!!!
// bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu); // unnecessary overhead
memcpy(db_pdu.pdu, p_value, value_len);
bleprofile_WriteHandle(HDLC_DEMO_CHREGISTERHS_VALUE, &db_pdu);
return TRUE;
}
Please tell us if this helped. Thank you.
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That did not make a difference, unfortunately.
Even, writing a string value that is longer by a byte or two, the value from the previous write, is retained and becomes part of the new value.
That is the issue, regardless of the bytes being zeroed out. I will gladly attach the project for anyone to try out to confirm this.
I am familiar with the concept of arrays decaying into pointers of type T.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure. I'll look into the project if you attach it.
How and where are you calling your function?
Does it happen in the write_handle function?
I'm trying see the big picture.
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi jamesle1
Many thanks for your assistance, it would be greatly appreciated.
I have attached the demo project.
Kind regards,
Tom.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello again.
I looked at the code and ran the application myself.
I found out that what you are trying to do is not supported by our stack, and we confirmed it with the developers.
Let me explain.
When LightBlue writes something to the characteristic value, it writes to the GATT database. Then your application gets a callback handled by the write_handle function. The thing is the writing to the GATT database is done by the stack and you don't have any control of it. It supports variable length writes, which means when you write 10 bytes, only the first 10 bytes get changed and the rest stay the same. If you want to change the whole characteristic value, resetting the previous value, you must write the whole max length of the characteristic. That means if you want to overwrite 'A','B','C','D','E','F','G','H','I','J', 'K', you must write 'Z','Y','X','W','V','U','T','S','R',' '.
I also want to comment on the source code.
The two functions generated by the wizard:
store_in_db_demo_chregisterhs and store_in_db_demo_charegisterhs
never get called in the application unless you make the call yourself.
So if you want to use these functions, you must make a function call, probably in the write_handle function.
In the source code that you posted, you've never called these functions, so they were not being used in the app.
However, even if the functions were used, they wouldn't have solved your problem because of the reason I mentioned above.
I hope this helped.
Please let us know if you have any other questions.
Thank you.
James