I'm not having an actual runtime problem; I'm just trying to wrap my head around the nrf_ble_gatt library module. The purpose appears to be to negotiate a couple of options that arise with new connections; specifically, MTU size and data length.
It looks like this module was designed to allow multiple instances because there is a pointer to a nrf_ble_gatt_t passed into every function. The structure holds the preference values. On a new connection, the connection handle is used as an index into an array of possible connections and the preferences are pushed into the indexed link and negotiation ensues for that connection. That seems straightforward.
I can see why you might want to have different preferences for different devices if you were connecting to multiple peers simultaneously. But it looks like each of the structures has its own copy of a links array that are indexed by the same connection handles. Immediately, I'm concerned. I believe that the connection handles are unique for all connections (otherwise, how could they be used as indexes). Therefore, I would expect one table of connection parameters shared amongst all nrf_ble_gatt_t instances.
The larger issue is that I don't see how multiple configurations can even work. Every configuration gets an entry in the ble event callback; each with a unique context that identifies the nrf_ble_gatt instance. Therefore, every configuration gets a callback for every connection. It looks an awful lot like two different configurations would compete for configuring every connection.
Basically, it looks like you can really only have one nrf_ble_gatt instance and I'm just wondering if someone can verify that.