⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mstp.c

📁 Bacnet protocol stack for linux
💻 C
📖 第 1 页 / 共 4 页
字号:
        case MSTP_RECEIVE_STATE_PREAMBLE:
            /* Timeout */
            if (mstp_port->SilenceTimer > Tframe_abort) {
                /* a correct preamble has not been received */
                /* wait for the start of a frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            }
            /* Error */
            else if (mstp_port->ReceiveError == true) {
                mstp_port->ReceiveError = false;
                mstp_port->SilenceTimer = 0;
                INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                /* wait for the start of a frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            } else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
                fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
                /* Preamble2 */
                if (mstp_port->DataRegister == 0xFF) {
                    mstp_port->DataAvailable = false;
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->Index = 0;
                    mstp_port->HeaderCRC = 0xFF;
                    /* receive the remainder of the frame. */
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* ignore RepeatedPreamble1 */
                else if (mstp_port->DataRegister == 0x55) {
                    mstp_port->DataAvailable = false;
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    /* wait for the second preamble octet. */
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE;
                }
                /* NotPreamble */
                else {
                    mstp_port->DataAvailable = false;
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    /* wait for the start of a frame. */
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
                }
            }
            break;
            /* In the HEADER state, the node waits for the fixed message header. */
        case MSTP_RECEIVE_STATE_HEADER:
            /* Timeout */
            if (mstp_port->SilenceTimer > Tframe_abort) {
                /* indicate that an error has occurred during the reception of a frame */
                mstp_port->ReceivedInvalidFrame = true;
                /* wait for the start of a frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            }
            /* Error */
            else if (mstp_port->ReceiveError == true) {
                mstp_port->ReceiveError = false;
                mstp_port->SilenceTimer = 0;
                INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                /* indicate that an error has occurred during the reception of a frame */
                mstp_port->ReceivedInvalidFrame = true;
                /* wait for the start of a frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            } else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
                fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
                /* FrameType */
                if (mstp_port->Index == 0) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->FrameType = mstp_port->DataRegister;
                    mstp_port->DataAvailable = false;
                    mstp_port->Index = 1;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* Destination */
                else if (mstp_port->Index == 1) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->DestinationAddress = mstp_port->DataRegister;
                    mstp_port->DataAvailable = false;
                    mstp_port->Index = 2;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* Source */
                else if (mstp_port->Index == 2) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->SourceAddress = mstp_port->DataRegister;
                    mstp_port->DataAvailable = false;
                    mstp_port->Index = 3;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* Length1 */
                else if (mstp_port->Index == 3) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->DataLength = mstp_port->DataRegister * 256;
                    mstp_port->DataAvailable = false;
                    mstp_port->Index = 4;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* Length2 */
                else if (mstp_port->Index == 4) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->DataLength += mstp_port->DataRegister;
                    mstp_port->DataAvailable = false;
                    mstp_port->Index = 5;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
                }
                /* HeaderCRC */
                else if (mstp_port->Index == 5) {
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    mstp_port->HeaderCRC =
                        CRC_Calc_Header(mstp_port->DataRegister,
                        mstp_port->HeaderCRC);
                    mstp_port->DataAvailable = false;
                    /* don't wait for next state - do it here */
                    /* MSTP_RECEIVE_STATE_HEADER_CRC */
                    if (mstp_port->HeaderCRC != 0x55) {
                        /* BadCRC */
                        /* indicate that an error has occurred during the reception of a frame */
                        mstp_port->ReceivedInvalidFrame = true;
                        /* wait for the start of the next frame. */
                        mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
                    } else {
                        if ((mstp_port->DestinationAddress ==
                                mstp_port->This_Station)
                            || (mstp_port->DestinationAddress ==
                                MSTP_BROADCAST_ADDRESS)) {
                            /* FrameTooLong */
                            if (mstp_port->DataLength > MAX_MPDU) {
                                /* indicate that a frame with an illegal or  */
                                /* unacceptable data length has been received */
                                mstp_port->ReceivedInvalidFrame = true;
                                /* wait for the start of the next frame. */
                                mstp_port->receive_state =
                                    MSTP_RECEIVE_STATE_IDLE;
                            }
                            /* NoData */
                            else if (mstp_port->DataLength == 0) {
                                /* indicate that a frame with no data has been received */
                                mstp_port->ReceivedValidFrame = true;
                                /* wait for the start of the next frame. */
                                mstp_port->receive_state =
                                    MSTP_RECEIVE_STATE_IDLE;
                            }
                            /* Data */
                            else {
                                mstp_port->Index = 0;
                                mstp_port->DataCRC = 0xFFFF;
                                /* receive the data portion of the frame. */
                                mstp_port->receive_state =
                                    MSTP_RECEIVE_STATE_DATA;
                            }
                        }
                        /* NotForUs */
                        else {
                            /* wait for the start of the next frame. */
                            mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
                        }
                    }


                }
                /* not per MS/TP standard, but it is a case not covered */
                else {
                    mstp_port->ReceiveError = false;
                    mstp_port->SilenceTimer = 0;
                    INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
                    /* indicate that an error has occurred during  */
                    /* the reception of a frame */
                    mstp_port->ReceivedInvalidFrame = true;
                    /* wait for the start of a frame. */
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
                }
            }
            break;
            /* In the HEADER_CRC state, the node validates the CRC on the fixed */
            /* message header. */
        case MSTP_RECEIVE_STATE_HEADER_CRC:
            break;
            /* In the DATA state, the node waits for the data portion of a frame. */
        case MSTP_RECEIVE_STATE_DATA:
            /* Timeout */
            if (mstp_port->SilenceTimer > Tframe_abort) {
                /* indicate that an error has occurred during the reception of a frame */
                mstp_port->ReceivedInvalidFrame = true;
                /* wait for the start of the next frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            }
            /* Error */
            else if (mstp_port->ReceiveError == true) {
                mstp_port->ReceiveError = false;
                mstp_port->SilenceTimer = 0;
                /* indicate that an error has occurred during the reception of a frame */
                mstp_port->ReceivedInvalidFrame = true;
                /* wait for the start of the next frame. */
                mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            } else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
                fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
                /* DataOctet */
                if (mstp_port->Index < mstp_port->DataLength) {
                    mstp_port->DataCRC =
                        CRC_Calc_Data(mstp_port->DataRegister,
                        mstp_port->DataCRC);
                    mstp_port->InputBuffer[mstp_port->Index] =
                        mstp_port->DataRegister;
                    mstp_port->Index++;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
                }
                /* CRC1 */
                else if (mstp_port->Index == mstp_port->DataLength) {
                    mstp_port->DataCRC =
                        CRC_Calc_Data(mstp_port->DataRegister,
                        mstp_port->DataCRC);
                    mstp_port->Index++;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
                }
                /* CRC2 */
                else if (mstp_port->Index == (mstp_port->DataLength + 1)) {
                    mstp_port->DataCRC =
                        CRC_Calc_Data(mstp_port->DataRegister,
                        mstp_port->DataCRC);
                    /* STATE DATA CRC - no need for new state */
                    /* indicate the complete reception of a valid frame */
                    if (mstp_port->DataCRC == 0xF0B8)
                        mstp_port->ReceivedValidFrame = true;
                    else
                        mstp_port->ReceivedInvalidFrame = true;
                    mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
                }
                mstp_port->DataAvailable = false;
                mstp_port->SilenceTimer = 0;
            }
            break;
        default:
            /* shouldn't get here - but if we do... */
            mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
            break;
    }
#if PRINT_ENABLED_RECEIVE_DATA
    if ((receive_state != MSTP_RECEIVE_STATE_IDLE) &&
        (mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE)) {
        fprintf(stderr, "\n");
        fflush(stderr);
    }
    receive_state = mstp_port->receive_state;
#endif

    return;
}

/* returns true if we need to transition immediately */
bool MSTP_Master_Node_FSM(
    volatile struct mstp_port_struct_t * mstp_port)
{
    int mtu_len = 0;
    int frame_type = 0;
    uint8_t next_poll_station = 0;
    uint8_t next_this_station = 0;
    uint8_t next_next_station = 0;
    uint16_t my_timeout = 10, ns_timeout = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -