crc_byte.c 6.31 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22 23 24
/* file: crc_byte.c
   purpose: generate 3GPP LTE CRCs. Byte-oriented implementation of CRC's
   author: raymond.knopp@eurecom.fr
25
   date: 21.10.2009
26 27 28 29 30 31 32 33

   Original UMTS version by
   P. Humblet
   May 10, 2001
   Modified in June, 2001, to include  the length non multiple of 8
*/


34
#include "coding_defs.h"
35 36 37 38 39 40 41 42 43 44 45


/*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */
unsigned int             poly24a = 0x864cfb00;   //1000 0110 0100 1100 1111 1011  D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1
unsigned int             poly24b = 0x80006300;    // 1000 0000 0000 0000 0110 0011  D^24 + D^23 + D^6 + D^5 + D + 1
unsigned int             poly16 = 0x10210000;    // 0001 0000 0010 0001            D^16 + D^12 + D^5 + 1
unsigned int             poly12 = 0x80F00000;    // 1000 0000 1111                 D^12 + D^11 + D^3 + D^2 + D + 1
unsigned int             poly8 = 0x9B000000;     // 1001 1011                      D^8  + D^7  + D^4 + D^3 + D + 1
/*********************************************************

46
For initialization && verification purposes,
47 48 49 50 51 52 53 54 55
   bit by bit implementation with any polynomial

The first bit is in the MSB of each byte

*********************************************************/
unsigned int
crcbit (unsigned char * inputptr, int octetlen, unsigned int poly)
{
  unsigned int             i, crc = 0, c;
56

57 58
  while (octetlen-- > 0) {
    c = (*inputptr++) << 24;
59

60 61 62 63 64
    for (i = 8; i != 0; i--) {
      if ((1 << 31) & (c ^ crc))
        crc = (crc << 1) ^ poly;
      else
        crc <<= 1;
65

66 67 68
      c <<= 1;
    }
  }
69

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  return crc;
}

/*********************************************************

crc table initialization

*********************************************************/
static unsigned int      crc24aTable[256];
static unsigned int      crc24bTable[256];
static unsigned short      crc16Table[256];
static unsigned short      crc12Table[256];
static unsigned char       crc8Table[256];

void crcTableInit (void)
{
  unsigned char              c = 0;
87

88 89 90 91 92 93 94 95 96 97
  do {
    crc24aTable[c] = crcbit (&c, 1, poly24a);
    crc24bTable[c] = crcbit (&c, 1, poly24b);
    crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
    crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16);
    crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
  } while (++c);
}
/*********************************************************

98
Byte by byte implementations,
99 100 101 102 103 104 105 106 107 108 109
assuming initial byte is 0 padded (in MSB) if necessary

*********************************************************/
unsigned int
crc24a (unsigned char * inptr, int bitlen)
{

  int             octetlen, resbit;
  unsigned int             crc = 0;
  octetlen = bitlen / 8;        /* Change in octets */
  resbit = (bitlen % 8);
110

111
  while (octetlen-- > 0) {
knopp's avatar
knopp committed
112
    //   printf("crc24a: in %x => crc %x\n",crc,*inptr);
113 114
    crc = (crc << 8) ^ crc24aTable[(*inptr++) ^ (crc >> 24)];
  }
115

116 117
  if (resbit > 0)
    crc = (crc << resbit) ^ crc24aTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
118

119 120 121 122 123 124 125 126 127 128
  return crc;
}

unsigned int crc24b (unsigned char * inptr, int bitlen)
{

  int             octetlen, resbit;
  unsigned int             crc = 0;
  octetlen = bitlen / 8;        /* Change in octets */
  resbit = (bitlen % 8);
129

130
  while (octetlen-- > 0) {
knopp's avatar
knopp committed
131
    //    printf("crc24b: in %x => crc %x (%x)\n",crc,*inptr,crc24bTable[(*inptr) ^ (crc >> 24)]);
132 133
    crc = (crc << 8) ^ crc24bTable[(*inptr++) ^ (crc >> 24)];
  }
134

135 136
  if (resbit > 0)
    crc = (crc << resbit) ^ crc24bTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
137

138 139 140 141 142 143 144 145 146 147
  return crc;
}

unsigned int
crc16 (unsigned char * inptr, int bitlen)
{
  int             octetlen, resbit;
  unsigned int             crc = 0;
  octetlen = bitlen / 8;        /* Change in octets */
  resbit = (bitlen % 8);
148

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
  while (octetlen-- > 0) {

    crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16);
  }

  if (resbit > 0)
    crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);

  return crc;
}

unsigned int
crc12 (unsigned char * inptr, int bitlen)
{
  int             octetlen, resbit;
  unsigned int             crc = 0;
  octetlen = bitlen / 8;        /* Change in octets */
  resbit = (bitlen % 8);
167

168 169 170
  while (octetlen-- > 0) {
    crc = (crc << 8) ^ (crc12Table[(*inptr++) ^ (crc >> 24)] << 16);
  }
171

172 173
  if (resbit > 0)
    crc = (crc << resbit) ^ (crc12Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
174

175 176 177 178 179 180 181 182 183 184
  return crc;
}

unsigned int
crc8 (unsigned char * inptr, int bitlen)
{
  int             octetlen, resbit;
  unsigned int             crc = 0;
  octetlen = bitlen / 8;        /* Change in octets */
  resbit = (bitlen % 8);
185

186 187 188
  while (octetlen-- > 0) {
    crc = crc8Table[(*inptr++) ^ (crc >> 24)] << 24;
  }
189

190 191
  if (resbit > 0)
    crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
192

193 194 195 196 197 198
  return crc;
}

#ifdef DEBUG_CRC
/*******************************************************************/
/**
199
   Test code
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
********************************************************************/

#include <stdio.h>

main()
{
  unsigned char test[] = "Thebigredfox";
  crcTableInit();
  printf("%x\n", crcbit(test, sizeof(test) - 1, poly24));
  printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
  printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
  printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
}
#endif