/*
 * crcXXgen.c
 *
 * Generic CRC routines (for max XX bits poly)
 *
 * Copyright (C) 2011  Sylvain Munaut <tnt@246tNt.com>
 *
 * All Rights Reserved
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/*! \addtogroup crcgen
 *  @{
 *  Osmocom generic CRC routines
 */

/*! \file crcXXgen.c
 * Osmocom generic CRC routines (for max XX bits poly)
 */

#include <stdint.h>

#include <osmocom/core/bits.h>
#include <osmocom/core/crcXXgen.h>


/*! Compute the CRC value of a given array of hard-bits
 *  \param[in] code The CRC code description to apply
 *  \param[in] in Array of hard bits
 *  \param[in] len Length of the array of hard bits
 *  \returns The CRC value
 */
uintXX_t
osmo_crcXXgen_compute_bits(const struct osmo_crcXXgen_code *code,
                           const ubit_t *in, int len)
{
	const uintXX_t poly = code->poly;
	uintXX_t crc = code->init;
	int i, n = code->bits-1;

	for (i=0; i<len; i++) {
		uintXX_t bit = in[i] & 1;
		crc ^= (bit << n);
		if (crc & ((uintXX_t)1 << n)) {
			crc <<= 1;
			crc ^= poly;
		} else {
			crc <<= 1;
		}
		crc &= ((uintXX_t)1 << code->bits) - 1;
	}

	crc ^= code->remainder;

	return crc;
}


/*! Checks the CRC value of a given array of hard-bits
 *  \param[in] code The CRC code description to apply
 *  \param[in] in Array of hard bits
 *  \param[in] len Length of the array of hard bits
 *  \param[in] crc_bits Array of hard bits with the alleged CRC
 *  \returns 0 if CRC matches. 1 in case of error.
 *
 * The crc_bits array must have a length of code->len
 */
int
osmo_crcXXgen_check_bits(const struct osmo_crcXXgen_code *code,
                         const ubit_t *in, int len, const ubit_t *crc_bits)
{
	uintXX_t crc;
	int i;

	crc = osmo_crcXXgen_compute_bits(code, in, len);

	for (i=0; i<code->bits; i++)
		if (crc_bits[i] ^ ((crc >> (code->bits-i-1)) & 1))
			return 1;

	return 0;
}


/*! Computes and writes the CRC value of a given array of bits
 *  \param[in] code The CRC code description to apply
 *  \param[in] in Array of hard bits
 *  \param[in] len Length of the array of hard bits
 *  \param[in] crc_bits Array of hard bits to write the computed CRC to
 *
 * The crc_bits array must have a length of code->len
 */
void
osmo_crcXXgen_set_bits(const struct osmo_crcXXgen_code *code,
                       const ubit_t *in, int len, ubit_t *crc_bits)
{
	uintXX_t crc;
	int i;

	crc = osmo_crcXXgen_compute_bits(code, in, len);

	for (i=0; i<code->bits; i++)
		crc_bits[i] = ((crc >> (code->bits-i-1)) & 1);
}

/*! @} */

/* vim: set syntax=c: */
