Круги с текстом внутри являются состояниями.Текст описывает состояние.
Пунктирная стрелка указывает на начальное состояние.
Исходящие стрелки определяют, где это состояние может измениться.Рядом со стрелкой находится текст, разделенный линией на верхнюю и нижнюю части.Нижняя часть - это действия, которые должны выполняться при переходе стрелки.Верхняя часть - это условия.Когда они истинны - этот переход выполняется (и, следовательно, нижняя часть).
Лямбда-символ означает, что вы ничего не должны делать, кроме изменения текущего состояния, когда происходит переход.
Таким образом, нижние части имеют грубую соответствующуюк вашим функциям.А верхние части - это точки, где вы должны ждать условий - опроса или асинхронного ожидания ожидающих пакетов ввода-вывода, что угодно.
Вот некоторый псевдокод, похожий на C (я написал его вот такне предполагайте, что это работает или даже компилируется):
enum State { WaitFor0Call, WaitForAck0, WaitForCall1, WaitForAck1 }
int main() {
State state = WaitFor0Call;
while (1) {
switch (state) {
case WaitFor0Call:
if (rdt_rcv(rcvpkt)) continue;
if (rdt_send(data)) {
state = WaitForAck0;
sndpkt = make_pkt(0, data, checksum);
udt_send(sndpkt);
start_timer();
}
break;
case WaitForAck0:
// ...similar code...
break;
case WaitForCall1:
// ...similar code...
break;
case WaitForAck1:
// ...similar code...
break;
}
}
}
Следует также учитывать, что функции приема и отправки могут блокировать, поэтому код if (rdt_rcv(rcvpkt)) whatever;
технически неверен, так как вы не проверяете rdt_send
пока не вернет контроль.Итак, FSM передает только логический поток, а не технические аспекты того, как он должен быть организован, управление потоками и т. Д. И мой код не показывает эти аспекты также потому, что он может быть довольно сложным в зависимости от ваших потребностей и потому, что вы не предоставили достаточно деталейчтобы дать информированные советы о таких вещах:)
Мое единственное предположение, что у вас будет некоторый двунаправленный поток (для ввода и вывода соответственно), и условия будут такими, как if (there_is_ready_for_consuming_packet_in_the_input_queue) continue;
и if (data_was_put_to_outgoing_stream_successfully) ...;