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; }
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; }
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; }
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; } }
inline bool operator!=( const jdksavdecc_eui64 &lhs, const jdksavdecc_eui64 &rhs ) { return jdksavdecc_eui64_compare( &lhs, &rhs ) != 0; }
/// /// \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 ); }