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 <ccoll...@apache.org> > > > 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. > > > >