aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom
diff options
context:
space:
mode:
Diffstat (limited to 'include/osmocom')
-rw-r--r--include/osmocom/mgcp/Makefile.am2
-rw-r--r--include/osmocom/mgcp/debug.h1
-rw-r--r--include/osmocom/mgcp/iuup_cn_node.h47
-rw-r--r--include/osmocom/mgcp/iuup_protocol.h117
-rw-r--r--include/osmocom/mgcp/mgcp_codec.h2
-rw-r--r--include/osmocom/mgcp/mgcp_endp.h22
-rw-r--r--include/osmocom/mgcp/mgcp_internal.h19
7 files changed, 202 insertions, 8 deletions
diff --git a/include/osmocom/mgcp/Makefile.am b/include/osmocom/mgcp/Makefile.am
index 65ca6707a..a618b948c 100644
--- a/include/osmocom/mgcp/Makefile.am
+++ b/include/osmocom/mgcp/Makefile.am
@@ -7,4 +7,6 @@ noinst_HEADERS = \
mgcp_sdp.h \
mgcp_codec.h \
debug.h \
+ iuup_cn_node.h \
+ iuup_protocol.h \
$(NULL)
diff --git a/include/osmocom/mgcp/debug.h b/include/osmocom/mgcp/debug.h
index ddeb0dc63..1eed7697f 100644
--- a/include/osmocom/mgcp/debug.h
+++ b/include/osmocom/mgcp/debug.h
@@ -29,6 +29,7 @@
/* Debug Areas of the code */
enum {
DRTP,
+ DIUUP,
Debug_LastEntry,
};
diff --git a/include/osmocom/mgcp/iuup_cn_node.h b/include/osmocom/mgcp/iuup_cn_node.h
new file mode 100644
index 000000000..ca69b4db7
--- /dev/null
+++ b/include/osmocom/mgcp/iuup_cn_node.h
@@ -0,0 +1,47 @@
+/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
+/* IuUP CN node, minimal implementation */
+
+/* _____IuUP_CN_____
+ * | |
+ * UE <--> RNC --PDU-> osmo_iuup_cn_rx_pdu() -+-> ---+-> rx_payload()
+ * | | |
+ * | <-PDU-- tx_msg() <-------------+-- <-+--- osmo_iuup_cn_tx_payload()
+ * | |
+ * -----------------
+ */
+
+#pragma once
+
+struct msgb;
+
+typedef int (*osmo_iuup_data_cb_t)(struct msgb *msg, void *node_priv);
+
+struct osmo_iuup_cn_cfg {
+ void *node_priv;
+
+ /* When the IuUP peer sent a voice packet, the clean RTP without the IuUP header is fed to this
+ * callback. */
+ osmo_iuup_data_cb_t rx_payload;
+
+ /* IuUP handler requests that a PDU shall be sent to the IuUP peer (e.g. the RNC).
+ * It is guaranteed that the msgb->dst pointer is preserved or copied from the msgb that
+ * originated the request. */
+ osmo_iuup_data_cb_t tx_msg;
+};
+
+struct osmo_iuup_cn {
+ struct osmo_iuup_cn_cfg cfg;
+ char *name;
+ uint8_t next_frame_nr;
+ int rtp_payload_type;
+};
+
+bool osmo_iuup_cn_is_iuup_init(struct msgb *msg);
+
+struct osmo_iuup_cn *osmo_iuup_cn_init(void *ctx, struct osmo_iuup_cn_cfg *cfg,
+ const char *name_fmt, ...);
+void osmo_iuup_cn_free(struct osmo_iuup_cn *cn);
+
+int osmo_iuup_cn_tx_payload(struct osmo_iuup_cn *cn, struct msgb *payload);
+
+int osmo_iuup_cn_rx_pdu(struct osmo_iuup_cn *cn, struct msgb *pdu);
diff --git a/include/osmocom/mgcp/iuup_protocol.h b/include/osmocom/mgcp/iuup_protocol.h
new file mode 100644
index 000000000..f4aec1f8c
--- /dev/null
+++ b/include/osmocom/mgcp/iuup_protocol.h
@@ -0,0 +1,117 @@
+/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
+/* IuUP protocol handling, minimal implementation */
+
+#pragma once
+
+#include <osmocom/core/endian.h>
+#include <osmocom/core/msgb.h>
+
+#define OSMO_IUUP_HEADROOM 32
+
+enum osmo_iuup_pdu_type {
+ OSMO_IUUP_PDU_DATA_WITH_CRC = 0,
+ OSMO_IUUP_PDU_CONTROL_PROCEDURE = 14,
+};
+
+enum osmo_iuup_acknack {
+ OSMO_IUUP_ACKNACK_PROCEDURE = 0,
+ OSMO_IUUP_ACKNACK_ACK = 1,
+ OSMO_IUUP_ACKNACK_NACK = 2,
+};
+
+enum osmo_iuup_procedure {
+ OSMO_IUUP_PROC_INITIALIZATION = 0,
+ OSMO_IUUP_PROC_RATE_CONTROL = 1,
+ OSMO_IUUP_PROC_TIME_ALIGNMENT = 2,
+ OSMO_IUUP_PROC_ERROR_EVENT = 3,
+};
+
+enum osmo_iuup_frame_good {
+ OSMO_IUUP_FRAME_GOOD = 0,
+ OSMO_IUUP_FRAME_BAD = 1,
+ OSMO_IUUP_FRAME_BAD_DUE_TO_RADIO = 2,
+};
+
+struct osmo_iuup_hdr_ctrl {
+#if OSMO_IS_BIG_ENDIAN
+ uint8_t pdu_type:4,
+ ack_nack:2,
+ frame_nr:2;
+ uint8_t mode_version:4,
+ procedure:4;
+ uint8_t header_crc:6,
+ payload_crc_hi:2;
+ uint8_t payload_crc_lo;
+ uint8_t payload[0];
+#elif OSMO_IS_LITTLE_ENDIAN
+ uint8_t frame_nr:2,
+ ack_nack:2,
+ pdu_type:4;
+ uint8_t procedure:4,
+ mode_version:4;
+ uint8_t payload_crc_hi:2,
+ header_crc:6;
+ uint8_t payload_crc_lo;
+ uint8_t payload[0];
+#endif
+} __attribute__((packed));
+
+union osmo_iuup_hdr_ctrl_payload {
+ struct {
+#if OSMO_IS_BIG_ENDIAN
+ uint8_t spare:3,
+ iptis_present:1,
+ subflows:3,
+ chain:1;
+#elif OSMO_IS_LITTLE_ENDIAN
+ uint8_t spare:3,
+ iptis_present:1,
+ subflows:3,
+ chain:1;
+#endif
+ } initialization;
+
+ struct {
+#if OSMO_IS_BIG_ENDIAN
+ uint8_t error_distance:2,
+ error_cause:6;
+#elif OSMO_IS_LITTLE_ENDIAN
+ uint8_t error_cause:6,
+ error_distance:2;
+#endif
+ } error_event;
+};
+
+extern const struct value_string osmo_iuup_error_cause_names[];
+static inline const char *osmo_iuup_error_cause_name(uint8_t val)
+{ return get_value_string(osmo_iuup_error_cause_names, val); }
+
+struct osmo_iuup_hdr_data {
+#if OSMO_IS_BIG_ENDIAN
+ uint8_t pdu_type:4,
+ frame_nr:4;
+ uint8_t frame_good:2,
+ rfci:6;
+ uint8_t header_crc:6,
+ payload_crc_hi:2;
+ uint8_t payload_crc_lo;
+#elif OSMO_IS_LITTLE_ENDIAN
+ uint8_t frame_nr:4,
+ pdu_type:4;
+ uint8_t rfci:6,
+ frame_good:2;
+ uint8_t payload_crc_hi:2,
+ header_crc:6;
+ uint8_t payload_crc_lo;
+#endif
+ uint8_t payload[0];
+} __attribute__((packed));
+
+int osmo_iuup_classify(bool log_errors,
+ const char *log_label,
+ struct msgb *pdu,
+ struct osmo_iuup_hdr_ctrl **is_ctrl,
+ struct osmo_iuup_hdr_data **is_data);
+bool osmo_iuup_is_init(struct msgb *pdu);
+void osmo_iuup_make_init_ack(struct msgb *ack);
+void osmo_iuup_set_checksums(uint8_t *iuup_header_and_payload, unsigned int header_and_payload_len);
diff --git a/include/osmocom/mgcp/mgcp_codec.h b/include/osmocom/mgcp/mgcp_codec.h
index 3ead60a6b..caeecb00a 100644
--- a/include/osmocom/mgcp/mgcp_codec.h
+++ b/include/osmocom/mgcp/mgcp_codec.h
@@ -5,3 +5,5 @@ void mgcp_codec_reset_all(struct mgcp_conn_rtp *conn);
int mgcp_codec_add(struct mgcp_conn_rtp *conn, int payload_type, const char *audio_name, const struct mgcp_codec_param *param);
int mgcp_codec_decide(struct mgcp_conn_rtp *conn);
int mgcp_codec_pt_translate(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, int payload_type);
+const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,
+ const char *subtype_name, unsigned int match_nr);
diff --git a/include/osmocom/mgcp/mgcp_endp.h b/include/osmocom/mgcp/mgcp_endp.h
index 75f093deb..9c0dc8cd8 100644
--- a/include/osmocom/mgcp/mgcp_endp.h
+++ b/include/osmocom/mgcp/mgcp_endp.h
@@ -23,15 +23,27 @@
#pragma once
+#include <osmocom/core/msgb.h>
+
struct sockaddr_in;
struct mgcp_conn;
+struct mgcp_conn_rtp;
struct mgcp_endpoint;
-/* Callback type for RTP dispatcher functions
- (e.g mgcp_dispatch_rtp_bridge_cb, see below) */
-typedef int (*mgcp_dispatch_rtp_cb) (int proto, struct sockaddr_in *addr,
- char *buf, unsigned int buf_size,
- struct mgcp_conn *conn);
+struct osmo_rtp_msg_ctx {
+ int proto;
+ struct mgcp_conn_rtp *conn_src;
+ struct sockaddr_in *from_addr;
+};
+
+#define OSMO_RTP_MSG_CTX(MSGB) (*(struct osmo_rtp_msg_ctx**)&((MSGB)->dst))
+
+#define LOG_ENDP(endp, level, fmt, args...) \
+ LOGP(DRTP, level, "%x@ " fmt, ENDPOINT_NUMBER(endp), ## args)
+
+/* Callback type for RTP dispatcher functions (e.g mgcp_dispatch_rtp_bridge_cb, see below).
+ * The OSMO_RTP_MSG_CTX() should be set appropriately on the msg. */
+typedef int (*mgcp_dispatch_rtp_cb) (struct msgb *msg);
/* Callback type for endpoint specific cleanup actions. This function
* is automatically executed when a connection is freed (see mgcp_conn_free()
diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h
index e9d5d2db3..3e83bdffd 100644
--- a/include/osmocom/mgcp/mgcp_internal.h
+++ b/include/osmocom/mgcp/mgcp_internal.h
@@ -37,6 +37,13 @@
#define CONN_ID_BTS "0"
#define CONN_ID_NET "1"
+#define LOG_CONN(conn, level, fmt, args...) \
+ LOGP(DRTP, level, "(%d@ I:%s) " fmt, \
+ ENDPOINT_NUMBER((conn)->endp), (conn)->id, ## args)
+
+#define LOG_CONN_RTP(conn_rtp, level, fmt, args...) \
+ LOG_CONN(conn_rtp->conn, level, fmt, ## args)
+
enum mgcp_trunk_type {
MGCP_TRUNK_VIRTUAL,
MGCP_TRUNK_E1,
@@ -204,6 +211,8 @@ struct mgcp_conn_rtp {
} osmux;
struct rate_ctr_group *rate_ctr_group;
+
+ struct osmo_iuup_cn *iuup;
};
/*! Connection type, specifies which member of the union "u" in mgcp_conn
@@ -266,11 +275,10 @@ struct mgcp_parse_data {
};
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,
- char *buf, int rc, struct mgcp_conn_rtp *conn_src,
+ struct msgb *msg, struct mgcp_conn_rtp *conn_src,
struct mgcp_conn_rtp *conn_dst);
int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
-int mgcp_dispatch_rtp_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,
- unsigned int buf_size, struct mgcp_conn *conn);
+int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg);
void mgcp_cleanup_rtp_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,
struct mgcp_conn_rtp *conn);
@@ -350,3 +358,8 @@ LOGP(cat, level, "endpoint:0x%x " fmt, \
LOGPENDP((conn)->endp, cat, level, "CI:%s " fmt, \
(conn)->id, \
## args)
+
+void mgcp_patch_and_count(struct mgcp_endpoint *endp,
+ struct mgcp_rtp_state *state,
+ struct mgcp_rtp_end *rtp_end,
+ struct sockaddr_in *addr, struct msgb *msg);