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.