summaryrefslogtreecommitdiffstats
path: root/src/bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bridge.c')
-rw-r--r--src/bridge.c515
1 files changed, 0 insertions, 515 deletions
diff --git a/src/bridge.c b/src/bridge.c
deleted file mode 100644
index d66a7b2..0000000
--- a/src/bridge.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
- Queen in Right of Canada (Communications Research Center Canada)
- */
-/*
- This file is part of ODR-DabMux.
-
- ODR-DabMux 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.
-
- ODR-DabMux 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 ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <netinet/in.h>
-#endif // _WIN32
-#include <string.h>
-#include "bridge.h"
-#include "crc.h"
-
-#include <assert.h>
-#include "PcDebug.h"
-
-#ifdef _WIN32
-# ifdef _DEBUG
- int bridgeVerbosity = 0;
-# endif
-#else
-# ifdef DEBUG
- int bridgeVerbosity = 0;
-# endif
-#endif
-
-void printStats(struct bridgeInfo* info, FILE* out)
-{
- struct bridgeStats stats = getStats(info);
- fprintf(out, "frames : %lu\n", stats.frames);
- fprintf(out, " valids : %lu\n", stats.valids);
- fprintf(out, " invalids : %lu\n", stats.invalids);
- fprintf(out, " bytes : %lu\n", stats.bytes);
- fprintf(out, " packets : %lu\n", stats.packets);
- fprintf(out, " errors : %lu\n", stats.errors);
- fprintf(out, " missings : %lu\n", stats.missings);
- fprintf(out, " dropped : %lu\n", stats.dropped);
- fprintf(out, " crc : %lu\n", stats.crc);
- fprintf(out, " overruns : %lu\n", stats.overruns);
-}
-
-
-void resetStats(struct bridgeInfo* info)
-{
- memset(&info->stats, 0, sizeof(info->stats));
-}
-
-
-struct bridgeStats getStats(struct bridgeInfo* info)
-{
- return info->stats;
-}
-
-
-void bridgeInitInfo(struct bridgeInfo* info)
-{
- memset(info, 0, sizeof(*info));
- info->transmitted = -8;
-};
-
-
-int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
- struct bridgeInfo* info)
-{
- static struct bridgeHdr header = { 0 };
-
- PDEBUG4_VERBOSE(1, bridgeVerbosity, "writePacket\n sizeIn: %i, sizeOut: %i, "
- "offset: %i, transmitted: %i\n",
- sizeIn, sizeOut, info->offset, info->transmitted);
-
- assert(info->transmitted < sizeIn);
-
- if ((info->offset == 0) && (sizeIn > 0)) {
- ((unsigned short*)dataOut)[0] = 0xb486;
- info->offset = 2;
- }
- if (sizeIn == 0) {
- memset((unsigned char*)dataOut + info->offset, 0, sizeOut - info->offset);
- info->offset = 0;
- info->transmitted = -8;
- PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (sizeIn == 0)\n",
- sizeOut);
- return 0;
- }
-
- while (info->offset < sizeOut) {
- switch (info->transmitted) {
- case (-8):
- ((unsigned char*)dataOut)[info->offset++] = 0xcb;
- ++info->transmitted;
- break;
- case (-7):
- ((unsigned char*)dataOut)[info->offset++] = 0x28;
- ++info->transmitted;
- break;
- case (-6):
- header.size = htons((unsigned short)sizeIn);
- header.crc = htons((unsigned short)(crc16(0xffff, &header, 4) ^ 0xffff));
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[0];
- ++info->transmitted;
- break;
- case (-5):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[1];
- ++info->transmitted;
- break;
- case (-4):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[2];
- ++info->transmitted;
- break;
- case (-3):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[3];
- ++info->transmitted;
- break;
- case (-2):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[4];
- ++info->transmitted;
- break;
- case (-1):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[5];
- ++info->transmitted;
- header.seqNb = htons((unsigned short)(ntohs(header.seqNb) + 1));
- break;
- default:
- ((unsigned char*)dataOut)[info->offset++] =
- ((unsigned char*)dataIn)[info->transmitted++];
- if (info->transmitted == sizeIn) {
- PDEBUG2_VERBOSE(1, bridgeVerbosity,
- " Packet done, %i bytes at offset %i\n",
- info->transmitted, info->offset);
- PDEBUG1_VERBOSE(1, bridgeVerbosity,
- " return %i (sizeIn == transmitted)\n", info->offset);
- info->transmitted = -8;
- return info->offset;
- }
- }
- }
-
- PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (offset >= sizeOut)\n",
- info->offset);
- info->offset = 0;
- return 0;
-}
-
-
-int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
- struct bridgeInfo* info, char async)
-{
- unsigned char* in = (unsigned char*)dataIn;
- unsigned char* out = (unsigned char*)dataOut;
- unsigned char ch;
- unsigned short crc;
- unsigned short diff;
-
- PDEBUG3_VERBOSE(1, bridgeVerbosity,
- "getPacket\n pos\t%i\n state\t%i\n received\t%i\n",
- info->pos, info->state, info->received);
-
- if (info->pos == 0) {
- ++info->stats.frames;
- if (((unsigned short*)dataIn)[0] != 0xb486) {
- if (((unsigned short*)dataIn)[0] != 0) {
- ++info->stats.invalids;
- printf("WARNING: processing frame with invalid magic "
- "number!\n");
- } else {
- PDEBUG0_VERBOSE(1, bridgeVerbosity,
- "getPacket: not a valid frame\n");
- return 0;
- }
- } else {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Valid frame\n");
- info->pos += 2;
- ++info->stats.valids;
- }
- info->stats.bytes += sizeIn;
- }
- while (info->pos < sizeIn) {
- ch = in[info->pos++];
- switch (info->state) {
- case 0: // sync search
- info->sync <<= 8;
- info->sync |= ch;
- if (info->sync == 0xcb28) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Sync found\n");
- ++info->stats.packets;
- info->received = 0;
- info->state = 1;
- }
- if (info->sync == 0) { // Padding
- info->pos = 0;
- return 0;
- }
- break;
- case 1: // header search
- ((char*)&info->header)[info->received++] = ch;
- if (info->received == sizeof(struct bridgeHdr)) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Header found\n");
- out = (unsigned char*)dataOut;
- info->received = 0;
- info->state = 2;
- crc = crc16(0xffff, &info->header, 4);
- crc ^= 0xffff;
- info->header.size = ntohs(info->header.size);
- info->header.seqNb = ntohs(info->header.seqNb);
- info->header.crc = ntohs(info->header.crc);
- PDEBUG4_VERBOSE(2, bridgeVerbosity,
- " size\t%i\n seq\t%i\n crc\t0x%.4x (0x%.4x)\n",
- info->header.size, info->header.seqNb,
- info->header.crc, crc);
- if (crc != info->header.crc) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "CRC error\n");
- ++info->stats.errors;
- ++info->stats.crc;
- info->state = 0;
- if (info->pos < sizeof(struct bridgeHdr) + 2 + 2) {
- info->pos = 2;
- }
- } else {
- if (!info->initSeq) {
- info->lastSeq = info->header.seqNb;
- info->initSeq = 1;
- } else {
- if (info->header.seqNb > info->lastSeq) {
- diff = (info->header.seqNb - info->lastSeq) - 1;
- } else {
- diff = ((short)info->lastSeq -
- (short)info->header.seqNb) - 1;
- }
- info->stats.errors += diff;
- info->stats.missings += diff;
- info->lastSeq = info->header.seqNb;
- }
- }
- }
- break;
- case 2: // data
- out[info->received++] = ch;
- if (info->received == info->header.size) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "data found\n");
- info->state = 0;
- return info->received;
- }
- if (info->received == sizeOut) {
- PDEBUG1_VERBOSE(1, bridgeVerbosity, "To much data: %i\n",
- info->received);
- ++info->stats.errors;
- ++info->stats.overruns;
- info->sync = 0;
- info->state = 0;
- return -1;
- }
- break;
- case 3: // Padding or sync
- if (ch == 0) { // Padding
- info->pos = 0;
- return 0;
- }
- if (ch != 0xcb) { // error
- info->sync = ch;
- info->state = 0;
- } else {
- info->state = 4;
- }
- break;
- case 4: // Low byte sync
- if (ch != 28) { // error
- info->sync <<= 8;
- info->sync |= ch;
- info->state = 0;
- } else {
- info->state = 2;
- }
- break;
- }
- }
- info->pos = 0;
- return 0;
-}
-
-
-void dump(void* data, int size, FILE* stream)
-{
- int i;
- fprintf(stream, "%i bytes\n", size);
- for (i = 0; i < size; ++i) {
- fprintf(stream, " 0x%.2x", ((unsigned char*)data)[i]);
- if (i % 8 == 7)
- fprintf(stream, "\n");
- }
- fprintf(stream, "\n");
-}
-
-
-#ifdef BRIDGE_TEST
-#include <stdlib.h>
-
-
-int test(const unsigned char* data)
-{
- unsigned char bridgeSize = data[0];
- unsigned char nbInput = data[1];
- unsigned char nbBridge = 1;
- struct bridgeInfo info;
-
- int i, j;
- int index = 0;
- int max = 0;
- int nbBytes;
-
- unsigned char** inputData;
- unsigned char** bridgeData;
- unsigned char* outputData;
-
- inputData = malloc(nbInput * 4);
- bridgeData = malloc(nbBridge * 4);
- for (i = 0; i < nbInput; ++i) {
- if (data[i + 2] > 0)
- inputData[i] = malloc(data[i + 2]);
- if (data[i + 2] > max) {
- max = data[i + 2];
- }
- for (j = 0; j < data[i + 2]; ++j) {
- inputData[i][j] = index++;
- }
- }
- bridgeData[0] = malloc(bridgeSize);
- memset(bridgeData[0], 0, bridgeSize);
- outputData = malloc(max);
- bridgeInitInfo(&info);
-
- // Write packets
- index = 0;
- while (1) {
- if (data[index + 2] == 0) {
- if (++index == nbInput)
- break;
- }
- while ((nbBytes = writePacket(inputData[index], data[index + 2],
- bridgeData[nbBridge - 1], bridgeSize, &info))
- != 0) {
- if (++index == nbInput) {
- break;
- }
- }
- if (index == nbInput)
- break;
- // TODO check null
- bridgeData = realloc(bridgeData, (++nbBridge) * 4);
- bridgeData[nbBridge - 1] = malloc(bridgeSize);
- memset(bridgeData[nbBridge - 1], 0, bridgeSize);
- }
-// if (nbBytes != bridgeSize) {
- writePacket(NULL, 0, bridgeData[nbBridge - 1], bridgeSize, &info);
-// }
-
- // read packets
- index = 0;
- for (i = 0; i < nbBridge; ++i) {
- while ((nbBytes = getPacket(bridgeData[i], bridgeSize, outputData, max,
- &info, 0)) != 0) {
- while (data[index + 2] == 0) {
- ++index;
- }
- if (nbBytes != data[index + 2]) {
- printf("FAILED\n");
- printf("Invalid size at bridge %i, data %i: %i != %i\n",
- i, index, nbBytes, data[index + 2]);
- for (i = 0; i < nbInput; ++i) {
- printf("Input %i: ", i);
- dump(inputData[i], data[i + 2], stdout);
- }
- for (i = 0; i < nbBridge; ++i) {
- printf("Bridge %i: ", i);
- dump(bridgeData[i], bridgeSize, stdout);
- }
- printf("Output %i: ", index);
- dump(outputData, nbBytes, stdout);
- return -1;
- }
- if (memcmp(outputData, inputData[index], data[index + 2]) != 0) {
- printf("FAILED\n");
- printf("output != input\n");
- for (i = 0; i < nbInput; ++i) {
- printf("Input %i: ", i);
- dump(inputData[i], data[i + 2], stdout);
- }
- for (i = 0; i < nbBridge; ++i) {
- printf("Bridge %i: ", i);
- dump(bridgeData[i], bridgeSize, stdout);
- }
- printf("Output %i: ", index);
- dump(outputData, nbBytes, stdout);
- }
- ++index;
- }
- }
-
- printf("SUCCESS\n");
-
- for (i = 0; i < nbInput; ++i) {
- if (data[i + 2] > 0)
- free(inputData[i]);
- }
- free(inputData);
- free(outputData);
- for (i = 0; i < nbBridge; ++i) {
- free(bridgeData[i]);
- }
- free(bridgeData);
-
- return -1;
-}
-
-
-int main(int argc, char* argv[])
-{
- int i;
- // test: bridgesize, nbinput [, input1, input2, ... ]
- const unsigned char complete[] = { 32, 1, 16 };
- const unsigned char split[] = { 32, 1, 48 };
- const unsigned char twice[] = {32, 2, 8, 4 };
- const unsigned char secondSplit[] = { 32, 2, 16, 16 };
- const unsigned char headerSplit[][4] = {
- { 32, 2, 23, 16 },
- { 32, 2, 22, 16 },
- { 32, 2, 21, 16 },
- { 32, 2, 20, 16 },
- { 32, 2, 19, 16 },
- { 32, 2, 18, 16 },
- { 32, 2, 17, 16 }
- };
- const unsigned char two[] = { 32, 3, 16, 0, 16 };
- const unsigned char doubleSplit[] = { 32, 2, 32, 32 };
- const unsigned char full[] = { 32, 2, 24, 12 };
- const unsigned char empty[] = { 32, 3, 0, 0, 5 };
-
-#ifdef _WIN32
- #ifdef _DEBUG
- bridgeVerbosity = argc - 1;
- #endif // DEBUG
-#else
- #ifdef DEBUG
- bridgeVerbosity = argc - 1;
- #endif // DEBUG
-#endif // _WIN32
-
- printf("Complete: ");
- test(complete);
- // printStats(stdout);
- fflush(stdout);
-
- printf("split: ");
- test(split);
- // printStats(stdout);
- fflush(stdout);
-
- printf("twice: ");
- test(twice);
- // printStats(stdout);
- fflush(stdout);
-
- printf("second split: ");
- test(secondSplit);
- // printStats(stdout);
- fflush(stdout);
-
- for (i = 0; i < sizeof(headerSplit) / sizeof(headerSplit[0]); ++i) {
- printf("headerSplit%i: ", i);
- test(headerSplit[i]);
- // printStats(stdout);
- fflush(stdout);
- }
-
- printf("two: ");
- test(two);
- // printStats(stdout);
- fflush(stdout);
-
- printf("doubleSplit: ");
- test(doubleSplit);
- // printStats(stdout);
- fflush(stdout);
-
- printf("full: ");
- test(full);
- // printStats(stdout);
- fflush(stdout);
-
- printf("empty: ");
- test(empty);
- // printStats(stdout);
- fflush(stdout);
-
- return 0;
-}
-
-#endif // BRIDGE_TEST