Argh... I messed up the call to ble_gatts_chr_updated(). I forgot to
pass the characteristic handle to this function. The corrected code is
below:
/* Update characteristic value. */
gatt_svr_new_alert_val[0] = 10;
gatt_svr_new_alert_val[1] = 20;
gatt_svr_new_alert_val[2] = 30;
gatt_svr_new_alert_val[3] = 40;
gatt_svr_new_alert_val_len = 4
/* Look up characteristic handle. */
uint16_t chr_val_handle;
rc = ble_gatts_find_chr(BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
BLE_UUID16(GATT_SVR_CHR_NEW_ALERT),
NULL, &chr_val_handle);
assert(rc == 0);
ble_gatts_chr_updated(chr_val_handle);
Sorry about that,
Chris
On Mon, Nov 28, 2016 at 03:01:52PM -0800, Christopher Collins wrote:
> On Mon, Nov 28, 2016 at 04:33:23PM -0500, David G. Simmons wrote:
> > Thanks to both of you for hugely helpful answers!
> >
> > Now, the last bit ...
> >
> > Where is the value -- or the variable, more accurately -- associated
> > with a characteristic defined? So that I know which one to update. :-)
>
> The source of the characteristic data is determined by the GATT callback
> function. In English, your app defines a variable to hold the
> characteristic value, and the callback retrieves this variable when the
> characteristic is read. To change the value of the characteristic,
> write to the source variable that the callback reads from.
>
> Looking at bleprph's alert notification service callback:
>
> case GATT_SVR_CHR_NEW_ALERT:
> if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
> rc = gatt_svr_chr_write(ctxt->om, 0,
> sizeof gatt_svr_new_alert_val,
> gatt_svr_new_alert_val,
> &gatt_svr_new_alert_val_len);
> return rc;
> } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
> rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_val,
> sizeof gatt_svr_new_alert_val);
> return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
> }
>
> This callback uses the "gatt_svr_new_alert_val" variable to hold the
> "new alert" characteristic value. So, if you wanted send a notification
> with the four-byte value {10,20,30,40} to to all subscribed peers, you
> might do something like this (not compiled!):
>
> /* Update characteristic value. */
> gatt_svr_new_alert_val[0] = 10;
> gatt_svr_new_alert_val[1] = 20;
> gatt_svr_new_alert_val[2] = 30;
> gatt_svr_new_alert_val[3] = 40;
> gatt_svr_new_alert_val_len = 4
>
> /* Look up characteristic handle. */
> uint16_t chr_val_handle;
> rc = ble_gatts_find_chr(BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
> BLE_UUID16(GATT_SVR_CHR_NEW_ALERT),
> NULL, &chr_val_handle);
> assert(rc == 0);
>
>
> ble_gatts_chr_updated();
>
> I hope that clears things up. If not, I probably am not explaining it
> well, so please don't hesitate to ask again :).
>
> There are a few secondary issues this email raises that I should mention
> for completeness:
>
> 1. Using ble_gatts_find_chr() is not the preferred way to determine a
> characteristic's attribute handle. Rather, it is better to discover
> this information at registration time via the "val_handle" pointer in
> the characteristic definition. For an example of how this is done, see
> the New Alert characteristic definition in
> net/nimble/host/services/ans/src/ble_svc_ans.c.
>
> 2. The above point leads to this one: why does bleprph re-implement the
> Alert Notification Service when there is already an ANS Mynewt package?!
> This is my screw-up; I merged the ANS pull request without removing the
> duplicate implementation from the sample apps.
>
> Thanks,
> Chris
>
> >
> > dg
> >
> > > On Nov 28, 2016, at 4:30 PM, Christopher Collins <[email protected]>
> > > wrote:
> > >
> > > As long as you specify one of the BLE_GATT_CHR_F_NOTIFY or
> > > BLE_GATT_CHR_F_INDICATE flags in the characteristic definition, the
> > > characteristic will be subscribable.
> > >
> > > When a peer subscribes to a characteristic, the stack signals this event
> > > to the application via the GAP event callback associated with the peer.
> > > When a peer unsubscribes, this is signalled via the same mechanism. For
> > > rationale on why the GAP event callback is used here, see this email:
> > > https://lists.apache.org/thread.html/8706f7914d2b716a02c25bdfc57fe942f7c7fca82446dd3523014d43@%3Cdev.mynewt.apache.org%3E
> > >
> > > <https://lists.apache.org/thread.html/8706f7914d2b716a02c25bdfc57fe942f7c7fca82446dd3523014d43@%3Cdev.mynewt.apache.org%3E>
> > >
> > > As Mike indicated, your application tells the stack that a
> > > characteristic's value has changed via the ble_gatts_chr_updated()
> > > function. It is up to the application to actually change the value
> > > prior to calling this function.
> > >
> > > If you are not sure which handle is associated with a particular
> > > characteristic, you can perform a lookup by
> > > service-characteristic-UUID-pair using the ble_gatts_find_chr()
> > > function.
> >
> > --
> > David G. Simmons
> > (919) 534-5099
> > Web <https://davidgs.com/> • Blog <https://davidgs.com/davidgs_blog> •
> > Linkedin <http://linkedin.com/in/davidgsimmons> • Twitter
> > <http://twitter.com/TechEvangelist1> • GitHub <http://github.com/davidgs>
> > /** Message digitally signed for security and authenticity.
> > * If you cannot read the PGP.sig attachment, please go to
> > * http://www.gnupg.com/ <http://www.gnupg.com/> Secure your email!!!
> > * Public key available at keyserver.pgp.com <http://keyserver.pgp.com/>
> > **/
> > ♺ This email uses 100% recycled electrons. Don't blow it by printing!
> >
> > There are only 2 hard things in computer science: Cache invalidation,
> > naming things, and off-by-one errors.
> >
> >