client: allow passing and receiving full SDP to/from MGW
Clients can continue to use the current way of providing the information contained in the SDP part. A client may also decide to directly provide an SDP string. That may be useful to send a list of payload types with mixed fmtp (e.g. two entries, one for AMR OA and one for AMR BE) or any other custom SDP that is not possible to be represented with the previous structure of struct mgcp_conn_peer: struct sdp_msg sdp = {}; sdp_audio_codecs_add(&sdp.audio_codecs, 96, "AMR", 8000, "octet-align=1"); sdp_audio_codecs_add(&sdp.audio_codecs, 97, "AMR", 8000, "octet-align=0"); struct mgcp_conn_peer verb_info = { ... }; sdp_msg_to_sdp_str_buf(verb_info.sdp, sizeof(verb_info.sdp), &sdp); osmo_mgcpc_ep_ci_request(my_ci, MGCP_VERB_MDCX, &verb_info,...); (TODO: sdp_msg, sdp_audio_codecs_add() and sdp_msg_to_sdp_str_buf() so far only exists in osmo-msc.git) If no SDP is present in the passed verb_info, the SDP part is composed as before from the mgcp_conn_peer members addr, port, ptime, ptmap, param. If an SDP string is present in the passed verb_info, ignore the data in the individual members, and directly pass the given SDP string instead -- the caller does not need to pass both the individual members and SDP, either one suffices. A client can read the full SDP response from the MGW, again for example to accurately parse a list with mixed fmtp for AMR like above, like this: /* Handling successful event after osmo_mgcpc_ep_ci_request(my_fi, my_notify_event): */ const struct mgcp_conn_peer *response_info = osmo_mgcpc_ep_ci_get_rtp_info(ci); struct sdp_msg sdp; sdp_msg_from_sdp_str(&sdp, response_info->sdp); for (int i = 0; i < sdp.audio_codecs.count; i++) printf("PT %u = %s %s", sdp.audio_codecs.codec[i].payload_type, sdp.audio_codecs.codec[i].subtype_name, sdp.audio_codecs.codec[i].fmtp); Related: OS#5723 Change-Id: Ib26b4d24546a9a9af65d4313fdf87cdeff9cbc22
This commit is contained in:
parent
9f70f78ae3
commit
1b46b3405a
|
@ -83,6 +83,7 @@ struct mgcp_response_head {
|
|||
};
|
||||
|
||||
struct mgcp_response {
|
||||
/* The complete MGCP + SDP response. See also 'sdp' below. */
|
||||
char *body;
|
||||
struct mgcp_response_head head;
|
||||
uint16_t audio_port;
|
||||
|
@ -92,6 +93,8 @@ struct mgcp_response {
|
|||
unsigned int codecs_len;
|
||||
struct ptmap ptmap[MGCP_MAX_CODECS];
|
||||
unsigned int ptmap_len;
|
||||
/* Start of the SDP part of 'body'. */
|
||||
char *sdp;
|
||||
};
|
||||
|
||||
enum mgcp_verb {
|
||||
|
@ -131,6 +134,8 @@ struct mgcp_msg {
|
|||
int x_osmo_osmux_cid; /* -1 is wildcard */
|
||||
bool param_present;
|
||||
struct mgcp_codec_param param;
|
||||
|
||||
char sdp[1024];
|
||||
};
|
||||
|
||||
void mgcp_client_conf_init(struct mgcp_client_conf *conf);
|
||||
|
|
|
@ -61,6 +61,8 @@ struct mgcp_conn_peer {
|
|||
* mgcp_common.h */
|
||||
bool param_present;
|
||||
struct mgcp_codec_param param;
|
||||
|
||||
char sdp[1024];
|
||||
};
|
||||
|
||||
struct osmo_fsm_inst *mgcp_conn_create(struct mgcp_client *mgcp, struct osmo_fsm_inst *parent_fi, uint32_t parent_term_evt,
|
||||
|
|
|
@ -493,6 +493,7 @@ int mgcp_response_parse_params(struct mgcp_response *r)
|
|||
rc = 0;
|
||||
goto exit;
|
||||
}
|
||||
r->sdp = data_ptr;
|
||||
|
||||
/* data_ptr now points to the beginning of the section-end-marker; for_each_non_empty_line()
|
||||
* skips any \r and \n characters for free, so we don't need to skip the marker. */
|
||||
|
@ -1194,6 +1195,13 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
|
|||
/* Add separator to mark the beginning of the SDP block */
|
||||
MSGB_PRINTF_OR_RET("\r\n");
|
||||
|
||||
if (mgcp_msg->sdp[0] != '\0') {
|
||||
/* The caller provided a full SDP string, no need to compose SDP. */
|
||||
MSGB_PRINTF_OR_RET("%s", mgcp_msg->sdp);
|
||||
return 0;
|
||||
}
|
||||
/* The caller did not provide a full SDP section, compose SDP string from the mgcp_msg members. */
|
||||
|
||||
/* Add SDP protocol version */
|
||||
MSGB_PRINTF_OR_RET("v=0\r\n");
|
||||
|
||||
|
@ -1376,8 +1384,9 @@ struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg)
|
|||
|
||||
/* Using SDP makes sense when a valid IP/Port combination is specifiec,
|
||||
* if we do not know this information yet, we fall back to LCO */
|
||||
if (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_IP
|
||||
&& mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT)
|
||||
if (((mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_IP)
|
||||
&& (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT))
|
||||
|| mgcp_msg->sdp[0] != '\0')
|
||||
use_sdp = true;
|
||||
|
||||
/* Add local connection options (LCO) */
|
||||
|
|
|
@ -140,6 +140,9 @@ static void add_audio(struct mgcp_msg *mgcp_msg, struct mgcp_conn_peer *info)
|
|||
mgcp_msg->audio_ip = info->addr;
|
||||
mgcp_msg->audio_port = info->port;
|
||||
mgcp_msg->conn_mode = MGCP_CONN_RECV_SEND;
|
||||
|
||||
if (info->sdp[0] != '\0')
|
||||
OSMO_STRLCPY_ARRAY(mgcp_msg->sdp, info->sdp);
|
||||
}
|
||||
|
||||
static void set_conn_mode(struct mgcp_msg *mgcp_msg, struct mgcp_conn_peer *peer)
|
||||
|
@ -179,6 +182,9 @@ static struct msgb *make_mdcx_msg(struct mgcp_ctx *mgcp_ctx)
|
|||
mgcp_msg.presence |= MGCP_MSG_PRESENCE_X_OSMO_OSMUX_CID;
|
||||
}
|
||||
|
||||
if (mgcp_ctx->conn_peer_local.sdp[0] != '\0')
|
||||
OSMO_STRLCPY_ARRAY(mgcp_msg.sdp, mgcp_ctx->conn_peer_local.sdp);
|
||||
|
||||
/* Note: We take the endpoint and the call_id from the remote
|
||||
* connection info, because we can be confident that the
|
||||
* information there is valid. For the local info, we explicitly
|
||||
|
@ -319,6 +325,9 @@ static void mgw_crcx_resp_cb(struct mgcp_response *r, void *priv)
|
|||
return;
|
||||
}
|
||||
|
||||
if (r->sdp && r->sdp[0] != '\0')
|
||||
OSMO_STRLCPY_ARRAY(mgcp_ctx->conn_peer_remote.sdp, r->sdp);
|
||||
|
||||
mgcp_ctx->conn_peer_remote.call_id = mgcp_ctx->conn_peer_local.call_id;
|
||||
|
||||
osmo_fsm_inst_dispatch(fi, EV_CRCX_RESP, mgcp_ctx);
|
||||
|
@ -426,6 +435,9 @@ static void mgw_mdcx_resp_cb(struct mgcp_response *r, void *priv)
|
|||
osmo_strlcpy(mgcp_ctx->conn_peer_remote.addr, r->audio_ip, sizeof(mgcp_ctx->conn_peer_remote.addr));
|
||||
mgcp_ctx->conn_peer_remote.port = r->audio_port;
|
||||
|
||||
if (r->sdp && r->sdp[0] != '\0')
|
||||
OSMO_STRLCPY_ARRAY(mgcp_ctx->conn_peer_remote.sdp, r->sdp);
|
||||
|
||||
osmo_fsm_inst_dispatch(fi, EV_MDCX_RESP, mgcp_ctx);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue