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

📄 dlmstp.c

📁 Bacnet protocol stack for linux
💻 C
📖 第 1 页 / 共 4 页
字号:
                    /* Some other node exists at a lower address.  */
                    /* Enter the IDLE state to receive and 
                       process the incoming frame. */
                    Master_State = MSTP_MASTER_STATE_IDLE;
                    transition_now = true;
                }
            } else {
                ns_timeout = Tno_token + (Tslot * (This_Station + 1));
                if (Timer_Silence() < ns_timeout) {
                    /* GenerateToken */
                    /* Assume that this node is the lowest numerical address  */
                    /* on the network and is empowered to create a token.  */
                    Poll_Station = next_this_station;
                    /* Transmit a Poll For Master frame to PS. */
                    MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
                        This_Station, NULL, 0);
                    /* indicate that the next station is unknown */
                    Next_Station = This_Station;
                    RetryCount = 0;
                    TokenCount = 0;
                    /* EventCount = 0; removed Addendum 135-2004d-8 */
                    /* enter the POLL_FOR_MASTER state 
                       to find a new successor to TS. */
                    Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
                }
            }
            break;
            /* In the POLL_FOR_MASTER state, the node listens for a reply to */
            /* a previously sent Poll For Master frame in order to find  */
            /* a successor node. */
        case MSTP_MASTER_STATE_POLL_FOR_MASTER:
            if (MSTP_Flag.ReceivedValidFrame == true) {
                if ((DestinationAddress == This_Station)
                    && (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
                    /* ReceivedReplyToPFM */
                    MSTP_Flag.SoleMaster = false;
                    Next_Station = SourceAddress;
                    EventCount = 0;
                    /* Transmit a Token frame to NS */
                    MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
                        This_Station, NULL, 0);
                    Poll_Station = This_Station;
                    TokenCount = 0;
                    RetryCount = 0;
                    Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
                } else {
                    /* ReceivedUnexpectedFrame */
                    /* An unexpected frame was received.  */
                    /* This may indicate the presence of multiple tokens. */
                    /* enter the IDLE state to synchronize with the network.  */
                    /* This action drops the token. */
                    Master_State = MSTP_MASTER_STATE_IDLE;
                    transition_now = true;
                }
                MSTP_Flag.ReceivedValidFrame = false;
            } else if ((Timer_Silence() > Tusage_timeout) ||
                (MSTP_Flag.ReceivedInvalidFrame == true)) {
                if (MSTP_Flag.SoleMaster == true) {
                    /* SoleMaster */
                    /* There was no valid reply to the periodic poll  */
                    /* by the sole known master for other masters. */
                    FrameCount = 0;
                    /* TokenCount++; removed in 2004 */
                    Master_State = MSTP_MASTER_STATE_USE_TOKEN;
                    transition_now = true;
                } else {
                    if (Next_Station != This_Station) {
                        /* DoneWithPFM */
                        /* There was no valid reply to the maintenance  */
                        /* poll for a master at address PS.  */
                        EventCount = 0;
                        /* transmit a Token frame to NS */
                        MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
                            This_Station, NULL, 0);
                        RetryCount = 0;
                        Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
                    } else {
                        if (next_poll_station != This_Station) {
                            /* SendNextPFM */
                            Poll_Station = next_poll_station;
                            /* Transmit a Poll For Master frame to PS. */
                            MSTP_Send_Frame(FRAME_TYPE_POLL_FOR_MASTER,
                                Poll_Station, This_Station, NULL, 0);
                            RetryCount = 0;
                            /* Re-enter the current state. */
                        } else {
                            /* DeclareSoleMaster */
                            /* to indicate that this station 
                               is the only master */
                            MSTP_Flag.SoleMaster = true;
                            FrameCount = 0;
                            Master_State = MSTP_MASTER_STATE_USE_TOKEN;
                            transition_now = true;
                        }
                    }
                }
                MSTP_Flag.ReceivedInvalidFrame = false;
            }
            break;
            /* The ANSWER_DATA_REQUEST state is entered when a  */
            /* BACnet Data Expecting Reply, a Test_Request, or  */
            /* a proprietary frame that expects a reply is received. */
        case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
            /* Note: we could wait for up to Treply_delay */
            if (MSTP_Flag.TransmitPacketPending) {
                matched =
                    dlmstp_compare_data_expecting_reply(&InputBuffer[0],
                    DataLength, SourceAddress, &TransmitPacket[0],
                    TransmitPacketLen, TransmitPacketDest);
            }
            if (MSTP_Flag.TransmitPacketPending && matched) {
                /* Reply */
                /* If a reply is available from the higher layers  */
                /* within Treply_delay after the reception of the  */
                /* final octet of the requesting frame  */
                /* (the mechanism used to determine this is a local matter), */
                /* then call MSTP_Send_Frame to transmit the reply frame  */
                /* and enter the IDLE state to wait for the next frame. */
                uint8_t frame_type;
                if (MSTP_Flag.TransmitPacketDER) {
                    frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
                } else {
                    frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
                }
                MSTP_Send_Frame(frame_type, TransmitPacketDest, This_Station,
                    (uint8_t *) & TransmitPacket[0], TransmitPacketLen);
                MSTP_Flag.TransmitPacketPending = false;
                Master_State = MSTP_MASTER_STATE_IDLE;
            } else {
                /* DeferredReply */
                /* If no reply will be available from the higher layers */
                /* within Treply_delay after the reception of the */
                /* final octet of the requesting frame (the mechanism */
                /* used to determine this is a local matter), */
                /* then an immediate reply is not possible. */
                /* Any reply shall wait until this node receives the token. */
                /* Call MSTP_Send_Frame to transmit a Reply Postponed frame, */
                /* and enter the IDLE state. */
                MSTP_Send_Frame(FRAME_TYPE_REPLY_POSTPONED, SourceAddress,
                    This_Station, NULL, 0);
                Master_State = MSTP_MASTER_STATE_IDLE;
            }
            /* clear our flag we were holding for comparison */
            MSTP_Flag.ReceivedValidFrame = false;
            break;
        default:
            Master_State = MSTP_MASTER_STATE_IDLE;
            break;
    }

    return transition_now;
}

/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(
    BACNET_ADDRESS * dest,      /* destination address */
    BACNET_NPDU_DATA * npdu_data,       /* network information */
    uint8_t * pdu,      /* any data to be sent - may be null */
    unsigned pdu_len)
{       /* number of bytes of data */
    int bytes_sent = 0;

    if (MSTP_Flag.TransmitPacketPending == false) {
        MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply;
        TransmitPacket = pdu;
        TransmitPacketLen = pdu_len;
        bytes_sent = pdu_len;
        TransmitPacketDest = dest->mac[0];
        MSTP_Flag.TransmitPacketPending = true;
    }

    return bytes_sent;
}

/* Return the length of the packet */
uint16_t dlmstp_receive(
    BACNET_ADDRESS * src,       /* source address */
    uint8_t * pdu,      /* PDU data */
    uint16_t max_pdu,   /* amount of space available in the PDU  */
    unsigned timeout)
{       /* milliseconds to wait for a packet */
    uint16_t pdu_len = 0;       /* return value */

    /* set the input buffer to the same data storage for zero copy */
    if (!InputBuffer) {
        InputBuffer = pdu;
        InputBufferSize = max_pdu;
    }
    /* only do receive state machine while we don't have a frame */
    if ((MSTP_Flag.ReceivedValidFrame == false) &&
        (MSTP_Flag.ReceivedInvalidFrame == false)) {
        for (;;) {
            MSTP_Receive_Frame_FSM();
            if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame)
                break;
            /* if we are not idle, then we are 
               receiving a frame or timing out */
            if (Receive_State == MSTP_RECEIVE_STATE_IDLE)
                break;
        }
    }
    /* only do master state machine while rx is idle */
    if (Receive_State == MSTP_RECEIVE_STATE_IDLE) {
        while (MSTP_Master_Node_FSM()) {
            /* do nothing while some states fast transition */
        };
    }
    /* if there is a packet that needs processed, do it now. */
    if (MSTP_Flag.ReceivePacketPending) {
        MSTP_Flag.ReceivePacketPending = false;
        pdu_len = DataLength;
        src->mac_len = 1;
        src->mac[0] = SourceAddress;
        /* data is already in the pdu pointer */
    }

    return pdu_len;
}

void dlmstp_set_mac_address(
    uint8_t mac_address)
{
    /* Master Nodes can only have address 0-127 */
    if (mac_address <= 127) {
        This_Station = mac_address;
        /* FIXME: implement your data storage */
        /* I2C_Write_Byte(
           EEPROM_DEVICE_ADDRESS, 
           mac_address,
           EEPROM_MSTP_MAC_ADDR); */
        if (mac_address > Nmax_master)
            dlmstp_set_max_master(mac_address);
    }

    return;
}

uint8_t dlmstp_mac_address(
    void)
{
    return This_Station;
}

/* This parameter represents the value of the Max_Info_Frames property of */
/* the node's Device object. The value of Max_Info_Frames specifies the */
/* maximum number of information frames the node may send before it must */
/* pass the token. Max_Info_Frames may have different values on different */
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(
    uint8_t max_info_frames)
{
    if (max_info_frames >= 1) {
        Nmax_info_frames = max_info_frames;
        /* FIXME: implement your data storage */
        /* I2C_Write_Byte(  
           EEPROM_DEVICE_ADDRESS, 
           (uint8_t)max_info_frames,
           EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
    }

    return;
}

uint8_t dlmstp_max_info_frames(
    void)
{
    return Nmax_info_frames;
}

/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(
    uint8_t max_master)
{
    if (max_master <= 127) {
        if (This_Station <= max_master) {
            Nmax_master = max_master;
            /* FIXME: implement your data storage */
            /* I2C_Write_Byte(
               EEPROM_DEVICE_ADDRESS, 
               max_master,
               EEPROM_MSTP_MAX_MASTER_ADDR); */
        }
    }

    return;
}

uint8_t dlmstp_max_master(
    void)
{
    return Nmax_master;
}

void dlmstp_get_my_address(
    BACNET_ADDRESS * my_address)
{
    int i = 0;  /* counter */

    my_address->mac_len = 1;
    my_address->mac[0] = This_Station;
    my_address->net = 0;        /* local only, no routing */
    my_address->len = 0;
    for (i = 0; i < MAX_MAC_LEN; i++) {
        my_address->adr[i] = 0;
    }

    return;
}

void dlmstp_get_broadcast_address(
    BACNET_ADDRESS * dest)
{       /* destination address */
    int i = 0;  /* counter */

    if (dest) {
        dest->mac_len = 1;
        dest->mac[0] = MSTP_BROADCAST_ADDRESS;
        dest->net = BACNET_BROADCAST_NETWORK;
        dest->len = 0;  /* always zero when DNET is broadcast */
        for (i = 0; i < MAX_MAC_LEN; i++) {
            dest->adr[i] = 0;
        }
    }

    return;
}

⌨️ 快捷键说明

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