Hi Łukasz,

On Mon, May 15, 2017 at 12:33:59PM +0100, Łukasz Wolnik wrote:
> Hello,
> 
> From time to time my ble_gattc_write_flat (run as central) is timing out
> after 20 seconds while sending to an Android 6 phone (in peripherial mode).
> Is there a way to reduce the timeout to just 1 second? At the moment if
> there's an issue with writing, my newt program has to wait 20 seconds until
> it can respond to a timeout.
> 
> What's the best strategy here? Keep "bombarding" the peripherial with
> multiple writes until receiving first confirmation. Or reduce the timeout
> from 20 seconds (I don't know where this value is coming from) and resend
> only when got an HCI 19 timeout error in the callback?

The lower layers should ensure all packets are delivered, so the
application should not perform any retries.  In fact, once an ATT
exchange times out, the connection is terminated.

I think the problem is the resource exhaustion, as indicated by the
BLE_HS_ENOMEM codes you are seeing.  This particular error code is,
unfortunately, quite general; it applies to several different resource
types.  Since your device is initiating several GATT procedures in
parallel, my guess is that the problematic resource is one of the
following:

    * mbufs
    * GATT client procedure objects

If you have gdb attached to your device, you can check if either of
these is the problem.  Let me know if you are interested in this.

I would recommend just increasing the following setting and seeing what
happens:

    MSYS_1_BLOCK_COUNT      # default: 12
    BLE_GATT_MAX_PROCS      # default: 4

As an aside, this issue tells me two things:
    1. We need to make sure there are statistics available that indicate
       failure to allocate each resource type.
    2. We should log the exact cause of failure when a procedure fails.

Chris

> My logs are below:
> 
> * CONNECTED 3 *
> 007034 [ts=54953064ssb, mod=64 level=1] peer's connection handle;
> conn_handle=3; addr=2000719b; attr_read=0 attr_write=0
> 007037 [ts=54976500ssb, mod=4 level=1] GATT procedure initiated: write;
> att_handle=42 len=4
> 007039 [ts=54992124ssb, mod=4 level=1] GAP procedure initiated: discovery;
> own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=0
> duration=forever
> 007059 [ts=55148428ssb, mod=64 level=1] wb_on_write msg=5, err=0
> 007060 [ts=55156240ssb, mod=64 level=1] Error: Failed to read
> characteristic; rc=6
> 
> 
> Again sometimes I'm getting BLE_HS_ENOMEM error while trying to read
> attribute from a different handle than the write one.
> 
> My syscfg.yml:
> 
> LOG_LEVEL: 1
> UART_0: 1
> 
> # Default task settings
> OS_MAIN_STACK_SIZE: 512
> 
> # BLE settings
> BLE_MAX_CONNECTIONS: 4
> 
> # Make BLE more stable
> BLE_LL_CFG_FEAT_DATA_LEN_EXT: 0
> 
> BLE_GATT_READ_MAX_ATTRS: 2
> BLE_GATT_WRITE_MAX_ATTRS: 2
> 
> I have tried reducing OS_MAIN_STACK_SIZE to 384, also tried with
> BLE_MAX_CONNECTIONS to 3, etc. This read BLE_HS_ENOMEM seems to pop up in a
> random manner.
> 
> Is there a way to check how much of device's RAM has been already used
> (nrf52xx)?
> 
> Kind regards,
> Łukasz

Reply via email to