/*
   The Hacker's Choice - http://www.thc.org
   Part of THC's GSM SCANNER PROJECT
*/


#include "fire_crc.h"
#include <stdio.h>
#include <string.h>

#define REM(x, y)	(x) % (y)

static int FC_syndrome_shift(FC_CTX *ctx, unsigned int bit);

static int
outit(int *data, int len)
{
	int i;

	for (i = 0; i < len; i++)
		printf("%d ", data[i]);
	printf("\n");
	return 0;
}

int
FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size)
{
	ctx->crc_size = crc_size;
	ctx->data_size = data_size;
	ctx->syn_start = 0;

	return 0;
}

int
FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data)
{ 
	int j,error_count = 0, error_index = 0, success_flag = 0, syn_index = 0;
	unsigned int i;

	ctx->syn_start = 0;
	// reset the syndrome register
	memset(ctx->syndrome_reg, 0, sizeof ctx->syndrome_reg);

	// shift in the data bits
    for (i=0; i < ctx->data_size; i++) {
        error_count = FC_syndrome_shift(ctx, input_bits[i]);
        control_data[i] = input_bits[i];
    }

    // shift in the crc bits
    for (i=0; i < ctx->crc_size; i++) {
        error_count = FC_syndrome_shift(ctx, 1-input_bits[i+ctx->data_size]);
    }

    // Find position of error burst
    if (error_count == 0) {
        error_index = 0;
    }
    else {
        error_index = 1;
        error_count = FC_syndrome_shift(ctx, 0);
        error_index += 1;
        while (error_index < (ctx->data_size + ctx->crc_size) ) {
            error_count = FC_syndrome_shift(ctx, 0);
            error_index += 1;
            if ( error_count == 0 ) break;
        }
    }

    // Test for correctable errors
    //printf("error_index %d\n",error_index);
    if (error_index == 224) success_flag = 0;
    else {

        // correct index depending on the position of the error
        if (error_index == 0) syn_index = error_index;
        else syn_index = error_index - 1;
        
        // error burst lies within data bits
        if (error_index < 184) {
            //printf("error < bit 184,%d\n",error_index);
            j = error_index;
            while ( j < (error_index+12) ) {
                if (j < 184) {
                    control_data[j] = control_data[j] ^ 
                       ctx->syndrome_reg[REM(ctx->syn_start+39-j+syn_index,40)];
                }               
                else break;
                j = j + 1;
            }
        }
        else if ( error_index > 212 ) {
            //printf("error > bit 212,%d\n",error_index);
            j = 0;
            while ( j < (error_index - 212) ) {
                control_data[j] = control_data[j] ^ 
                      ctx->syndrome_reg[REM(ctx->syn_start+39-j-224+syn_index,40)];
                j = j + 1;
            }
        }
        // for 183 < error_index < 213 error in parity alone so ignore
        success_flag = 1;
    }
    return success_flag;
}    

static int 
FC_syndrome_shift(FC_CTX *ctx, unsigned int bit)
{
	int error_count = 0;
	unsigned int i;

	if (ctx->syn_start == 0)
		ctx->syn_start = 39;
	else ctx->syn_start -= 1;

	int temp_syndrome_reg[sizeof ctx->syndrome_reg];

	memcpy(temp_syndrome_reg, ctx->syndrome_reg, sizeof temp_syndrome_reg);

    temp_syndrome_reg[REM(ctx->syn_start+3,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+3,40)] ^
                       ctx->syndrome_reg[ctx->syn_start];
    temp_syndrome_reg[REM(ctx->syn_start+17,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+17,40)] ^
                       ctx->syndrome_reg[ctx->syn_start];
    temp_syndrome_reg[REM(ctx->syn_start+23,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+23,40)] ^
                       ctx->syndrome_reg[ctx->syn_start];
    temp_syndrome_reg[REM(ctx->syn_start+26,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+26,40)] ^
                       ctx->syndrome_reg[ctx->syn_start];

    temp_syndrome_reg[REM(ctx->syn_start+4,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+4,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+6,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+6,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+10,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+10,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+16,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+16,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+27,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+27,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+29,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+29,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+33,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+33,40)] ^ bit;
    temp_syndrome_reg[REM(ctx->syn_start+39,40)] = 
                       ctx->syndrome_reg[REM(ctx->syn_start+39,40)] ^ bit;

    temp_syndrome_reg[ctx->syn_start] = ctx->syndrome_reg[ctx->syn_start] ^ bit;

	memcpy(ctx->syndrome_reg, temp_syndrome_reg, sizeof ctx->syndrome_reg);

    for (i = 0; i < 28; i++) {
       error_count = error_count + ctx->syndrome_reg[REM(ctx->syn_start+i,40)];
    }
    return error_count;
}
 

