Code CRC Reshaped to libLTE format

master
agelonch 11 years ago
parent 07528df864
commit 7e21282dec

@ -36,8 +36,34 @@
#define LTE_CRC8 0x19B #define LTE_CRC8 0x19B
int init_crc(int lorder, unsigned long polynom); #define _WITHMALLOC
#ifndef _WITHMALLOC
#define MAX_LENGTH 1024*16
#endif
typedef struct {
unsigned long table[256];
#ifdef _WITHMALLOC
unsigned char *data0;
#else
unsigned char data0[MAX_LENGTH];
#endif
int polynom;
int order;
unsigned long crcinit;
unsigned long crcxor;
unsigned long crcmask;
unsigned long crchighbit;
unsigned int crc_out;
} crc_t;
//ELIMINATE////////////////////
unsigned int crc(unsigned int crc, char *bufptr, int len, unsigned int crc(unsigned int crc, char *bufptr, int len,
int long_crc,unsigned int poly, int paste_word); int long_crc, unsigned int poly, int paste_word);
///////////////////////////////
int crc_init(crc_t *crc_par);
unsigned int crc_attach(char *bufptr, int len, crc_t *crc_params);
#endif #endif

@ -31,116 +31,103 @@
#include <string.h> #include <string.h>
#include "lte/utils/pack.h" #include "lte/utils/pack.h"
#define _WITHMALLOC #include "lte/fec/crc.h"
unsigned int cword;
char *cdata;
const unsigned long crcinit = 0x00000000; //initial CRC value
const unsigned long crcxor = 0x00000000; //final XOR value
unsigned long crcmask;
unsigned long crchighbit;
unsigned long crctab[256];
void gen_crc_table(crc_t *crc_params) {
int i, j, ord=(crc_params->order-8);
void gen_crc_table(int lorder, unsigned long poly) {
int i, j, ord=(lorder-8);
unsigned long bit, crc; unsigned long bit, crc;
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
crc = ((unsigned long)i)<<ord; crc = ((unsigned long)i)<<ord;
for (j=0; j<8; j++) { for (j=0; j<8; j++) {
bit = crc & crchighbit; bit = crc & crc_params->crchighbit;
crc<<= 1; crc<<= 1;
if (bit) crc^= poly; if (bit) crc^= crc_params->polynom;
} }
crctab[i] = crc & crcmask; crc_params->table[i]=crc & crc_params->crcmask;
} }
} }
unsigned long crctable (unsigned char* data, unsigned long length, int lorder) { unsigned long crctable (unsigned long length, crc_t *crc_params) {
// Polynom lorders of 8, 16, 24 or 32. // Polynom order 8, 16, 24 or 32 only.
unsigned long crc = crcinit; int ord=crc_params->order-8;
unsigned long crc = crc_params->crcinit;
unsigned char* data = crc_params->data0;
while (length--) crc = (crc << 8) ^ crctab[ ((crc >> (lorder-8)) & 0xff) ^ *data++]; while (length--){
crc = (crc << 8) ^ crc_params->table[ ((crc >> (ord)) & 0xff) ^ *data++];
return((crc^crcxor)&crcmask); }
return((crc ^ crc_params->crcxor) & crc_params->crcmask);
} }
unsigned long reversecrcbit(unsigned int crc, unsigned int polynom, int lorder, int nbits) { unsigned long reversecrcbit(unsigned int crc, int nbits, crc_t *crc_params) {
unsigned long m, rmask=0x1; unsigned long m, rmask=0x1;
for(m=0; m<nbits; m++){ for(m=0; m<nbits; m++){
if((rmask & crc) == 0x01 )crc = (crc ^ polynom)>>1; if((rmask & crc) == 0x01 )crc = (crc ^ crc_params->polynom)>>1;
else crc = crc >> 1; else crc = crc >> 1;
} }
return((crc^crcxor)&crcmask); return((crc ^ crc_params->crcxor) & crc_params->crcmask);
} }
int init_crc(int lorder, unsigned long polynom){ int crc_init(crc_t *crc_par){
unsigned long polyhighbit;
// Compute bit masks for whole CRC and CRC high bit // Compute bit masks for whole CRC and CRC high bit
crcmask = ((((unsigned long)1<<(lorder-1))-1)<<1)|1; crc_par->crcmask = ((((unsigned long)1<<(crc_par->order-1))-1)<<1)|1;
polyhighbit=0xFFFFFFFF ^ (crcmask+1); crc_par->crchighbit = (unsigned long)1<<(crc_par->order-1);
crchighbit = (unsigned long)1<<(lorder-1);
// Eliminate highest bit in polynom word printf("crcmask=%x, crchightbit=%x\n",
polynom=polynom & polyhighbit; (unsigned int)crc_par->crcmask, (unsigned int)crc_par->crchighbit);
// check parameters // check parameters
if (lorder < 1 || lorder > 32) { if (crc_par->order%8 != 0) {
printf("ERROR, invalid order, it must be between 1..32.\n"); printf("ERROR, invalid order=%d, it must be 8, 16, 24 or 32.\n", crc_par->order);
return(0); return(0);
} }
if (lorder%8 != 0) {
printf("ERROR, invalid order=%d, it must be 8, 16, 24 or 32.\n", lorder); if (crc_par->crcinit != (crc_par->crcinit & crc_par->crcmask)) {
return(0);
}
if (polynom != (polynom & crcmask)) {
printf("ERROR, invalid polynom.\n");
return(0);
}
if (crcinit != (crcinit & crcmask)) {
printf("ERROR, invalid crcinit.\n"); printf("ERROR, invalid crcinit.\n");
return(0); return(0);
} }
if (crcxor != (crcxor & crcmask)) { if (crc_par->crcxor != (crc_par->crcxor & crc_par->crcmask)) {
printf("ERROR, invalid crcxor.\n"); printf("ERROR, invalid crcxor.\n");
return(0); return(0);
} }
// generate lookup table // generate lookup table
gen_crc_table(lorder, polynom); gen_crc_table(crc_par);
return(1); return(1);
} }
#define MAX_LENGTH 8192 ///ELIMINATE//////////////////////////
unsigned int crc(unsigned int crc, char *bufptr, int len, unsigned int crc(unsigned int crc, char *bufptr, int len,
int long_crc, unsigned int poly, int paste_word) { int long_crc, unsigned int poly, int paste_word){
return(0);
}
///////////////////////////////////////
unsigned int crc_attach(char *bufptr, int len, crc_t *crc_params) {
int i, len8, res8, a; int i, len8, res8, a;
#ifdef _WITHMALLOC unsigned int crc;
char *data0, *pter; char *pter;
data0 = (char *)malloc(sizeof(char) * (len+long_crc)*2); #ifdef _WITHMALLOC
if (!data0) { crc_params->data0 = (unsigned char *)malloc(sizeof(*crc_params->data0) * (len+crc_params->order)*2);
if (!crc_params->data0) {
perror("malloc ERROR: Allocating memory for data pointer in crc() function"); perror("malloc ERROR: Allocating memory for data pointer in crc() function");
return(-1); return(-1);
} }
#endif #else
#ifndef _WITHMALLOC if((((len+crc_params->order)>>3) + 1) > MAX_LENGTH){
char data0[MAX_LENGTH], *pter;
if((((len+long_crc)>>3) + 1) > MAX_LENGTH){
printf("ERROR: Not enough memory allocated\n"); printf("ERROR: Not enough memory allocated\n");
return(-1); return(-1);
} }
@ -156,24 +143,22 @@ unsigned int crc(unsigned int crc, char *bufptr, int len,
for(i=0; i<len8+a; i++){ for(i=0; i<len8+a; i++){
pter=(char *)(bufptr+8*i); pter=(char *)(bufptr+8*i);
data0[i]=(char)(unpack_bits(&pter, 8)&0xFF); crc_params->data0[i]=(unsigned char)(unpack_bits(&pter, 8)&0xFF);
} }
// Calculate CRC // Calculate CRC
pter=data0; crc=crctable(len8+a, crc_params);
crc=crctable ((unsigned char *)pter, len8+a, long_crc);
// Reverse CRC res8 positions // Reverse CRC res8 positions
if(a==1)crc=reversecrcbit(crc, poly, long_crc, res8); if(a==1)crc=reversecrcbit(crc, res8, crc_params);
// Add CRC // Add CRC
pter=(char *)(bufptr+len); pter=(char *)(bufptr+len);
pack_bits(crc, &pter, long_crc); pack_bits(crc, &pter, crc_params->order);
#ifdef _WITHMALLOC #ifdef _WITHMALLOC
free(data0); free(crc_params->data0);
data0=NULL; crc_params->data0=NULL;
#endif #endif
//Return CRC value //Return CRC value
return crc; return crc;
} }

@ -77,6 +77,7 @@ int main(int argc, char **argv) {
int i; int i;
char *data; char *data;
unsigned int crc_word, expected_word; unsigned int crc_word, expected_word;
crc_t crc_p;
parse_args(argc, argv); parse_args(argc, argv);
@ -96,22 +97,24 @@ int main(int argc, char **argv) {
data[i] = rand()%2; data[i] = rand()%2;
} }
//Initialize crc params and tables //Initialize CRC params and tables
if(!init_crc(crc_length, crc_poly))exit(0); crc_p.polynom=crc_poly;
crc_p.order=crc_length;
crc_p.crcinit=0x00000000;
crc_p.crcxor=0x00000000;
if(!crc_init(&crc_p))exit(0);
// generate CRC word // generate CRC word
crc_word = crc(0, data, num_bits, crc_length, crc_poly, 1); crc_word = crc_attach(data, num_bits, &crc_p);
// check if result is zero // check if result is zero
if (crc(0, data, num_bits + crc_length, crc_length, crc_poly, 0)) { if (crc_attach(data, num_bits + crc_length, &crc_p)) {
printf("CRC check is non-zero\n"); printf("CRC check is non-zero\n");
exit(-1); exit(-1);
} }
free(data); free(data);
printf("CRC word: 0x%x\n", crc_word);
// check if generated word is as expected // check if generated word is as expected
if (get_expected_word(num_bits, crc_length, crc_poly, seed, &expected_word)) { if (get_expected_word(num_bits, crc_length, crc_poly, seed, &expected_word)) {
fprintf(stderr, "Test parameters not defined in test_results.h\n"); fprintf(stderr, "Test parameters not defined in test_results.h\n");

@ -39,11 +39,13 @@ typedef struct {
static expected_word_t expected_words[] = { static expected_word_t expected_words[] = {
//ELIMINATE///////////
/* {5000, 24, LTE_CRC24A, 1, 0x4D0836}, // LTE CRC24A (36.212 Sec 5.1.1) /* {5000, 24, LTE_CRC24A, 1, 0x4D0836}, // LTE CRC24A (36.212 Sec 5.1.1)
{5000, 24, LTE_CRC24B, 1, 0x9B68F8}, // LTE CRC24B {5000, 24, LTE_CRC24B, 1, 0x9B68F8}, // LTE CRC24B
{5000, 16, LTE_CRC16, 1, 0xBFFA}, // LTE CRC16: 0xBFFA {5000, 16, LTE_CRC16, 1, 0xBFFA}, // LTE CRC16: 0xBFFA
{5000, 8, LTE_CRC8, 1, 0xF8}, // LTE CRC8 0xF8 {5000, 8, LTE_CRC8, 1, 0xF8}, // LTE CRC8 0xF8
*/ */
//////////////////////
{5001, 24, LTE_CRC24A, 1, 0x1C5C97}, // LTE CRC24A (36.212 Sec 5.1.1) {5001, 24, LTE_CRC24A, 1, 0x1C5C97}, // LTE CRC24A (36.212 Sec 5.1.1)
{5001, 24, LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B {5001, 24, LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B
{5001, 16, LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4 {5001, 16, LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4

Loading…
Cancel
Save