blob: e9672602c9bfb5752c7d629b568951923da46a18 [file] [log] [blame]
Harald Weltec4338de2015-12-24 00:40:52 +01001/* IuCS/IuPS Core Network interface of HNB-GW */
2
3/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
Neels Hofmeyr37017f52016-04-15 22:47:21 +020021#include <arpa/inet.h>
22
Harald Weltec4338de2015-12-24 00:40:52 +010023#include <osmocom/core/msgb.h>
24#include <osmocom/core/utils.h>
25#include <osmocom/core/timer.h>
26
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020027#include <osmocom/sigtran/protocol/m3ua.h>
Harald Weltec4338de2015-12-24 00:40:52 +010028#include <osmocom/sigtran/sccp_sap.h>
Neels Hofmeyr3da86082016-03-30 12:36:15 +020029#include <osmocom/sigtran/sccp_helpers.h>
Harald Weltec4338de2015-12-24 00:40:52 +010030
Neels Hofmeyrdf63de22016-08-18 13:13:55 +020031#include <osmocom/iuh/hnbgw.h>
32#include <osmocom/iuh/hnbgw_rua.h>
Neels Hofmeyr96979af2016-01-05 15:19:44 +010033#include <osmocom/ranap/ranap_ies_defs.h>
34#include <osmocom/ranap/ranap_msg_factory.h>
Neels Hofmeyrdf63de22016-08-18 13:13:55 +020035#include <osmocom/iuh/context_map.h>
Harald Weltec4338de2015-12-24 00:40:52 +010036
Harald Weltec4338de2015-12-24 00:40:52 +010037/***********************************************************************
38 * Outbound RANAP RESET to CN
39 ***********************************************************************/
40
41int hnbgw_cnlink_change_state(struct hnbgw_cnlink *cnlink, enum hnbgw_cnlink_state state);
42
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020043static int transmit_rst(struct hnb_gw *gw, RANAP_CN_DomainIndicator_t domain,
44 struct osmo_sccp_addr *remote_addr)
Harald Weltec4338de2015-12-24 00:40:52 +010045{
46 struct msgb *msg;
47 struct msgb *msgprim;
Harald Weltec4338de2015-12-24 00:40:52 +010048 RANAP_Cause_t cause = {
49 .present = RANAP_Cause_PR_transmissionNetwork,
50 .choice. transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure,
51 };
52
Harald Weltec4338de2015-12-24 00:40:52 +010053 msg = ranap_new_msg_reset(domain, &cause);
54
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020055 return osmo_sccp_tx_unitdata_msg(gw->sccp.cnlink->sccp_user,
56 &gw->sccp.local_addr,
57 remote_addr,
58 msg);
Harald Weltec4338de2015-12-24 00:40:52 +010059}
60
61/* Timer callback once T_RafC expires */
62static void cnlink_trafc_cb(void *data)
63{
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020064 struct hnb_gw *gw = data;
Harald Weltec4338de2015-12-24 00:40:52 +010065
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020066 transmit_rst(gw, RANAP_CN_DomainIndicator_cs_domain, &gw->sccp.remote_addr_cs);
67 transmit_rst(gw, RANAP_CN_DomainIndicator_ps_domain, &gw->sccp.remote_addr_ps);
68 hnbgw_cnlink_change_state(gw->sccp.cnlink, CNLINK_S_EST_RST_TX_WAIT_ACK);
Harald Weltec4338de2015-12-24 00:40:52 +010069 /* The spec states that we should abandon after a configurable
70 * number of times. We decide to simply continue trying */
71}
72
73/* change the state of a CN Link */
74int hnbgw_cnlink_change_state(struct hnbgw_cnlink *cnlink, enum hnbgw_cnlink_state state)
75{
76 switch (state) {
77 case CNLINK_S_NULL:
78 case CNLINK_S_EST_PEND:
79 break;
80 case CNLINK_S_EST_CONF:
Neels Hofmeyr0f88c112017-07-03 16:49:43 +020081 cnlink_trafc_cb(cnlink->gw);
Harald Weltec4338de2015-12-24 00:40:52 +010082 break;
83 case CNLINK_S_EST_RST_TX_WAIT_ACK:
84 osmo_timer_schedule(&cnlink->T_RafC, 5, 0);
85 break;
86 case CNLINK_S_EST_ACTIVE:
87 osmo_timer_del(&cnlink->T_RafC);
88 break;
89 }
90}
91
92/***********************************************************************
93 * Incoming primitives from SCCP User SAP
94 ***********************************************************************/
95
96static int cn_ranap_rx_reset_cmd(struct hnbgw_cnlink *cnlink,
97 RANAP_InitiatingMessage_t *imsg)
98{
99 RANAP_ResetIEs_t ies;
100 int rc;
101
102 rc = ranap_decode_reseties(&ies, &imsg->value);
103 /* FIXME: reset resources and return reset ack */
Daniel Willmann11e912a2016-01-07 13:19:30 +0100104
105 ranap_free_reseties(&ies);
Harald Weltec4338de2015-12-24 00:40:52 +0100106 return rc;
107}
108
109static int cn_ranap_rx_reset_ack(struct hnbgw_cnlink *cnlink,
110 RANAP_SuccessfulOutcome_t *omsg)
111{
112 RANAP_ResetAcknowledgeIEs_t ies;
113 int rc;
114
115 rc = ranap_decode_resetacknowledgeies(&ies, &omsg->value);
116
117 hnbgw_cnlink_change_state(cnlink, CNLINK_S_EST_ACTIVE);
118
Daniel Willmann11e912a2016-01-07 13:19:30 +0100119 ranap_free_resetacknowledgeies(&ies);
Harald Weltec4338de2015-12-24 00:40:52 +0100120 return rc;
121}
122
123static int cn_ranap_rx_paging_cmd(struct hnbgw_cnlink *cnlink,
Harald Weltebc4560c2015-12-24 08:46:58 +0100124 RANAP_InitiatingMessage_t *imsg,
125 const uint8_t *data, unsigned int len)
Harald Weltec4338de2015-12-24 00:40:52 +0100126{
Neels Hofmeyr2b01f3a2016-04-19 17:57:03 +0200127 struct hnb_gw *gw = cnlink->gw;
Harald Weltebc4560c2015-12-24 08:46:58 +0100128 struct hnb_context *hnb;
Harald Weltec4338de2015-12-24 00:40:52 +0100129 RANAP_PagingIEs_t ies;
Harald Weltebc4560c2015-12-24 08:46:58 +0100130 int rc = 0;
Harald Weltec4338de2015-12-24 00:40:52 +0100131
132 rc = ranap_decode_pagingies(&ies, &imsg->value);
133
Harald Weltebc4560c2015-12-24 08:46:58 +0100134 /* FIXME: determine which HNBs to send this Paging command,
135 * rather than broadcasting to all HNBs */
136 llist_for_each_entry(hnb, &gw->hnb_list, list) {
137 rc = rua_tx_udt(hnb, data, len);
138 }
Daniel Willmann11e912a2016-01-07 13:19:30 +0100139
140 ranap_free_pagingies(&ies);
Harald Weltebc4560c2015-12-24 08:46:58 +0100141 return 0;
Harald Weltec4338de2015-12-24 00:40:52 +0100142}
143
144static int cn_ranap_rx_initiating_msg(struct hnbgw_cnlink *cnlink,
Harald Weltebc4560c2015-12-24 08:46:58 +0100145 RANAP_InitiatingMessage_t *imsg,
146 const uint8_t *data, unsigned int len)
Harald Weltec4338de2015-12-24 00:40:52 +0100147{
148 int rc;
149
150 switch (imsg->procedureCode) {
151 case RANAP_ProcedureCode_id_Reset:
152 return cn_ranap_rx_reset_cmd(cnlink, imsg);
153 case RANAP_ProcedureCode_id_Paging:
Harald Weltebc4560c2015-12-24 08:46:58 +0100154 return cn_ranap_rx_paging_cmd(cnlink, imsg, data, len);
Harald Weltec4338de2015-12-24 00:40:52 +0100155 case RANAP_ProcedureCode_id_OverloadControl: /* Overload ind */
156 break;
157 case RANAP_ProcedureCode_id_ErrorIndication: /* Error ind */
158 break;
159 case RANAP_ProcedureCode_id_ResetResource: /* request */
160 case RANAP_ProcedureCode_id_InformationTransfer:
161 case RANAP_ProcedureCode_id_DirectInformationTransfer:
162 case RANAP_ProcedureCode_id_UplinkInformationExchange:
163 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
164 "Procedure %u from CN, ignoring\n", imsg->procedureCode);
165 break;
166 default:
167 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
168 "Procedure %u from CN, ignoring\n", imsg->procedureCode);
169 break;
170 }
171 return 0;
172}
173
174static int cn_ranap_rx_successful_msg(struct hnbgw_cnlink *cnlink,
175 RANAP_SuccessfulOutcome_t *omsg)
176{
177 int rc;
178
179 switch (omsg->procedureCode) {
180 case RANAP_ProcedureCode_id_Reset: /* Reset acknowledge */
181 return cn_ranap_rx_reset_ack(cnlink, omsg);
182 case RANAP_ProcedureCode_id_ResetResource: /* response */
183 case RANAP_ProcedureCode_id_InformationTransfer:
184 case RANAP_ProcedureCode_id_DirectInformationTransfer:
185 case RANAP_ProcedureCode_id_UplinkInformationExchange:
186 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
187 "Procedure %u from CN, ignoring\n", omsg->procedureCode);
188 break;
189 default:
190 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
191 "Procedure %u from CN, ignoring\n", omsg->procedureCode);
192 break;
193 }
194 return 0;
195}
196
197
Harald Weltebc4560c2015-12-24 08:46:58 +0100198static int _cn_ranap_rx(struct hnbgw_cnlink *cnlink, RANAP_RANAP_PDU_t *pdu,
199 const uint8_t *data, unsigned int len)
Harald Weltec4338de2015-12-24 00:40:52 +0100200{
201 int rc;
202
203 switch (pdu->present) {
204 case RANAP_RANAP_PDU_PR_initiatingMessage:
Harald Weltebc4560c2015-12-24 08:46:58 +0100205 rc = cn_ranap_rx_initiating_msg(cnlink, &pdu->choice.initiatingMessage,
206 data, len);
Harald Weltec4338de2015-12-24 00:40:52 +0100207 break;
208 case RANAP_RANAP_PDU_PR_successfulOutcome:
209 rc = cn_ranap_rx_successful_msg(cnlink, &pdu->choice.successfulOutcome);
210 break;
211 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
212 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
213 "unsuccessful outcome procedure %u from CN, ignoring\n",
214 pdu->choice.unsuccessfulOutcome.procedureCode);
215 break;
216 default:
217 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
218 "presence %u from CN, ignoring\n", pdu->present);
219 break;
220 }
221}
222
223static int handle_cn_ranap(struct hnbgw_cnlink *cnlink, const uint8_t *data,
224 unsigned int len)
225{
226 RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu;
227 asn_dec_rval_t dec_ret;
228 int rc;
229
230 memset(pdu, 0, sizeof(*pdu));
231 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
232 data, len, 0, 0);
233 if (dec_ret.code != RC_OK) {
234 LOGP(DRANAP, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
Neels Hofmeyra6a68e62016-11-25 13:21:02 +0100235 return -1;
Harald Weltec4338de2015-12-24 00:40:52 +0100236 }
237
Harald Weltebc4560c2015-12-24 08:46:58 +0100238 rc = _cn_ranap_rx(cnlink, pdu, data, len);
Harald Weltec4338de2015-12-24 00:40:52 +0100239
240 return rc;
241}
242
Neels Hofmeyra3bcd6d2017-07-03 14:29:04 +0200243static bool pc_and_ssn_match(const struct osmo_sccp_addr *a, const struct osmo_sccp_addr *b)
244{
245 return (a == b)
246 || ((a->pc == b->pc)
247 && (a->ssn == b->ssn));
248}
249
250static int classify_cn_remote_addr(const struct hnb_gw *gw,
251 const struct osmo_sccp_addr *cn_remote_addr,
252 bool *is_ps)
253{
254 if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.remote_addr_cs)) {
255 if (is_ps)
256 *is_ps = false;
257 return 0;
258 }
259 if (pc_and_ssn_match(cn_remote_addr, &gw->sccp.remote_addr_ps)) {
260 if (is_ps)
261 *is_ps = true;
262 return 0;
263 }
264 LOGP(DMAIN, LOGL_ERROR, "Unexpected remote address, matches neither CS nor PS address: %s\n",
265 osmo_sccp_addr_dump(cn_remote_addr));
266 return -1;
267}
Harald Weltec4338de2015-12-24 00:40:52 +0100268
269static int handle_cn_unitdata(struct hnbgw_cnlink *cnlink,
270 const struct osmo_scu_unitdata_param *param,
271 struct osmo_prim_hdr *oph)
272{
Harald Welte8c572fe2015-12-26 08:42:07 +0100273 if (param->called_addr.ssn != OSMO_SCCP_SSN_RANAP) {
Harald Weltec4338de2015-12-24 00:40:52 +0100274 LOGP(DMAIN, LOGL_NOTICE, "N-UNITDATA.ind for unknown SSN %u\n",
275 param->called_addr.ssn);
276 return -1;
277 }
278
Neels Hofmeyra3bcd6d2017-07-03 14:29:04 +0200279 if (classify_cn_remote_addr(cnlink->gw, &param->calling_addr, NULL) < 0)
280 return -1;
281
Harald Weltec4338de2015-12-24 00:40:52 +0100282 return handle_cn_ranap(cnlink, msgb_l2(oph->msg), msgb_l2len(oph->msg));
283}
284
Neels Hofmeyr65037672016-04-19 18:00:54 +0200285static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink,
Neels Hofmeyr630483b2016-04-19 18:01:25 +0200286 const struct osmo_scu_connect_param *param,
287 struct osmo_prim_hdr *oph)
Harald Weltec4338de2015-12-24 00:40:52 +0100288{
289 /* we don't actually need to do anything, as RUA towards the HNB
290 * doesn't seem to know any confirmations to its CONNECT
291 * operation */
292
Neels Hofmeyr0ff24432016-04-04 18:33:33 +0200293 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d\n",
294 param->conn_id);
295 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() called_addr=%s\n",
296 inet_ntoa(param->called_addr.ip.v4));
297 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() calling_addr=%s\n",
298 inet_ntoa(param->calling_addr.ip.v4));
299 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() responding_addr=%s\n",
300 inet_ntoa(param->responding_addr.ip.v4));
301
Harald Weltec4338de2015-12-24 00:40:52 +0100302 return 0;
303}
304
Neels Hofmeyr65037672016-04-19 18:00:54 +0200305static int handle_cn_data_ind(struct hnbgw_cnlink *cnlink,
Harald Weltec4338de2015-12-24 00:40:52 +0100306 const struct osmo_scu_data_param *param,
307 struct osmo_prim_hdr *oph)
308{
309 struct hnbgw_context_map *map;
310
311 /* connection-oriented data is always passed transparently
312 * towards the specific HNB, via a RUA connection identified by
313 * conn_id */
314
315 map = context_map_by_cn(cnlink, param->conn_id);
316 if (!map) {
317 /* FIXME: Return an error / released primitive */
318 return 0;
319 }
320
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200321 return rua_tx_dt(map->hnb_ctx, map->is_ps, map->rua_ctx_id,
Harald Weltec4338de2015-12-24 00:40:52 +0100322 msgb_l2(oph->msg), msgb_l2len(oph->msg));
323}
324
Neels Hofmeyr65037672016-04-19 18:00:54 +0200325static int handle_cn_disc_ind(struct hnbgw_cnlink *cnlink,
Harald Weltec4338de2015-12-24 00:40:52 +0100326 const struct osmo_scu_disconn_param *param,
327 struct osmo_prim_hdr *oph)
328{
329 struct hnbgw_context_map *map;
330
Neels Hofmeyr02be4e32016-04-04 19:29:35 +0200331 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() conn_id=%d originator=%d\n",
332 param->conn_id, param->originator);
333 LOGP(DMAIN, LOGL_DEBUG, "handle_cn_disc_ind() responding_addr=%s\n",
334 inet_ntoa(param->responding_addr.ip.v4));
335
Harald Weltec4338de2015-12-24 00:40:52 +0100336 RUA_Cause_t rua_cause = {
337 .present = RUA_Cause_PR_NOTHING,
338 /* FIXME: Convert incoming SCCP cause to RUA cause */
339 };
340
341 /* we need to notify the HNB associated with this connection via
342 * a RUA DISCONNECT */
343
344 map = context_map_by_cn(cnlink, param->conn_id);
345 if (!map) {
346 /* FIXME: Return an error / released primitive */
347 return 0;
348 }
349
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200350 return rua_tx_disc(map->hnb_ctx, map->is_ps, map->rua_ctx_id,
Harald Weltec4338de2015-12-24 00:40:52 +0100351 &rua_cause, msgb_l2(oph->msg), msgb_l2len(oph->msg));
352}
353
354/* Entry point for primitives coming up from SCCP User SAP */
Neels Hofmeyra1bf4f32016-07-07 15:36:07 +0200355static int sccp_sap_up(struct osmo_prim_hdr *oph, void *ctx)
Harald Weltec4338de2015-12-24 00:40:52 +0100356{
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200357 struct osmo_sccp_user *scu = ctx;
Neels Hofmeyrcb246312017-06-20 22:49:34 +0200358 struct hnbgw_cnlink *cnlink;
Harald Weltec4338de2015-12-24 00:40:52 +0100359 struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph;
360 int rc;
361
362 LOGP(DMAIN, LOGL_DEBUG, "sccp_sap_up(%s)\n", osmo_scu_prim_name(oph));
363
Neels Hofmeyrcb246312017-06-20 22:49:34 +0200364 if (!scu) {
365 LOGP(DMAIN, LOGL_ERROR,
366 "sccp_sap_up(): NULL osmo_sccp_user, cannot send prim (sap %u prim %u op %d)\n",
367 oph->sap, oph->primitive, oph->operation);
368 return -1;
369 }
370
371 cnlink = osmo_sccp_user_get_priv(scu);
372 if (!cnlink) {
373 LOGP(DMAIN, LOGL_ERROR,
374 "sccp_sap_up(): NULL hnbgw_cnlink, cannot send prim (sap %u prim %u op %d)\n",
375 oph->sap, oph->primitive, oph->operation);
376 return -1;
377 }
378
Harald Weltec4338de2015-12-24 00:40:52 +0100379 switch (OSMO_PRIM_HDR(oph)) {
380 case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
Neels Hofmeyr65037672016-04-19 18:00:54 +0200381 rc = handle_cn_unitdata(cnlink, &prim->u.unitdata, oph);
Harald Weltec4338de2015-12-24 00:40:52 +0100382 break;
383 case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
Neels Hofmeyr65037672016-04-19 18:00:54 +0200384 rc = handle_cn_conn_conf(cnlink, &prim->u.connect, oph);
Harald Weltec4338de2015-12-24 00:40:52 +0100385 break;
386 case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
Neels Hofmeyr65037672016-04-19 18:00:54 +0200387 rc = handle_cn_data_ind(cnlink, &prim->u.data, oph);
Harald Weltec4338de2015-12-24 00:40:52 +0100388 break;
389 case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
Neels Hofmeyr65037672016-04-19 18:00:54 +0200390 rc = handle_cn_disc_ind(cnlink, &prim->u.disconnect, oph);
Harald Weltec4338de2015-12-24 00:40:52 +0100391 break;
392 defualt:
393 LOGP(DMAIN, LOGL_ERROR,
394 "Received unknown prim %u from SCCP USER SAP\n",
395 OSMO_PRIM_HDR(oph));
396 break;
397 }
398
399 msgb_free(oph->msg);
400
401 return 0;
402}
403
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200404int hnbgw_cnlink_init(struct hnb_gw *gw, const char *stp_host, uint16_t stp_port,
405 const char *local_ip, uint32_t local_pc)
Harald Weltec4338de2015-12-24 00:40:52 +0100406{
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200407 struct hnbgw_cnlink *cnlink;
Harald Weltec4338de2015-12-24 00:40:52 +0100408 int rc;
409
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200410 OSMO_ASSERT(!gw->sccp.instance);
411 OSMO_ASSERT(!gw->sccp.cnlink);
412
413 gw->sccp.instance = osmo_sccp_simple_client(gw, "OsmoHNBGW", local_pc,
414 OSMO_SS7_ASP_PROT_M3UA, 0, local_ip,
415 stp_port, stp_host);
416 if (!gw->sccp.instance) {
417 LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP Instance\n");
418 return -1;
419 }
420
421 LOGP(DRUA, LOGL_DEBUG, "SCCP uplink to STP: %s %u\n", stp_host, stp_port);
422
423 osmo_sccp_make_addr_pc_ssn(&gw->sccp.local_addr, local_pc,
424 OSMO_SCCP_SSN_RANAP);
425
426 cnlink = talloc_zero(gw, struct hnbgw_cnlink);
Neels Hofmeyr2b01f3a2016-04-19 17:57:03 +0200427 cnlink->gw = gw;
Harald Weltec4338de2015-12-24 00:40:52 +0100428 INIT_LLIST_HEAD(&cnlink->map_list);
429 cnlink->T_RafC.cb = cnlink_trafc_cb;
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200430 cnlink->T_RafC.data = gw;
Harald Welte552fdf12015-12-26 23:39:30 +0100431 cnlink->next_conn_id = 1000;
Harald Weltec4338de2015-12-24 00:40:52 +0100432
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200433 cnlink->sccp_user = osmo_sccp_user_bind_pc(gw->sccp.instance,
434 "OsmoHNBGW",
435 sccp_sap_up, OSMO_SCCP_SSN_RANAP,
436 gw->sccp.local_addr.pc);
437 if (!cnlink->sccp_user) {
438 LOGP(DMAIN, LOGL_ERROR, "Failed to init SCCP User\n");
439 return -1;
Harald Weltec4338de2015-12-24 00:40:52 +0100440 }
441
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200442 /* In sccp_sap_up() we expect the cnlink in the user's priv. */
443 osmo_sccp_user_set_priv(cnlink->sccp_user, cnlink);
Harald Weltec4338de2015-12-24 00:40:52 +0100444
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200445 gw->sccp.cnlink = cnlink;
Harald Weltec4338de2015-12-24 00:40:52 +0100446
Neels Hofmeyr0f88c112017-07-03 16:49:43 +0200447 return 0;
Harald Weltec4338de2015-12-24 00:40:52 +0100448}