diff options
Diffstat (limited to 'include/osmocom')
-rw-r--r-- | include/osmocom/mgcp/Makefile.am | 2 | ||||
-rw-r--r-- | include/osmocom/mgcp/debug.h | 1 | ||||
-rw-r--r-- | include/osmocom/mgcp/iuup_cn_node.h | 47 | ||||
-rw-r--r-- | include/osmocom/mgcp/iuup_protocol.h | 117 | ||||
-rw-r--r-- | include/osmocom/mgcp/mgcp_codec.h | 2 | ||||
-rw-r--r-- | include/osmocom/mgcp/mgcp_endp.h | 22 | ||||
-rw-r--r-- | include/osmocom/mgcp/mgcp_internal.h | 19 |
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); |