mirror of https://gerrit.osmocom.org/gapk
151 lines
3.9 KiB
C
151 lines
3.9 KiB
C
/*
|
|
* This file is part of GAPK (GSM Audio Pocket Knife).
|
|
*
|
|
* (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com>
|
|
*
|
|
* GAPK 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GAPK 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 GAPK. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <talloc.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
#include <osmocom/codec/codec.h>
|
|
|
|
#include <osmocom/gapk/procqueue.h>
|
|
#include <osmocom/gapk/codecs.h>
|
|
#include <osmocom/gapk/common.h>
|
|
|
|
/* A good FR frame */
|
|
static const char *sample_frame_hex = \
|
|
"d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da";
|
|
|
|
static void talloc_ctx_walk_cb(const void *chunk, int depth,
|
|
int max_depth, int is_ref, void *data)
|
|
{
|
|
const char *chunk_name = talloc_get_name(chunk);
|
|
int spaces_cnt;
|
|
|
|
/* Hierarchical spacing */
|
|
for (spaces_cnt = 0; spaces_cnt < depth; spaces_cnt++)
|
|
printf(" ");
|
|
|
|
/* Chunk info */
|
|
printf("chunk %s: depth=%d\n", chunk_name, depth);
|
|
}
|
|
|
|
void pq_execute(struct osmo_gapk_pq *pq, uint8_t *frame, size_t len)
|
|
{
|
|
struct osmo_gapk_pq_item *pq_item;
|
|
unsigned int len_prev = len;
|
|
uint8_t *buf_prev = frame;
|
|
int rv;
|
|
|
|
/* Iterate over all items in the chain */
|
|
llist_for_each_entry(pq_item, &pq->items, list) {
|
|
printf("Block '%s/%s/%s' in (len=%d): %s\n", pq->name,
|
|
pq_item->cat_name, pq_item->sub_name, len_prev,
|
|
osmo_hexdump(buf_prev, len_prev));
|
|
|
|
/* Call item's processing handler */
|
|
rv = pq_item->proc(pq_item->state, pq_item->buf, buf_prev, len_prev);
|
|
assert(rv > 0);
|
|
|
|
printf("Block '%s/%s/%s' out (len=%d): %s\n", pq->name,
|
|
pq_item->cat_name, pq_item->sub_name, rv,
|
|
osmo_hexdump(pq_item->buf, rv));
|
|
|
|
buf_prev = pq_item->buf;
|
|
len_prev = rv;
|
|
}
|
|
}
|
|
|
|
void test_fr_concealment(struct osmo_gapk_pq *pq)
|
|
{
|
|
uint8_t fb[GSM_FR_BYTES];
|
|
int i;
|
|
|
|
/* Init frame buffer with BFI */
|
|
memset(fb, 0x00, sizeof(fb));
|
|
fb[0] = 0xd0;
|
|
|
|
/* Process a BFI frame */
|
|
printf("[i] Process a BFI frame: %s\n", osmo_hexdump(fb, sizeof(fb)));
|
|
pq_execute(pq, fb, sizeof(fb));
|
|
printf("\n");
|
|
|
|
/* Parse frame from string to hex */
|
|
osmo_hexparse(sample_frame_hex, fb, GSM_FR_BYTES);
|
|
|
|
/* Process a good frame (reset ECU) */
|
|
printf("[i] Process a good frame: %s\n", osmo_hexdump(fb, sizeof(fb)));
|
|
pq_execute(pq, fb, sizeof(fb));
|
|
printf("\n");
|
|
|
|
/* Now pretend that we do not receive any good frames anymore */
|
|
memset(fb, 0x00, sizeof(fb));
|
|
fb[0] = 0xd0;
|
|
|
|
printf("[i] Pretend that we do not receive any good frames anymore\n");
|
|
for (i = 0; i < 20; i++)
|
|
pq_execute(pq, fb, sizeof(fb));
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
const struct osmo_gapk_codec_desc *codec;
|
|
struct osmo_gapk_pq *pq;
|
|
int rc;
|
|
|
|
/* Enable tracking the use of NULL memory contexts */
|
|
talloc_enable_null_tracking();
|
|
|
|
/* Allocate a single processing chain */
|
|
pq = osmo_gapk_pq_create("pq_ecu_test");
|
|
assert(pq != NULL);
|
|
|
|
/* Obtain FR codec description */
|
|
codec = osmo_gapk_codec_get_from_type(CODEC_FR);
|
|
assert(codec->ecu_proc);
|
|
|
|
/* Put a FR ECU */
|
|
rc = osmo_gapk_pq_queue_ecu(pq, codec);
|
|
assert(rc == 0);
|
|
|
|
/* Put a FR decoder */
|
|
rc = osmo_gapk_pq_queue_codec(pq, codec, 0);
|
|
assert(rc == 0);
|
|
|
|
/* Prepare the chain */
|
|
rc = osmo_gapk_pq_prepare(pq);
|
|
assert(rc == 0);
|
|
|
|
test_fr_concealment(pq);
|
|
|
|
/* Release memory */
|
|
osmo_gapk_pq_destroy(pq);
|
|
|
|
/* Make sure we have no memleaks */
|
|
talloc_report_depth_cb(NULL, 0, 10, &talloc_ctx_walk_cb, NULL);
|
|
|
|
/* Make both Valgrind and LeakSanitizer happy */
|
|
talloc_disable_null_tracking();
|
|
|
|
return 0;
|
|
}
|