You are here: Elements > Frame Recognizers > A Frame Recognizer for FP

A Frame Recognizer for FP

When we introduced our Fictitious Protocol in Chapter 2 we carefully said nothing about how protocol units were framed. Indeed, we did not even suggest what type of communication link FP would be used on. Let us now suppose that FP is used over an RS-232 type of connection and framed like this:

Start Flag Frame Stop Flag

 

using the following values:

Start Flag F1 hex (or 11110001 binary)
Stop Flag F2 hex (or 11110010 binary)

Let us look at the Frame Recognizer for FP:

RECOGNIZER __FP__ PER_STREAM

//

// Fictitious Protocol data

//

enum {START_FLAG = 0xF1, /* frames start with F1 hex */

STOP_FLAG = 0xF2}; /* frames end with F2 hex */

//

// Processing states

//

#define STATE_NOT_IN_FRAME 1

#define STATE_IN_FRAME 2

private:

int iState;

@RESET

iState = STATE_NOT_IN_FRAME;

@EACH_BYTE

//

// Process the data byte based on the state

//

switch (iState)

{

//

// If we are not within a frame then we look

// only for a frame-start flag.

//

case STATE_NOT_IN_FRAME:

if (iByte == START_FLAG)

{

iState = STATE_IN_FRAME;

return eInsertSofAfter;

}

break;

 

//

// If we are within a frame then need to look

// only for a frame-end flag.

//

case STATE_IN_FRAME:

if (iByte == STOP_FLAG)

{

iState = STATE_NOT_IN_FRAME;

return eInsertThisSideEofBefore;

}

else if (iByte == START_FLAG)

{

iState = STATE_NOT_IN_FRAME;

return eBrokenFrame;

}

}

return eContinue;

@END_RECOGNIZER

Almost any Frame Recognizer will need to maintain some member variables, at least to record its state between invocations and perhaps to save other information as well. FP's recognizer uses a private variable iState to hold its state. This state is simply "in frame" or "out of frame".

Let us look at the method piece by piece starting with its framing:

RECOGNIZER FP PER_STREAM

@END_RECOGNIZER

As we observed above, a recognizer is not a method and it does not start and end like a method. You may however include a recognizer in a source file along with methods.

Now let us get into the nitty gritty of recognizing FP frames. First, note that the RESET code initializes the value of our state variable:

@RESET

iState = STATE_NOT_IN_FRAME;

Then we find the main work of the recognizer done in the EACH_BYTE block:

case STATE_NOT_IN_FRAME:

if (iByte == START_FLAG)

{

iState = STATE_IN_FRAME;

return eInsertSofAfter;

}

break;

 

On finding a start flag, we switch state to "in frame" and return eInsertSofAfter. This indicates that there is a start-of-frame after the current byte. Note that we do not include the start flag within the frame since we do not want the flag itself to appear in our decoder. In some other protocols, this may not be the appropriate procedure. If the flag has meaning beyond that of simply marking the start of a frame then it should be included. Suppose for example that an opening flag can be either F1 or F6 with one indicating a command and the other a response. Then you would want to put the SOF in front of the flag.

The second case is when we are "in frame" and looking for a stop flag:

case STATE_IN_FRAME:

if (iByte == STOP_FLAG)

{

iState = STATE_NOT_IN_FRAME;

return eInsertThisSideEofBefore;

}

else if (iByte == START_FLAG)

{

iState = STATE_NOT_IN_FRAME;

return eBrokenFrame;

}

break;

When we find our stop flag we switch back to "out of frame" state and set the output to eInsertThisSideEofBefore so that an end-of-frame marker will be inserted immediately before the current byte. Why is this value not called eInsertEofBefore? Look back at the list of return codes and you will see there is also one called eInsertOtherSideEofBefore. Inserting an EOF before the current event is the one case where we need to be able to do that for either stream.

To be careful we also check for another start flag since a start flag should never appear inside a frame. If one does, it could be because a frame was incorrectly terminated, because a station died while transmitting a frame, or because a byte was corrupted in transmission. In other words, there is no reliable conclusion we can draw about what is up and we output eBrokenFrame.