212 lines
5.6 KiB
C
212 lines
5.6 KiB
C
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <osmocom/core/application.h>
|
|
#include <osmocom/core/talloc.h>
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include "log.h"
|
|
#include "frame_rifo.h"
|
|
|
|
static void *g_e1d_ctx;
|
|
static uint32_t init_next_out_fn;
|
|
|
|
#define FN_ABS_TO_REL(fn) ((int) (((int64_t) (fn)) - ((int64_t) init_next_out_fn)))
|
|
#define ABS_DECISION(depth) (((long long int) ((depth))) <= \
|
|
((long long int) (FRAMES_PER_FIFO / 2)))
|
|
#define DEPTH_ABS_TO_REL(depth) ((ABS_DECISION((depth))) ? ((int) (depth)) : \
|
|
(((int) (depth)) - (FRAMES_PER_FIFO - 1)))
|
|
#define ABS_DEPTH_STR(depth) ((ABS_DECISION((depth))) ? ("") : \
|
|
("FRAMES_PER_FIFO - 1 + "))
|
|
#define ABS_DEPTH_PRINT(depth) ABS_DEPTH_STR((depth)), DEPTH_ABS_TO_REL((depth))
|
|
#define FN_PRINT(fn) ABS_DEPTH_PRINT(FN_ABS_TO_REL((fn)))
|
|
|
|
static void rifo_init(struct frame_rifo *rifo)
|
|
{
|
|
frame_rifo_init(rifo, 0);
|
|
rifo->next_out_fn = init_next_out_fn;
|
|
rifo->last_in_fn = init_next_out_fn - 1;
|
|
}
|
|
|
|
static void rifo_in(struct frame_rifo *rifo, uint8_t *frame, uint32_t fn)
|
|
{
|
|
int rc = frame_rifo_in(rifo, frame, fn);
|
|
unsigned int depth = frame_rifo_depth(rifo);
|
|
printf("RIFO_IN(%s, start fn + %s%d)=%d [depth=%s%d, frames=%u]\n",
|
|
osmo_hexdump_nospc(frame, BYTES_PER_FRAME), FN_PRINT(fn), rc,
|
|
ABS_DEPTH_PRINT(depth), frame_rifo_frames(rifo));
|
|
}
|
|
|
|
static int rifo_out(struct frame_rifo *rifo, uint8_t *out)
|
|
{
|
|
int rc = frame_rifo_out(rifo, out);
|
|
printf("RIFO_OUT(%s)=%d [depth=%u, frames=%u]\n", osmo_hexdump_nospc(out, BYTES_PER_FRAME),
|
|
rc, frame_rifo_depth(rifo), frame_rifo_frames(rifo));
|
|
return rc;
|
|
}
|
|
|
|
static void missing_frames(uint8_t modulo)
|
|
{
|
|
struct frame_rifo rifo;
|
|
frame_rifo_init(&rifo, 0);
|
|
rifo.next_out_fn = init_next_out_fn;
|
|
rifo.last_in_fn = init_next_out_fn - 1;
|
|
|
|
printf("\nTEST: %s, starting at FN: %u\n", __func__, init_next_out_fn);
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, i, sizeof(frame));
|
|
|
|
if (i % 2 == modulo) {
|
|
rifo_in(&rifo, frame, init_next_out_fn + i);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, 0xff, sizeof(frame));
|
|
rifo_out(&rifo, frame);
|
|
}
|
|
}
|
|
|
|
static void reordered_in(void)
|
|
{
|
|
struct frame_rifo rifo;
|
|
rifo_init(&rifo);
|
|
|
|
printf("\nTEST: %s, starting at FN: %u\n", __func__, init_next_out_fn);
|
|
|
|
const uint8_t in[] = { 0, 1, 4, 3, 5, 2, 6, 7, 8, 9 };
|
|
for (int i = 0; i < sizeof(in); i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, in[i], sizeof(frame));
|
|
rifo_in(&rifo, frame, init_next_out_fn + in[i]);
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, 0xff, sizeof(frame));
|
|
rifo_out(&rifo, frame);
|
|
}
|
|
}
|
|
|
|
static void correct_order(void)
|
|
{
|
|
struct frame_rifo rifo;
|
|
rifo_init(&rifo);
|
|
|
|
printf("\nTEST: %s, starting at FN: %u\n", __func__, init_next_out_fn);
|
|
|
|
const uint8_t in[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
for (int i = 0; i < sizeof(in); i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, in[i], sizeof(frame));
|
|
rifo_in(&rifo, frame, init_next_out_fn + in[i]);
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, 0xff, sizeof(frame));
|
|
rifo_out(&rifo, frame);
|
|
}
|
|
}
|
|
|
|
static void too_old_frames(void)
|
|
{
|
|
struct frame_rifo rifo;
|
|
rifo_init(&rifo);
|
|
|
|
printf("\nTEST: %s, starting at FN: %u\n", __func__, init_next_out_fn);
|
|
|
|
// Put 10 frames at absolute frame numbers FRAMES_PER_FIFO+50
|
|
// to FRAMES_PER_FIFO+60 (to get outside of the
|
|
// FRAMES_PER_FIFO frame buffer)
|
|
const uint8_t in[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
for (int i = 0; i < sizeof(in); i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, in[i], sizeof(frame));
|
|
rifo_in(&rifo, frame, init_next_out_fn + in[i] + FRAMES_PER_FIFO + 50);
|
|
}
|
|
|
|
// Skip the first FRAMES_PER_FIFO + 50 frames
|
|
for (int i = 0; i < FRAMES_PER_FIFO + 50; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, 0xff, sizeof(frame));
|
|
// Note: frame_rifo_out instead of rifo_out
|
|
// (just to ignore the output)
|
|
frame_rifo_out(&rifo, frame);
|
|
}
|
|
|
|
// Try to read the 10 real frames (which shouldn't be in the buffer)
|
|
for (int i = 0; i < 10; i++) {
|
|
uint8_t frame[32];
|
|
memset(frame, 0xff, sizeof(frame));
|
|
rifo_out(&rifo, frame);
|
|
}
|
|
}
|
|
|
|
static void bound_check(void)
|
|
{
|
|
uint8_t frame[32];
|
|
struct frame_rifo rifo;
|
|
rifo_init(&rifo);
|
|
|
|
printf("\nTEST: %s, starting at FN: %u\n", __func__, init_next_out_fn);
|
|
|
|
// Put 1 frame and get it
|
|
memset(frame, 0xa5, sizeof(frame));
|
|
frame_rifo_in(&rifo, frame, init_next_out_fn);
|
|
frame_rifo_out(&rifo, frame);
|
|
|
|
// Put 11 frames at absolute frame numbers FRAMES_PER_FIFO -
|
|
// 10 + 1 to FRAMES_PER_FIFO + 1
|
|
const uint8_t in[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
|
for (int i = 0; i < sizeof(in); i++) {
|
|
memset(frame, in[i], sizeof(frame));
|
|
rifo_in(&rifo, frame, init_next_out_fn + in[i] + FRAMES_PER_FIFO - 10 + 1);
|
|
}
|
|
|
|
// Add frame at start offset
|
|
memset(frame, 0xa5, sizeof(frame));
|
|
rifo_in(&rifo, frame, init_next_out_fn);
|
|
|
|
// Skip the first FRAMES_PER_FIFO - 10 frames
|
|
for (int i = 0; i < FRAMES_PER_FIFO - 10; i++) {
|
|
memset(frame, 0xff, sizeof(frame));
|
|
// Note: frame_rifo_out instead of rifo_out
|
|
// (just to ignore the output)
|
|
frame_rifo_out(&rifo, frame);
|
|
}
|
|
|
|
// Try to read the 10 real frames
|
|
for (int i = 0; i < 10; i++) {
|
|
memset(frame, 0xff, sizeof(frame));
|
|
rifo_out(&rifo, frame);
|
|
}
|
|
}
|
|
|
|
void run_all_tests(void)
|
|
{
|
|
missing_frames(0);
|
|
missing_frames(1);
|
|
reordered_in();
|
|
correct_order();
|
|
too_old_frames();
|
|
bound_check();
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
g_e1d_ctx = talloc_named_const(NULL, 0, "osmo-e1d");
|
|
osmo_init_logging2(g_e1d_ctx, &log_info);
|
|
|
|
// run all tests starting with a framenumber of 0
|
|
init_next_out_fn = 0;
|
|
run_all_tests();
|
|
|
|
// re-run all tests at the edge of a framenumber rollover
|
|
init_next_out_fn = 0xFFFFFFFF - 5;
|
|
run_all_tests();
|
|
}
|