In summary: * separate osmo_scu_prim.*.conn_id from osmo_sccp_inst->next_id * separate each osmo_sccp_user's conn_ids number spaces * separate incoming from outgoing osmo_scu_prim.*.conn_id number spaces Details: The osmo_sccp_instance.next_id is responsible for local-reference IDs on the SCCP wire. Currently, this same next_id number space is also used towards the SCU user, i.e. as osmo_scu_prim.*.conn_id. Not only should this conn_id be scoped separately from the osmo_sccp_instance.next_id, but also be a distinct number space per SCU user. struct sccp_connection in sccp_scoc.c is the place where an SCCP local-reference is correlated to an osmo_sccp_user.conn_id, it must store these IDs separately. The number space for the osmo_scu_prim.*.conn_id should be guarded by some "next_id" counter in osmo_sccp_user. Incoming and outgoing conn_ids must be made sure to not collide, best divide the number space in two for incoming and outgoing conn_ids. For example, in osmo-msc, there may be two SCCP users connected to the same osmo_sccp_instance: one for OSMO_SCCP_SSN_BSSAP (= GERAN-A = 2G) and one for OSMO_SCCP_SSN_RANAP (= UTRAN-Iu = 3G). Implementations using the SCU API might be completely separate, and it would be a "scoping violation" if these distinct users have to negotiate with each other about unused osmo_scu_prim conn_ids. Another aspect is that there may be incoming SCCP connections and outgoing SCCP connections. As an example: From the perspective of osmo-msc, usually the BSC connects to the MSC: <pre> BSC MSC AS SCCP-User | ---N_CONNECT--> | ---osmo_scu_prim.connect.conn_id--> | BSSAP implementation stores new conn_id. | | | | <--N_DATA-----> | <---osmo_scu_prim.data.conn_id----> | </pre> But in case of an inter-BSC HO, the MSC initiates a connection to the BSC instead: <pre> BSC MSC AS SCCP-User | <--N_CONNECT--- | <--osmo_scu_prim.connect.conn_id--- | BSSAP implementation *invents* new conn_id. | | | | <--N_DATA-----> | <---osmo_scu_prim.data.conn_id----> | </pre> (Note, this is only relevant for Connection-Oriented Initial messages, i.e. Layer 3 Complete (incoming to MSC) and Handover Request (outgoing from MSC). For example, Paging is done by a connection-less message that has no conn_id at all, after which the BSC establishes established a connection when the MS has responded.) To keep sane layer separation, it is important to maintain the osmo_scu_prim struct as the *only* communication interface between the SCCP-User and the SCCP instance. Hence we cannot iterate all existing conn_ids and pick an unused one: an incoming SCCP connection might asynchronously pick the exact same conn_id. In practice, this cannot happen right now, but the scoping should be such that it would be possible to place the SCCP User in a separate process. So, a proposal is that for incoming connections, the libosmo-sccp creates new osmo_scu_prim.*.conn_id in the number space 0..0x7fffffff for incoming N-CONNECT, while for outgoing N-CONNECT, the SCCP-User implementation creates new osmo_scu_prim.*.conn_id in the number space 0x80000000..0xffffffff. (Or rather, use the lowest bit to separate for shorter logging) There should be osmo_sccp_user_* API to fetch an unused outgoing SCCP-User conn_id, so SCCP-Users don't need to implement their own.