Best Practice for Custom GATT Service + Mesh GATT Proxy Coexistence on nRF52840

Use Case: We are developing a Bluetooth Mesh people-counter on the nRF52840 DK.

  • Primary: Mesh network for publishing/receiving sensor data.

  • Secondary: Custom BLE GATT interface for direct device access.

Architecture:

  • Mesh: Config, Health, and Sensor (Server/Client) models.

  • GATT: Custom service with Read (count), Write (config), and planned Notifications/MTU exchange (500 bytes).

  • Config: BT_MESH_GATT_PROXY=y and BT_MESH_PB_GATT=y.

Questions:

  1. Is it recommended to expose custom GATT characteristics alongside the Mesh Proxy on the same connection?

  2. Does this scale? Can we add notifications and MTU negotiation without Mesh stack conflicts?

  3. Option A vs. Option B:

    • A: Single Mesh Proxy advertiser + custom GATT service.

    • B: Extended advertising with separate identities (per ble_peripheral_lbs_coex). Which is better for a production device requiring both Mesh and Peripheral features?

  4. Best Practices: Are there specific Kconfig requirements, registration orders, or callback handling tips for this coexistence?

Environment:

  • Hardware: nRF52840 DK

  • SDK: nRF Connect SDK v2.8.0 (Zephyr 3.7.99)

  • Hi, 

    I am working on your case and will reply next week. 

    Regards,
    Amanda H.

  • Hi, 

    Is it recommended to expose custom GATT characteristics alongside the Mesh Proxy on the same connection?

    Yes, see the Bluetooth Mesh: Coexistence with other LE services sample.

    Does this scale? Can we add notifications and MTU negotiation without Mesh stack conflicts?

    This should be possible. Increase CONFIG_BT_L2CAP_TX_BUF_COUNTand CONFIG_BT_ATT_TX_COUNT appropriately. Increase CONFIG_BT_BUF_CMD_TX_COUNT to 3 (from 2). Increase CONFIG_BT_BUF_ACL_TX_SIZE (Must be >= ATT_MTU + L2CAP overhead (4 bytes) = 507 for MTU 503)

    Option A vs. Option B:

    • A: Single Mesh Proxy advertiser + custom GATT service.

    • B: Extended advertising with separate identities (per ble_peripheral_lbs_coex). Which is better for a production device requiring both Mesh and Peripheral features?

    Option B. You must do this as demonstrated in the Bluetooth Mesh: Coexistence with other LE services sample. Option A is not good because if you use the same identity, the mesh stack will treat the second connection also as a proxy connection and start sending packets to it (which, of course, your app will have to drop because they won't make sense). When you use an identity other than BT_ID_DEFAULT for this new connectable adv, the mesh stack ignores the connection established under that identity.

    Best Practices: Are there specific Kconfig requirements, registration orders, or callback handling tips for this coexistence?

    Please refer to the Bluetooth Mesh: Coexistence with other LE services sample.

    Regards,
    Amanda H.

Related