コード例 #1
0
ファイル: aecp.c プロジェクト: AVB-YJ/avdecc-cmd
int aecp_aem_check( const struct jdksavdecc_frame *frame,
                    struct jdksavdecc_aecpdu_aem *aem,
                    const struct jdksavdecc_eui64 controller_entity_id,
                    const struct jdksavdecc_eui64 target_entity_id,
                    uint16_t sequence_id )
{
    int r = -1;
    ssize_t pos = jdksavdecc_aecpdu_aem_read( aem, frame->payload, 0, frame->length );
    if ( pos > 0 )
    {
        struct jdksavdecc_aecpdu_common_control_header *h = &aem->aecpdu_header.header;
        if ( h->version == 0 && h->subtype == JDKSAVDECC_SUBTYPE_AECP && h->cd == 1 )
        {
            if ( h->message_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_RESPONSE )
            {
                if ( h->control_data_length >= JDKSAVDECC_AECPDU_AEM_LEN - JDKSAVDECC_COMMON_CONTROL_HEADER_LEN )
                {
                    if ( jdksavdecc_eui64_compare( &aem->aecpdu_header.controller_entity_id, &controller_entity_id ) == 0 )
                    {
                        if ( jdksavdecc_eui64_compare( &aem->aecpdu_header.header.target_entity_id, &target_entity_id ) == 0 )
                        {
                            if ( aem->aecpdu_header.sequence_id == sequence_id )
                            {
                                r = 0;
                            }
                        }
                    }
                }
            }
        }
    }

    return r;
}
コード例 #2
0
    int controller_imp::find_in_end_station(struct jdksavdecc_eui64 &other_entity_id, const uint8_t *frame)
    {
        struct jdksavdecc_eui64 other_controller_id = jdksavdecc_acmpdu_get_controller_entity_id(frame, ETHER_HDR_SIZE);

        for(uint32_t i = 0; i < end_station_vec.size(); i++)
        {
            struct jdksavdecc_eui64 end_entity_id = end_station_vec.at(i)->get_adp()->get_entity_entity_id();
            struct jdksavdecc_eui64 this_controller_id = end_station_vec.at(i)->get_adp()->get_controller_entity_id();

            if((jdksavdecc_eui64_compare(&end_entity_id, &other_entity_id) == 0) &&
                ((jdksavdecc_eui64_compare(&other_controller_id, &this_controller_id) == 0) ||
                (jdksavdecc_eui64_compare(&other_controller_id, &end_entity_id) == 0)))
            {
                return i;
            }
        }

        return -1;
    }
コード例 #3
0
ファイル: controller_imp.cpp プロジェクト: AVnu/avdecc-lib
int controller_imp::find_in_end_station(struct jdksavdecc_eui64 & other_entity_id, bool isUnsolicited, const uint8_t * frame)
{
    struct jdksavdecc_eui64 other_controller_id = jdksavdecc_acmpdu_get_controller_entity_id(frame, ETHER_HDR_SIZE);

    for (uint32_t i = 0; i < end_station_array->size(); i++)
    {
        struct jdksavdecc_eui64 end_entity_id = end_station_array->at(i)->get_adp()->get_entity_entity_id();
        struct jdksavdecc_eui64 this_controller_id = end_station_array->at(i)->get_adp()->get_controller_entity_id();
        bool entity_id_match = false;
        bool controller_id_match = false;

        if (jdksavdecc_eui64_compare(&end_entity_id, &other_entity_id) == 0)
        {
            entity_id_match = true;
        }

        //Do not try to find the controller_id if it is an unsolicited response
        if (isUnsolicited && entity_id_match)
        {
            return i;
        }
        else
        {
            if (jdksavdecc_eui64_compare(&other_controller_id, &this_controller_id) == 0 ||
                jdksavdecc_eui64_compare(&other_controller_id, &end_entity_id) == 0)
            {
                controller_id_match = true;
            }

            if (entity_id_match && controller_id_match)
            {
                return i;
            }
        }
    }

    return -1;
}
コード例 #4
0
ファイル: controller_imp.cpp プロジェクト: AVnu/avdecc-lib
void controller_imp::rx_packet_event(void *& notification_id,
                                     bool & is_notification_id_valid,
                                     const uint8_t * frame,
                                     size_t frame_len,
                                     int & status,
                                     uint16_t & operation_id,
                                     bool & is_operation_id_valid)
{
    uint64_t dest_mac_addr;
    utility::convert_eui48_to_uint64(frame, dest_mac_addr);
    is_operation_id_valid = false;

    if ((dest_mac_addr == net_interface_ref->mac_addr()) || (dest_mac_addr & UINT64_C(0x010000000000))) // Process if the packet dest is our MAC address or a multicast address
    {
        uint8_t subtype = jdksavdecc_common_control_header_get_subtype(frame, ETHER_HDR_SIZE);

        switch (subtype)
        {
        case JDKSAVDECC_SUBTYPE_ADP:
        {
            end_station_imp * end_station = NULL;
            bool found_adp_in_end_station = false;

            jdksavdecc_adpdu adpdu;
            memset(&adpdu, 0, sizeof(adpdu));
            jdksavdecc_adpdu_read(&adpdu, frame, ETHER_HDR_SIZE, frame_len);

            status = AVDECC_LIB_STATUS_INVALID;
            is_notification_id_valid = false;

            if ((adpdu.entity_capabilities & JDKSAVDECC_ADP_ENTITY_CAPABILITY_GENERAL_CONTROLLER_IGNORE) ||
                (adpdu.entity_capabilities & JDKSAVDECC_ADP_ENTITY_CAPABILITY_ENTITY_NOT_READY))
            {
                // The entity indicates that we should not enumerate it
                break;
            }

            if ((m_entity_capabilities_flags & adpdu.entity_capabilities) != m_entity_capabilities_flags ||
                (m_talker_capabilities_flags & adpdu.talker_capabilities) != m_talker_capabilities_flags ||
                (m_listener_capabilities_flags & adpdu.listener_capabilities) != m_listener_capabilities_flags)
            {
                //The entity has been filtered out by the user set exclusion flags
                break;
            }

            /**
             * Check if an ADP object is already in the system. If not, create a new End Station object storing the ADPDU information
             * and add the End Station object to the system.
             */
            for (uint32_t i = 0; i < end_station_array->size(); i++)
            {
                struct jdksavdecc_eui64 end_entity_id = end_station_array->at(i)->get_adp()->get_entity_entity_id();
                if (jdksavdecc_eui64_compare(&end_entity_id, &adpdu.header.entity_id) == 0)
                {
                    found_adp_in_end_station = true;
                    end_station = end_station_array->at(i);
                }
            }

            if (jdksavdecc_eui64_convert_to_uint64(&adpdu.header.entity_id) != 0)
            {
                if (!found_adp_in_end_station)
                {
                    if (adp_discovery_state_machine_ref)
                        adp_discovery_state_machine_ref->state_avail(frame, frame_len);
                    end_station_array->push_back(new end_station_imp(frame, frame_len));
                    end_station_array->at(end_station_array->size() - 1)->set_connected();
                }
                else
                {
                    if ((adpdu.available_index < end_station->get_adp()->get_available_index()) ||
                        (jdksavdecc_eui64_convert_to_uint64(&adpdu.entity_model_id) != end_station->get_adp()->get_entity_model_id()))
                    {
                        log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "Re-enumerating end station with entity_id %ull", end_station->entity_id());
                        end_station->end_station_reenumerate();
                    }

                    end_station->get_adp()->proc_adpdu(frame, frame_len);

                    if (end_station->get_connection_status() == 'D')
                    {
                        end_station->set_connected();
                        if (adp_discovery_state_machine_ref)
                            adp_discovery_state_machine_ref->state_avail(frame, frame_len);
                    }
                    else
                    {
                        if (adp_discovery_state_machine_ref)
                            adp_discovery_state_machine_ref->state_avail(frame, frame_len);
                    }
                }
            }
            else if (adpdu.header.message_type != JDKSAVDECC_ADP_MESSAGE_TYPE_ENTITY_DISCOVER)
            {
                log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "Invalid ADP packet with an entity ID of 0.");
            }
        }
        break;

        case JDKSAVDECC_SUBTYPE_AECP:
        {
            int found_end_station_index = -1;
            uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ETHER_HDR_SIZE);
            struct jdksavdecc_eui64 entity_entity_id = jdksavdecc_common_control_header_get_stream_id(frame, ETHER_HDR_SIZE);
            uint16_t cmd_type = jdksavdecc_aecpdu_aem_get_command_type(frame, ETHER_HDR_SIZE);
            bool isUnsolicited = cmd_type >> 15 & 0x01;

            /* check dest mac address is ours */
            if (dest_mac_addr == net_interface_ref->mac_addr())
            {
                if (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_COMMAND &&
                    cmd_type == JDKSAVDECC_AEM_COMMAND_CONTROLLER_AVAILABLE)
                {
                    send_controller_avail_response(frame, frame_len);
                }
                else
                {
                    /**
                     * Check if an AECP object is already in the system. If yes, process response for the AECP packet.
                     */
                    found_end_station_index = find_in_end_station(entity_entity_id, isUnsolicited, frame);
                    if (found_end_station_index >= 0)
                    {
                        switch (msg_type)
                        {

                        case JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_RESPONSE:
                        {
                            end_station_array->at(found_end_station_index)->proc_rcvd_aem_resp(notification_id, frame, frame_len, status, operation_id, is_operation_id_valid);

                            is_notification_id_valid = true;
                            break;
                        }
                        case JDKSAVDECC_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE:
                        {
                            end_station_array->at(found_end_station_index)->proc_rcvd_aecp_aa_resp(notification_id, frame, frame_len, status);

                            is_notification_id_valid = true;
                            break;
                        }
                        }
                    }
                    else
                    {
                        status = AVDECC_LIB_STATUS_INVALID;
                    }
                }
            }
        }
        break;

        case JDKSAVDECC_SUBTYPE_ACMP:
        {
            int found_end_station_index = -1;
            bool found_acmp_in_end_station = false;
            struct jdksavdecc_eui64 entity_entity_id;
            uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ETHER_HDR_SIZE);

            if ((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) ||
                (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE))
            {
                entity_entity_id = jdksavdecc_acmpdu_get_talker_entity_id(frame, ETHER_HDR_SIZE);
            }
            else if ((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE) ||
                     (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE) ||
                     (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE))
            {
                entity_entity_id = jdksavdecc_acmpdu_get_listener_entity_id(frame, ETHER_HDR_SIZE);
            }

            found_end_station_index = find_in_end_station(entity_entity_id, false, frame);
            if (found_end_station_index >= 0)
                found_acmp_in_end_station = true;

            if (found_acmp_in_end_station)
            {
                end_station_array->at(found_end_station_index)->proc_rcvd_acmp_resp(msg_type, notification_id, frame, frame_len, status);
                is_notification_id_valid = true;
            }
            else
            {
                log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "Wait for correct ACMP response packet.");
                status = AVDECC_LIB_STATUS_INVALID;
            }
        }
        break;

        default:
            break;
        }
    }
コード例 #5
0
ファイル: Eui.hpp プロジェクト: jdkoftinoff/jdksavdecc-mcu
inline bool operator!=( const jdksavdecc_eui64 &lhs, const jdksavdecc_eui64 &rhs )
{
    return jdksavdecc_eui64_compare( &lhs, &rhs ) != 0;
}
コード例 #6
0
ファイル: Eui.hpp プロジェクト: jdkoftinoff/jdksavdecc-mcu
 ///
 /// \brief compare Numeric compare with other Eui64
 /// \param other jdksavdecc_eui64 reference to compare to
 /// \return -1 if less than other, 0 if equal to other, 1 if greater than
 /// other
 ///
 int compare( const Eui64 &other ) const {
     return jdksavdecc_eui64_compare( this, &other );
 }