Пример #1
0
// syndrome takes a bitstream and uses the parity bits from the BCH polynomial
// generator to calculate if the bits are received correctly.
// A 0 return means the bits are correct.
// Thanks to multimon-ng (https://github.com/EliasOenal/multimon-ng) for
// detailing implmentation of this.
func syndrome(bits []datatypes.Bit) uint32 {
	bytes := utils.MSBBitsToBytes(bits, 8)

	// take the parity-bit out from our codeword
	codeword := utils.Btouint32(bytes) >> 1

	// put the mask bit to the far left in the bitstream
	mask := uint32(1 << (BCH_N))
	coeff := uint32(BHC_COEFF)

	// step over each data-bit (the first 21)
	for a := 0; a < BCH_K; a += 1 {
		// step the coefficient and mask right in the bitstream
		mask >>= 1
		coeff >>= 1

		// if the current bit in the codeword is 1 then XOR the codeword with the coefficient
		if (codeword & mask) > 0 {
			codeword = codeword ^ coeff
		}
	}

	// in the end, if the coefficient matches the codeword they
	// are canceled out by the XOR, returning 0

	return codeword
}
Пример #2
0
// NewCodeword takes 32 bits, creates a new codeword construct, sets the type and checks for parity errors.
func NewCodeword(bits []datatypes.Bit) (*Codeword, error) {
	if len(bits) != 32 {
		return nil, fmt.Errorf("invalid number of bits for codeword: ", len(bits))
	}

	bits, corrected := BitCorrection(bits)

	mtype := CodewordTypeAddress
	if bits[0] == true {
		mtype = CodewordTypeMessage
	}

	bytes := utils.MSBBitsToBytes(bits, 8)
	if isIdle(bytes) {
		mtype = CodewordTypeIdle
	}

	c := &Codeword{
		Type:           mtype,
		Payload:        bits[1:21],
		ParityBits:     bits[21:31],
		EvenParity:     bits[31],
		ValidParity:    (syndrome(bits) == 0) && utils.ParityCheck(bits[:31], bits[31]),
		BitCorrections: corrected,
	}

	return c, nil
}
Пример #3
0
// ParseBatches takes bits decoded from the stream and parses them for
// batches of codewords.
func (p *POCSAG) ParseBatches(bits []datatypes.Bit) ([]*Batch, error) {

	batches := []*Batch{}

	var start = -1
	var batchno = -1
	// synchornize with the decoded bits
	for a := 0; a < len(bits)-32; a += 1 {

		bytes := utils.MSBBitsToBytes(bits[a:a+32], 8)

		if isPreamble(bytes) {

			batchno += 1
			start = a + 32

			// for file output as bin data
			batchbits := bits[a : a+POCSAG_BATCH_LEN+32]
			stream := utils.MSBBitsToBytes(batchbits, 8)

			if DEBUG && LEVEL > 2 {
				out, err := os.Create(fmt.Sprintf("batches/batch-%d.bin", batchno))
				if err != nil {
					return nil, err
				}
				out.Write(stream)
			}

			batch, err := NewBatch(bits[start : start+POCSAG_BATCH_LEN])
			if err != nil {
				println(err.Error())
			} else {
				batches = append(batches, batch)
			}

		}

	}

	if start < 0 {
		return nil, fmt.Errorf("could not obtain message sync")
	}

	return batches, nil

}
Пример #4
0
// ReciptientString returns the reciptient address as a hexadecimal representation,
// with the function bits as 0 or 1.
func (m *Message) ReciptientString() string {
	bytes := utils.MSBBitsToBytes(m.Reciptient.Payload[0:17], 8)
	addr := uint(bytes[1])
	addr += uint(bytes[0]) << 8

	return fmt.Sprintf("%X%d%d", addr,
		m.Reciptient.Payload[18].Int(),
		m.Reciptient.Payload[19].Int())
}
Пример #5
0
// Print the address for debugging
func (c *Codeword) Adress() string {
	bytes := utils.MSBBitsToBytes(c.Payload[0:17], 8)
	addr := uint(bytes[1])
	addr += uint(bytes[0]) << 8

	return fmt.Sprintf("%X:%s%s", addr,
		utils.TernaryStr(bool(c.Payload[18]), "1", "0"),
		utils.TernaryStr(bool(c.Payload[19]), "1", "0"))

}