ble_gatts_set_value VS ble_storage_put_u32

Learn MoreFAQsTutorials

7 posts / 0 new
Last post
alexedge
Offline
Last seen:5 months 3 weeks ago
加入:2016-12-14 17:12
ble_gatts_set_value VS ble_storage_put_u32

Hi,

hope someone could clarify the difference between the use of these two functions and when / where they should be used.

uint32_t yyy = 0x12345678;

ble_gatts_set_value(xxx_val_h, sizeof(yyy), &yyy);

OR

ble_storage_put_u32(conn_idx, xxx_val_h, yyy, true); // with param conn_idx is this per connection?

Thanks,

Alex.

Device:
JK_Dialog
Offline
Last seen:1 day 8 hours ago
工作人员
加入:2016-08-22 23:07
Hi Alex,

Hi Alex,

ble_gatts_set/get() are APIs intended for accessing the local BLE database. E.g. reading and setting a value in the database during a connection. The ble_storage_put_uXX() API creates a persistent copy of the value in the flash device - in the NVMS partition for access across connection/reconnection, etc. The latter API is intended for application data handling, while the first, is for directly manipulation of the database.

A quick example is in the Battery service in the SDK:

/Jon

void bas_set_level(ble_service_t *svc, uint8_t level, bool notify) { bat_service_t *bas = (bat_service_t *) svc; uint8_t prev_level = 0x00; uint16_t prev_level_len = sizeof(prev_level); uint8_t num_conn; uint16_t *conn_idx; if (level > 100) { return; } ble_gatts_get_value(bas->bl_val_h, &prev_level_len, &prev_level); if (level == prev_level) { return; } ble_gatts_set_value(bas->bl_val_h, sizeof(level), &level); /* * for each connected device we need to: * - notify new value, if requested by caller * - put new value to storage to use when device is reconnected */ ble_gap_get_connected(&num_conn, &conn_idx); while (num_conn--) { if (notify) { notify_level(svc, conn_idx[num_conn], level); } ble_storage_put_u32(conn_idx[num_conn], bas->bl_val_h, level, true); } if (conn_idx) { OS_FREE(conn_idx); } }

alexedge
Offline
Last seen:5 months 3 weeks ago
加入:2016-12-14 17:12
Hi Jon,

Hi Jon,

thanks for the explanation.

将explain why the notification / indication (xxx_ccc_h) are stored to flash.

I presume the MAC address of the connected central is stored along with the data?

JK_Dialog
Offline
Last seen:1 day 8 hours ago
工作人员
加入:2016-08-22 23:07
Hi Alex,

Hi Alex,

My apologies for the confusion above. The connection/reconnection was misleading. This particular API should be used to store local values for later access during the connection, in this instance (The BAS example).

If you take a look at this example, the cleanup gets called on disconnect to remove all the storage. This is done since, the values can only be associated with the conn_idx, and the conn_idx can only be assured through one connection.

So in this case, we use ble storage for storing a local copy of the CCC (not having to get it from the DB each time), and we also use it for doing a 'sanity' check on the previous levels of the BAS. Example, we poll the battery value, and go to notify - we check the previous value stored in ble_storage.c to see if the notification is necessary. If the notification is necessary, since the level has changed - the ble_storage is updated with the new value for subsequent reads.

This is the general idea behind it.

alexedge
Offline
Last seen:5 months 3 weeks ago
加入:2016-12-14 17:12
Hi Jon,

Hi Jon,

ah now I'm more confused!

I can see you are fetching the value from DB using: ble_gatts_get_value

and testing with the value passed as a param and only updating the DB if changed using: ble_gatts_set_value

but I don't see why it's necessary to use: ble_storage_put_u32

especially if the value isn't persistant for the same central across different connections.

please could you turn the lights on for me!?

JK_Dialog
Offline
Last seen:1 day 8 hours ago
工作人员
加入:2016-08-22 23:07
Hi Alex,

Hi Alex,

You are not confused :). I believe that I am using a poor example to illustrate this concept but I think you have the general idea.

The storage is primarily just being used a local copy instead of accessing the database. In most cases, you should be able to just use ble_gatts_get_value and ble_gatts_set_value to access the most current database values. If you wish to store a local copy, which we do in most of our examples, use the storage. If you wish to get the latest database value, use the ble_gatts API.

There are both forms of this used in our examples, and I agree it tends to get a little confusing. For the ble_gatts_set/get, this is illustrated in a straightforward manner in bas_notify_level. We have already set the level with bas_set_level, so we can just use ble_gatts_get_value and then follow it with notify_level. Using the ble_storage_put_32 just now stores a local copy of this in the flash.

So basically - if you want to read and modify the database, the ble_gatts_set/get is required for proper BLE functionality, and then you could use ble_storage for application reasons.

alexedge
Offline
Last seen:5 months 3 weeks ago
加入:2016-12-14 17:12
Thanks Jon. This makes sense.

Thanks Jon.

This makes sense.