[GITLAB] - UPGRADE TO v12 on Wednesday the 18th of December at 11.30AM

ccoding_byte_lte.c 8.6 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: ccoding_byte_lte.c
   purpose: Tail-biting convolutional code from 36-212, V8.6 2009-03.  Includes CRC (8-UCI,16-DCI)and RNTI scrambling (DCI)
   author: raymond.knopp@eurecom.fr
25
   date: 21.10.2009
26
*/
27
#include "coding_defs.h"
28 29 30 31

//#define DEBUG_CCODE 1

unsigned short glte[] = { 0133, 0171, 0165 }; // {A,B}
32
unsigned short glte_rev[] = { 0155, 0117, 0127 }; // {A,B}
33
unsigned short gdab[] = { 0133, 0171, 0145 }; // {A,B}
34
unsigned short gdab_rev[] = { 0155, 0117, 0123 }; // {A,B}
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
unsigned char  ccodelte_table[128];      // for transmitter
unsigned char  ccodelte_table_rev[128];  // for receiver


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

  Encodes for an arbitrary convolutional code of rate 1/3
  with a constraint length of 7 bits.
  The inputs are bit packed in octets (from MSB to LSB).
  An optional 8-bit CRC (3GPP) can be added.
  Trellis tail-biting is included here
*************************************************************************/



void
51 52 53 54 55
ccodelte_encode (int32_t numbits,
                 uint8_t add_crc,
                 uint8_t *inPtr,
                 uint8_t *outPtr,
                 uint16_t rnti)
56
{
57
  uint32_t             state;
58

59 60 61 62 63
  uint8_t              c, out, first_bit;
  int8_t shiftbit=0;
  uint16_t c16;
  uint16_t next_last_byte=0;
  uint32_t crc=0;
64 65

#ifdef DEBUG_CCODE
66
  uint32_t  dummy=0;
67 68 69 70 71
#endif //DEBUG_CCODE

  /* The input bit is shifted in position 8 of the state.
     Shiftbit will take values between 1 and 8 */
  state = 0;
72

73 74 75
  if (add_crc == 1) {
    crc = crc8(inPtr,numbits);
    first_bit      = 2;
76
    c = (uint8_t)(crc>>24);
77
  } else if (add_crc == 2) {
78 79 80 81 82
    crc = crc16(inPtr,numbits);
#ifdef DEBUG_CCODE
    printf("ccode_lte : crc %x\n",crc);
#endif
    // scramble with RNTI
83
    crc ^= (((uint32_t)rnti)<<16);
84 85 86 87
#ifdef DEBUG_CCODE
    printf("ccode_lte : crc %x (rnti %x)\n",crc,rnti);
#endif
    first_bit      = 2;
88
    c = (uint8_t)((crc>>16)&0xff);
89
  } else {
90
    next_last_byte = numbits>>3;
91
    first_bit      = (numbits-6)&7;
92 93
    c = inPtr[next_last_byte-1];
  }
94

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
#ifdef DEBUG_CCODE
  printf("next_last_byte %x (numbits %d, %d)\n",c,numbits,next_last_byte);
#endif

  // Perform Tail-biting

  // get bits from last byte of input (or crc)
  //  for (shiftbit = first_bit; shiftbit<8; shiftbit++) {
  for (shiftbit = 0 ; shiftbit <(8-first_bit) ; shiftbit++) {
    if ((c&(1<<(7-first_bit-shiftbit))) != 0)
      state |= (1<<shiftbit);

#ifdef DEBUG_CCODE
    printf("shiftbit %d, %d -> %d \n",shiftbit,c&(1<<(7-first_bit-shiftbit)),state);
    dummy+=3;
#endif
  }
112

113 114 115
  // get bits from next to last byte of input (not when crc is added)
  if ((add_crc==0)&&((numbits&7)>0)) {
    c = inPtr[next_last_byte];
116

117 118 119 120
    //    printf("last_byte %x\n",c);
    //    for (shiftbit = 0 ; shiftbit < (numbits&7) ; shiftbit++) {
    for (shiftbit = (numbits&7)-1 ; shiftbit>=0 ; shiftbit--) {
      state >>= 1;
121

122
      if ((c&(1<<shiftbit)) != 0)
123 124
        state |= 64;

125
#ifdef DEBUG_CCODE
126 127
      printf("shiftbit %d, %d: %d -> %d \n",shiftbit,state>>6,dummy,state);
      dummy+=3;
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#endif
    }
  }

  state = state & 0x3f;   // true initial state of Tail-biting CCode
  state<<=1;              // because of loop structure in CCode
#ifdef DEBUG_CCODE
  printf("Initial state %d\n",state);
  dummy = 0;
#endif //DEBUG_CCODE
  /* Do not increment inPtr until we read the next octet */




  while (numbits > 0) {

    c = *inPtr++;
#ifdef DEBUG_CCODE
    printf("** %x **\n",c);
#endif //DEBUG_CCODE


    //    for (shiftbit = 0; (shiftbit<8) && (numbits>0);shiftbit++,numbits--) {
152
    for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
153
      state >>= 1;
154 155 156

      if ((c&(1<<shiftbit)) != 0) {
        state |= 64;
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
      }

      out = ccodelte_table[state];

      *outPtr++ = out  & 1;
      *outPtr++ = (out>>1)&1;
      *outPtr++ = (out>>2)&1;

#ifdef DEBUG_CCODE
      printf("numbits %d, input %d, outbit %d: %d -> %d (%d%d%d)\n",numbits,state>>6,dummy,state,out,out&1,(out>>1)&1,(out>>2)&1);
      dummy+=3;
#endif //DEBUG_CCODE      

    }

  }

  // now code 8-bit CRC for UCI
175
  if (add_crc == 1) {
176

177
    c = (uint8_t)(crc>>24);
178

179
    //    for (shiftbit = 0; (shiftbit<8);shiftbit++) {
180
    for (shiftbit = 7; (shiftbit>=0); shiftbit--) {
181
      state >>= 1;
182 183 184

      if ((c&(1<<shiftbit)) != 0) {
        state |= 64;
185
      }
186

187
      out = ccodelte_table[state];
188

189 190 191
      *outPtr++ = out  & 1;
      *outPtr++ = (out>>1)&1;
      *outPtr++ = (out>>2)&1;
192

193 194 195 196
#ifdef DEBUG_CCODE
      printf("crc bit %d input %d, outbit %d: %d -> %d (%d)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
      dummy+=3;
#endif //DEBUG_CCODE      
197

198 199 200 201 202 203
    }
  }

  // now code 16-bit CRC for DCI
  if (add_crc == 2) {

204
    c16 = (uint16_t)(crc>>16);
205

206
    //    for (shiftbit = 0; (shiftbit<16);shiftbit++) {
207
    for (shiftbit = 15; (shiftbit>=0); shiftbit--) {
208
      state >>= 1;
209 210 211

      if ((c16&(1<<shiftbit)) != 0) {
        state |= 64;
212
      }
213

214
      out = ccodelte_table[state];
215

216 217 218
      *outPtr++ = out  & 1;
      *outPtr++ = (out>>1)&1;
      *outPtr++ = (out>>2)&1;
219

220 221 222 223
#ifdef DEBUG_CCODE
      printf("crc bit %d input %d, outbit %d: %d -> %d (%d)\n",shiftbit,state>>6,dummy,state,out,ccodelte_table[state]);
      dummy+=3;
#endif //DEBUG_CCODE      
224

225 226 227 228 229 230 231
    }
  }
}



/*************************************************************************
232

233 234 235 236 237 238 239 240 241 242 243 244 245 246
  Functions to initialize the code tables

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


/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */

void ccodelte_init(void)
{
  unsigned int  i, j, k, sum;

  for (i = 0; i < 128; i++) {
    ccodelte_table[i] = 0;
247

248 249 250
    /* Compute 3 output bits */
    for (j = 0; j < 3; j++) {
      sum = 0;
251

252 253 254
      for (k = 0; k < 7; k++)
        if ((i & glte[j]) & (1 << k))
          sum++;
255

256 257 258 259 260 261 262 263 264 265 266 267 268
      /* Write the sum modulo 2 in bit j */
      ccodelte_table[i] |= (sum & 1) << j;
    }
  }
}

/* Input in LSB, followed by state in 6 MSBs */
void ccodelte_init_inv(void)
{
  unsigned int  i, j, k, sum;

  for (i = 0; i < 128; i++) {
    ccodelte_table_rev[i] = 0;
269

270 271 272
    /* Compute R output bits */
    for (j = 0; j < 3; j++) {
      sum = 0;
273

274 275 276
      for (k = 0; k < 7; k++)
        if ((i & glte_rev[j]) & (1 << k))
          sum++;
277

278 279 280 281 282 283 284 285 286 287 288 289
      /* Write the sum modulo 2 in bit j */
      ccodelte_table_rev[i] |= (sum & 1) << j;
    }
  }
}

void ccodedab_init(void)
{
  unsigned int  i, j, k, sum;

  for (i = 0; i < 128; i++) {
    ccodelte_table[i] = 0;
290

291 292 293
    /* Compute 3 output bits */
    for (j = 0; j < 3; j++) {
      sum = 0;
294

295 296 297
      for (k = 0; k < 7; k++)
        if ((i & gdab[j]) & (1 << k))
          sum++;
298

299 300 301 302 303 304 305 306 307 308 309 310 311
      /* Write the sum modulo 2 in bit j */
      ccodelte_table[i] |= (sum & 1) << j;
    }
  }
}

/* Input in LSB, followed by state in 6 MSBs */
void ccodedab_init_inv(void)
{
  unsigned int  i, j, k, sum;

  for (i = 0; i < 128; i++) {
    ccodelte_table_rev[i] = 0;
312

313 314 315
    /* Compute R output bits */
    for (j = 0; j < 3; j++) {
      sum = 0;
316

317 318 319
      for (k = 0; k < 7; k++)
        if ((i & gdab_rev[j]) & (1 << k))
          sum++;
320

321 322 323 324 325 326 327 328 329
      /* Write the sum modulo 2 in bit j */
      ccodelte_table_rev[i] |= (sum & 1) << j;
    }
  }
}


/*****************************************************************/
/**
330
  Test program
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347

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

#ifdef CCODE_MAIN
#include <stdio.h>

main()
{
  unsigned char test[] = "Thebigredfox";
  unsigned char output[512], *inPtr, *outPtr;
  unsigned int i;

  test[0] = 128;
  test[1] = 0;


  ccodelte_init();
348

349 350 351 352
  inPtr = test;
  outPtr = output;

  ccodelte_encode(21, inPtr, outPtr);
353

354 355 356 357 358 359 360
  for (i = 0; i < 21*3; i++) printf("%x ", output[i]);

  printf("\n");
}
#endif

/** @}*/