aboutsummaryrefslogtreecommitdiffstats
path: root/sigtran
diff options
context:
space:
mode:
Diffstat (limited to 'sigtran')
-rw-r--r--sigtran/Makefile17
-rw-r--r--sigtran/proto_sua.h122
-rw-r--r--sigtran/sccp_sap.c43
-rw-r--r--sigtran/sccp_sap.h199
-rw-r--r--sigtran/sua.c1431
-rw-r--r--sigtran/sua.h21
-rw-r--r--sigtran/sua_client_test.c57
-rw-r--r--sigtran/sua_server_test.c79
-rw-r--r--sigtran/sua_test_common.c95
-rw-r--r--sigtran/sua_test_common.h31
10 files changed, 0 insertions, 2095 deletions
diff --git a/sigtran/Makefile b/sigtran/Makefile
deleted file mode 100644
index 06a8ba6..0000000
--- 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 0943556..0000000
--- a/sigtran/proto_sua.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* RFC 3868 SUA SCCP User Adaption */
-
-/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
- %
- % 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 <http://www.gnu.org/licenses/>.
- */
-
-/* FIXME: Move this to libosmocore osmocom/core/gsm/protocol/sua.h */
-
-#pragma once
-#include <stdint.h>
-
-#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 207d7ea..0000000
--- a/sigtran/sccp_sap.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <string.h>
-#include <osmocom/core/utils.h>
-
-#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 89d92a9..0000000
--- a/sigtran/sccp_sap.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#pragma once
-
-/* SCCP User SAP description */
-
-/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <osmocom/core/prim.h>
-
-#include <netinet/in.h>
-
-/* 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 42c3b94..0000000
--- a/sigtran/sua.c
+++ /dev/null
@@ -1,1431 +0,0 @@
-/* Minimal implementation of RFC 3868 - SCCP User Adaptation Layer */
-
-/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/write_queue.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-
-#include <osmocom/netif/stream.h>
-#include <osmocom/sigtran/xua_msg.h>
-
-#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(&param->called_addr, xua, SUA_IEI_DEST_ADDR);
- sua_parse_addr(&param->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(&param->called_addr, &conn->called_addr,
- sizeof(param->called_addr));
- memcpy(&param->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(&param->called_addr, &conn->called_addr,
- sizeof(param->called_addr));
- memcpy(&param->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(&param->called_addr, &conn->called_addr,
- sizeof(param->called_addr));
- memcpy(&param->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(&param->called_addr, &conn->called_addr,
- sizeof(param->called_addr));
- memcpy(&param->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(&param->called_addr, &conn->called_addr,
- sizeof(param->called_addr));
- memcpy(&param->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 <osmocom/netif/stream.h>
-#include <netinet/sctp.h>
-
-/* 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 2aa99f4..0000000
--- a/sigtran/sua.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <osmocom/core/prim.h>
-
-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 968a7d1..0000000
--- 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 9b9706f..0000000
--- 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 a0da4c1..0000000
--- 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 0fb62f5..0000000
--- a/sigtran/sua_test_common.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/prim.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/vty/logging.h>
-
-#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);