mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-msc.git
				synced 2025-11-04 05:53:23 +00:00 
			
		
		
		
	transaction: move cc.codecs.result -> cc.local
Prepare for CSD where this will be used too. Related: OS#4394 Change-Id: Iaf954be0455625faa06a64c19905b79b7045f8e4
This commit is contained in:
		@@ -42,20 +42,16 @@ struct codec_filter {
 | 
			
		||||
 | 
			
		||||
	/* After a channel was assigned, this reflects the chosen codec. */
 | 
			
		||||
	struct sdp_audio_codec assignment;
 | 
			
		||||
 | 
			
		||||
	/* Resulting choice of supported codecs, usually the intersection of the above,
 | 
			
		||||
	 * and the local RTP address to be sent to the remote call leg.
 | 
			
		||||
	 * The RTP address:port in result.rtp is not modified by codec_filter_run() -- set it once. */
 | 
			
		||||
	struct sdp_msg result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void codec_filter_set_ran(struct codec_filter *codec_filter, enum osmo_rat_type ran_type);
 | 
			
		||||
void codec_filter_set_bss(struct codec_filter *codec_filter,
 | 
			
		||||
			  const struct gsm0808_speech_codec_list *codec_list_bss_supported);
 | 
			
		||||
void codec_filter_set_local_rtp(struct codec_filter *codec_filter, const struct osmo_sockaddr_str *rtp);
 | 
			
		||||
int codec_filter_run(struct codec_filter *codec_filter, const struct sdp_msg *remote);
 | 
			
		||||
int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote);
 | 
			
		||||
 | 
			
		||||
int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter,
 | 
			
		||||
			    const struct sdp_msg *result, const struct sdp_msg *remote);
 | 
			
		||||
char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result,
 | 
			
		||||
			    const struct sdp_msg *remote);
 | 
			
		||||
char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *remote);
 | 
			
		||||
const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *remote);
 | 
			
		||||
const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result,
 | 
			
		||||
				const struct sdp_msg *remote);
 | 
			
		||||
 
 | 
			
		||||
@@ -109,6 +109,9 @@ struct gsm_trans {
 | 
			
		||||
			struct sdp_msg remote;
 | 
			
		||||
			/* Track codec choices from BSS and remote call leg */
 | 
			
		||||
			struct codec_filter codecs;
 | 
			
		||||
			/* Resulting choice from codecs/bearer services and the
 | 
			
		||||
			 * local RTP address to be sent to the remote call leg. */
 | 
			
		||||
			struct sdp_msg local;
 | 
			
		||||
		} cc;
 | 
			
		||||
		struct {
 | 
			
		||||
			struct gsm411_smc_inst smc_inst;
 | 
			
		||||
 
 | 
			
		||||
@@ -84,19 +84,11 @@ void codec_filter_set_bss(struct codec_filter *codec_filter,
 | 
			
		||||
		sdp_audio_codecs_from_speech_codec_list(&codec_filter->bss, codec_list_bss_supported);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void codec_filter_set_local_rtp(struct codec_filter *codec_filter, const struct osmo_sockaddr_str *rtp)
 | 
			
		||||
{
 | 
			
		||||
	if (!rtp)
 | 
			
		||||
		codec_filter->result.rtp = (struct osmo_sockaddr_str){0};
 | 
			
		||||
	else
 | 
			
		||||
		codec_filter->result.rtp = *rtp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Render intersections of all known audio codec constraints to reach a resulting choice of favorite audio codec, plus
 | 
			
		||||
 * possible set of alternative audio codecs, in codec_filter->result. (The result.rtp address remains unchanged.) */
 | 
			
		||||
int codec_filter_run(struct codec_filter *codec_filter, const struct sdp_msg *remote)
 | 
			
		||||
int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote)
 | 
			
		||||
{
 | 
			
		||||
	struct sdp_audio_codecs *r = &codec_filter->result.audio_codecs;
 | 
			
		||||
	struct sdp_audio_codecs *r = &result->audio_codecs;
 | 
			
		||||
	struct sdp_audio_codec *a = &codec_filter->assignment;
 | 
			
		||||
	*r = codec_filter->ran;
 | 
			
		||||
	if (codec_filter->ms.count)
 | 
			
		||||
@@ -150,10 +142,10 @@ int codec_filter_run(struct codec_filter *codec_filter, const struct sdp_msg *re
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter,
 | 
			
		||||
			    const struct sdp_msg *remote)
 | 
			
		||||
			    const struct sdp_msg *result, const struct sdp_msg *remote)
 | 
			
		||||
{
 | 
			
		||||
	struct osmo_strbuf sb = { .buf = buf, .len = buflen };
 | 
			
		||||
	OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, &codec_filter->result);
 | 
			
		||||
	OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result);
 | 
			
		||||
	OSMO_STRBUF_PRINTF(sb, " (from:");
 | 
			
		||||
 | 
			
		||||
	if (sdp_audio_codec_is_set(&codec_filter->assignment)) {
 | 
			
		||||
@@ -188,12 +180,14 @@ int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter
 | 
			
		||||
	return sb.chars_needed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *remote)
 | 
			
		||||
char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result,
 | 
			
		||||
			    const struct sdp_msg *remote)
 | 
			
		||||
{
 | 
			
		||||
	OSMO_NAME_C_IMPL(ctx, 128, "codec_filter_to_str_c-ERROR", codec_filter_to_str_buf, codec_filter, remote)
 | 
			
		||||
	OSMO_NAME_C_IMPL(ctx, 128, "codec_filter_to_str_c-ERROR", codec_filter_to_str_buf, codec_filter, result, remote)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *remote)
 | 
			
		||||
const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result,
 | 
			
		||||
				const struct sdp_msg *remote)
 | 
			
		||||
{
 | 
			
		||||
	return codec_filter_to_str_c(OTC_SELECT, codec_filter, remote);
 | 
			
		||||
	return codec_filter_to_str_c(OTC_SELECT, codec_filter, result, remote);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -731,9 +731,9 @@ void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans)
 | 
			
		||||
		trans_free(trans);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	codec_filter_set_local_rtp(&trans->cc.codecs, rtp_cn_local);
 | 
			
		||||
	trans->cc.local.rtp = *rtp_cn_local;
 | 
			
		||||
 | 
			
		||||
	sdp = trans->cc.codecs.result.audio_codecs.count ? &trans->cc.codecs.result : NULL;
 | 
			
		||||
	sdp = trans->cc.local.audio_codecs.count ? &trans->cc.local : NULL;
 | 
			
		||||
	rc = sdp_msg_to_sdp_str_buf(setup.sdp, sizeof(setup.sdp), sdp);
 | 
			
		||||
	if (rc >= sizeof(setup.sdp)) {
 | 
			
		||||
		LOG_TRANS(trans, LOGL_ERROR, "MNCC_SETUP_IND: SDP too long (%d > %zu bytes)\n", rc, sizeof(setup.sdp));
 | 
			
		||||
@@ -829,7 +829,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
 | 
			
		||||
	bearer_cap = (struct gsm_mncc_bearer_cap){
 | 
			
		||||
		.speech_ver = { -1 },
 | 
			
		||||
	};
 | 
			
		||||
	sdp_audio_codecs_to_bearer_cap(&bearer_cap, &trans->cc.codecs.result.audio_codecs);
 | 
			
		||||
	sdp_audio_codecs_to_bearer_cap(&bearer_cap, &trans->cc.local.audio_codecs);
 | 
			
		||||
	rc = bearer_cap_set_radio(&bearer_cap);
 | 
			
		||||
	if (rc) {
 | 
			
		||||
		LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n");
 | 
			
		||||
@@ -844,7 +844,8 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
 | 
			
		||||
	 * finding a matching codec. */
 | 
			
		||||
	if (bearer_cap.speech_ver[0] == -1) {
 | 
			
		||||
		LOG_TRANS(trans, LOGL_ERROR, "%s: no codec match possible: %s\n",
 | 
			
		||||
			  get_mncc_name(setup->msg_type), codec_filter_to_str(&trans->cc.codecs, &trans->cc.remote));
 | 
			
		||||
			  get_mncc_name(setup->msg_type),
 | 
			
		||||
			  codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));
 | 
			
		||||
 | 
			
		||||
		/* incompatible codecs */
 | 
			
		||||
		rc = mncc_release_ind(trans->net, trans, trans->callref,
 | 
			
		||||
@@ -978,7 +979,7 @@ static int gsm48_cc_mt_rtp_port_and_codec_known(struct gsm_trans *trans)
 | 
			
		||||
		trans_free(trans);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	codec_filter_set_local_rtp(&trans->cc.codecs, rtp_cn_local);
 | 
			
		||||
	trans->cc.local.rtp = *rtp_cn_local;
 | 
			
		||||
 | 
			
		||||
	trans_cc_filter_run(trans);
 | 
			
		||||
 | 
			
		||||
@@ -989,7 +990,7 @@ static int gsm48_cc_mt_rtp_port_and_codec_known(struct gsm_trans *trans)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mncc_recv_rtp(msc_a_net(msc_a), trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, 0, 0,
 | 
			
		||||
			     &trans->cc.codecs.result);
 | 
			
		||||
			     &trans->cc.local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg)
 | 
			
		||||
@@ -1060,7 +1061,7 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
 | 
			
		||||
	new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
 | 
			
		||||
 | 
			
		||||
	trans_cc_filter_run(trans);
 | 
			
		||||
	rc = sdp_msg_to_sdp_str_buf(alerting.sdp, sizeof(alerting.sdp), &trans->cc.codecs.result);
 | 
			
		||||
	rc = sdp_msg_to_sdp_str_buf(alerting.sdp, sizeof(alerting.sdp), &trans->cc.local);
 | 
			
		||||
	if (rc >= sizeof(alerting.sdp)) {
 | 
			
		||||
		LOG_TRANS(trans, LOGL_ERROR, "MNCC_ALERT_IND: SDP too long (%d > %zu bytes)\n",
 | 
			
		||||
			  rc, sizeof(alerting.sdp));
 | 
			
		||||
@@ -1206,7 +1207,7 @@ static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
 | 
			
		||||
	rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_CONNECT));
 | 
			
		||||
 | 
			
		||||
	trans_cc_filter_run(trans);
 | 
			
		||||
	sdp_msg_to_sdp_str_buf(connect.sdp, sizeof(connect.sdp), &trans->cc.codecs.result);
 | 
			
		||||
	sdp_msg_to_sdp_str_buf(connect.sdp, sizeof(connect.sdp), &trans->cc.local);
 | 
			
		||||
	return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2044,7 +2045,7 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	trans_cc_filter_run(trans);
 | 
			
		||||
	codecs = &trans->cc.codecs.result.audio_codecs;
 | 
			
		||||
	codecs = &trans->cc.local.audio_codecs;
 | 
			
		||||
	if (!codecs->count) {
 | 
			
		||||
		LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR,
 | 
			
		||||
			      "Cannot RTP CREATE to MNCC, there is no codec available\n");
 | 
			
		||||
@@ -2063,7 +2064,7 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local,
 | 
			
		||||
			     codec->payload_type, mncc_payload_msg_type, &trans->cc.codecs.result);
 | 
			
		||||
			     codec->payload_type, mncc_payload_msg_type, &trans->cc.local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *rtp)
 | 
			
		||||
 
 | 
			
		||||
@@ -640,18 +640,18 @@ static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
 | 
			
		||||
	trans_cc_filter_run(cc_trans);
 | 
			
		||||
	LOG_TRANS(cc_trans, LOGL_DEBUG, "Sending Assignment Command\n");
 | 
			
		||||
 | 
			
		||||
	if (!cc_trans->cc.codecs.result.audio_codecs.count) {
 | 
			
		||||
	if (!cc_trans->cc.local.audio_codecs.count) {
 | 
			
		||||
		LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching codec: %s\n",
 | 
			
		||||
			  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.remote));
 | 
			
		||||
			  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
 | 
			
		||||
		call_leg_release(msc_a->cc.call_leg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Compose 48.008 Channel Type from the current set of codecs determined from both local and remote codec
 | 
			
		||||
	 * capabilities. */
 | 
			
		||||
	if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.codecs.result.audio_codecs)) {
 | 
			
		||||
	if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.audio_codecs)) {
 | 
			
		||||
		LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type (Permitted Speech) from codecs: %s\n",
 | 
			
		||||
			  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.remote));
 | 
			
		||||
			  codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
 | 
			
		||||
		trans_free(cc_trans);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1455,7 +1455,7 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
 | 
			
		||||
	trans_cc_filter_run(cc_trans);
 | 
			
		||||
	LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete: RAN: %s, CN: %s\n",
 | 
			
		||||
		  sdp_audio_codecs_to_str(&rtps_to_ran->codecs),
 | 
			
		||||
		  sdp_audio_codecs_to_str(&cc_trans->cc.codecs.result.audio_codecs));
 | 
			
		||||
		  sdp_audio_codecs_to_str(&cc_trans->cc.local.audio_codecs));
 | 
			
		||||
 | 
			
		||||
	if (cc_on_assignment_done(cc_trans)) {
 | 
			
		||||
		/* If an error occurred, it was logged in cc_assignment_done() */
 | 
			
		||||
@@ -1874,13 +1874,13 @@ static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_tran
 | 
			
		||||
	 * issued first here will also be the first CRCX sent to the MGW. Usually both still need to be set up. */
 | 
			
		||||
	if (!cn_rtp_available)
 | 
			
		||||
		call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->callref, cc_trans,
 | 
			
		||||
				   &cc_trans->cc.codecs.result.audio_codecs, NULL);
 | 
			
		||||
				   &cc_trans->cc.local.audio_codecs, NULL);
 | 
			
		||||
	if (!ran_rtp_available) {
 | 
			
		||||
		struct sdp_audio_codecs *codecs;
 | 
			
		||||
		if (msc_a->c.ran->force_mgw_codecs_to_ran.count)
 | 
			
		||||
			codecs = &msc_a->c.ran->force_mgw_codecs_to_ran;
 | 
			
		||||
		else
 | 
			
		||||
			codecs = &cc_trans->cc.codecs.result.audio_codecs;
 | 
			
		||||
			codecs = &cc_trans->cc.local.audio_codecs;
 | 
			
		||||
		return call_leg_ensure_ci(cl, RTP_TO_RAN, cc_trans->callref, cc_trans, codecs, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -416,14 +416,14 @@ static void msc_ho_send_handover_request(struct msc_a *msc_a)
 | 
			
		||||
 | 
			
		||||
	if (cc_trans) {
 | 
			
		||||
		if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type,
 | 
			
		||||
							     &cc_trans->cc.codecs.result.audio_codecs)) {
 | 
			
		||||
							     &cc_trans->cc.local.audio_codecs)) {
 | 
			
		||||
			msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
 | 
			
		||||
				      "Failed to determine Channel Type for Handover Request message\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		ran_enc_msg.handover_request.geran.channel_type = &channel_type;
 | 
			
		||||
 | 
			
		||||
		sdp_audio_codecs_to_speech_codec_list(&scl, &cc_trans->cc.codecs.result.audio_codecs);
 | 
			
		||||
		sdp_audio_codecs_to_speech_codec_list(&scl, &cc_trans->cc.local.audio_codecs);
 | 
			
		||||
		if (!scl.len) {
 | 
			
		||||
			msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to compose"
 | 
			
		||||
				      " Codec List (MSC Preferred) for Handover Request message\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -42,8 +42,9 @@ void trans_cc_filter_set_bss(struct gsm_trans *trans, struct msc_a *msc_a)
 | 
			
		||||
 | 
			
		||||
void trans_cc_filter_run(struct gsm_trans *trans)
 | 
			
		||||
{
 | 
			
		||||
	codec_filter_run(&trans->cc.codecs, &trans->cc.remote);
 | 
			
		||||
	LOG_TRANS(trans, LOGL_DEBUG, "codecs: %s\n", codec_filter_to_str(&trans->cc.codecs, &trans->cc.remote));
 | 
			
		||||
	codec_filter_run(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote);
 | 
			
		||||
	LOG_TRANS(trans, LOGL_DEBUG, "codecs: %s\n",
 | 
			
		||||
		  codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user