This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
dexter gerrit-no-reply at lists.osmocom.orgHello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/4146 to look at the new patch set (#3). client: add unified function to generate MGCP messages currently the only way to generate MGCP messages is to use mgcp_msg_crcx(), mgcp_msg_mdcx() and mgcp_msg_dlcx(). All three function take a fixed set of parameters via their parameter list. There is no way to add or leave away optional parameters. add function mgcp_msg_gen(), this function takes a unified message struct. The struct features a presence bitmask which allows to enable and disable parameters as needed. It is also possible to add new parameters in the future without breaking the API. This commit depends on libosmocore Change: Change-Id I15e1af68616309555d0ed9ac5da027c9833d42e3 Change-Id: I29c5e2fb972896faeb771ba040f015592487fcbe --- M include/osmocom/mgcp_client/mgcp_client.h M src/libosmo-mgcp-client/mgcp_client.c M tests/mgcp_client/mgcp_client_test.c M tests/mgcp_client/mgcp_client_test.ok 4 files changed, 223 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/46/4146/3 diff --git a/include/osmocom/mgcp_client/mgcp_client.h b/include/osmocom/mgcp_client/mgcp_client.h index efc1f76..1e92da7 100644 --- a/include/osmocom/mgcp_client/mgcp_client.h +++ b/include/osmocom/mgcp_client/mgcp_client.h @@ -1,6 +1,7 @@ #pragma once #include <stdint.h> +#include <arpa/inet.h> #include <osmocom/mgcp_client/mgcp_common.h> @@ -37,6 +38,36 @@ uint16_t audio_port; }; +enum mgcp_verb { + MGCP_VERB_CRCX, + MGCP_VERB_MDCX, + MGCP_VERB_DLCX, + MGCP_VERB_AUEP, + MGCP_VERB_RSIP, +}; + +#define MGCP_MSG_PRESENCE_ENDPOINT 0x0001 +#define MGCP_MSG_PRESENCE_CALL_ID 0x0002 +#define MGCP_MSG_PRESENCE_CONN_ID 0x0004 +#define MGCP_MSG_PRESENCE_AUDIO_IP 0x0008 +#define MGCP_MSG_PRESENCE_AUDIO_PORT 0x0010 +#define MGCP_MSG_PRESENCE_CONN_MODE 0x0020 + +/* See also RFC3435 section 3.2.1.3 */ +#define MGCP_ENDPOINT_MAXLEN (255*2+1+1) + +struct mgcp_msg { + enum mgcp_verb verb; + /* See MGCP_MSG_PRESENCE_* constands above */ + uint32_t presence; + char endpoint[MGCP_ENDPOINT_MAXLEN]; + unsigned int call_id; + uint32_t conn_id; + uint16_t audio_port; + char audio_ip[INET_ADDRSTRLEN]; + enum mgcp_connection_mode conn_mode; +}; + void mgcp_client_conf_init(struct mgcp_client_conf *conf); void mgcp_client_vty_init(void *talloc_ctx, int node, struct mgcp_client_conf *conf); int mgcp_client_config_write(struct vty *vty, const char *indent); @@ -63,17 +94,22 @@ enum mgcp_connection_mode; +OSMO_DEPRECATED("Use mgcp_msg_gen() instead") struct msgb *mgcp_msg_crcx(struct mgcp_client *mgcp, uint16_t rtp_endpoint, unsigned int call_id, enum mgcp_connection_mode mode); +OSMO_DEPRECATED("Use mgcp_msg_gen() instead") struct msgb *mgcp_msg_mdcx(struct mgcp_client *mgcp, uint16_t rtp_endpoint, const char *rtp_conn_addr, uint16_t rtp_port, enum mgcp_connection_mode mode); +OSMO_DEPRECATED("Use mgcp_msg_gen() instead") struct msgb *mgcp_msg_dlcx(struct mgcp_client *mgcp, uint16_t rtp_endpoint, unsigned int call_id); +struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg); + extern const struct value_string mgcp_client_connection_mode_strs[]; static inline const char *mgcp_client_cmode_name(enum mgcp_connection_mode mode) { diff --git a/src/libosmo-mgcp-client/mgcp_client.c b/src/libosmo-mgcp-client/mgcp_client.c index 1cd37be..2bb669e 100644 --- a/src/libosmo-mgcp-client/mgcp_client.c +++ b/src/libosmo-mgcp-client/mgcp_client.c @@ -23,6 +23,7 @@ #include <osmocom/core/write_queue.h> #include <osmocom/core/msgb.h> #include <osmocom/core/logging.h> +#include <osmocom/core/byteswap.h> #include <osmocom/mgcp_client/mgcp_client.h> #include <osmocom/mgcp_client/mgcp_client_internal.h> @@ -614,6 +615,104 @@ "C: %x\r\n", trans_id, rtp_endpoint, call_id); } +#define MGCP_CRCX_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT | \ + MGCP_MSG_PRESENCE_CALL_ID | \ + MGCP_MSG_PRESENCE_CONN_ID | \ + MGCP_MSG_PRESENCE_CONN_MODE) +#define MGCP_MDCX_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT | \ + MGCP_MSG_PRESENCE_CONN_ID) +#define MGCP_DLCX_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT) +#define MGCP_AUEP_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT) +#define MGCP_RSIP_MANDATORY 0 /* none */ + +struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg) +{ + mgcp_trans_id_t trans_id = mgcp_client_next_trans_id(mgcp); + uint32_t mandatory_mask; + struct msgb *msg = msgb_alloc_headroom(4096, 128, "MGCP tx"); + int rc = 0; + + /* Add command verb */ + switch (mgcp_msg->verb) { + case MGCP_VERB_CRCX: + mandatory_mask = MGCP_CRCX_MANDATORY; + rc += msgb_printf(msg, "CRCX %u", trans_id); + break; + case MGCP_VERB_MDCX: + mandatory_mask = MGCP_MDCX_MANDATORY; + rc += msgb_printf(msg, "MDCX %u", trans_id); + break; + case MGCP_VERB_DLCX: + mandatory_mask = MGCP_DLCX_MANDATORY; + rc += msgb_printf(msg, "DLCX %u", trans_id); + break; + case MGCP_VERB_AUEP: + mandatory_mask = MGCP_AUEP_MANDATORY; + rc += msgb_printf(msg, "AUEP %u", trans_id); + break; + case MGCP_VERB_RSIP: + mandatory_mask = MGCP_RSIP_MANDATORY; + rc += msgb_printf(msg, "RSIP %u", trans_id); + break; + default: + LOGP(DLMGCP, LOGL_ERROR, + "Invalid command verb, can not generate MGCP message"); + return NULL; + } + + /* Check if mandatory fields are missing */ + if (!((mgcp_msg->presence & mandatory_mask) == mandatory_mask)) { + LOGP(DLMGCP, LOGL_ERROR, + "One or more missing mandatory fields, can not generate MGCP message"); + return NULL; + } + + /* Add endpoint name */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_ENDPOINT) + rc += msgb_printf(msg, " %s", mgcp_msg->endpoint); + + /* Add protocol version */ + msgb_printf(msg, " MGCP 1.0\r\n"); + + /* Add call id */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CALL_ID) + rc += msgb_printf(msg, "C: %x\r\n", mgcp_msg->call_id); + + /* Add connection id */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_ID) + rc += msgb_printf(msg, "I: %u\r\n", mgcp_msg->conn_id); + + /* Add local connection options */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_ID + && mgcp_msg->verb == MGCP_VERB_CRCX) + rc += msgb_printf(msg, "L: p:20, a:AMR, nt:IN\r\n"); + + /* Add mode */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_MODE) + rc += + msgb_printf(msg, "M: %s\r\n", + mgcp_client_cmode_name(mgcp_msg->conn_mode)); + + /* Add RTP address and port (SDP) */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_IP + && mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT) { + rc += msgb_printf(msg, "\r\n"); + rc += msgb_printf(msg, "c=IN IP4 %s\r\n", mgcp_msg->audio_ip); + rc += + msgb_printf(msg, "m=audio %u RTP/AVP 255\r\n", + mgcp_msg->audio_port); + } + + if (rc != 0) { + LOGP(DLMGCP, LOGL_ERROR, + "message buffer to small, can not generate MGCP message"); + msgb_free(msg); + msg = NULL; + } + + return msg; +} + struct mgcp_client_conf *mgcp_client_conf_actual(struct mgcp_client *mgcp) { return &mgcp->actual; diff --git a/tests/mgcp_client/mgcp_client_test.c b/tests/mgcp_client/mgcp_client_test.c index f2f0e0f..750aa0e 100644 --- a/tests/mgcp_client/mgcp_client_test.c +++ b/tests/mgcp_client/mgcp_client_test.c @@ -149,6 +149,65 @@ "a=ptime:20\r\n"); } +void test_mgcp_msg(void) +{ + struct msgb *msg; + + struct mgcp_msg mgcp_msg; + + if (mgcp) + talloc_free(mgcp); + mgcp = mgcp_client_init(ctx, &conf); + + /* Pre-fill the message struct with some arbitary values */ + strcpy(mgcp_msg.audio_ip, "192.168.100.23"); + strcpy(mgcp_msg.endpoint, "23 at mgw"); + mgcp_msg.call_id = 47; + mgcp_msg.conn_id = 11; + mgcp_msg.conn_mode = MGCP_CONN_RECV_SEND; + + printf("\n"); + + printf("Generated CRCX message:\n"); + mgcp_msg.verb = MGCP_VERB_CRCX; + mgcp_msg.presence = + (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | + MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE); + msg = mgcp_msg_gen(mgcp, &mgcp_msg); + printf("%s\n", msg->data); + + printf("Generated MDCX message:\n"); + mgcp_msg.verb = MGCP_VERB_MDCX; + mgcp_msg.presence = + (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | + MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE | + MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT); + msg = mgcp_msg_gen(mgcp, &mgcp_msg); + printf("%s\n", msg->data); + + printf("Generated DLCX message:\n"); + mgcp_msg.verb = MGCP_VERB_DLCX; + mgcp_msg.presence = + (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | + MGCP_MSG_PRESENCE_CONN_ID); + msg = mgcp_msg_gen(mgcp, &mgcp_msg); + printf("%s\n", msg->data); + + printf("Generated AUEP message:\n"); + mgcp_msg.verb = MGCP_VERB_AUEP; + mgcp_msg.presence = (MGCP_MSG_PRESENCE_ENDPOINT); + msg = mgcp_msg_gen(mgcp, &mgcp_msg); + printf("%s\n", msg->data); + + printf("Generated RSIP message:\n"); + mgcp_msg.verb = MGCP_VERB_RSIP; + mgcp_msg.presence = (MGCP_MSG_PRESENCE_ENDPOINT); + msg = mgcp_msg_gen(mgcp, &mgcp_msg); + printf("%s\n", msg->data); + + msgb_free(msg); +} + static const struct log_info_cat log_categories[] = { }; @@ -167,6 +226,7 @@ mgcp_client_conf_init(&conf); test_crcx(); + test_mgcp_msg(); printf("Done\n"); fprintf(stderr, "Done\n"); diff --git a/tests/mgcp_client/mgcp_client_test.ok b/tests/mgcp_client/mgcp_client_test.ok index d35f2d6..7c4819d 100644 --- a/tests/mgcp_client/mgcp_client_test.ok +++ b/tests/mgcp_client/mgcp_client_test.ok @@ -28,4 +28,32 @@ head.trans_id = 1 head.comment = OK audio_port = 16002 + +Generated CRCX message: +CRCX 1 23 at mgw MGCP 1.0 +C: 2f +I: 11 +L: p:20, a:AMR, nt:IN +M: sendrecv + +Generated MDCX message: +MDCX 2 23 at mgw MGCP 1.0 +C: 2f +I: 11 +M: sendrecv + +c=IN IP4 192.168.100.23 +m=audio 1234 RTP/AVP 255 + +Generated DLCX message: +DLCX 3 23 at mgw MGCP 1.0 +C: 2f +I: 11 + +Generated AUEP message: +AUEP 4 23 at mgw MGCP 1.0 + +Generated RSIP message: +RSIP 5 23 at mgw MGCP 1.0 + Done -- To view, visit https://gerrit.osmocom.org/4146 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I29c5e2fb972896faeb771ba040f015592487fcbe Gerrit-PatchSet: 3 Gerrit-Project: osmo-mgw Gerrit-Branch: master Gerrit-Owner: dexter <pmaier at sysmocom.de> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>