When implementing a layered communications protocol are layers commonly implemented as state machines?
I have an implementation of PMBus I am currently working on for an embedded device. I have a interrupt driven interface for handling how the I2C uses the H/W driver to receive and transmit bytes onto and off of a buffer, essentially serialising the data.
A state machine then implements the "middle" SMBus layer taking the data from the buffer and forming messages from it according to how the protocol dictates what to expect for a generic type message, this state machine may also adds information based on input from additional I/O lines.
A second state machine then caps the stack with the PMBus layer by checking the generic message as it applies to specific types of messages, again adding some further information from I/O lines and subsequently looks up a command handler according to the message and passes it data from the message.
The whole caboodle then works in reverse for transmitting responses from the command handler or requests by other parts of the system (which works from a third state machine) to change output on I/O lines, such as recording an error status requiring a request for service signal.
I'm coming from a low level embedded background with little real-job programming experience consequently having only a little idea of the expected and accepted design patterns for common problems. Thus my question; is such state machine layering a common or logically expected solution to implementing layered protocols?
It seemed effective and robust to me (a soft requirement is that the layer functionality be encapsulated) when I thought it up some time ago but looking back on it it begins to seem somewhat over-engineered and that there could be some simpler method.
EDIT: I remembered the main reason that I followed this route is so that the execution of the higher layers is de-coupled from the interrupt driven interface. This is handy because from an interrupt for data being received up to the return from the command handler for the transmitted data may (depending on how the implementation is to be used) may constitute a relatively long time in comparison to my device's main business logic which operates quite fast and has a worst-case execution time requirement. Thus my business logic state machine (the third one from above) is what calls the protocol state machines, from the top on down, when it has time to. This means that while data receipt and transmission is asynchronous, the processing of the data is not.