gov.nasa.gsfc.drl.rtstps.core.fs
Class AbstractSynchronizer

java.lang.Object
  extended by gov.nasa.gsfc.drl.rtstps.core.fs.AbstractSynchronizer
Direct Known Subclasses:
Synchronizer, XSynchronizer

abstract class AbstractSynchronizer
extends java.lang.Object

This class handles the frame synchronizer pattern logic for the Frame Synchronizer subsystem. It assumes there are no bit errors in the pattern. It can detect bit slips of 1 or 2 bits. The pattern may be 16, 24, or 32 bits in length.

This class's search strategy is to take each byte in a input buffer and treat it as an index into a 256-byte lookup table, which returns a "bit index." The index will either be NOSYNC or a value indicating it is a sync pattern candidate.

If a buffer contains a sync pattern of 16 or more bits, then we know that we can search for known bytes in the input buffer. For example, the standard CCSDS sync pattern is 0x1ACFFC1D (designated here as s1=1A, s2=CF, s3=FC, s4=1D). If we find a CF (s2), then we have a sync pattern candidate. Since the bits could be shifted, we could have up to 8 unique candidate patterns. (Take CF and shift 1A into it 7 times, dropping CF's low-order bit each time. If you shift 8 bits, the CF drops into the next byte.) As a consequence, when we search the input buffer, we want to test each byte against the 8 test patterns. To speed this up, we build a 256-byte lookup table with 8 non-NOSYNC values, which are the bit shift counts. i.e. CF is bit shift 0. Each input byte is an index into the table. So, for example, if the input byte is 0x67, the table lookup would return bit index 1 (1ACF shifted right one bit, i.e. (1ACF >> 1) & 0x0FF). Once we have a NOSYNC value, we can test the surrounding bits to see if it is really a sync pattern.

There are two catches to this plan.

(1) Permitting bit errors in the sync pattern really complicates matters. Since in my experience operators rarely configure systems for sync pattern bit errors, I omit it from this class because disallowing bit errors improves performance. If bit error detection is required, I would suggest writing a separate companion class that would replace this one when that option were chosen.

(2) Although I have said that shifting down the pattern creates 8 unique values, which is the case for 1ACFFC1D, this is not necessarily true for general patterns. For example, the absurd 0xFFFFFFFF would create only one value. I call this an ambiguous pattern because the lookup value maps to more than one possible bit shift. I handle ambiguous patterns in a separate class.


Field Summary
protected  int frameLength
           
protected static int NOSYNC
           
protected  int[] s1
          s1 is the first pattern byte.
protected  int[] s1mask
           
protected  int[] s2
          This is the 256-byte lookup table as described above.
protected  byte[] s2value
           
protected  byte[] s3
          When the pattern length is 3 or 4 bytes, I know the expected third byte.
protected  byte[] s4
          When the pattern length is 4 bytes, I know the expected fourth byte.
protected  int[] s5
           
protected  int[] s5mask
           
protected  int slippage
           
protected  int syncLength
           
 
Constructor Summary
AbstractSynchronizer(byte[] pattern, int frameLength)
          Create an AbstractSynchronizer.
 
Method Summary
(package private)  boolean checkSlip(Buffer buffer)
          Test bit slip at the buffer's current index.
(package private)  boolean checkSync(Buffer buffer)
          Check if sync is present at the buffer's current index.
(package private) abstract  Location search(byte[] data, int dataLength, int start, int end)
          Search for sync in the data array.
(package private)  void setSlip(int slip)
          Set the allowable bit slip.
private  boolean testSlip(Buffer buffer, int slip)
          Test for an exact bit position slip at the buffer's current index.
(package private)  boolean testSync(byte[] data, int keyByte, int bitIndex)
          Test if sync is present.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

NOSYNC

protected static final int NOSYNC
See Also:
Constant Field Values

s1

protected int[] s1
s1 is the first pattern byte. When verifying the first byte, I usually must mask off some leading bits. I use two arrays to hold the masks and the expected values.


s1mask

protected int[] s1mask

s2

protected int[] s2
This is the 256-byte lookup table as described above. It is keyed to the second pattern byte. The s2value array contains the 8 shifted s2-patterns,


s2value

protected byte[] s2value

s3

protected byte[] s3
When the pattern length is 3 or 4 bytes, I know the expected third byte.


s4

protected byte[] s4
When the pattern length is 4 bytes, I know the expected fourth byte.


s5

protected int[] s5

s5mask

protected int[] s5mask

syncLength

protected int syncLength

frameLength

protected int frameLength

slippage

protected int slippage
Constructor Detail

AbstractSynchronizer

AbstractSynchronizer(byte[] pattern,
                     int frameLength)
Create an AbstractSynchronizer.

Parameters:
pattern - The synchronization pattern. The length may be 1 to 4 bytes.
frameLength - The expected frame length, which includes the sync pattern.
Method Detail

setSlip

final void setSlip(int slip)
            throws java.lang.IllegalArgumentException
Set the allowable bit slip. The value must be 0, 1, or 2. The default is 0.

Throws:
java.lang.IllegalArgumentException

checkSync

final boolean checkSync(Buffer buffer)
Check if sync is present at the buffer's current index. Do not slip. The entire pattern must be able to fit in the buffer at the current location.

Parameters:
buffer - The input buffer.
Returns:
true if sync was present and false otherwise.

testSync

final boolean testSync(byte[] data,
                       int keyByte,
                       int bitIndex)
Test if sync is present. Do not slip. The entire pattern must be able to fit in the buffer at the location.

Parameters:
data - The input data array.
keyByte - data array index of key sync byte to be tested
bitIndex - bit shift of keyByte
Returns:
true if sync was present and false otherwise.

checkSlip

final boolean checkSlip(Buffer buffer)
Test bit slip at the buffer's current index. If it detects slip, it changes the buffer's current index. If N is the current buffer index, then array locations N-1 through N+syncLength should exist.

Parameters:
buffer - The buffer to be tested
Returns:
true if a slipped sync was detected and false otherwise.

testSlip

private boolean testSlip(Buffer buffer,
                         int slip)
Test for an exact bit position slip at the buffer's current index. That is, if you test for 2-bit slippage, it does not check 1-bit slip. If it detects slip, it changes the buffer's current index. If N is the current buffer index, then array locations N-1 through N+syncLength should exist.

Parameters:
buffer - The buffer to be tested
Returns:
true if a slipped sync was detected and false otherwise. It returns false if there is an unslipped pattern at the buffer's current location.

search

abstract Location search(byte[] data,
                         int dataLength,
                         int start,
                         int end)
Search for sync in the data array.

Parameters:
data - The data array.
dataLength - The actual length of the data array, which may be less than data.length.
start - A start byte in data[].
end - An end byte in data[]. It cannot detect partial sync, so it will adjust the end byte if necessary to be no greater than dataLength-syncLength.
Returns:
A location in data where the first sync pattern was detected between start and end. It returns null if it did not detect sync.