diff --git a/sigtran/Makefile b/sigtran/Makefile deleted file mode 100644 index 06a8ba61..00000000 --- a/sigtran/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -LDADD := -ltalloc -lsctp $(shell pkg-config --libs libosmo-sccp) $(shell pkg-config --libs libosmocore) $(shell pkg-config --libs libosmo-netif) -LDFLAGS += $(LDADD) -CFLAGS += -Wall - -all: sua_client_test sua_server_test - -%.o: %.c - $(CC) $(CFLAGS) -o $@ -c $^ - -sua_client_test: sccp_sap.o sua.o sua_client_test.o sua_test_common.o /usr/local/lib/libxua.a - $(CC) $(LDFLAGS) -o $@ $^ - -sua_server_test: sccp_sap.o sua.o sua_server_test.o sua_test_common.o /usr/local/lib/libxua.a - $(CC) $(LDFLAGS) -o $@ $^ - -clean: - @rm *.o sua_client_test sua_server_test diff --git a/sigtran/proto_sua.h b/sigtran/proto_sua.h deleted file mode 100644 index 09435568..00000000 --- a/sigtran/proto_sua.h +++ /dev/null @@ -1,122 +0,0 @@ -/* RFC 3868 SUA SCCP User Adaption */ - -/* (C) 2012 by Harald Welte - % - % All Rights Reserved - % - % This program is free software; you can redistribute it and/or modify - % it under the terms of the GNU Affero General Public License as - % published by the Free Software Foundation; either version 3 of the - % License, or (at your option) any later version. - % - % This program is distributed in the hope that it will be useful, - % but WITHOUT ANY WARRANTY; without even the implied warranty of - % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - % GNU General Public License for more details. - % - % You should have received a copy of the GNU Affero General Public License - % along with this program. If not, see . - */ - -/* FIXME: Move this to libosmocore osmocom/core/gsm/protocol/sua.h */ - -#pragma once -#include - -#define SUA_PPID 4 -#define SUA_PORT 14001 - -/* 3.1.2 Message Classes */ -#define SUA_MSGC_MGMT 0 -#define SUA_MSGC_SNM 2 -#define SUA_MSGC_ASPSM 3 -#define SUA_MSGC_ASPTM 4 -#define SUA_MSGC_CL 7 -#define SUA_MSGC_CO 8 -#define SUA_MSGC_RKM 9 - -/* 3.1.3 Message Types */ -#define SUA_MGMT_ERR 0 -#define SUA_MGMT_NTFY 1 - -#define SUA_SNM_DUNA 1 -#define SUA_SNM_DAVA 2 -#define SUA_SNM_DAUD 3 -#define SUA_SNM_SCON 4 -#define SUA_SNM_DUPU 5 -#define SUA_SNM_DRST 6 - -#define SUA_ASPSM_UP 1 -#define SUA_ASPSM_DOWN 2 -#define SUA_ASPSM_BEAT 3 -#define SUA_ASPSM_UP_ACK 4 -#define SUA_ASPSM_DOWN_ACK 5 -#define SUA_ASPSM_BEAT_ACK 6 - -#define SUA_ASPTM_ACTIVE 1 -#define SUA_ASPTM_INACTIVE 2 -#define SUA_ASPTM_ACTIVE_ACK 3 -#define SUA_ASPTM_INACTIVE_ACK 4 - -#define SUA_RKM_REG_REQ 1 -#define SUA_RKM_REG_RSP 2 -#define SUA_RKM_DEREG_REQ 3 -#define SUA_RKM_DEREG_RSP 4 - -#define SUA_CL_CLDT 1 -#define SUA_CL_CLDR 2 - -#define SUA_CO_CORE 1 -#define SUA_CO_COAK 2 -#define SUA_CO_COREF 3 -#define SUA_CO_RELRE 4 -#define SUA_CO_RELCO 5 -#define SUA_CO_RESCO 6 -#define SUA_CO_RESRE 7 -#define SUA_CO_CODT 8 -#define SUA_CO_CODA 9 -#define SUA_CO_COERR 10 -#define SUA_CO_COIT 11 - -#define SUA_IEI_ROUTE_CTX 0x0006 -#define SUA_IEI_CORR_ID 0x0013 -#define SUA_IEI_REG_RESULT 0x0014 -#define SUA_IEI_DEREG_RESULT 0x0015 - -/* 3.10 SUA specific parameters */ - -#define SUA_IEI_S7_HOP_CTR 0x0101 -#define SUA_IEI_SRC_ADDR 0x0102 -#define SUA_IEI_DEST_ADDR 0x0103 -#define SUA_IEI_SRC_REF 0x0104 -#define SUA_IEI_DEST_REF 0x0105 -#define SUA_IEI_CAUSE 0x0106 -#define SUA_IEI_SEQ_NR 0x0107 -#define SUA_IEI_RX_SEQ_NR 0x0108 -#define SUA_IEI_ASP_CAPA 0x0109 -#define SUA_IEI_CREDIT 0x010A -#define SUA_IEI_DATA 0x010B -#define SUA_IEI_USER_CAUSE 0x010C -#define SUA_IEI_NET_APPEARANCE 0x010D -#define SUA_IEI_ROUTING_KEY 0x010E -#define SUA_IEI_DRN 0x010F -#define SUA_IEI_TID 0x0110 -#define SUA_IEI_SMI 0x0112 -#define SUA_IEI_IMPORTANCE 0x0113 -#define SUA_IEI_MSG_PRIO 0x0114 -#define SUA_IEI_PROTO_CLASS 0x0115 -#define SUA_IEI_SEQ_CTRL 0x0116 -#define SUA_IEI_SEGMENTATION 0x0117 -#define SUA_IEI_CONG_LEVEL 0x0118 - -#define SUA_IEI_GT 0x8001 -#define SUA_IEI_PC 0x8002 -#define SUA_IEI_SSN 0x8003 -#define SUA_IEI_IPv4 0x8004 -#define SUA_IEI_HOST 0x8005 -#define SUA_IEI_IPv6 0x8006 - -#define SUA_RI_GT 1 -#define SUA_RI_SSN_PC 2 -#define SUA_RI_HOST 3 -#define SUA_RI_SSN_IP 4 diff --git a/sigtran/sccp_sap.c b/sigtran/sccp_sap.c deleted file mode 100644 index 207d7ea1..00000000 --- a/sigtran/sccp_sap.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -#include "sccp_sap.h" - -const struct value_string osmo_scu_prim_names[] = { - { OSMO_SCU_PRIM_N_CONNECT, "N-CONNECT" }, - { OSMO_SCU_PRIM_N_DATA, "N-DATA" }, - { OSMO_SCU_PRIM_N_EXPEDITED_DATA, "N-EXPEDITED-DATA" }, - { OSMO_SCU_PRIM_N_DISCONNECT, "N-DISCONNECT" }, - { OSMO_SCU_PRIM_N_RESET, "N-RESET" }, - { OSMO_SCU_PRIM_N_INFORM, "N-INFORM" }, - { OSMO_SCU_PRIM_N_UNITDATA, "N-UNITDATA" }, - { OSMO_SCU_PRIM_N_NOTICE, "N-NOTICE" }, - /* management */ - { OSMO_SCU_PRIM_N_COORD, "N-COORD" }, - { OSMO_SCU_PRIM_N_STATE, "N-STATE" }, - { OSMO_SCU_PRIM_N_PCSTATE, "N-PCSATE" }, - { 0, NULL } -}; - -const struct value_string osmo_prim_op_names[] = { - { PRIM_OP_REQUEST, "request" }, - { PRIM_OP_RESPONSE, "response" }, - { PRIM_OP_INDICATION, "indication" }, - { PRIM_OP_CONFIRM, "confirm" }, - { 0, NULL } -}; - -static char prim_name_buf[128]; - -char *osmo_sccp_prim_name(struct osmo_prim_hdr *oph) -{ - const char *name = get_value_string(osmo_scu_prim_names, oph->primitive); - - prim_name_buf[0] = '\0'; - strncpy(prim_name_buf, name, sizeof(prim_name_buf)-1); - prim_name_buf[sizeof(prim_name_buf)-1] = '\0'; - name = get_value_string(osmo_prim_op_names, oph->operation); - strncat(prim_name_buf, name, sizeof(prim_name_buf)-strlen(prim_name_buf)-2); - - return prim_name_buf; -} diff --git a/sigtran/sccp_sap.h b/sigtran/sccp_sap.h deleted file mode 100644 index 89d92a9d..00000000 --- a/sigtran/sccp_sap.h +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once - -/* SCCP User SAP description */ - -/* (C) 2015 by Harald Welte - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include - -#include - -/* FIXME: properly define this based on libosmocore */ -#define SCCP_SAP_USER 0x2342 - -/* detailed coding of primitives at the SAP_SCCP_USER */ - -/*! \brief SCCP-User primitives as per Q.711 */ -enum osmo_scu_prim_type { - /* connection oriented, 6.1.1 */ - OSMO_SCU_PRIM_N_CONNECT, - OSMO_SCU_PRIM_N_DATA, - OSMO_SCU_PRIM_N_EXPEDITED_DATA, - OSMO_SCU_PRIM_N_DISCONNECT, - OSMO_SCU_PRIM_N_RESET, - OSMO_SCU_PRIM_N_INFORM, - /* connectionless, 6.2.2 */ - OSMO_SCU_PRIM_N_UNITDATA, - OSMO_SCU_PRIM_N_NOTICE, - /* management */ - OSMO_SCU_PRIM_N_COORD, - OSMO_SCU_PRIM_N_STATE, - OSMO_SCU_PRIM_N_PCSTATE, -}; - -#define OSMO_SCCP_ADDR_T_GT 0x0001 -#define OSMO_SCCP_ADDR_T_PC 0x0002 -#define OSMO_SCCP_ADDR_T_SSN 0x0004 -#define OSMO_SCCP_ADDR_T_IPv4 0x0008 -#define OSMO_SCCP_ADDR_T_IPv6 0x0010 - -/* Q.713 3.4.1 + RFC 3868 3.10.2.3 */ -enum osmo_sccp_routing_ind { - OSMO_SCCP_RI_GT, - OSMO_SCCP_RI_SSN_PC, - OSMO_SCCP_RI_SSN_IP, -}; - -/* Q.713 3.4.1 + RFC 3868 3.10.2.3 */ -enum osmo_sccp_gti { - OSMO_SCCP_GTI_NO_GT, - OSMO_SCCP_GTI_NAI_ONLY, - OSMO_SCCP_GTI_TT_ONLY, - OSMO_SCCP_GTI_TT_NPL_ENC, - OSMO_SCCP_GTI_TT_NPL_ENC_NAI, -}; - -/* RFC 3868 3.10.2.3 */ -enum osmo_sccp_npi { - OSMO_SCCP_NPI_UNKNOWN = 0, - OSMO_SCCP_NPI_E164_ISDN = 1, - OSMO_SCCP_NPI_GEERIC = 2, - OSMO_SCCP_NPI_X121_DATA = 3, - OSMO_SCCP_NPI_F69_TELEX = 4, - OSMO_SCCP_NPI_E210_MARITIME = 5, - OSMO_SCCP_NPI_E212_LAND = 6, - OSMO_SCCP_NPI_E214_ISDN_MOBILE = 7, - OSMO_SCCP_NPI_PRIVATE = 14, -}; - -/* Q.713 3.4.2.3.1 + RFC 3868 3.10.2.3 */ -enum osmo_sccp_nai { - OSMO_SCCP_NAI_UNKNOWN = 0, - OSMO_SCCP_NAI_SUBSCR = 1, - OSMO_SCCP_NAI_RES_NAT_USE = 2, - OSMO_SCCP_NAI_NATL = 3, - OSMO_SCCP_NAI_INTL = 4, - /* 5.. 255: Spare */ -}; - -/* Q.713 3.4.2.2 */ -enum osmo_sccp_ssn { - OSMO_SCCP_SSN_MGMT = 1, - OSMO_SCCP_SSN_ISUP = 3, - OSMO_SCCP_SSN_OMAP = 4, - OSMO_SCCP_SSN_MAP = 5, - OSMO_SCCP_SSN_HLR = 6, - OSMO_SCCP_SSN_VLR = 7, - OSMO_SCCP_SSN_MSC = 8, - OSMO_SCCP_SSN_EIR = 9, - OSMO_SCCP_SSN_AUC = 0x0a, - OSMO_SCCP_SSN_ISDN_SS = 0x0b, - OSMO_SCCP_SSN_RES_INTL = 0x0c, - OSMO_SCCP_SSN_BISDN = 0x0d, - OSMO_SCCP_SSN_TC_TEST = 0x0e, -}; - -struct osmo_sccp_gt { - uint8_t gti; - uint8_t nr_digits; - uint8_t tt; - uint32_t npi; - uint32_t nai; - uint8_t digits[32]; -}; - -struct osmo_sccp_addr { - uint32_t presence; - struct osmo_sccp_gt gt; - uint32_t pc; - uint32_t ssn; - union { - struct in_addr v4; - struct in6_addr v6; - } ip; - /* we don't do hostnames */ -}; - -/* OSMO_SCU_PRIM_N_CONNECT */ -struct osmo_scu_connect_param { - struct osmo_sccp_addr called_addr; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr responding_addr; - //struct osmo_sccp_qos_pars qos_pars; - uint32_t sccp_class; - uint32_t importance; - uint32_t conn_id; - /* user data */ -}; - -/* OSMO_SCU_PRIM_N_DATA / OSMO_SCU_PRIM_N_EXPEDITED_DATA */ -struct osmo_scu_data_param { - uint32_t conn_id; - uint32_t importance; - /* user data */ -}; - -enum osmo_sccp_originator { - OSMO_SCCP_ORIG_NS_PROVIDER, - OSMO_SCCP_ORIG_NS_USER, - OSMO_SCCP_ORIG_UNDEFINED, -}; - -/* OSMO_SCU_PRIM_N_DISCONNECT */ -struct osmo_scu_disconn_param { - enum osmo_sccp_originator originator; - struct osmo_sccp_addr repsonding_addr; - uint32_t cause; - uint32_t conn_id; - uint32_t importance; - /* user data */ -}; - -/* OSMO_SCU_PRIM_N_RESET */ -struct osmo_scu_reset_param { - enum osmo_sccp_originator originator; - uint32_t cause; - uint32_t conn_id; -}; - -/* OSMO_SCU_PRIM_N_UNITDATA */ -struct osmo_scu_unitdata_param { - struct osmo_sccp_addr called_addr; - struct osmo_sccp_addr calling_addr; - uint32_t in_sequence_control; - uint32_t return_option; - uint32_t importance; - /* user data */ -}; - -struct osmo_scu_prim { - struct osmo_prim_hdr oph; - union { - struct osmo_scu_connect_param connect; - struct osmo_scu_data_param data; - struct osmo_scu_disconn_param disconnect; - struct osmo_scu_reset_param reset; - struct osmo_scu_unitdata_param unitdata; - } u; -}; - -#define msgb_scu_prim(msg) ((struct osmo_scu_prim *)(msg)->l1h) - -char *osmo_sccp_prim_name(struct osmo_prim_hdr *oph); diff --git a/sigtran/sua.c b/sigtran/sua.c deleted file mode 100644 index 42c3b949..00000000 --- a/sigtran/sua.c +++ /dev/null @@ -1,1431 +0,0 @@ -/* Minimal implementation of RFC 3868 - SCCP User Adaptation Layer */ - -/* (C) 2015 by Harald Welte - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "sccp_sap.h" -#include "proto_sua.h" -#include "sua.h" - -#define SUA_MSGB_SIZE 1500 - -/* Appendix C.4 of Q.714 (all in milliseconds) */ -#define CONNECTION_TIMER ( 1 * 60 * 100) -#define TX_INACT_TIMER ( 7 * 60 * 100) /* RFC 3868 Ch. 8. */ -#define RX_INACT_TIMER (15 * 60 * 100) /* RFC 3868 Ch. 8. */ -#define RELEASE_TIMER ( 10 * 100) -#define RELEASE_REP_TIMER ( 10 * 100) -#define INT_TIMER ( 1 * 60 * 100) -#define GUARD_TIMER (23 * 60 * 100) -#define RESET_TIMER ( 10 * 100) - -static int DSUA = -1; - -struct osmo_sua_user { - /* global list of SUA users? */ - struct llist_head list; - /* set if we are a server */ - struct osmo_stream_srv_link *server; - struct osmo_stream_cli *client; - struct llist_head links; - /* user call-back function in case of incoming primitives */ - osmo_prim_cb prim_cb; -}; - -struct osmo_sua_link { - /* list of SUA links per sua_user */ - struct llist_head list; - /* sua user to which we belong */ - struct osmo_sua_user *user; - /* local list of (SCCP) connections in this link */ - struct llist_head connections; - /* next connection local reference */ - uint32_t next_id; - int is_server; - void *data; -}; - -enum sua_connection_state { - S_IDLE, - S_CONN_PEND_IN, - S_CONN_PEND_OUT, - S_ACTIVE, - S_DISCONN_PEND, - S_RESET_IN, - S_RESET_OUT, - S_BOTHWAY_RESET, - S_WAIT_CONN_CONF, -}; - -static const struct value_string conn_state_names[] = { - { S_IDLE, "IDLE" }, - { S_CONN_PEND_IN, "CONN_PEND_IN" }, - { S_CONN_PEND_OUT, "CONN_PEND_OUT" }, - { S_ACTIVE, "ACTIVE" }, - { S_DISCONN_PEND, "DISCONN_PEND" }, - { S_RESET_IN, "RESET_IN" }, - { S_RESET_OUT, "RESET_OUT" }, - { S_BOTHWAY_RESET, "BOTHWAY_RESET" }, - { S_WAIT_CONN_CONF, "WAIT_CONN_CONF" }, - { 0, NULL } -}; - -struct sua_connection { - struct llist_head list; - struct osmo_sua_link *link; - struct osmo_sccp_addr calling_addr; - struct osmo_sccp_addr called_addr; - uint32_t conn_id; - uint32_t remote_ref; - enum sua_connection_state state; - struct osmo_timer_list timer; - /* inactivity timers */ - struct osmo_timer_list tias; - struct osmo_timer_list tiar; -}; - - -/*********************************************************************** - * Message encoding helper functions - ***********************************************************************/ - -#define XUA_HDR(class, type) ((struct xua_common_hdr) { .spare = 0, .msg_class = (class), .msg_type = (type) }) - -static int msgb_t16l16vp_put(struct msgb *msg, uint16_t tag, uint16_t len, const uint8_t *data) -{ - uint8_t *cur; - unsigned int rest; - unsigned int tlv_len = 4 + len + (4 - (len % 4)); - - if (msgb_tailroom(msg) < tlv_len) - return -ENOMEM; - - /* tag */ - msgb_put_u16(msg, tag); - /* length */ - msgb_put_u16(msg, len + 4); - /* value */ - cur = msgb_put(msg, len); - memcpy(cur, data, len); - /* padding */ - rest = (4 - (len % 4)) & 0x3; - if (rest > 0) { - cur = msgb_put(msg, rest); - memset(cur, 0, rest); - } - - return 0; -} - -static int msgb_t16l16vp_put_u32(struct msgb *msg, uint16_t tag, uint32_t val) -{ - uint32_t val_n = htonl(val); - - return msgb_t16l16vp_put(msg, tag, sizeof(val_n), (uint8_t *)&val_n); -} - -static int xua_msg_add_u32(struct xua_msg *xua, uint16_t iei, uint32_t val) -{ - uint32_t val_n = htonl(val); - return xua_msg_add_data(xua, iei, sizeof(val_n), (uint8_t *) &val_n); -} - -static uint32_t xua_msg_get_u32(struct xua_msg *xua, uint16_t iei) -{ - struct xua_msg_part *part = xua_msg_find_tag(xua, iei); - uint32_t rc = 0; - if (part) - rc = ntohl(*(uint32_t *)part->dat); - return rc; -} - -static int xua_msg_add_sccp_addr(struct xua_msg *xua, uint16_t iei, const struct osmo_sccp_addr *addr) -{ - struct msgb *tmp = msgb_alloc(128, "SCCP Address"); - int rc; - - if (!tmp) - return -ENOMEM; - - msgb_put_u16(tmp, 2); /* route on SSN + PC */ - msgb_put_u16(tmp, 7); /* always put all addresses on SCCP side */ - - if (addr->presence & OSMO_SCCP_ADDR_T_GT) { - /* FIXME */ - } - if (addr->presence & OSMO_SCCP_ADDR_T_PC) { - msgb_t16l16vp_put_u32(tmp, SUA_IEI_PC, addr->pc); - } - if (addr->presence & OSMO_SCCP_ADDR_T_SSN) { - msgb_t16l16vp_put_u32(tmp, SUA_IEI_SSN, addr->ssn); - } - if (addr->presence & OSMO_SCCP_ADDR_T_IPv4) { - /* FIXME: IPv4 address */ - } else if (addr->presence & OSMO_SCCP_ADDR_T_IPv6) { - /* FIXME: IPv6 address */ - } - rc = xua_msg_add_data(xua, iei, msgb_length(tmp), tmp->data); - msgb_free(tmp); - - return rc; -} - - -/*********************************************************************** - * SUA Link and Connection handling - ***********************************************************************/ - -static struct osmo_sua_link *sua_link_new(struct osmo_sua_user *user, int is_server) -{ - struct osmo_sua_link *link; - - link = talloc_zero(user, struct osmo_sua_link); - if (!link) - return NULL; - - link->user = user; - link->is_server = is_server; - INIT_LLIST_HEAD(&link->connections); - - llist_add_tail(&link->list, &user->links); - - return link; -} - -static void conn_destroy(struct sua_connection *conn); - -static void sua_link_destroy(struct osmo_sua_link *link) -{ - struct sua_connection *conn; - - llist_for_each_entry(conn, &link->connections, list) - conn_destroy(conn); - - llist_del(&link->list); - - /* FIXME: do we need to cleanup the sccp link? */ - - talloc_free(link); -} - -static int sua_link_send(struct osmo_sua_link *link, struct msgb *msg) -{ - msgb_sctp_ppid(msg) = SUA_PPID; - - if (link->is_server) - osmo_stream_srv_send(link->data, msg); - else - osmo_stream_cli_send(link->data, msg); - - return 0; -} - -static struct sua_connection *conn_find_by_id(struct osmo_sua_link *link, uint32_t id) -{ - struct sua_connection *conn; - - llist_for_each_entry(conn, &link->connections, list) { - if (conn->conn_id == id) - return conn; - } - return NULL; -} - -static void tx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COIT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 2); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &conn->called_addr); - /* optional: sequence number; credit (both class 3 only) */ - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - sua_link_send(conn->link, outmsg); -} - -static void rx_inact_tmr_cb(void *data) -{ - struct sua_connection *conn = data; - - /* FIXME: release connection */ - /* Send N-DISCONNECT.ind to local user */ - /* Send RLSD to peer */ - /* enter disconnect pending state with release timer pending */ -} - - -static struct sua_connection *conn_create_id(struct osmo_sua_link *link, uint32_t conn_id) -{ - struct sua_connection *conn = talloc_zero(link, struct sua_connection); - - conn->conn_id = conn_id; - conn->link = link; - conn->state = S_IDLE; - - llist_add_tail(&conn->list, &link->connections); - - conn->tias.cb = tx_inact_tmr_cb; - conn->tias.data = conn; - conn->tiar.cb = rx_inact_tmr_cb; - conn->tiar.data = conn; - - return conn; -} - -static struct sua_connection *conn_create(struct osmo_sua_link *link) -{ - uint32_t conn_id; - - do { - conn_id = link->next_id++; - } while (conn_find_by_id(link, conn_id)); - - return conn_create_id(link, conn_id); -} - -static void conn_destroy(struct sua_connection *conn) -{ - /* FIXME: do some cleanup; inform user? */ - osmo_timer_del(&conn->tias); - osmo_timer_del(&conn->tiar); - llist_del(&conn->list); - talloc_free(conn); -} - -static void conn_state_set(struct sua_connection *conn, - enum sua_connection_state state) -{ - DEBUGP(DSUA, "(%u) state chg %s->", conn->conn_id, - get_value_string(conn_state_names, conn->state)); - DEBUGPC(DSUA, "%s\n", - get_value_string(conn_state_names, state)); - conn->state = state; -} - -static void conn_restart_tx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tias, TX_INACT_TIMER / 100, - (TX_INACT_TIMER % 100) * 10); -} - -static void conn_restart_rx_inact_timer(struct sua_connection *conn) -{ - osmo_timer_schedule(&conn->tiar, RX_INACT_TIMER / 100, - (RX_INACT_TIMER % 100) * 10); -} - -static void conn_start_inact_timers(struct sua_connection *conn) -{ - conn_restart_tx_inact_timer(conn); - conn_restart_rx_inact_timer(conn); -} - - -static struct msgb *sua_msgb_alloc(void) -{ - return msgb_alloc(SUA_MSGB_SIZE, "SUA Primitive"); -} - - -/*********************************************************************** - * Handling of messages from the User SAP - ***********************************************************************/ - -/* user program sends us a N-CONNNECT.req to initiate a new connection */ -static int sua_connect_req(struct osmo_sua_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - if (par->sccp_class != 2) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.req for unsupported " - "SCCP class %u\n", par->sccp_class); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn = conn_create_id(link, par->conn_id); - if (!conn) { - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - memcpy(&conn->called_addr, &par->called_addr, - sizeof(conn->called_addr)); - memcpy(&conn->calling_addr, &par->calling_addr, - sizeof(conn->calling_addr)); - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CORE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority; credit */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - /* FIXME: Start CONNECTION_TIMER */ - conn_state_set(conn, S_CONN_PEND_OUT); - - return sua_link_send(link, outmsg); -} - -/* user program sends us a N-CONNNECT.resp, presumably against a - * N-CONNECT.ind */ -static int sua_connect_resp(struct osmo_sua_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_connect_param *par = &prim->u.connect; - struct xua_msg *xua = xua_msg_alloc(); - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we already know a connection for this conn_id */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_CONN_PEND_IN) { - LOGP(DSUA, LOGL_ERROR, "N-CONNECT.resp in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - /* encode + send the COAK message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_COAK); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, par->sccp_class); - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, 0); /* FIXME */ - /* sequence number */ - if (par->calling_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - /* optional: hop count; importance; priority */ - /* FIXME: destination address will be present in case the CORE - * message conveys the source address parameter */ - if (par->called_addr.presence) - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - return sua_link_send(link, outmsg); -} - -/* user wants to send connection-oriented data */ -static int sua_data_req(struct osmo_sua_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_data_param *par = &prim->u.data; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* check if we know about this conncetion, and obtain reference */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "N-DATA.req in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: Send primitive to user */ - return -EINVAL; - } - - conn_restart_tx_inact_timer(conn); - - /* encode + send the CODT message */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_CODT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - /* Sequence number only in expedited data */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - /* optional: priority; correlation id */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user wants to disconnect a connection */ -static int sua_disconnect_req(struct osmo_sua_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_disconn_param *par = &prim->u.disconnect; - struct xua_msg *xua; - struct sua_connection *conn; - struct msgb *outmsg; - - /* resolve reference of connection */ - conn = conn_find_by_id(link, par->conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "N-DISCONNECT.resp for unknown " - "connection ID %u\n", par->conn_id); - /* FIXME: Send primitive to user */ - return -ENODEV; - } - - /* encode + send the RELRE */ - xua = xua_msg_alloc(); - xua->hdr = XUA_HDR(SUA_MSGC_CO, SUA_CO_RELRE); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_DEST_REF, conn->remote_ref); - xua_msg_add_u32(xua, SUA_IEI_SRC_REF, conn->conn_id); - xua_msg_add_u32(xua, SUA_IEI_CAUSE, par->cause); - /* optional: importance */ - if (msgb_l2(prim->oph.msg)) - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - conn_state_set(conn, S_DISCONN_PEND); - - return sua_link_send(link, outmsg); -} - -/* user wants to send connectionless data */ -static int sua_unitdata_req(struct osmo_sua_link *link, struct osmo_scu_prim *prim) -{ - struct osmo_scu_unitdata_param *par = &prim->u.unitdata; - struct xua_msg *xua = xua_msg_alloc(); - struct msgb *outmsg; - - /* encode + send the CLDT */ - xua->hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT); - xua_msg_add_u32(xua, SUA_IEI_ROUTE_CTX, 0); /* FIXME */ - xua_msg_add_u32(xua, SUA_IEI_PROTO_CLASS, 0); - xua_msg_add_sccp_addr(xua, SUA_IEI_SRC_ADDR, &par->calling_addr); - xua_msg_add_sccp_addr(xua, SUA_IEI_DEST_ADDR, &par->called_addr); - xua_msg_add_u32(xua, SUA_IEI_SEQ_CTRL, par->in_sequence_control); - /* optional: importance, ... correlation id? */ - xua_msg_add_data(xua, SUA_IEI_DATA, msgb_l2len(prim->oph.msg), - msgb_l2(prim->oph.msg)); - - outmsg = xua_to_msg(1, xua); - xua_msg_free(xua); - - return sua_link_send(link, outmsg); -} - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sua_link *link, struct osmo_prim_hdr *oph) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct msgb *msg = prim->oph.msg; - int rc = 0; - - LOGP(DSUA, LOGL_DEBUG, "Received SCCP User Primitive (%s)\n", - osmo_sccp_prim_name(&prim->oph)); - - switch (OSMO_PRIM_HDR(&prim->oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_REQUEST): - rc = sua_connect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_RESPONSE): - rc = sua_connect_resp(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_REQUEST): - rc = sua_data_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_REQUEST): - rc = sua_disconnect_req(link, prim); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST): - rc = sua_unitdata_req(link, prim); - break; - default: - rc = -1; - } - - if (rc != 1) - msgb_free(msg); - - return rc; -} - - -/*********************************************************************** - * Mandatory IE checking - ***********************************************************************/ - -#define MAND_IES(msgt, ies) [msgt] = (ies) - -static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 -}; - -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 -}; - -static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 -}; - -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 -}; - -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 -}; - -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 -}; - -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 -}; - -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 -}; - -static const uint16_t *mand_ies_cl[256] = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), -}; - -static const uint16_t *mand_ies_co[256] = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), -}; - -static int check_all_mand_ies(const uint16_t **mand_ies, struct xua_msg *xua) -{ - uint8_t msg_type = xua->hdr.msg_type; - const uint16_t *ies = mand_ies[msg_type]; - uint16_t ie; - - for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { - LOGP(DSUA, LOGL_ERROR, "SUA Message %u:%u should " - "contain IE 0x%04x, but doesn't\n", - xua->hdr.msg_class, msg_type, ie); - return 0; - } - } - - return 1; -} - - -/*********************************************************************** - * Receiving SUA messsages from SCTP - ***********************************************************************/ - -static int sua_parse_addr(struct osmo_sccp_addr *out, - struct xua_msg *xua, - uint16_t iei) -{ - const struct xua_msg_part *param = xua_msg_find_tag(xua, iei); - - if (!param) - return -ENODEV; - - /* FIXME */ - return 0; -} - -static int sua_rx_cldt(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg = sua_msgb_alloc(); - uint32_t protocol_class; - - /* fill primitive */ - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.unitdata; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_UNITDATA, - PRIM_OP_INDICATION, upmsg); - sua_parse_addr(¶m->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(¶m->calling_addr, xua, SUA_IEI_SRC_ADDR); - param->in_sequence_control = xua_msg_get_u32(xua, SUA_IEI_SEQ_CTRL); - protocol_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS); - param->return_option = protocol_class & 0x80; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - - -/* connectioness messages received from socket */ -static int sua_rx_cl(struct osmo_sua_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - if (!check_all_mand_ies(mand_ies_cl, xua)) - return -1; - - switch (xua->hdr.msg_type) { - case SUA_CL_CLDT: - rc = sua_rx_cldt(link, xua); - break; - case SUA_CL_CLDR: - default: - break; - } - - return rc; -} - -/* RFC 3868 3.3.3 / SCCP CR */ -static int sua_rx_core(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - struct sua_connection *conn; - uint8_t *cur; - - /* fill conn */ - conn = conn_create(link); - sua_parse_addr(&conn->called_addr, xua, SUA_IEI_DEST_ADDR); - sua_parse_addr(&conn->calling_addr, xua, SUA_IEI_SRC_ADDR); - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_CONN_PEND_IN); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.4 / SCCP CC */ -static int sua_rx_coak(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COAK for unknwon reference %u\n", - conn_id); - /* FIXME: error message? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - if (conn->state != S_CONN_PEND_OUT) { - LOGP(DSUA, LOGL_ERROR, "COAK in wrong state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: error message? */ - return -EINVAL; - } - - /* track remote reference */ - conn->remote_ref = xua_msg_get_u32(xua, SUA_IEI_SRC_REF); - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_CONFIRM, upmsg); - param->conn_id = conn->conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - param->sccp_class = xua_msg_get_u32(xua, SUA_IEI_PROTO_CLASS) & 3; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - conn_state_set(conn, S_ACTIVE); - conn_start_inact_timers(conn); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - -/* RFC 3868 3.3.5 / SCCP CREF */ -static int sua_rx_coref(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "COREF for unknwon reference %u\n", - conn_id); - /* FIXME: error message? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - //param->in_sequence_control; - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - /* optional: src addr */ - /* optional: dest addr */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.6 / SCCP RLSD */ -static int sua_rx_relre(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint32_t cause; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELRE for unknwon reference %u\n", - conn_id); - /* FIXME: error message? */ - return -1; - } - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_INDICATION, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - cause = xua_msg_get_u32(xua, SUA_IEI_CAUSE); - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - if (data_ie) { - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - } - - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_state_set(conn, S_IDLE); - conn_destroy(conn); - - return 0; -} - -/* RFC 3868 3.3.7 / SCCP RLC */ -static int sua_rx_relco(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_connect_param *param; - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "RELCO for unknwon reference %u\n", - conn_id); - /* FIXME: error message? */ - return -1; - } - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.connect; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DISCONNECT, - PRIM_OP_CONFIRM, upmsg); /* what primitive? */ - - param->conn_id = conn_id; - /* source reference */ - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - memcpy(¶m->called_addr, &conn->called_addr, - sizeof(param->called_addr)); - memcpy(¶m->calling_addr, &conn->calling_addr, - sizeof(param->calling_addr)); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - conn_destroy(conn); - - return 0; - -} - -/* RFC3868 3.3.1 / SCCP DT1 */ -static int sua_rx_codt(struct osmo_sua_link *link, struct xua_msg *xua) -{ - struct osmo_scu_prim *prim; - struct sua_connection *conn; - struct osmo_scu_data_param *param; - struct xua_msg_part *data_ie = xua_msg_find_tag(xua, SUA_IEI_DATA); - struct msgb *upmsg; - uint32_t conn_id = xua_msg_get_u32(xua, SUA_IEI_DEST_REF); - uint8_t *cur; - - /* resolve conn */ - conn = conn_find_by_id(link, conn_id); - if (!conn) { - LOGP(DSUA, LOGL_ERROR, "DT1 for unknwon reference %u\n", - conn_id); - /* FIXME: error message? */ - return -1; - } - - if (conn->state != S_ACTIVE) { - LOGP(DSUA, LOGL_ERROR, "DT1 in invalid state %s\n", - get_value_string(conn_state_names, conn->state)); - /* FIXME: error message? */ - return -1; - } - - conn_restart_rx_inact_timer(conn); - - /* fill primitive */ - upmsg = sua_msgb_alloc(); - prim = (struct osmo_scu_prim *) msgb_put(upmsg, sizeof(*prim)); - param = &prim->u.data; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_INDICATION, upmsg); - param->conn_id = conn_id; - param->importance = xua_msg_get_u32(xua, SUA_IEI_IMPORTANCE); - - /* copy data */ - upmsg->l2h = msgb_put(upmsg, data_ie->len); - memcpy(upmsg->l2h, data_ie->dat, data_ie->len); - - /* send to user SAP */ - link->user->prim_cb(&prim->oph, link); - - return 0; -} - - -/* connection-oriented messages received from socket */ -static int sua_rx_co(struct osmo_sua_link *link, - struct xua_msg *xua, struct msgb *msg) -{ - int rc = -1; - - if (!check_all_mand_ies(mand_ies_co, xua)) - return -1; - - switch (xua->hdr.msg_type) { - case SUA_CO_CORE: - rc = sua_rx_core(link, xua); - break; - case SUA_CO_COAK: - rc = sua_rx_coak(link, xua); - break; - case SUA_CO_COREF: - rc = sua_rx_coref(link, xua); - break; - case SUA_CO_RELRE: - rc = sua_rx_relre(link, xua); - break; - case SUA_CO_RELCO: - rc = sua_rx_relco(link, xua); - break; - case SUA_CO_CODT: - rc = sua_rx_codt(link, xua); - break; - case SUA_CO_RESCO: - case SUA_CO_RESRE: - case SUA_CO_CODA: - case SUA_CO_COERR: - case SUA_CO_COIT: - /* FIXME */ - default: - break; - } - - return rc; -} - -/* process SUA message received from socket */ -static int sua_rx_msg(struct osmo_sua_link *link, struct msgb *msg) -{ - struct xua_msg *xua; - int rc = -1; - - xua = xua_from_msg(1, msgb_length(msg), msg->data); - if (!xua) { - LOGP(DSUA, LOGL_ERROR, "Unable to parse incoming " - "SUA message\n"); - return -EIO; - } - - LOGP(DSUA, LOGL_DEBUG, "Received SUA Message (%u:%u)\n", - xua->hdr.msg_class, xua->hdr.msg_type); - - switch (xua->hdr.msg_class) { - case SUA_MSGC_CL: - rc = sua_rx_cl(link, xua, msg); - break; - case SUA_MSGC_CO: - rc = sua_rx_co(link, xua, msg); - break; - case SUA_MSGC_MGMT: - case SUA_MSGC_SNM: - case SUA_MSGC_ASPSM: - case SUA_MSGC_ASPTM: - case SUA_MSGC_RKM: - /* FIXME */ - default: - break; - } - - xua_msg_free(xua); - - return rc; -} - -/*********************************************************************** - * libosmonetif integration - ***********************************************************************/ - -#include -#include - -/* netif code tells us we can read something from the socket */ -static int sua_srv_conn_cb(struct osmo_stream_srv *conn) -{ - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct osmo_sua_link *link = osmo_stream_srv_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Server Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -static int sua_srv_conn_closed_cb(struct osmo_stream_srv *srv) -{ - struct osmo_sua_link *sual = osmo_stream_srv_get_data(srv); - struct sua_connection *conn; - - LOGP(DSUA, LOGL_INFO, "SCTP connection closed\n"); - - /* remove from per-user list of sua links */ - llist_del(&sual->list); - - llist_for_each_entry(conn, &sual->connections, list) { - /* FIXME: send RELEASE request */ - } - talloc_free(sual); - osmo_stream_srv_set_data(srv, NULL); - - return 0; -} - -static int sua_accept_cb(struct osmo_stream_srv_link *link, int fd) -{ - struct osmo_sua_user *user = osmo_stream_srv_link_get_data(link); - struct osmo_stream_srv *srv; - struct osmo_sua_link *sual; - - LOGP(DSUA, LOGL_INFO, "New SCTP connection accepted\n"); - - srv = osmo_stream_srv_create(user, link, fd, - sua_srv_conn_cb, - sua_srv_conn_closed_cb, NULL); - if (!srv) - close(fd); - - /* create new SUA link and connect both data structures */ - sual = sua_link_new(user, 1); - if (!sual) { - osmo_stream_srv_destroy(srv); - return -1; - } - sual->data = srv; - osmo_stream_srv_set_data(srv, sual); - - return 0; -} - -int osmo_sua_server_listen(struct osmo_sua_user *user, const char *hostname, uint16_t port) -{ - int rc; - - if (user->server) - osmo_stream_srv_link_close(user->server); - else { - user->server = osmo_stream_srv_link_create(user); - osmo_stream_srv_link_set_data(user->server, user); - osmo_stream_srv_link_set_accept_cb(user->server, sua_accept_cb); - } - - osmo_stream_srv_link_set_addr(user->server, hostname); - osmo_stream_srv_link_set_port(user->server, port); - osmo_stream_srv_link_set_proto(user->server, IPPROTO_SCTP); - - rc = osmo_stream_srv_link_open(user->server); - if (rc < 0) { - osmo_stream_srv_link_destroy(user->server); - user->server = NULL; - return rc; - } - - return 0; -} - -/* netif code tells us we can read something from the socket */ -static int sua_cli_conn_cb(struct osmo_stream_cli *conn) -{ - struct osmo_fd *ofd = osmo_stream_cli_get_ofd(conn); - struct osmo_sua_link *link = osmo_stream_cli_get_data(conn); - struct msgb *msg = msgb_alloc(SUA_MSGB_SIZE, "SUA Client Rx"); - struct sctp_sndrcvinfo sinfo; - unsigned int ppid; - int flags = 0; - int rc; - - if (!msg) - return -ENOMEM; - - /* read SUA message from socket and process it */ - rc = sctp_recvmsg(ofd->fd, msgb_data(msg), msgb_tailroom(msg), - NULL, NULL, &sinfo, &flags); - if (rc < 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - return rc; - } else if (rc == 0) { - close(ofd->fd); - osmo_fd_unregister(ofd); - ofd->fd = -1; - } else { - msgb_put(msg, rc); - } - - if (flags & MSG_NOTIFICATION) { - msgb_free(msg); - return 0; - } - - ppid = ntohl(sinfo.sinfo_ppid); - msgb_sctp_ppid(msg) = ppid; - msgb_sctp_stream(msg) = ntohl(sinfo.sinfo_stream); - msg->dst = link; - - switch (ppid) { - case SUA_PPID: - rc = sua_rx_msg(link, msg); - break; - default: - LOGP(DSUA, LOGL_NOTICE, "SCTP chunk for unknown PPID %u " - "received\n", ppid); - rc = 0; - break; - } - - msgb_free(msg); - return rc; -} - -int osmo_sua_client_connect(struct osmo_sua_user *user, const char *hostname, uint16_t port) -{ - struct osmo_stream_cli *cli; - struct osmo_sua_link *sual; - int rc; - - cli = osmo_stream_cli_create(user); - if (!cli) - return -1; - osmo_stream_cli_set_addr(cli, hostname); - osmo_stream_cli_set_port(cli, port); - osmo_stream_cli_set_proto(cli, IPPROTO_SCTP); - osmo_stream_cli_set_reconnect_timeout(cli, 5); - osmo_stream_cli_set_read_cb(cli, sua_cli_conn_cb); - - /* create SUA link and associate it with stream_cli */ - sual = sua_link_new(user, 0); - if (!sual) { - osmo_stream_cli_destroy(cli); - return -1; - } - sual->data = cli; - osmo_stream_cli_set_data(cli, sual); - - rc = osmo_stream_cli_open(cli); - if (rc < 0) { - sua_link_destroy(sual); - osmo_stream_cli_destroy(cli); - return rc; - } - user->client = cli; - - return 0; -} - -struct osmo_sua_link *osmo_sua_client_get_link(struct osmo_sua_user *user) -{ - return osmo_stream_cli_get_data(user->client); -} - -static LLIST_HEAD(sua_users); - -struct osmo_sua_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb) -{ - struct osmo_sua_user *user = talloc_zero(ctx, struct osmo_sua_user); - - user->prim_cb = prim_cb; - INIT_LLIST_HEAD(&user->links); - - llist_add_tail(&user->list, &sua_users); - - return user; -} - -void osmo_sua_user_destroy(struct osmo_sua_user *user) -{ - struct osmo_sua_link *link; - - llist_del(&user->list); - - llist_for_each_entry(link, &user->links, list) - sua_link_destroy(link); - - talloc_free(user); -} - -void osmo_sua_set_log_area(int area) -{ - DSUA = area; -} diff --git a/sigtran/sua.h b/sigtran/sua.h deleted file mode 100644 index 2aa99f44..00000000 --- a/sigtran/sua.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -struct osmo_sua_user; -struct osmo_sua_link; - -void osmo_sua_set_log_area(int area); - -struct osmo_sua_user *osmo_sua_user_create(void *ctx, osmo_prim_cb prim_cb); -void osmo_sua_user_destroy(struct osmo_sua_user *user); - -int osmo_sua_server_listen(struct osmo_sua_user *user, const char *hostname, uint16_t port); - -int osmo_sua_client_connect(struct osmo_sua_user *user, const char *hostname, uint16_t port); -struct osmo_sua_link *osmo_sua_client_get_link(struct osmo_sua_user *user); - -/* user hands us a SCCP-USER SAP primitive down into the stack */ -int osmo_sua_user_link_down(struct osmo_sua_link *link, struct osmo_prim_hdr *oph); - diff --git a/sigtran/sua_client_test.c b/sigtran/sua_client_test.c deleted file mode 100644 index 968a7d15..00000000 --- a/sigtran/sua_client_test.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_sua_user *g_user; -struct sua_link *g_link; - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - uint8_t payload[] = { 0xa1, 0xa2, 0xa3 }; - - printf("sccp_sap_up(%s)\n", osmo_sccp_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - printf("N-CONNECT.ind(%u), issuing DATA.req\n", - prim->u.connect.conn_id); - resp = make_dt1_req(prim->u.connect.conn_id, payload, sizeof(payload)); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - - -int main(int argc, char **argv) -{ - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - xua_set_log_area(DXUA); - - osmo_init_logging(&test_log_info); - - g_user = osmo_sua_user_create(ctx, sccp_sap_up); - - rc = osmo_sua_client_connect(g_user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - g_link = osmo_sua_client_get_link(g_user); - - int i = 8000; - - while (1) { - if (i < 8010) - tx_conn_req(g_link, i++); - //tx_unitdata(g_link); - osmo_select_main(0); - } -} diff --git a/sigtran/sua_server_test.c b/sigtran/sua_server_test.c deleted file mode 100644 index 9b9706f5..00000000 --- a/sigtran/sua_server_test.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "sua_test_common.h" - -struct osmo_prim_hdr *make_conn_resp(struct osmo_scu_connect_param *param) -{ - struct msgb *msg = msgb_alloc(1024, "conn_resp"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_RESPONSE, msg); - memcpy(&prim->u.connect, param, sizeof(prim->u.connect)); - return &prim->oph; -} - -static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link) -{ - struct osmo_scu_prim *prim = (struct osmo_scu_prim *) oph; - struct osmo_prim_hdr *resp = NULL; - const uint8_t payload[] = { 0xb1, 0xb2, 0xb3 }; - - printf("sccp_sap_up(%s)\n", osmo_sccp_prim_name(oph)); - - switch (OSMO_PRIM_HDR(oph)) { - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): - /* confirmation of outbound connection */ - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION): - /* indication of new inbound connection request*/ - printf("N-CONNECT.ind(X->%u)\n", prim->u.connect.conn_id); - resp = make_conn_resp(&prim->u.connect); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION): - /* indication of disconnect */ - printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-DATA.ind(%u, %s)\n", prim->u.data.conn_id, - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - resp = make_dt1_req(prim->u.data.conn_id, payload, sizeof(payload)); - break; - case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION): - /* connection-oriented data received */ - printf("N-UNITDATA.ind(%s)\n", - osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - tx_unitdata(link); - break; - } - - if (resp) - osmo_sua_user_link_down(link, resp); - - msgb_free(oph->msg); - return 0; -} - -int main(int argc, char **argv) -{ - struct osmo_sua_user *user; - void *ctx = talloc_named_const(NULL, 1, "root"); - int rc; - - osmo_sua_set_log_area(DSUA); - xua_set_log_area(DXUA); - - osmo_init_logging(&test_log_info); - - user = osmo_sua_user_create(ctx, sccp_sap_up); - - rc = osmo_sua_server_listen(user, "127.0.0.1", 2342); - if (rc < 0) { - exit(1); - } - - while (1) { - osmo_select_main(0); - } -} diff --git a/sigtran/sua_test_common.c b/sigtran/sua_test_common.c deleted file mode 100644 index a0da4c1a..00000000 --- a/sigtran/sua_test_common.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "sua_test_common.h" - -static const struct log_info_cat log_cat[] = { - [DMAIN] = { - .name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "Main program", - }, - [DSUA] = { - .name = "DSUA", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "SCCP User Adaption", - }, - [DXUA] = { - .name = "DXUA", .loglevel = LOGL_DEBUG, .enabled = 1, - .color = "", - .description = "X User Adaption encoding/decoding", - }, - -}; - -const struct log_info test_log_info = { - .cat = log_cat, - .num_cat = ARRAY_SIZE(log_cat), -}; - -int tx_unitdata(struct osmo_sua_link *link) -{ - struct msgb *msg = msgb_alloc(1024, "tx_unitdata"); - struct osmo_scu_prim *prim; - struct osmo_scu_unitdata_param *param; - uint8_t *cur; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - param = &prim->u.unitdata; - param->calling_addr.presence = OSMO_SCCP_ADDR_T_SSN; - param->called_addr.presence = OSMO_SCCP_ADDR_T_SSN; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_REQUEST, msg); - - cur = msg->l2h = msgb_put(msg, 3); - cur[0] = 1; cur[1] = 2; cur[2] = 3; - - return osmo_sua_user_link_down(link, &prim->oph); -} - -static void sccp_make_addr_pc_ssn(struct osmo_sccp_addr *addr, uint32_t pc, uint32_t ssn) -{ - addr->presence = OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC; - addr->ssn = ssn; - addr->pc = pc; -} - -#define SSN_RANAP 142 - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id) -{ - struct msgb *msg = msgb_alloc(1024, "conn_req"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_CONNECT, - PRIM_OP_REQUEST, msg); - /* Set SSN for calling and called addr */ - sccp_make_addr_pc_ssn(&prim->u.connect.called_addr, 2, SSN_RANAP); - sccp_make_addr_pc_ssn(&prim->u.connect.calling_addr, 1, SSN_RANAP); - prim->u.connect.sccp_class = 2; - prim->u.connect.conn_id = conn_id; - - return &prim->oph; -} - -int tx_conn_req(struct osmo_sua_link *link, uint32_t conn_id) -{ - struct osmo_prim_hdr *prim = make_conn_req(conn_id); - return osmo_sua_user_link_down(link, prim); -} - -struct osmo_prim_hdr * -make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len) -{ - struct msgb *msg = msgb_alloc(1024, "dt1"); - struct osmo_scu_prim *prim; - - prim = (struct osmo_scu_prim *) msgb_put(msg, sizeof(*prim)); - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_REQUEST, msg); - prim->u.data.conn_id = conn_id; - - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); - - return &prim->oph; -} diff --git a/sigtran/sua_test_common.h b/sigtran/sua_test_common.h deleted file mode 100644 index 0fb62f55..00000000 --- a/sigtran/sua_test_common.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "sua.h" -#include "sccp_sap.h" - - -enum log_cat { - DMAIN, - DSUA, - DXUA, -}; - -extern const struct log_info test_log_info; - -int tx_unitdata(struct osmo_sua_link *link); -int tx_conn_req(struct osmo_sua_link *link, uint32_t conn_id); - -struct osmo_prim_hdr *make_conn_req(uint32_t conn_id); -struct osmo_prim_hdr *make_dt1_req(uint32_t conn_id, const uint8_t *data, unsigned int len);