Esempio n. 1
0
static void create_transcoder(struct mgcp_endpoint *endp)
{
    int port;
    int in_endp = ENDPOINT_NUMBER(endp);
    int out_endp = endp_back_channel(in_endp);

    if (!endp->is_transcoded)
        return;

    send_msg(endp, in_endp, endp->trans_bts.local_port, "CRCX", "sendrecv");
    send_msg(endp, in_endp, endp->trans_bts.local_port, "MDCX", "sendrecv");
    send_msg(endp, out_endp, endp->trans_net.local_port, "CRCX", "sendrecv");
    send_msg(endp, out_endp, endp->trans_net.local_port, "MDCX", "sendrecv");

    port = rtp_calculate_port(in_endp, endp->cfg->transcoder_remote_base);
    endp->trans_bts.rtp_port = htons(port);
    endp->trans_bts.rtcp_port = htons(port + 1);

    port = rtp_calculate_port(out_endp, endp->cfg->transcoder_remote_base);
    endp->trans_net.rtp_port = htons(port);
    endp->trans_net.rtcp_port = htons(port + 1);
}
Esempio n. 2
0
/*
 * Handle the assignment request message.
 *
 * See §3.2.1.1 for the message type
 */
static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
				     struct msgb *msg, unsigned int length)
{
	struct msgb *resp;
	struct osmo_msc_data *msc;
	struct tlv_parsed tp;
	uint8_t *data;
	uint8_t timeslot;
	uint8_t multiplex;
	enum gsm48_chan_mode chan_mode = GSM48_CMODE_SIGN;
	int i, supported, port, full_rate = -1;

	if (!conn->conn) {
		LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
		return -1;
	}

	tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);

	if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE)) {
		LOGP(DMSC, LOGL_ERROR, "Mandatory channel type not present.\n");
		goto reject;
	}

	if (!TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) {
		LOGP(DMSC, LOGL_ERROR, "Identity code missing. Audio routing will not work.\n");
		goto reject;
	}

	conn->cic = ntohs(read_data16(TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)));
	timeslot = conn->cic & 0x1f;
	multiplex = (conn->cic & ~0x1f) >> 5;

	/*
	 * Currently we only support a limited subset of all
	 * possible channel types. The limitation ends by not using
	 * multi-slot, limiting the channel coding, speech...
	 */
	if (TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE) < 3) {
		LOGP(DMSC, LOGL_ERROR, "ChannelType len !=3 not supported: %d\n",
			TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE));
		goto reject;
	}

	/*
	 * Try to figure out if we support the proposed speech codecs. For
	 * now we will always pick the full rate codecs.
	 */

	data = (uint8_t *) TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE);
	if ((data[0] & 0xf) != 0x1) {
		LOGP(DMSC, LOGL_ERROR, "ChannelType != speech: %d\n", data[0]);
		goto reject;
	}

	/*
	 * go through the list of preferred codecs of our gsm network
	 * and try to find it among the permitted codecs. If we found
	 * it we will send chan_mode to the right mode and break the
	 * inner loop. The outer loop will exit due chan_mode having
	 * the correct value.
	 */
	full_rate = 0;
	msc = conn->msc;
	for (supported = 0;
		chan_mode == GSM48_CMODE_SIGN && supported < msc->audio_length;
		++supported) {

		int perm_val = audio_support_to_gsm88(msc->audio_support[supported]);
		for (i = 2; i < TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE); ++i) {
			if ((data[i] & 0x7f) == perm_val) {
				chan_mode = gsm88_to_chan_mode(perm_val);
				full_rate = (data[i] & 0x4) == 0;
				break;
			} else if ((data[i] & 0x80) == 0x00) {
				break;
			}
		}
	}

	if (chan_mode == GSM48_CMODE_SIGN) {
		LOGP(DMSC, LOGL_ERROR, "No supported audio type found.\n");
		goto reject;
	}

	/* map it to a MGCP Endpoint and a RTP port */
	port = mgcp_timeslot_to_endpoint(multiplex, timeslot);
	conn->rtp_port = rtp_calculate_port(port, msc->rtp_base);

	return gsm0808_assign_req(conn->conn, chan_mode, full_rate);

reject:
	resp = gsm0808_create_assignment_failure(GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
	if (!resp) {
		LOGP(DMSC, LOGL_ERROR, "Channel allocation failure.\n");
		return -1;
	}

	bsc_queue_for_msc(conn, resp);
	return -1;
}