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.
> > 
> > 

Reply via email to