Compare commits

...

2 Commits

Author SHA1 Message Date
Keith
9153cac1d0 bad hacks: Add all changes in working tree
Change-Id: I999f821ea362f4a3e15741d39a7a5194f6e93a69
2023-03-27 19:39:16 -06:00
Keith
069ba5838e Eeprom hack 2023-03-27 15:40:45 -06:00
10 changed files with 102 additions and 46 deletions

BIN
eeprom Normal file

Binary file not shown.

View File

@@ -137,17 +137,24 @@ static uint32_t fn_ms_adj(uint32_t fn, const struct gsm_lchan *lchan)
/* 12/13 frames usable for audio in TCH, /* 12/13 frames usable for audio in TCH,
160 samples per RTP packet, 160 samples per RTP packet,
1 RTP packet per 4 frames */ 1 RTP packet per 4 frames */
/*! Return the difference of two specified TDMA frame numbers (subtraction) */
const uint32_t _num_fn = (fn - lchan->tch.last_fn) * 12 * 160 / (13 * 4); //GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn);
const uint32_t num_fn = GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn); const uint32_t num_fn = GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn);
samples_passed = num_fn * 12 * 160 / (13 * 4); samples_passed = num_fn * 12 * 160 / (13 * 4);
//LOGPLCHAN(lchan, DRTP, LOGL_NOTICE, "OLD [%d], NEW [%d]\n", _num_fn, samples_passed);
/* round number of samples to the nearest multiple of /* round number of samples to the nearest multiple of
GSM_RTP_DURATION */ GSM_RTP_DURATION = 160 */
r = samples_passed + GSM_RTP_DURATION / 2; r = samples_passed + GSM_RTP_DURATION / 2;
r -= r % GSM_RTP_DURATION; r -= r % GSM_RTP_DURATION;
if (r != GSM_RTP_DURATION) if (r != GSM_RTP_DURATION) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "RTP clock out of sync with lower layer:" LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "RTP clock out of sync with lower layer:"
" %"PRIu32" vs %d (%"PRIu32"->%"PRIu32")\n", " %"PRIu32" vs %d (%"PRIu32"->%"PRIu32") DIFF[%d] SAMPLES[%d]\n ",
r, GSM_RTP_DURATION, lchan->tch.last_fn, fn); r, GSM_RTP_DURATION, lchan->tch.last_fn, fn, num_fn, samples_passed);
//return r;
}
} }
return GSM_RTP_DURATION; return GSM_RTP_DURATION;
} }
@@ -181,7 +188,8 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
{ {
struct osmo_phsap_prim *l1sap; struct osmo_phsap_prim *l1sap;
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len)); if (rmsg->len > 0)
LOGPLCHAN(lchan, DL1P, LOGL_INFO, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len));
rmsg->l2h = rmsg->data; rmsg->l2h = rmsg->data;
rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap)); rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap));
@@ -635,7 +643,7 @@ static int l1sap_info_time_ind(struct gsm_bts *bts,
unsigned int frames_expired; unsigned int frames_expired;
unsigned int i; unsigned int i;
DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n"); //DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n");
/* Calculate and check frame difference */ /* Calculate and check frame difference */
frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn); frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn);
@@ -1603,35 +1611,54 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
* the content is not available due to decoding issues. Content not * the content is not available due to decoding issues. Content not
* available is expected as empty payload. We also check if quality is * available is expected as empty payload. We also check if quality is
* good enough. */ * good enough. */
if (msg->len && tch_ind->lqual_cb >= bts->min_qual_norm) { //if (1 == 1) {
/* hand msg to RTP code for transmission */ if (!msg->len || (tch_ind->lqual_cb / 10 < bts->min_qual_norm)) {
if (lchan->abis_ip.osmux.use) { LOGPGT(DRTP, LOGL_NOTICE, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
lchan_osmux_send_frame(lchan, msg->data, msg->len,
fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
} else if (lchan->abis_ip.rtp_socket) {
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
}
/* if loopback is enabled, also queue received RTP data */
if (lchan->loopback) {
/* add new frame to queue, make sure the queue doesn't get too long */
lchan_dl_tch_queue_enqueue(lchan, msg, 1);
/* Return 1 to signal that we're still using msg and it should not be freed */
return 1;
}
/* Only clear the marker bit once we have sent a RTP packet with it */
lchan->rtp_tx_marker = false;
} else {
DEBUGPGT(DRTP, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
chan_nr); chan_nr);
if (lchan->abis_ip.osmux.use) if (lchan->abis_ip.osmux.use)
lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan)); lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan));
else if (lchan->abis_ip.rtp_socket) else if (lchan->abis_ip.rtp_socket)
osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan)); osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan));
lchan->rtp_tx_marker = true; lchan->rtp_tx_marker = true;
lchan->tch.last_fn = fn;
//lchan->tch.dtx.is_speech_resume = false;
return 0;
} }
if (lchan->abis_ip.osmux.use) {
lchan_osmux_send_frame(lchan, msg->data, msg->len,
fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
} else if (lchan->abis_ip.rtp_socket) {
if (msg->len > 0 || lchan->rtp_tx_marker)
LOGPGT(DL1P, LOGL_INFO, &g_time, "Send RTP Frame [%d]--> %s\n",
msg->len, osmo_hexdump(msg->data, msg->len));
/*
int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload,
unsigned int payload_len, unsigned int duration,
bool marker);
--> duration in number of RTP clock ticks.
The duration is the timestamp increase
*/
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
}
/* if loopback is enabled, also queue received RTP data */
if (lchan->loopback) {
/* add new frame to queue, make sure the queue doesn't get too long */
lchan_dl_tch_queue_enqueue(lchan, msg, 1);
/* Return 1 to signal that we're still using msg and it should not be freed */
return 1;
}
/* Only clear the marker bit once we have sent a RTP packet with it */
//lchan->rtp_tx_marker = false;
lchan->tch.last_fn = fn; lchan->tch.last_fn = fn;
if (lchan->tch.dtx.is_speech_resume)
lchan->tch.dtx.is_speech_resume = false;
return 0; return 0;
} }

View File

@@ -1677,7 +1677,7 @@ static int parse_multirate_config(struct gsm_lchan *lchan,
} }
parsed: parsed:
amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr); amr_log_mr_conf(DRTP, LOGL_INFO, gsm_lchan_name(lchan), &lchan->tch.amr_mr);
lchan->tch.last_cmr = AMR_CMR_NONE; lchan->tch.last_cmr = AMR_CMR_NONE;
return 0; return 0;
} }

View File

@@ -819,7 +819,7 @@ int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
if (tch_len) if (tch_len)
memcpy(msg->l2h, tch, tch_len); memcpy(msg->l2h, tch, tch_len);
LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n", LOGL1S(DL1P, LOGL_INFO, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n",
gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
/* forward primitive */ /* forward primitive */
l1sap_up(l1ts->ts->trx, l1sap); l1sap_up(l1ts->ts->trx, l1sap);

View File

@@ -79,7 +79,7 @@
/** /**
* EEPROM device file * EEPROM device file
*/ */
#define EEPROM_DEV "/sys/bus/i2c/devices/i2c-1/1-0050/eeprom" #define EEPROM_DEV "eeprom"
/** /**
* EEPROM configuration start address * EEPROM configuration start address

View File

@@ -56,7 +56,7 @@ enum l1prim_type {
}; };
#if !defined(SUPERFEMTO_API_VERSION) || SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,1,0) #if !defined(SUPERFEMTO_API_VERSION) || SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,1,0)
enum uperfemto_clk_src { enum Superfemto_clk_src {
SF_CLKSRC_NONE = 0, SF_CLKSRC_NONE = 0,
SF_CLKSRC_OCXO = 1, SF_CLKSRC_OCXO = 1,
SF_CLKSRC_TCXO = 2, SF_CLKSRC_TCXO = 2,

View File

@@ -966,7 +966,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
gsm_fn2gsmtime(&g_time, fn); gsm_fn2gsmtime(&g_time, fn);
DEBUGPGT(DL1P, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n", LOGPGT(DL1P, LOGL_INFO, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n",
get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2, get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2,
osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size), osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size),
LOG_PARAM_MEAS(&data_ind->measParam)); LOG_PARAM_MEAS(&data_ind->measParam));
@@ -980,6 +980,9 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
return rc; return rc;
} }
if (data_ind->sapi == GsmL1_Sapi_FacchF)
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "Rx SAPI FACCH\n");
/* fill L1SAP header */ /* fill L1SAP header */
sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size); sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size);
l1sap = msgb_l1sap_prim(sap_msg); l1sap = msgb_l1sap_prim(sap_msg);

View File

@@ -37,7 +37,7 @@
#include "sysmobts_par.h" #include "sysmobts_par.h"
#include "eeprom.h" #include "eeprom.h"
#define EEPROM_PATH "/sys/devices/platform/i2c_davinci.1/i2c-1/1-0050/eeprom" #define EEPROM_PATH "eeprom"
static const struct osmo_crc8gen_code crc8_ccit = { static const struct osmo_crc8gen_code crc8_ccit = {
.bits = 8, .bits = 8,

View File

@@ -56,6 +56,7 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
{ {
struct msgb *msg; struct msgb *msg;
uint8_t *cur; uint8_t *cur;
bool t;
msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP"); msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
if (!msg) if (!msg)
@@ -76,8 +77,9 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
cur[0] |= 0xD0; cur[0] |= 0xD0;
#endif /* USE_L1_RTP_MODE */ #endif /* USE_L1_RTP_MODE */
t = osmo_fr_check_sid(l1_payload, payload_len);
lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan); lchan_set_marker(t, lchan);
LOGP(DL1P, LOGL_ERROR, "FR SID:%d\n", t);
return msg; return msg;
} }
@@ -280,11 +282,12 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le
* Audiocode's MGW doesn't like receiving CMRs that are not * Audiocode's MGW doesn't like receiving CMRs that are not
* the same as the previous one. This means we need to patch * the same as the previous one. This means we need to patch
* the content here. * the content here.
*/
if ((cur[0] & 0xF0) == 0xF0) if ((cur[0] & 0xF0) == 0xF0)
cur[0]= lchan->tch.last_cmr << 4; cur[0]= lchan->tch.last_cmr << 4;
else else
lchan->tch.last_cmr = cur[0] >> 4; lchan->tch.last_cmr = cur[0] >> 4;
*/
#else #else
u_int8_t cmr; u_int8_t cmr;
uint8_t ft = l1_payload[2] & 0xF; uint8_t ft = l1_payload[2] & 0xF;
@@ -508,12 +511,13 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 }; uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
struct msgb *rmsg = NULL; struct msgb *rmsg = NULL;
struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
int len;
if (is_recv_only(lchan->abis_ip.speech_mode)) if (is_recv_only(lchan->abis_ip.speech_mode))
return -EAGAIN; return -EAGAIN;
if (data_ind->msgUnitParam.u8Size < 1) { if (data_ind->msgUnitParam.u8Size < 1) {
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr); LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr);
/* Push empty payload to upper layers */ /* Push empty payload to upper layers */
rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP");
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
@@ -528,6 +532,10 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
payload = data_ind->msgUnitParam.u8Buffer + 1; payload = data_ind->msgUnitParam.u8Buffer + 1;
payload_len = data_ind->msgUnitParam.u8Size - 1; payload_len = data_ind->msgUnitParam.u8Size - 1;
/* clear RTP marker if the marker has previously sent */
if (!lchan->tch.dtx.is_speech_resume)
lchan->rtp_tx_marker = false;
switch (payload_type) { switch (payload_type) {
case GsmL1_TchPlType_Fr: case GsmL1_TchPlType_Fr:
#if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE) #if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE)
@@ -544,40 +552,47 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
if (lchan->type != GSM_LCHAN_TCH_H && if (lchan->type != GSM_LCHAN_TCH_H &&
lchan->type != GSM_LCHAN_TCH_F) lchan->type != GSM_LCHAN_TCH_F)
goto err_payload_match; goto err_payload_match;
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received Speech from L1 "
"(%d bytes)\n", payload_len);
break; break;
case GsmL1_TchPlType_Amr_Onset: case GsmL1_TchPlType_Amr_Onset:
if (lchan->type != GSM_LCHAN_TCH_H && if (lchan->type != GSM_LCHAN_TCH_H &&
lchan->type != GSM_LCHAN_TCH_F) lchan->type != GSM_LCHAN_TCH_F)
goto err_payload_match; goto err_payload_match;
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received ONSET from L1 "
"(%d bytes)\n", payload_len);
/* according to 3GPP TS 26.093 ONSET frames precede the first /* according to 3GPP TS 26.093 ONSET frames precede the first
speech frame of a speech burst - set the marker for next RTP speech frame of a speech burst - set the marker for next RTP
frame */ frame */
lchan->tch.dtx.is_speech_resume = true;
lchan->rtp_tx_marker = true; lchan->rtp_tx_marker = true;
break; break;
case GsmL1_TchPlType_Amr_SidFirstP1: case GsmL1_TchPlType_Amr_SidFirstP1:
if (lchan->type != GSM_LCHAN_TCH_H) if (lchan->type != GSM_LCHAN_TCH_H)
goto err_payload_match; goto err_payload_match;
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 "
"(%d bytes)\n", payload_len); "(%d bytes)\n", payload_len);
break; break;
case GsmL1_TchPlType_Amr_SidFirstP2: case GsmL1_TchPlType_Amr_SidFirstP2:
if (lchan->type != GSM_LCHAN_TCH_H) if (lchan->type != GSM_LCHAN_TCH_H)
goto err_payload_match; goto err_payload_match;
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 "
"(%d bytes)\n", payload_len); "(%d bytes)\n", payload_len);
break; break;
case GsmL1_TchPlType_Amr_SidFirstInH: case GsmL1_TchPlType_Amr_SidFirstInH:
if (lchan->type != GSM_LCHAN_TCH_H) if (lchan->type != GSM_LCHAN_TCH_H)
goto err_payload_match; goto err_payload_match;
lchan->tch.dtx.is_speech_resume = true;
lchan->rtp_tx_marker = true; lchan->rtp_tx_marker = true;
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 "
"(%d bytes)\n", payload_len); "(%d bytes)\n", payload_len);
break; break;
case GsmL1_TchPlType_Amr_SidUpdateInH: case GsmL1_TchPlType_Amr_SidUpdateInH:
if (lchan->type != GSM_LCHAN_TCH_H) if (lchan->type != GSM_LCHAN_TCH_H)
goto err_payload_match; goto err_payload_match;
lchan->tch.dtx.is_speech_resume = true;
lchan->rtp_tx_marker = true; lchan->rtp_tx_marker = true;
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 "
"(%d bytes)\n", payload_len); "(%d bytes)\n", payload_len);
break; break;
default: default:
@@ -587,7 +602,6 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
break; break;
} }
switch (payload_type) { switch (payload_type) {
case GsmL1_TchPlType_Fr: case GsmL1_TchPlType_Fr:
rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan); rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan);
@@ -603,12 +617,24 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
case GsmL1_TchPlType_Amr: case GsmL1_TchPlType_Amr:
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
break; break;
case GsmL1_TchPlType_Amr_SidFirstP1: case GsmL1_TchPlType_Amr_Onset:
memcpy(sid_first, payload, payload_len); /*memcpy(sid_first+2, payload, payload_len);
int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); len = osmo_amr_rtp_enc(sid_first, 15, AMR_SID, AMR_GOOD);
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "ONSET resulted in length [%d]\n", len);
if (len < 0) if (len < 0)
return 0; return 0;
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); len = len+2;
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/
break;
case GsmL1_TchPlType_Amr_SidFirstP1:
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
lchan->rtp_tx_marker = false;
/*memcpy(sid_first, payload, payload_len);
len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD);
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "SID P1 resulted in length [%d]\n", len);
if (len < 0)
return 0;
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/
break; break;
/* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */ /* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */
} }

View File

@@ -434,7 +434,7 @@ struct msgb *tch_dl_dequeue(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br
if (chan_state->codec[i] == ft_codec) if (chan_state->codec[i] == ft_codec)
ft = i; ft = i;
} }
if (ft < 0) { if (ft_codec != 8 && ft < 0) {
LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,
"Codec (FT = %d) of RTP frame not in list\n", ft_codec); "Codec (FT = %d) of RTP frame not in list\n", ft_codec);
goto free_bad_msg; goto free_bad_msg;