Hi Chris,
Sorry I previous e-mail was a bit premature. The proposed solution is not
complete since once GATT services and characteristic attributes have been
registered with ble_att_scr_register() there is no way to unregister them.
I eventually get ENOMEM errors when I do the ble_gatts_start() the second
time around after adding my new services with ble_gatts_add_svcs().

The issue seems to be in
-> ble_att_svr_register()
  -> ble_att_svr_entry_alloc()
    -> os_memblock_get()

We never go through and call os_memblock_put() on the previous list of
attributes allocated for the old GATT service and so we run out of them.

Its starting to seem to me that this particular feature requires more
cleanup work than anticipated.
Do let me know your thoughts.
Thanks,
Pritish

On Wed, May 10, 2017 at 11:35 AM, Pritish Gandhi <prit...@aylanetworks.com>
wrote:

> Hey Chris,
>
>
>
> On Wed, May 3, 2017 at 12:16 PM, Christopher Collins <ch...@runtime.io>
> wrote:
>
>> On Wed, May 03, 2017 at 12:10:28PM -0700, Christopher Collins wrote:
>> > On Wed, May 03, 2017 at 10:59:59AM -0700, Pritish Gandhi wrote:
>> > > Hi All,
>> > > Just wanted to give an update to the community on the status of
>> trying to
>> > > start the GATT server after the OS is initialized.
>> > >
>> > > to ble_hs.c
>> > > @@ -606,5 +603,7 @@ ble_hs_init(void)
>> > >      /* Configure the HCI transport to communicate with a host. */
>> > >      ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data,
>> NULL);
>> > >
>> > > +#if 0 /* Let the Application set the queue and start the BLE stack */
>> > >      ble_hs_evq_set(os_eventq_dflt_get());
>> > > +#endif
>> > >  }
>> >
>> > Is there a particular reason you removed the call to ble_hs_evq_set(),
>> > rather than the call to ble_hs_start()?  I think it is preferable to
>> > keep ble_hs_evq_set() here, and just hold off on starting the host.  If
>> > some other package tries to use the host before its eventq is set, it
>> > will result in a null pointer dereference.
>>
> My application was setting the ble evq anyways
> and I thought it might be cleaner to just let the applications decide
> which queue
> to use and when to start it.
>
> But I didn't have a good reason, I guess I didn't expect anything to use
> the host before
> the application set the queue and started the stack since the way I
> understand it is that
> no one should call into the host without getting an on_sync callback which
> won't happen
> until ble_hs_evq_set().
>
> >
>> > > Then, I just have to call ble_hs_evq_set() with my ble thread's queue
>> after
>> > > registering my GATT services.
>> > >
>> > > The next thing I need to figure out though, is how to remove
>> registered
>> > > GATT services and add new ones after the GATT server has started.
>> > > I think ble_hs_sched_reset() might work, if I move its function
>> definition
>> > > from src/ble_hs_priv.h to include/ble_hs.h.
>> > > I haven't tried this out yet though. Will get to it soon.
>> >
>> > Unfortunately, I don't think ble_hs_sched_reset() will work here.  That
>> > function just resets the controller and connection / procedure lists,
>> > but it does not have any effect on the registered GATT services.]
>> >
>> > I haven't tried it, but I think the following sequence should do the
>> > trick:
>> >
>> > 1. Register your new services with ble_gatts_add_svcs().
>> > 2. Call ble_gatts_start()
>> >
>> > ble_gatts_start() should already get called at startup as soon as the
>> > host starts.  When this happens, the registered services get exposed to
>> > BLE peers, and the "working set" of services is cleared.  This is why
>> > you can just start adding new services in step 1; the working set has
>> > been cleared, so you are starting from scratch.  When you call
>> > ble_gatts_start() in step 2, the previously-exported services get
>> > replaced with the new ones.
>>
>> Actually, there is one more thing that you'll need to do here: set
>> ble_gatts_num_cfgable_chrs to 0.  This is a static variable, so you'll
>> need to hack the code a bit to get access to it.  So the sequence should
>> be:
>>
>> 1. ble_gatts_num_cfgable_chrs = 0;
>> 2. Register your new services with ble_gatts_add_svcs().
>> 3. Call ble_gatts_start()
>>
>> Without this step, the GATT server will try to allocate too many CCCD
>> entries, which could cause the ble_gatts_start() call to fail.
>>
>> Chris
>>
>
> This worked! I can now remove old GATT services and register new ones on
> the fly.
> Thanks,
> Pritish
>

Reply via email to