NordicPlayground / nRF51-ble-bcast-mesh

Other
324 stars 121 forks source link

Can't use MESH_HANDLE_COUNT lager than 15 #42

Closed itrs closed 8 years ago

itrs commented 9 years ago

Tested with Gateway example, integrate with S110 existing project under sdk 9.

I tried to test limit of MESH_HANDLE_COUNT but it failed under:

mesh_srv_init:

365│ /* add characteristics to mesh service */ 366│ for (uint8_t i = 0; i < g_mesh_service.value_count; ++i) 367│ { 368│ error_code = mesh_value_char_add(i); 369│ 370│ if (error_code != NRF_SUCCESS) 371│ { 372│ return error_code; 373│ } 374│ }

with error_code: 3 emitted by: uint32_t error_code = sd_ble_gatts_characteristic_add( g_mesh_service.service_handle, &ble_char_md, &ble_attr, &ble_value_char_handles);

if (error_code != NRF_SUCCESS)
{
    return NRF_ERROR_INTERNAL;
})

I use
-D__HEAP_SIZE=2048 -D__STACK_SIZE=1024 configuration. increasing values doesn't help.

Any suggestion to push the limit of handle count ? (more than 100 ?)

trond-snekvik commented 9 years ago

There is one additional adjustment required if you want to increase the amount of handles: As mentioned in the Scaling example readme file, you have to give the Softdevice space to allocate more data on the GATT server. This can be achieved by changing the #define RBC_MESH_GATTS_ATTR_TABLE_SIZE and the starting RAM address of the application.

As illustrated in the S110 Softdevice Specification v2.0, Table 20 on page 35, the amount of RAM required for the Softdevice is 0x1900 - 4 + RBC_MESH_GATTS_ATTR_TABLE_SIZE. The RBC_MESH_GATTS_ATTR_TABLE_SIZE is defined with a default value of 0x700 in mesh_srv.c, but you can redefine it as a predefined value for the compiler (as done in the Scaling example).

The scaling example has moved the application RAM start from 0x20002000 to 0x20006000, which will fit ~100 handles. For 15 handles, a start address of 0x20003000, and a ATTR size of 0x3000 - 0x1900 = 0x1700 should be sufficient.

itrs commented 9 years ago
  1. Is GATT char necessary to mesh handle value ? Currently it's highly coupled. If I don't need the 100 Chars to access 100 mesh handle values do I still need to allocate such resources for it ? (ex. for many non-gateway node the GATT is not required. Even for Gateway purpose we can design a simple UART/Serial-like GATT service to query and assign mesh handle value so we don't need to allocate 100 GATT Chars)
  2. from Scaling example it seems use 32K RAM configuration. for 16K RAM 51822 it seems resource heavy isn't it ? For 16K RAM configuration what's suggested settings ?
  3. Is it possible to decouple mesh GATT Service from MESH framework ?
trond-snekvik commented 9 years ago

Currently, the framework stores all values in the Softdevice GATT server. You are not required to advertise with the SD, but if you do, all characteristics are present in the service.

We're actually looking for ways around this, and would like your input. No matter how we do it, we want to pull the storage out of the SD memory and into the application. This way, we can stop having all these confusing memory adjustments, and we get much looser coupling with the Softdevice. Still, we want to allow direct access through the SD GATT interface.

Currently, our favorite solution is to reduce the GATT interface to a single characteristic, and make the first byte of the characteristic an address field. The characterstic should have write and indicate capability, so that it can be used both ways. With the indicate capability, the client would have to confirm the transaction, giving us some basic flow control.

This way, we can stop using the characteristic descriptors, and the boundary of 155 handles shouldn't apply anymore either.

An alternative approach could be to filter which characteristics are presented in the GATT server, by setting a flag on each characteristic. The biggest problem with this approach is that which characteristic is displayed shouldn't change once advertising has started, as this would trigger an expensive and poorly supported service-changed procedure, and we would like to avoid that at all costs. Also, the number of handles limit would not change.

We prefer the first approach for two reasons: it's more flexible in terms of handle-value allocation, and it can act as a stepping stone to a new approach to message propagation where we don't have a limited number of assigned slots, but go for a more dynamic solution, based off the mcast-trickle RFC draft.

We haven't made any decisions yet, but we see a lot of people fighting the locked handle-value pair system, and we think it has to change if the mesh is to improve further.


Back to your questions! The 16K RAM configuration will have some serious issues dealing with more than 20-30 handles. With the current system there isn't a lot we can do with this, unfortunately. The handles have to be stored on the chip anyway, and flash wouldn't work very well. We hope to improve this with the iteration I hinted at above, but that is still under consideration.

I'm not sure if I understand the last question correctly - do you want to have the mesh service not appear when you connect with an external device? In that case, I would recommend that you replace the mesh_srv module with your own, where you simply store the values in user memory without every signalling the SD about anything. In its core, the mesh_srv is just a database of data indexed by handles. Ignore the uint32_t mesh_srv_conn_handle_update(uint16_t conn_handle); and uint32_t mesh_srv_gatts_evt_write_handle(ble_gatts_evt_write_t* evt); functions (return NRF_SUCCESS without doing anything).

itrs commented 9 years ago

Thanks for the great explanation. I love the idea that pull out the mesh database to user space memory. Leave a lower-coupling GATT server to this database so we can optional turn on GATT server for Gateway or turn off for pure slave node. And it's great to leave limited number of characteristic as database access interface. (ex. similar to application controller serial interface over GATT). I believe this will save lots of memory resources to fit more handles on 16K RAM 51822.

daviddedwin commented 8 years ago

Option 1 was selected and the fix applied. The GATT table now does not grow with the number of handles. Fixed in 0.7.1.