libosmocodec: implement ECU (Error Concealment Unit) for FR

When a bad GSM voice frame is received, it's being replaced
by a silence frame. This may cause unpleasant audio effects.

This change implements a functionality to craft a replacement
frame from the last known good frame. Currently, only FR is
supported, support for other codecs may be added latter.

Change-Id: I06a21f60db01bfe1c2b838f93866fad1d53fdcd1
This commit is contained in:
Philipp Maier 2017-12-16 03:42:15 +07:00 committed by Vadim Yanitskiy
parent c0771d62c1
commit 40def49ac4
9 changed files with 535 additions and 3 deletions

View File

@ -9,3 +9,4 @@
#library what description / commit summary line
core msgb_queue_free() add inline func to msgb.h
coding gsm0503_rach_ext-encode() add func to gsm0503_coding.h
codec ecu.c / ecu.h implement ECU for FR (Error Concealment Unit)

View File

@ -1,6 +1,7 @@
BUILT_SOURCES = osmocom/gsm/gsm0503.h
nobase_include_HEADERS = \
osmocom/codec/ecu.h \
osmocom/codec/codec.h \
osmocom/codec/gsm610_bits.h \
osmocom/core/application.h \

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <osmocom/codec/codec.h>
/* Codec independent ECU state */
struct osmo_ecu_fr_state {
bool subsequent_lost_frame;
uint8_t frame_backup[GSM_FR_BYTES];
};
void osmo_ecu_fr_reset(struct osmo_ecu_fr_state *state, uint8_t *frame);
int osmo_ecu_fr_conceal(struct osmo_ecu_fr_state *state, uint8_t *frame);

View File

@ -13,6 +13,6 @@ endif
lib_LTLIBRARIES = libosmocodec.la
libosmocodec_la_SOURCES = gsm610.c gsm620.c gsm660.c gsm690.c
libosmocodec_la_SOURCES = gsm610.c gsm620.c gsm660.c gsm690.c ecu_fr.c
libosmocodec_la_LDFLAGS = -version-info $(LIBVERSION) -no-undefined
libosmocodec_la_LIBADD = $(top_builddir)/src/libosmocore.la

165
src/codec/ecu_fr.c Normal file
View File

@ -0,0 +1,165 @@
/*
* (C) 2017 by sysmocom - s.f.m.c. GmbH
* (C) 2017 by Philipp Maier <pmaier@sysmocom.de>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/codec/gsm610_bits.h>
#include <osmocom/codec/codec.h>
#include <osmocom/codec/ecu.h>
/* See also GSM 06.11, chapter 6 Example solution */
#define GSM610_XMAXC_REDUCE 4
#define GSM610_XMAXC_LEN 6
/**
* Reduce the XMAXC field. When the XMAXC field reaches
* zero the function will return true.
*/
static bool reduce_xmaxcr(struct bitvec *frame_bitvec,
const unsigned int index)
{
unsigned int field_index;
uint64_t field;
field_index = index;
field = bitvec_read_field(frame_bitvec, &field_index, GSM610_XMAXC_LEN);
if (field > GSM610_XMAXC_REDUCE)
field -= GSM610_XMAXC_REDUCE;
else
field = 0;
field_index = index;
bitvec_write_field(frame_bitvec, &field_index, field, GSM610_XMAXC_LEN);
return field == 0;
}
/**
* Reduce all XMAXC fields in the frame. When all XMAXC fields
* reach zero, then the function will return true.
*/
static bool reduce_xmaxcr_all(struct bitvec *frame_bitvec)
{
bool silent = false;
if (reduce_xmaxcr(frame_bitvec, GSM610_RTP_XMAXC00))
silent = true;
if (reduce_xmaxcr(frame_bitvec, GSM610_RTP_XMAXC10))
silent = true;
if (reduce_xmaxcr(frame_bitvec, GSM610_RTP_XMAXC20))
silent = true;
if (reduce_xmaxcr(frame_bitvec, GSM610_RTP_XMAXC30))
silent = true;
return silent;
}
/* Use certain modifications to conceal the errors in a full rate frame */
static int conceal_frame(uint8_t *frame)
{
struct bitvec *frame_bitvec;
unsigned int len;
bool silent;
int rc = 0;
/* In case we already deal with a silent frame,
* there is nothing to, we just abort immediately */
if (osmo_fr_check_sid(frame, GSM_FR_BYTES))
return 0;
/* Attempt to allocate memory for bitvec */
frame_bitvec = bitvec_alloc(GSM_FR_BYTES, NULL);
if (!frame_bitvec)
return -ENOMEM;
/* Convert a frame to bitvec */
len = bitvec_unpack(frame_bitvec, frame);
if (len != GSM_FR_BYTES) {
rc = -EIO;
goto leave;
}
/* Fudge frame parameters */
silent = reduce_xmaxcr_all(frame_bitvec);
/* If we reached silence level, mute the frame
* completely, this also means that we can
* save the bitvec_pack operation */
if (silent) {
memset(frame, 0x00, GSM_FR_BYTES);
frame[0] = 0xd0;
goto leave;
}
/* Convert back to packed byte form */
len = bitvec_pack(frame_bitvec, frame);
if (len != GSM_FR_BYTES) {
rc = -EIO;
goto leave;
}
leave:
bitvec_free(frame_bitvec);
return rc;
}
/**
* To be called when a good frame is received.
* This function will then create a backup of the frame
* and reset the internal state.
*/
void osmo_ecu_fr_reset(struct osmo_ecu_fr_state *state, uint8_t *frame)
{
state->subsequent_lost_frame = false;
memcpy(state->frame_backup, frame, GSM_FR_BYTES);
}
/**
* To be called when a bad frame is received.
* This function will then generate a replacement frame
* that can be used to conceal the dropout.
*/
int osmo_ecu_fr_conceal(struct osmo_ecu_fr_state *state, uint8_t *frame)
{
int rc;
/* For subsequent frames we run the error concealment
* functions on the backed up frame before we restore
* the backup */
if (state->subsequent_lost_frame) {
rc = conceal_frame(state->frame_backup);
if (rc)
return rc;
}
/* Restore the backed up frame and set flag in case
* we receive even more bad frames */
memcpy(frame, state->frame_backup, GSM_FR_BYTES);
state->subsequent_lost_frame = true;
return 0;
}

View File

@ -17,7 +17,8 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
write_queue/wqueue_test socket/socket_test \
coding/coding_test conv/conv_gsm0503_test \
abis/abis_test endian/endian_test sercomm/sercomm_test \
stats/stats_test prbs/prbs_test gsm23003/gsm23003_test
stats/stats_test prbs/prbs_test gsm23003/gsm23003_test \
codec/codec_ecu_fr_test
if ENABLE_MSGFILE
check_PROGRAMS += msgfile/msgfile_test
@ -136,6 +137,9 @@ fr_fr_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL) \
codec_codec_test_SOURCES = codec/codec_test.c
codec_codec_test_LDADD = $(LDADD) $(top_builddir)/src/codec/libosmocodec.la
codec_codec_ecu_fr_test_SOURCES = codec/codec_ecu_fr_test.c
codec_codec_ecu_fr_test_LDADD = $(LDADD) $(top_builddir)/src/codec/libosmocodec.la
loggingrb_loggingrb_test_SOURCES = loggingrb/loggingrb_test.c
loggingrb_loggingrb_test_LDADD = $(LDADD)
@ -205,11 +209,13 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \
gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \
gb/gprs_bssgp_test.ok gb/gprs_ns_test.ok gea/gea_test.ok \
gprs/gprs_test.ok kasumi/kasumi_test.ok codec/codec_test.ok \
gprs/gprs_test.ok kasumi/kasumi_test.ok \
msgfile/msgfile_test.ok msgfile/msgconfig.cfg \
logging/logging_test.ok logging/logging_test.err \
fr/fr_test.ok loggingrb/logging_test.ok \
loggingrb/logging_test.err strrb/strrb_test.ok \
codec/codec_test.ok \
codec/codec_ecu_fr_test.ok \
vty/vty_test.ok \
vty/fail_not_de-indented.cfg \
vty/fail_tabs_and_spaces.cfg \

View File

@ -0,0 +1,146 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/core/utils.h>
#include <osmocom/codec/codec.h>
#include <osmocom/codec/ecu.h>
/* Set with sample full-rate voice frames and some intentional dropouts */
static const char *fr_frames_hex[] = {
"d9aa93ae63de00471a91b95b8660471392b4a2daa037628f391c624039258dc723",
"d8eb83699a66c036ec89b7246e6034dc8d48948620589b7256e3a6603b2371b8da",
"d967abaa1cbe4035238da6ace4c036d46ec69ba600391c4eb8a2b040591c6a3924",
"d8e8a42662c240472469b91bd2e0452291b6dba600495b8e38dcb020491a71c91b",
"da2aac1ddbb00036e46e26dcec6039138db923822047137248e3560048e38dc8e3",
"d929ab2a9b5240395b6dc72ba020469c8d551c5440349c9148e36a4036a372471b",
"d9eb93215bb8a0271c69c724682036db71c71a94a0372491b72bee4044eb71b923",
"d9ab9aa19abc40391b6e5ae2ee40471b91c6dbe820492291b8e4b84036e47238db",
"d96b9be9db782044e371b55cb200389491c69b8ea034e271c8d3808038ec6db8e3",
"d9aa9365e3f060375c6db6ebc4c02764b1c51b78a0571c91a723de6049248dc8dd",
"BAD",
"d9ea9c219ce60046e38d3724e0c034e56e36eb7e0038d471b8dcb260491b8dbb23",
"d9e89be9d9e0a0391b6dd6a4624029247138e3a2a04713922524de0036db69d91c",
"d9699422a2b6a048dd90c91c6a802b6259395c8880575b4a58e4ac20269d7248d4",
"d967ac5b1baae0371c71b8ab9c804a9e8e58a55a8038626ec8dcb640395c7244dc",
"d9e8a3e262e68027638db52b88a038634e471a7ec049136e3b1bc8402923adcad2",
"d8eab36e1bbe0046e34d491b608035137658d3524044e48e375cdac0472b9238d4",
"d9689ba5e3d260491b516adb5e4027256e27227ee0351c8e549a5c60492471971b",
"BAD",
"BAD",
"d8e6a2e1d3d2605b1376c8d35280392451391cbc80392a71b6db8aa049238dc8ab",
"d9a87ba1a3982048eb8a471cac00472b4e391bbc40292489b71cc200495b8d3ae3",
"d9278b2a1ba4c0475b8dc722d6e0491b5228da70204ae36dc71d94a056a29236e3",
"d9ec9be2129520392335598c50c04b5bad3d4ba680789b69df5a5aa0469cd1b4da",
"d8ea932623e660669b8e4a9dd8a03aa32a76e466e028d396cc9bbe4047256dc8e5",
"d96a94215aa0403aab713f22e8e024e68db91ab6a027abd1a55b6e804aec9146e4",
"d867ac21e270a0350d6ac91a724037247246d2a6c0396c89d6dc562049244e48d5",
"d8a9b460d3b48026a4ad471b7c20452491b69bbc803ae48db722ee00292491a8db",
"d928a3e1d3b24036e37244abf02047634d371b74c047637148a29ac03b234e38e3",
"d9ab9b21d2e0c0471c693aec54e044dbae46dc7c20391badb724ee8038e469bb15",
"d9a99361a276403b1a6ad6dcd40026e489c8e3bc40371c4dc564e2c036e28eb963",
"BAD",
"BAD",
"BAD",
"BAD",
"BAD",
"BAD",
"d92c8b6d5aee4034ebb22724862047145634a5c0a038e371b8e4a880485c89dd25",
"d8e78b29e3c6c038dba9d91beca04723ad491cda80471471b6ec7ae03b1396b91b",
"d8a78b25e37a0022dd8a46dc68a0351bad391bde2046e56dd8dc96c038e396d89b",
"d8a88c255ab6e038e38e48dbde8038ad8dc8db8ec0376372b564b44038e49234dc",
"d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3",
"d8ee9bea5ae4003ae371b713eae05adc91995a5ea064dcc9571e786026ed51c52c",
"d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763",
"d92aab696190c046e26e392cae0026a376a8dc662048d291b75b54c04ad3ae3b1b",
"d8e7a469627a6038e289cb1baca0569b8db6dddec026dc8e38e5dc803722722d23",
"d8a88c299b64c03a548a58e37420272c6dd76b92c0471c9236dbc0e0551c71c713",
"BAD",
"d7299c19a3be8024e58ea7a49f20a522963ad976e0a76ecd92b38500cb62aa4c94",
"d7eb6c6262eee02b2c42e79a60a0aa55aed68a7f00ad358e10fad960e55a39396d",
"d970858dd2ab61d91355ebc15ca1a6a7ca48a05cc0dae66f2523c2a1bad3825daa",
"d8f0844a23ad20da50d6de025e81c37392b9039cc0c764c1bd1e94c1b699736a98",
"d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3",
"d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763",
"d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763",
"d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763",
"d2577a1cda50004924924924500049249249245000492492492450004923924924",
NULL
};
/* Example of a good frame */
static const char *sample_frame_hex = \
"d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da";
/**
* Start with a good voice frame and then simulate 20 consecutive bad frames,
* watching how the error concealment decreases the XMAXC parameters.
*/
void test_fr_concealment(void)
{
struct osmo_ecu_fr_state state;
uint8_t frame[GSM_FR_BYTES];
int i, rc;
/* Parse frame from string to hex */
osmo_hexparse(sample_frame_hex, frame, GSM_FR_BYTES);
printf("Start with: %s\n", sample_frame_hex);
/* Reset the ECU with the proposed known good frame */
osmo_ecu_fr_reset(&state, frame);
/* Now pretend that we do not receive any good frames anymore */
for (i = 0; i < 20; i++) {
rc = osmo_ecu_fr_conceal(&state, frame);
OSMO_ASSERT(rc == 0);
printf("conceal: %02i, result: %s\n",
i, osmo_hexdump_nospc(frame, GSM_FR_BYTES));
}
}
/* Simulate a real life situation: voice frames with a few dropouts */
void test_fr_concealment_realistic()
{
struct osmo_ecu_fr_state state;
uint8_t frame[GSM_FR_BYTES];
unsigned int frame_len;
int rc, i = 0;
while (fr_frames_hex[i] != NULL) {
/* Debug print */
printf("Frame No. %03i:\n", i);
/* Good or bad frame? */
frame_len = strlen(fr_frames_hex[i]) / 2;
if (frame_len == GSM_FR_BYTES) {
printf(" * input: %s\n", fr_frames_hex[i]);
osmo_hexparse(fr_frames_hex[i], frame, GSM_FR_BYTES);
osmo_ecu_fr_reset(&state, frame);
} else {
printf(" * input: (bad)\n");
memset(frame, 0x00, GSM_FR_BYTES);
rc = osmo_ecu_fr_conceal(&state, frame);
OSMO_ASSERT(rc == 0);
}
/* Print result */
printf(" * output: %s\n",
osmo_hexdump_nospc(frame, GSM_FR_BYTES));
/* Go to the next frame */
i++;
}
}
int main(int argc, char **argv)
{
/* Perform actual tests */
test_fr_concealment();
test_fr_concealment_realistic();
return 0;
}

View File

@ -0,0 +1,192 @@
Start with: d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da
conceal: 00, result: d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da
conceal: 01, result: d9ec9be212901d802335598c501d805bad3d4ba01d809b69df5a501d809cd1b4da
conceal: 02, result: d9ec9be212901b802335598c501b805bad3d4ba01b809b69df5a501b809cd1b4da
conceal: 03, result: d9ec9be2129019802335598c5019805bad3d4ba019809b69df5a5019809cd1b4da
conceal: 04, result: d9ec9be2129017802335598c5017805bad3d4ba017809b69df5a5017809cd1b4da
conceal: 05, result: d9ec9be2129015802335598c5015805bad3d4ba015809b69df5a5015809cd1b4da
conceal: 06, result: d9ec9be2129013802335598c5013805bad3d4ba013809b69df5a5013809cd1b4da
conceal: 07, result: d9ec9be2129011802335598c5011805bad3d4ba011809b69df5a5011809cd1b4da
conceal: 08, result: d9ec9be212900f802335598c500f805bad3d4ba00f809b69df5a500f809cd1b4da
conceal: 09, result: d9ec9be212900d802335598c500d805bad3d4ba00d809b69df5a500d809cd1b4da
conceal: 10, result: d9ec9be212900b802335598c500b805bad3d4ba00b809b69df5a500b809cd1b4da
conceal: 11, result: d9ec9be2129009802335598c5009805bad3d4ba009809b69df5a5009809cd1b4da
conceal: 12, result: d9ec9be2129007802335598c5007805bad3d4ba007809b69df5a5007809cd1b4da
conceal: 13, result: d9ec9be2129005802335598c5005805bad3d4ba005809b69df5a5005809cd1b4da
conceal: 14, result: d9ec9be2129003802335598c5003805bad3d4ba003809b69df5a5003809cd1b4da
conceal: 15, result: d9ec9be2129001802335598c5001805bad3d4ba001809b69df5a5001809cd1b4da
conceal: 16, result: d00000000000000000000000000000000000000000000000000000000000000000
conceal: 17, result: d00000000000000000000000000000000000000000000000000000000000000000
conceal: 18, result: d00000000000000000000000000000000000000000000000000000000000000000
conceal: 19, result: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 000:
* input: d9aa93ae63de00471a91b95b8660471392b4a2daa037628f391c624039258dc723
* output: d9aa93ae63de00471a91b95b8660471392b4a2daa037628f391c624039258dc723
Frame No. 001:
* input: d8eb83699a66c036ec89b7246e6034dc8d48948620589b7256e3a6603b2371b8da
* output: d8eb83699a66c036ec89b7246e6034dc8d48948620589b7256e3a6603b2371b8da
Frame No. 002:
* input: d967abaa1cbe4035238da6ace4c036d46ec69ba600391c4eb8a2b040591c6a3924
* output: d967abaa1cbe4035238da6ace4c036d46ec69ba600391c4eb8a2b040591c6a3924
Frame No. 003:
* input: d8e8a42662c240472469b91bd2e0452291b6dba600495b8e38dcb020491a71c91b
* output: d8e8a42662c240472469b91bd2e0452291b6dba600495b8e38dcb020491a71c91b
Frame No. 004:
* input: da2aac1ddbb00036e46e26dcec6039138db923822047137248e3560048e38dc8e3
* output: da2aac1ddbb00036e46e26dcec6039138db923822047137248e3560048e38dc8e3
Frame No. 005:
* input: d929ab2a9b5240395b6dc72ba020469c8d551c5440349c9148e36a4036a372471b
* output: d929ab2a9b5240395b6dc72ba020469c8d551c5440349c9148e36a4036a372471b
Frame No. 006:
* input: d9eb93215bb8a0271c69c724682036db71c71a94a0372491b72bee4044eb71b923
* output: d9eb93215bb8a0271c69c724682036db71c71a94a0372491b72bee4044eb71b923
Frame No. 007:
* input: d9ab9aa19abc40391b6e5ae2ee40471b91c6dbe820492291b8e4b84036e47238db
* output: d9ab9aa19abc40391b6e5ae2ee40471b91c6dbe820492291b8e4b84036e47238db
Frame No. 008:
* input: d96b9be9db782044e371b55cb200389491c69b8ea034e271c8d3808038ec6db8e3
* output: d96b9be9db782044e371b55cb200389491c69b8ea034e271c8d3808038ec6db8e3
Frame No. 009:
* input: d9aa9365e3f060375c6db6ebc4c02764b1c51b78a0571c91a723de6049248dc8dd
* output: d9aa9365e3f060375c6db6ebc4c02764b1c51b78a0571c91a723de6049248dc8dd
Frame No. 010:
* input: (bad)
* output: d9aa9365e3f060375c6db6ebc4c02764b1c51b78a0571c91a723de6049248dc8dd
Frame No. 011:
* input: d9ea9c219ce60046e38d3724e0c034e56e36eb7e0038d471b8dcb260491b8dbb23
* output: d9ea9c219ce60046e38d3724e0c034e56e36eb7e0038d471b8dcb260491b8dbb23
Frame No. 012:
* input: d9e89be9d9e0a0391b6dd6a4624029247138e3a2a04713922524de0036db69d91c
* output: d9e89be9d9e0a0391b6dd6a4624029247138e3a2a04713922524de0036db69d91c
Frame No. 013:
* input: d9699422a2b6a048dd90c91c6a802b6259395c8880575b4a58e4ac20269d7248d4
* output: d9699422a2b6a048dd90c91c6a802b6259395c8880575b4a58e4ac20269d7248d4
Frame No. 014:
* input: d967ac5b1baae0371c71b8ab9c804a9e8e58a55a8038626ec8dcb640395c7244dc
* output: d967ac5b1baae0371c71b8ab9c804a9e8e58a55a8038626ec8dcb640395c7244dc
Frame No. 015:
* input: d9e8a3e262e68027638db52b88a038634e471a7ec049136e3b1bc8402923adcad2
* output: d9e8a3e262e68027638db52b88a038634e471a7ec049136e3b1bc8402923adcad2
Frame No. 016:
* input: d8eab36e1bbe0046e34d491b608035137658d3524044e48e375cdac0472b9238d4
* output: d8eab36e1bbe0046e34d491b608035137658d3524044e48e375cdac0472b9238d4
Frame No. 017:
* input: d9689ba5e3d260491b516adb5e4027256e27227ee0351c8e549a5c60492471971b
* output: d9689ba5e3d260491b516adb5e4027256e27227ee0351c8e549a5c60492471971b
Frame No. 018:
* input: (bad)
* output: d9689ba5e3d260491b516adb5e4027256e27227ee0351c8e549a5c60492471971b
Frame No. 019:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 020:
* input: d8e6a2e1d3d2605b1376c8d35280392451391cbc80392a71b6db8aa049238dc8ab
* output: d8e6a2e1d3d2605b1376c8d35280392451391cbc80392a71b6db8aa049238dc8ab
Frame No. 021:
* input: d9a87ba1a3982048eb8a471cac00472b4e391bbc40292489b71cc200495b8d3ae3
* output: d9a87ba1a3982048eb8a471cac00472b4e391bbc40292489b71cc200495b8d3ae3
Frame No. 022:
* input: d9278b2a1ba4c0475b8dc722d6e0491b5228da70204ae36dc71d94a056a29236e3
* output: d9278b2a1ba4c0475b8dc722d6e0491b5228da70204ae36dc71d94a056a29236e3
Frame No. 023:
* input: d9ec9be2129520392335598c50c04b5bad3d4ba680789b69df5a5aa0469cd1b4da
* output: d9ec9be2129520392335598c50c04b5bad3d4ba680789b69df5a5aa0469cd1b4da
Frame No. 024:
* input: d8ea932623e660669b8e4a9dd8a03aa32a76e466e028d396cc9bbe4047256dc8e5
* output: d8ea932623e660669b8e4a9dd8a03aa32a76e466e028d396cc9bbe4047256dc8e5
Frame No. 025:
* input: d96a94215aa0403aab713f22e8e024e68db91ab6a027abd1a55b6e804aec9146e4
* output: d96a94215aa0403aab713f22e8e024e68db91ab6a027abd1a55b6e804aec9146e4
Frame No. 026:
* input: d867ac21e270a0350d6ac91a724037247246d2a6c0396c89d6dc562049244e48d5
* output: d867ac21e270a0350d6ac91a724037247246d2a6c0396c89d6dc562049244e48d5
Frame No. 027:
* input: d8a9b460d3b48026a4ad471b7c20452491b69bbc803ae48db722ee00292491a8db
* output: d8a9b460d3b48026a4ad471b7c20452491b69bbc803ae48db722ee00292491a8db
Frame No. 028:
* input: d928a3e1d3b24036e37244abf02047634d371b74c047637148a29ac03b234e38e3
* output: d928a3e1d3b24036e37244abf02047634d371b74c047637148a29ac03b234e38e3
Frame No. 029:
* input: d9ab9b21d2e0c0471c693aec54e044dbae46dc7c20391badb724ee8038e469bb15
* output: d9ab9b21d2e0c0471c693aec54e044dbae46dc7c20391badb724ee8038e469bb15
Frame No. 030:
* input: d9a99361a276403b1a6ad6dcd40026e489c8e3bc40371c4dc564e2c036e28eb963
* output: d9a99361a276403b1a6ad6dcd40026e489c8e3bc40371c4dc564e2c036e28eb963
Frame No. 031:
* input: (bad)
* output: d9a99361a276403b1a6ad6dcd40026e489c8e3bc40371c4dc564e2c036e28eb963
Frame No. 032:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 033:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 034:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 035:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 036:
* input: (bad)
* output: d00000000000000000000000000000000000000000000000000000000000000000
Frame No. 037:
* input: d92c8b6d5aee4034ebb22724862047145634a5c0a038e371b8e4a880485c89dd25
* output: d92c8b6d5aee4034ebb22724862047145634a5c0a038e371b8e4a880485c89dd25
Frame No. 038:
* input: d8e78b29e3c6c038dba9d91beca04723ad491cda80471471b6ec7ae03b1396b91b
* output: d8e78b29e3c6c038dba9d91beca04723ad491cda80471471b6ec7ae03b1396b91b
Frame No. 039:
* input: d8a78b25e37a0022dd8a46dc68a0351bad391bde2046e56dd8dc96c038e396d89b
* output: d8a78b25e37a0022dd8a46dc68a0351bad391bde2046e56dd8dc96c038e396d89b
Frame No. 040:
* input: d8a88c255ab6e038e38e48dbde8038ad8dc8db8ec0376372b564b44038e49234dc
* output: d8a88c255ab6e038e38e48dbde8038ad8dc8db8ec0376372b564b44038e49234dc
Frame No. 041:
* input: d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3
* output: d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3
Frame No. 042:
* input: d8ee9bea5ae4003ae371b713eae05adc91995a5ea064dcc9571e786026ed51c52c
* output: d8ee9bea5ae4003ae371b713eae05adc91995a5ea064dcc9571e786026ed51c52c
Frame No. 043:
* input: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
* output: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
Frame No. 044:
* input: d92aab696190c046e26e392cae0026a376a8dc662048d291b75b54c04ad3ae3b1b
* output: d92aab696190c046e26e392cae0026a376a8dc662048d291b75b54c04ad3ae3b1b
Frame No. 045:
* input: d8e7a469627a6038e289cb1baca0569b8db6dddec026dc8e38e5dc803722722d23
* output: d8e7a469627a6038e289cb1baca0569b8db6dddec026dc8e38e5dc803722722d23
Frame No. 046:
* input: d8a88c299b64c03a548a58e37420272c6dd76b92c0471c9236dbc0e0551c71c713
* output: d8a88c299b64c03a548a58e37420272c6dd76b92c0471c9236dbc0e0551c71c713
Frame No. 047:
* input: (bad)
* output: d8a88c299b64c03a548a58e37420272c6dd76b92c0471c9236dbc0e0551c71c713
Frame No. 048:
* input: d7299c19a3be8024e58ea7a49f20a522963ad976e0a76ecd92b38500cb62aa4c94
* output: d7299c19a3be8024e58ea7a49f20a522963ad976e0a76ecd92b38500cb62aa4c94
Frame No. 049:
* input: d7eb6c6262eee02b2c42e79a60a0aa55aed68a7f00ad358e10fad960e55a39396d
* output: d7eb6c6262eee02b2c42e79a60a0aa55aed68a7f00ad358e10fad960e55a39396d
Frame No. 050:
* input: d970858dd2ab61d91355ebc15ca1a6a7ca48a05cc0dae66f2523c2a1bad3825daa
* output: d970858dd2ab61d91355ebc15ca1a6a7ca48a05cc0dae66f2523c2a1bad3825daa
Frame No. 051:
* input: d8f0844a23ad20da50d6de025e81c37392b9039cc0c764c1bd1e94c1b699736a98
* output: d8f0844a23ad20da50d6de025e81c37392b9039cc0c764c1bd1e94c1b699736a98
Frame No. 052:
* input: d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3
* output: d9708ce6a39ce049646646a2c1a0272496b29a66c037db562863ace0795b55b2e3
Frame No. 053:
* input: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
* output: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
Frame No. 054:
* input: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
* output: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
Frame No. 055:
* input: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
* output: d9299421d2944036ed69b8e572a048e36d551cd480571d4ec95be680356c69c763
Frame No. 056:
* input: d2577a1cda50004924924924500049249249245000492492492450004923924924
* output: d2577a1cda50004924924924500049249249245000492492492450004923924924

View File

@ -157,6 +157,12 @@ cat $abs_srcdir/codec/codec_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/codec/codec_test], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([codec_ecu_fr])
AT_KEYWORDS([codec_ecu_fr])
cat $abs_srcdir/codec/codec_ecu_fr_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/codec/codec_ecu_fr_test], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([fr])
AT_KEYWORDS([fr])
cat $abs_srcdir/fr/fr_test.ok > expout