<commit_before>/* Traffic Channel (TCH) part of osmo-bts OCTPHY integration */

/* Copyright (c) 2014 Octasic Inc. All rights reserved.
 * Copyright (c) 2015 <NAME> <<EMAIL>>
 *
 * based on a copy of osmo-bts-sysmo/l1_tch.c, which is
 * Copyright (C) 2011-2013 by <NAME> <<EMAIL>>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <osmocom/core/bits.h>

#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/l1sap.h>

#include "l1_if.h"

struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	cur = msgb_put(msg, GSM_FR_BYTES);
	memcpy(cur, l1_payload, GSM_FR_BYTES);
#else
	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);

	cur = msgb_put(msg, GSM_FR_BYTES);

	/* step2: we need to shift the entire L1 payload by 4 bits right */
	osmo_nibble_shift_right(cur, l1_payload, GSM_FR_BITS / 4);

	cur[0] |= 0xD0;
#endif /* USE_L1_RTP_MODE */

	return msg;
}

/*! \brief convert GSM-FR from RTP payload to L1 format
 *  \param[out] l1_payload payload part of L1 buffer
 *  \param[in] rtp_payload pointer to RTP payload data
 *  \param[in] payload_len length of \a rtp_payload
 *  \returns number of \a l1_payload bytes filled
 */
int rtppayload_to_l1_fr(uint8_t *l1_payload, const uint8_t *rtp_payload,
			unsigned int payload_len)
{
#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	memcpy(l1_payload, rtp_payload, GSM_FR_BYTES);
#else
	/* step2: we need to shift the RTP payload left by one nibble */
	osmo_nibble_shift_left_unal(l1_payload, rtp_payload, GSM_FR_BITS / 4);

	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);
#endif /* USE_L1_RTP_MODE */
	return GSM_FR_BYTES;
}

static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	cur = msgb_put(msg, GSM_EFR_BYTES);
	memcpy(cur, l1_payload, GSM_EFR_BYTES);
#else
	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);

	cur = msgb_put(msg, GSM_EFR_BYTES);

	/* step 2: we need to shift the entire L1 payload by 4 bits right */
	osmo_nibble_shift_right(cur, l1_payload, GSM_EFR_BITS/4);

	cur[0] |= 0xC0;
#endif /* USE_L1_RTP_MODE */
	return msg;
}

static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload,
				unsigned int payload_len)
{
#ifndef USE_L1_RTP_MODE
#warning "We don't support EFR with L1 that doesn't support RTP mode!"
#else
	memcpy(l1_payload, rtp_payload, payload_len);

#endif
	return payload_len;
}

static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

	if (payload_len != GSM_HR_BYTES) {
		LOGP(DL1C, LOGL_ERROR, "L1 HR frame length %u != expected %u\n",
			payload_len, GSM_HR_BYTES);
		return NULL;
	}

	cur = msgb_put(msg, GSM_HR_BYTES);
	memcpy(cur, l1_payload, GSM_HR_BYTES);

#ifndef USE_L1_RTP_MODE
	/* reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(cur, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */

	return msg;
}

/*! \brief convert GSM-FR from RTP payload to L1 format
 *  \param[out] l1_payload payload part of L1 buffer
 *  \param[in] rtp_payload pointer to RTP payload data
 *  \param[in] payload_len length of \a rtp_payload
 *  \returns number of \a l1_payload bytes filled
 */
static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
				unsigned int payload_len)
{

	if (payload_len != GSM_HR_BYTES) {
		LOGP(DL1C, LOGL_ERROR, "RTP HR frame length %u != expected %u\n",
			payload_len, GSM_HR_BYTES);
		return 0;
	}

	memcpy(l1_payload, rtp_payload, GSM_HR_BYTES);

#ifndef USE_L1_RTP_MODE
	/* reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */

	return GSM_HR_BYTES;
}


/* brief receive a traffic L1 primitive for a given lchan */
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr,
		tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_DATA_INDICATION_EVT *
		data_ind)
{
	uint32_t payload_type = data_ind->Data.ulPayloadType;
	uint8_t *payload = data_ind->Data.abyDataContent;

	uint8_t payload_len;
	struct msgb *rmsg = NULL;
	struct gsm_lchan *lchan =
	    &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];

	if (data_ind->Data.ulDataLength < 1) {
		LOGP(DL1C, LOGL_ERROR, "chan_nr %d Rx Payload size 0\n",
		     chan_nr);
		return -EINVAL;
	}
	payload_len = data_ind->Data.ulDataLength;

	switch (payload_type) {
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_FULL_RATE:
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_ENH_FULL_RATE:
		if (lchan->type != GSM_LCHAN_TCH_F)
			goto err_payload_match;
		break;
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_HALF_RATE:
		if (lchan->type != GSM_LCHAN_TCH_H)
			goto err_payload_match;
		break;
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_AMR_FULL_RATE:
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_AMR_HALF_RATE:
		if (lchan->type != GSM_LCHAN_TCH_H &&
		    lchan->type != GSM_LCHAN_TCH_F)
			goto err_payload_match;
		break;<commit_msg>octphy: improve log output<commit_after>/* Traffic Channel (TCH) part of osmo-bts OCTPHY integration */

/* Copyright (c) 2014 Octasic Inc. All rights reserved.
 * Copyright (c) 2015 <NAME> <<EMAIL>>
 *
 * based on a copy of osmo-bts-sysmo/l1_tch.c, which is
 * Copyright (C) 2011-2013 by <NAME> <<EMAIL>>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <osmocom/core/bits.h>

#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/l1sap.h>

#include "l1_if.h"

struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	cur = msgb_put(msg, GSM_FR_BYTES);
	memcpy(cur, l1_payload, GSM_FR_BYTES);
#else
	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);

	cur = msgb_put(msg, GSM_FR_BYTES);

	/* step2: we need to shift the entire L1 payload by 4 bits right */
	osmo_nibble_shift_right(cur, l1_payload, GSM_FR_BITS / 4);

	cur[0] |= 0xD0;
#endif /* USE_L1_RTP_MODE */

	return msg;
}

/*! \brief convert GSM-FR from RTP payload to L1 format
 *  \param[out] l1_payload payload part of L1 buffer
 *  \param[in] rtp_payload pointer to RTP payload data
 *  \param[in] payload_len length of \a rtp_payload
 *  \returns number of \a l1_payload bytes filled
 */
int rtppayload_to_l1_fr(uint8_t *l1_payload, const uint8_t *rtp_payload,
			unsigned int payload_len)
{
#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	memcpy(l1_payload, rtp_payload, GSM_FR_BYTES);
#else
	/* step2: we need to shift the RTP payload left by one nibble */
	osmo_nibble_shift_left_unal(l1_payload, rtp_payload, GSM_FR_BITS / 4);

	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);
#endif /* USE_L1_RTP_MODE */
	return GSM_FR_BYTES;
}

static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

#ifdef USE_L1_RTP_MODE
	/* new L1 can deliver bits like we need them */
	cur = msgb_put(msg, GSM_EFR_BYTES);
	memcpy(cur, l1_payload, GSM_EFR_BYTES);
#else
	/* step1: reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, payload_len);

	cur = msgb_put(msg, GSM_EFR_BYTES);

	/* step 2: we need to shift the entire L1 payload by 4 bits right */
	osmo_nibble_shift_right(cur, l1_payload, GSM_EFR_BITS/4);

	cur[0] |= 0xC0;
#endif /* USE_L1_RTP_MODE */
	return msg;
}

static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload,
				unsigned int payload_len)
{
#ifndef USE_L1_RTP_MODE
#warning "We don't support EFR with L1 that doesn't support RTP mode!"
#else
	memcpy(l1_payload, rtp_payload, payload_len);

#endif
	return payload_len;
}

static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len)
{
	struct msgb *msg;
	uint8_t *cur;

	msg = msgb_alloc_headroom(1024, 128, "L1C-to-RTP");
	if (!msg)
		return NULL;

	if (payload_len != GSM_HR_BYTES) {
		LOGP(DL1C, LOGL_ERROR, "L1 HR frame length %u != expected %u\n",
			payload_len, GSM_HR_BYTES);
		return NULL;
	}

	cur = msgb_put(msg, GSM_HR_BYTES);
	memcpy(cur, l1_payload, GSM_HR_BYTES);

#ifndef USE_L1_RTP_MODE
	/* reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(cur, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */

	return msg;
}

/*! \brief convert GSM-FR from RTP payload to L1 format
 *  \param[out] l1_payload payload part of L1 buffer
 *  \param[in] rtp_payload pointer to RTP payload data
 *  \param[in] payload_len length of \a rtp_payload
 *  \returns number of \a l1_payload bytes filled
 */
static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
				unsigned int payload_len)
{

	if (payload_len != GSM_HR_BYTES) {
		LOGP(DL1C, LOGL_ERROR, "RTP HR frame length %u != expected %u\n",
			payload_len, GSM_HR_BYTES);
		return 0;
	}

	memcpy(l1_payload, rtp_payload, GSM_HR_BYTES);

#ifndef USE_L1_RTP_MODE
	/* reverse the bit-order of each payload byte */
	osmo_revbytebits_buf(l1_payload, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */

	return GSM_HR_BYTES;
}


/* brief receive a traffic L1 primitive for a given lchan */
int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr,
		tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_DATA_INDICATION_EVT *
		data_ind)
{
	uint32_t payload_type = data_ind->Data.ulPayloadType;
	uint8_t *payload = data_ind->Data.abyDataContent;

	uint8_t payload_len;
	struct msgb *rmsg = NULL;
	struct gsm_lchan *lchan =
	    &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];

	if (data_ind->Data.ulDataLength < 1) {
		LOGP(DL1C, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n",
		     chan_nr);
		return -EINVAL;
	}
	payload_len = data_ind->Data.ulDataLength;

	switch (payload_type) {
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_FULL_RATE:
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_ENH_FULL_RATE:
		if (lchan->type != GSM_LCHAN_TCH_F)
			goto err_payload_match;
		break;
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_HALF_RATE:
		if (lchan->type != GSM_LCHAN_TCH_H)
			goto err_payload_match;
		break;
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_AMR_FULL_RATE:
	case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_AMR_HALF_RATE:
		if (lchan->type != GSM_LCHAN_TCH_H &&
		    lchan->type != GSM_LCHAN_TCH_F)
			goto err_payload_match;
		break;
{'fraction_non_alphanumeric': 0.10154437064895575, 'fraction_numerical': 0.024005761382731857, 'mean_word_length': 4.559608540925267, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6691887', 'n_tokens_mistral': 5274, 'n_tokens_neox': 5044, 'n_words': 1302}