The UECP format has a head and tail bytes to signal the start and finish of a frame. These are reserved bytes and cannot be allowed in the remainder of the frame. Thus byte stuffing is used to replace these reserved bytes by byte pairs where there is a third reserved byte used as the introduction to a byte pair substitution.
Byte stuffing is a technique for replacing bytes code with special significance with an innocuous byte sequence. The substitution table for the UECD has been given before. Here we give a bit of code.
private Boolean RDS_Stuff(ref Byte[] buffer, Byte first, Byte last, ref Byte length)
{
// Scan the frame and byte stuff
UInt16 count = 0;
Byte b = 0x00;
Byte[] send = new Byte[512];
send[0] = buffer[0];
// first will be the start byte
Byte position = first;
// 256 is the maximum frame length. There are 8 byte for the header and tail
// so maximum position is 248 to allow margin
for (count = first; ((count <= last) && (count < buffer.Length)); count++)
{
b = buffer[count];
if (b == REPLACE_STUFF_FF)
{
send[position++] = STUFFING_IDENTIFIER;
send[position++] = STUFF_FF;
}
else if (b == REPLACE_STUFF_FE)
{
send[position++] = STUFFING_IDENTIFIER;
send[position++] = STUFF_FE;
}
else if (b == REPLACE_STUFF_FD)
{
send[position++] = STUFFING_IDENTIFIER;
send[position++] = STUFF_FD;
}
else send[position++] = b;
}
// position will now point to the last byte
send[position] = RDS_STOP_BYTE;
length = (Byte)(position + 1);
if ((position > 248) || (length > buffer.Length)) return false;
// Transfer send back into buffer, provided length <= buffer.Length
for (count = 0; count < length; count++)
buffer[count] = send[count];
return true;
}
This is C# coding. There are a number of constants such as STUFFING_IDENTIFIER or RDS_STOP_BYTE. These are defined elsewhere in the class.
public const byte STUFFING_IDENTIFIER = 0xFD;
public const byte STUFF_FF = 0x02;
public const byte STUFF_FE = 0x01;
public const byte STUFF_FD = 0x00;
public const byte REPLACE_STUFF_FF = 0xFF;
public const byte REPLACE_STUFF_FE = 0xFE;
public const byte REPLACE_STUFF_FD = 0xFD;
Likewise we can unstuff the code. This time as a simple loop in C code. Thsi would normally be embedded in a function.
bGo = true;
// Scan along Serial_InBuffer < SERIAL_BUFFER_SIZE and != 0xFF
for (i = 0; (i < SERIAL_BUFFER_SIZE) && bGo; i++)
{
if (Serial_InBuffer[i] == SERIAL_STOP_BYTE) bGo = FALSE;
if (Serial_InBuffer[i] == SERIAL_STUFF_BYTE)
{
// Byte stuffing detected
i++;
if (Serial_InBuffer[i] == STUFF_STUFF_CODE) UECD_InBuffer[k++] = SERIAL_STUFF_BYTE;
else if (Serial_InBuffer[i] == START_STUFF_CODE) UECD_InBuffer[k++] = SERIAL_START_BYTE;
else if (Serial_InBuffer[i] == STOP_STUFF_CODE) UECD_InBuffer[k++] = SERIAL_STOP_BYTE;
}
else
{
UECD_InBuffer[k++] = Serial_InBuffer[i];
}
}
The Serial_InBuffer has the raw, unstuffed data. This is un-stuffed into the UECD_InBuffer.