bool inflight_conference_command_exist(void) { inflight_plist guard = command_send_guard; inflight_plist inflight_station = NULL; bool found = false; for (inflight_station = guard->next; inflight_station != guard; inflight_station = inflight_station->next) { uint8_t data_type = inflight_station->host_tx.inflight_frame.data_type; if (data_type == JDKSAVDECC_SUBTYPE_AECP) { if (inflight_station->host_tx.inflight_frame.frame != NULL) { uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(inflight_station->host_tx.inflight_frame.frame, ZERO_OFFSET_IN_PAYLOAD); if (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND|| (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE)) { found = true; break; } } } } return found; }
int acmp_controller_state_machine::tx_cmd(void *notification_id, uint32_t notification_flag, struct jdksavdecc_frame *cmd_frame, bool resend) { int send_frame_returned; if(!resend) { uint16_t this_seq_id = acmp_seq_id; uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(cmd_frame->payload, ETHER_HDR_SIZE); uint32_t timeout_ms = utility->acmp_cmd_to_timeout(msg_type); // ACMP command timeout lookup jdksavdecc_acmpdu_set_sequence_id(acmp_seq_id++, cmd_frame->payload, ETHER_HDR_SIZE); inflight in_flight = inflight(cmd_frame, this_seq_id, notification_id, notification_flag, timeout_ms); in_flight.start_timer(); inflight_cmds.push_back(in_flight); } else { uint16_t resend_with_seq_id = jdksavdecc_acmpdu_get_sequence_id(cmd_frame->payload, ETHER_HDR_SIZE); std::vector<inflight>::iterator j = std::find_if(inflight_cmds.begin(), inflight_cmds.end(), SeqIdComp(resend_with_seq_id)); if(j != inflight_cmds.end()) // found? { (*j).start_timer(); } } send_frame_returned = net_interface_ref->send_frame(cmd_frame->payload, cmd_frame->length); if(send_frame_returned < 0) { log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "netif_send_frame error"); assert(send_frame_returned >= 0); } callback(notification_id, notification_flag, cmd_frame->payload); return 0; }
ssize_t jdksavdecc_common_control_header_read( struct jdksavdecc_common_control_header *p, void const *base, ssize_t pos, size_t len ) { ssize_t r = jdksavdecc_validate_range( pos, len, JDKSAVDECC_COMMON_CONTROL_HEADER_LEN ); if ( r >= 0 ) { p->cd = jdksavdecc_common_control_header_get_cd( base, pos ); p->subtype = jdksavdecc_common_control_header_get_subtype( base, pos ); p->sv = jdksavdecc_common_control_header_get_sv( base, pos ); p->version = jdksavdecc_common_control_header_get_version( base, pos ); p->control_data = jdksavdecc_common_control_header_get_control_data( base, pos ); p->status = jdksavdecc_common_control_header_get_status( base, pos ); p->control_data_length = jdksavdecc_common_control_header_get_control_data_length( base, pos ); p->stream_id = jdksavdecc_common_control_header_get_stream_id( base, pos ); } return r; }
void acmp_controller_state_machine::state_timeout(uint32_t inflight_cmd_index) { struct jdksavdecc_frame frame = inflight_cmds.at(inflight_cmd_index).frame(); bool is_retried = inflight_cmds.at(inflight_cmd_index).retried(); if(is_retried) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id(frame.payload, ETHER_HDR_SIZE); uint64_t end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame.payload, ETHER_HDR_SIZE); notification_imp_ref->post_notification_msg(RESPONSE_RECEIVED, end_station_entity_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, UINT_MAX, inflight_cmds.at(inflight_cmd_index).cmd_notification_id); log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "Command Timeout, 0x%llx, %s, %s, %s, %d", end_station_entity_id, utility->acmp_cmd_value_to_name(msg_type), "NULL", "NULL", inflight_cmds.at(inflight_cmd_index).cmd_seq_id); inflight_cmds.erase(inflight_cmds.begin() + inflight_cmd_index); } else { log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "Resend the command with sequence id = %d", inflight_cmds.at(inflight_cmd_index).cmd_seq_id); tx_cmd(inflight_cmds.at(inflight_cmd_index).cmd_notification_id, inflight_cmds.at(inflight_cmd_index).notification_flag(), &frame, true); } }
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; } }
int rx_raw_packet_event( const uint8_t dst_mac[6], const uint8_t src_mac[6], bool *is_notification_id_valid, solid_pdblist list_hdr, const uint8_t *frame, size_t frame_len, int *status, uint16_t operation_id, bool is_operation_id_valid ) { uint8_t subtype = jdksavdecc_common_control_header_get_subtype( frame, ZERO_OFFSET_IN_PAYLOAD ); solid_pdblist guard = list_hdr; switch( subtype ) { case JDKSAVDECC_SUBTYPE_ADP: { solid_pdblist end_station = NULL; uint64_t current_endpoint_id = 0; // 当前接收数据包的终端ID uint64_t end_entity_id = 0; // 存在于链表中的终端ID bool found_adp_in_end_station = false; struct jdksavdecc_adpdu adpdu; memset(&adpdu,0,sizeof(adpdu) ); jdksavdecc_adpdu_read( &adpdu, frame, 0, frame_len ); convert_eui64_to_uint64( adpdu.header.entity_id.value, ¤t_endpoint_id ); int list_len = get_endpoint_dblist_length( guard ); if ((adpdu.entity_capabilities & JDKSAVDECC_ADP_ENTITY_CAPABILITY_GENERAL_CONTROLLER_IGNORE) || (adpdu.entity_capabilities & JDKSAVDECC_ADP_ENTITY_CAPABILITY_ENTITY_NOT_READY)) { break; } if( NULL != guard ) { int i = 0; for( i = 0; i < list_len; i++) {// 查看系统是否存在此adp if(get_entity_id_endpoint_dblist( guard, i, &end_entity_id ) == 1 ) { if( end_entity_id == current_endpoint_id ) // 终端已存在于系统 { found_adp_in_end_station = true; end_station = search_endtity_node_endpoint_dblist(guard, end_entity_id ); break; } } } } else { DEBUG_INFO("invalid system list!"); break; } if(jdksavdecc_eui64_convert_to_uint64(&adpdu.header.entity_id) != 0) { if(!found_adp_in_end_station) // 终端不在系统中,加入系统 { end_station = adp_proccess_new_entity(guard, &end_station, &adpdu, list_len); if ((NULL != end_station) && (end_station->solid.connect_flag == CONNECT)) { DEBUG_ONINFO("[END_STATION CONNECT: 0x016%llx]", end_station->solid.entity_id); } } else// 终端在系统中 { // 终端已在系统中,只是available_index不同 if ((adpdu.available_index < (get_available_index_endpoint_dblist_node( end_station ))) ||\ ( jdksavdecc_eui64_convert_to_uint64(&adpdu.entity_model_id) != jdksavdecc_eui64_convert_to_uint64(get_entity_model_id_endpoint_dblist_node( end_station )))) { DEBUG_INFO("LOGGING_LEVEL_DEBUG:Re-enumerating end station with entity_id %llx", end_entity_id); // 重新枚举 /*找到id 并清除其内容而不free其节点*/ desc_pdblist descptor_info = NULL; descptor_info = search_desc_dblist_node(end_entity_id, descptor_guard ); if( NULL != descptor_info ) { memset(&descptor_info->endpoint_desc, 0, sizeof(struct endpoint_decriptor)); memcpy(descptor_info->endpoint_desc.firmware_version.value, "UNKNOWN", sizeof(struct jdksavdecc_string)); memcpy(descptor_info->endpoint_desc.entity_name.value, "UNKNOWN", sizeof(struct jdksavdecc_string)); descptor_info->endpoint_desc.entity_id = end_entity_id; central_control_recieve_uinit_free_connect_node(end_entity_id); central_control_transmit_unit_model_destroy_output(end_entity_id); } aecp_read_desc_init( JDKSAVDECC_DESCRIPTOR_ENTITY, 0, end_station->solid.entity_id); } // 更新adp数据包为最新的内容 update_entity_adpdu_endpoint_dblist( &adpdu, end_station ); // 设置终端的连接状态与更新终端的可用时间,即超时时间。因为终端存在系统的时间永远是最新的 // 原因:终端掉线但其ID的结构体节点不会被删除,重连时只需简单设置连接状态与最新状态 if( end_station->solid.connect_flag == DISCONNECT ) { end_station->solid.connect_flag = CONNECT; adp_entity_state_avail( guard, end_station, &adpdu.header ); DEBUG_ONINFO("[ END_STATION AFLESH CONNECT: 0x016%llx ] ", end_station->solid.entity_id ); } else// 更新终端的可用时间,即超时时间。因为终端存在系统的时间永远是最新的 { adp_entity_state_avail( guard, end_station, &adpdu.header ); } } } else if (adpdu.header.message_type != JDKSAVDECC_ADP_MESSAGE_TYPE_ENTITY_DISCOVER) { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_ERROR, "[ Invalid ADP packet with an entity ID of 0. ]"); } //*status = 0; } break; case JDKSAVDECC_SUBTYPE_ACMP: { bool found_acmp_in_end_station = false; struct jdksavdecc_eui64 entity_entity_id; uint64_t entity_id = 0; bzero( &entity_entity_id, sizeof(entity_entity_id) ); uint32_t msg_type = jdksavdecc_common_control_header_get_control_data( frame, 0 ); int list_len = get_endpoint_dblist_length( guard ); 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, ZERO_OFFSET_IN_PAYLOAD ); } 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, ZERO_OFFSET_IN_PAYLOAD ); } // listerner 在系统中 if( NULL != guard && (convert_eui64_to_uint64_return(entity_entity_id.value) != 0) ) { int i = 0; for( i = 0; i < list_len; i++) { if(get_entity_id_endpoint_dblist( guard, i, &entity_id ) == 1 ) { if( entity_id == convert_eui64_to_uint64_return(entity_entity_id.value) ) // 终端已存在于系统 { found_acmp_in_end_station = true; break; } } } } if( found_acmp_in_end_station ) { //接收到的处理不同的连接管理命令 proc_rcvd_acmp_resp( msg_type, frame, frame_len, status ); *is_notification_id_valid = true; } else { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, "LOGGING_LEVEL_DEBUG:Wait for correct ACMP response packet."); *status = AVDECC_LIB_STATUS_INVALID; } } break; case JDKSAVDECC_SUBTYPE_AECP: { uint32_t msg_type = jdksavdecc_common_control_header_get_control_data( frame, ZERO_OFFSET_IN_PAYLOAD ); struct jdksavdecc_eui64 entity_entity_id = jdksavdecc_common_control_header_get_stream_id( frame, ZERO_OFFSET_IN_PAYLOAD ); uint16_t cmd_type = jdksavdecc_aecpdu_aem_get_command_type( frame, ZERO_OFFSET_IN_PAYLOAD ); int list_len = get_endpoint_dblist_length( guard ); bool found_aecp_in_end_station = false; uint64_t entity_id; if( NULL != guard ) { int i = 0; for( i = 0; i < list_len; i++) { if(get_entity_id_endpoint_dblist( guard, i, &entity_id ) == 1 ) { if( entity_id == convert_eui64_to_uint64_return(entity_entity_id.value) ) // 终端已存在于系统 { found_aecp_in_end_station = true; break; } } } } else { DEBUG_INFO("invalid system list!"); break; } // 主机与终端的协议号,在1722中未被使用,此时命令类型即为会议系统协议数据负载的长度,包括备份的协议数据长度 if( ( msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND ) ) { if( found_aecp_in_end_station ) proc_aecp_message_type_vendor_unique_command_conference( frame, frame_len, status ); } else { /* check dest mac address is ours */ if ( is_mac_equal( dst_mac, net.m_my_mac)) { if (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_COMMAND && cmd_type == JDKSAVDECC_AEM_COMMAND_CONTROLLER_AVAILABLE)//这里只处理了这个命令类型 { send_controller_avail_response( frame, frame_len, src_mac, dst_mac ); } else { if ( found_aecp_in_end_station ) { switch(msg_type) { case JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_RESPONSE:// 控制命令是AEM_RESPONSE { proc_rcvd_aem_resp( frame, frame_len, status ); *is_notification_id_valid = true; break; } case JDKSAVDECC_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE:// 控制命令是ADDRESS_ACCESS_RESPONSE { proc_rcvd_aecp_aa_resp( frame, frame_len, status); *is_notification_id_valid = true; break; } } } else { *status = AVDECC_LIB_STATUS_INVALID; } } } } } break; default: break; } return 0; }
int aecp_controller_state_machine::callback(void *notification_id, uint32_t notification_flag, uint8_t *frame) { uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ETHER_HDR_SIZE); uint16_t cmd_type = jdksavdecc_aecpdu_aem_get_command_type(frame, ETHER_HDR_SIZE); cmd_type &= 0x7FFF; uint32_t status = jdksavdecc_common_control_header_get_status(frame, ETHER_HDR_SIZE); uint16_t desc_type = 0; uint16_t desc_index = 0; switch(cmd_type) { case JDKSAVDECC_AEM_COMMAND_ACQUIRE_ENTITY: desc_type = jdksavdecc_aem_command_acquire_entity_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_acquire_entity_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_LOCK_ENTITY: desc_type = jdksavdecc_aem_command_lock_entity_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_lock_entity_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_ENTITY_AVAILABLE: break; case JDKSAVDECC_AEM_COMMAND_CONTROLLER_AVAILABLE: break; case JDKSAVDECC_AEM_COMMAND_READ_DESCRIPTOR: desc_type = jdksavdecc_aem_command_read_descriptor_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_read_descriptor_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_SET_STREAM_FORMAT: desc_type = jdksavdecc_aem_command_set_stream_format_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_set_stream_format_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_STREAM_FORMAT: desc_type = jdksavdecc_aem_command_get_stream_format_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_stream_format_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_SET_STREAM_INFO: desc_type = jdksavdecc_aem_command_set_stream_info_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_set_stream_info_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_STREAM_INFO: desc_type = jdksavdecc_aem_command_get_stream_info_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_stream_info_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_SET_NAME: desc_type = jdksavdecc_aem_command_set_name_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_set_name_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_NAME: desc_type = jdksavdecc_aem_command_get_name_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_name_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_SET_SAMPLING_RATE: desc_type = jdksavdecc_aem_command_set_sampling_rate_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_set_sampling_rate_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_SAMPLING_RATE: desc_type = jdksavdecc_aem_command_get_sampling_rate_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_sampling_rate_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_SET_CLOCK_SOURCE: desc_type = jdksavdecc_aem_command_set_clock_source_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_set_clock_source_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_CLOCK_SOURCE: desc_type = jdksavdecc_aem_command_get_clock_source_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_clock_source_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_START_STREAMING: desc_type = jdksavdecc_aem_command_start_streaming_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_start_streaming_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_STOP_STREAMING: desc_type = jdksavdecc_aem_command_stop_streaming_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_stop_streaming_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_GET_COUNTERS: desc_type = jdksavdecc_aem_command_get_counters_response_get_descriptor_type(frame, ETHER_HDR_SIZE); desc_index = jdksavdecc_aem_command_get_counters_response_get_descriptor_index(frame, ETHER_HDR_SIZE); break; case JDKSAVDECC_AEM_COMMAND_REGISTER_UNSOLICITED_NOTIFICATION: break; default: log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "NO_MATCH_FOUND for %s", utility::aem_cmd_value_to_name(cmd_type)); break; } jdksavdecc_eui64 id = jdksavdecc_common_control_header_get_stream_id(frame, ETHER_HDR_SIZE); if((notification_flag == CMD_WITH_NOTIFICATION) && ((msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_RESPONSE) || (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE))) { notification_imp_ref->post_notification_msg(RESPONSE_RECEIVED, jdksavdecc_uint64_get(&id, 0), cmd_type, desc_type, desc_index, status, notification_id); if(status != AEM_STATUS_SUCCESS) { log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %d, %d, %s", jdksavdecc_uint64_get(&id, 0), utility::aem_cmd_value_to_name(cmd_type), utility::aem_desc_value_to_name(desc_type), desc_index, jdksavdecc_aecpdu_common_get_sequence_id(frame, ETHER_HDR_SIZE), utility::aem_cmd_status_value_to_name(status)); } } else if(((notification_flag == CMD_WITH_NOTIFICATION) || (notification_flag == CMD_WITHOUT_NOTIFICATION)) && ((msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_COMMAND) || (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_COMMAND))) { log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "COMMAND_SENT, 0x%llx, %s, %s, %d, %d", jdksavdecc_uint64_get(&id, 0), utility::aem_cmd_value_to_name(cmd_type), utility::aem_desc_value_to_name(desc_type), desc_index, jdksavdecc_aecpdu_common_get_sequence_id(frame, ETHER_HDR_SIZE)); } else if((notification_flag == CMD_WITHOUT_NOTIFICATION) && ((msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_RESPONSE) || (msg_type == JDKSAVDECC_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE))) { if(status == AEM_STATUS_SUCCESS) { log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %d, %d, %s", jdksavdecc_uint64_get(&id, 0), utility::aem_cmd_value_to_name(cmd_type), utility::aem_desc_value_to_name(desc_type), desc_index, jdksavdecc_aecpdu_common_get_sequence_id(frame, ETHER_HDR_SIZE), utility::aem_cmd_status_value_to_name(status)); } else { log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %d, %d, %s", jdksavdecc_uint64_get(&id, 0), utility::aem_cmd_value_to_name(cmd_type), utility::aem_desc_value_to_name(desc_type), desc_index, jdksavdecc_aecpdu_common_get_sequence_id(frame, ETHER_HDR_SIZE), utility::aem_cmd_status_value_to_name(status)); } } return 0; }
void jdksavdecc_pdu_print( struct jdksavdecc_printer *self, const uint8_t *p, size_t len, int dump_payload ) { if ( len > 12 ) { int cd = jdksavdecc_common_control_header_get_cd( p, 0 ); uint8_t version = (uint8_t)jdksavdecc_common_control_header_get_version( p, 0 ); jdksavdecc_printer_print_label( self, "version" ); jdksavdecc_printer_print_uint8( self, version ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "cd and subtype" ); jdksavdecc_printer_print_uint16_name( self, jdksavdecc_pdu_print_cd_subtype, p[0] ); jdksavdecc_printer_print_eol( self ); if ( version == 0 ) { jdksavdecc_printer_print_label( self, "sv" ); if ( jdksavdecc_common_control_header_get_sv( p, 0 ) ) { jdksavdecc_printer_print( self, "valid" ); } else { jdksavdecc_printer_print( self, "not valid" ); } jdksavdecc_printer_print_eol( self ); if ( cd == 0 ) // version 0 stream data { jdksavdecc_printer_print_label( self, "mr" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_stream_header_get_mr( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "gv" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_stream_header_get_gv( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "tv" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_stream_header_get_tv( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "sequence_num" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_stream_header_get_sequence_num( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "tu" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_stream_header_get_tu( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "stream_id" ); jdksavdecc_printer_print_streamid( self, jdksavdecc_common_stream_header_get_stream_id( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "avtp_timestamp" ); jdksavdecc_printer_print_uint32( self, jdksavdecc_common_stream_header_get_avtp_timestamp( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "gateway_info" ); jdksavdecc_printer_print_uint32( self, jdksavdecc_common_stream_header_get_gateway_info( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "stream_data_length" ); jdksavdecc_printer_print_uint16( self, jdksavdecc_common_stream_header_get_stream_data_length( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "protocol_specific_header" ); jdksavdecc_printer_print_uint16( self, jdksavdecc_common_stream_header_get_protocol_specific_header( p, 0 ) ); jdksavdecc_printer_print_eol( self ); if ( dump_payload && len > JDKSAVDECC_COMMON_STREAM_HEADER_LEN ) { jdksavdecc_printer_print_label( self, "stream_data_payload" ); jdksavdecc_printer_print_block( self, p, len, JDKSAVDECC_COMMON_STREAM_HEADER_LEN, len ); } } else // version 0 control data { jdksavdecc_printer_print_label( self, "control_data" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_control_header_get_control_data( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "status" ); jdksavdecc_printer_print_uint8( self, (uint8_t)jdksavdecc_common_control_header_get_status( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "control_data_length" ); jdksavdecc_printer_print_uint16( self, (uint16_t)jdksavdecc_common_control_header_get_control_data_length( p, 0 ) ); jdksavdecc_printer_print_eol( self ); jdksavdecc_printer_print_label( self, "stream_id" ); jdksavdecc_printer_print_streamid( self, jdksavdecc_common_control_header_get_stream_id( p, 0 ) ); jdksavdecc_printer_print_eol( self ); } if ( dump_payload && len > JDKSAVDECC_COMMON_CONTROL_HEADER_LEN ) { jdksavdecc_printer_print_label( self, "payload" ); jdksavdecc_printer_print_block( self, p, len, JDKSAVDECC_COMMON_CONTROL_HEADER_LEN, len ); } } } }
int acmp_callback( uint32_t notification_flag, uint8_t *frame, uint16_t frame_len ) { uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ZERO_OFFSET_IN_PAYLOAD); uint16_t seq_id = jdksavdecc_acmpdu_get_sequence_id(frame, ZERO_OFFSET_IN_PAYLOAD); uint32_t status = jdksavdecc_common_control_header_get_status(frame, ZERO_OFFSET_IN_PAYLOAD); uint64_t end_station_entity_id; struct jdksavdecc_eui64 stream_entity_station = jdksavdecc_common_control_header_get_stream_id( frame, ZERO_OFFSET_IN_PAYLOAD ); uint64_t end_stream_id = jdksavdecc_uint64_get(&stream_entity_station, 0); subject_data_elem elem; // acmp info struct jdksavdecc_acmpdu node_acmpdu; jdksavdecc_acmpdu_read( &node_acmpdu, frame, ZERO_OFFSET_IN_PAYLOAD, frame_len ); if((notification_flag == CMD_WITH_NOTIFICATION) && ((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) || (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE))) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_talker_entity_id(frame, ZERO_OFFSET_IN_PAYLOAD); struct jdksavdecc_eui64 listener_entity = jdksavdecc_acmpdu_get_listener_entity_id(frame, ZERO_OFFSET_IN_PAYLOAD); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); uint64_t listener_id = jdksavdecc_uint64_get(&listener_entity, 0); if (status == ACMP_STATUS_SUCCESS) { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, " [ RESPONSE_RECEIVED: %d 0x%016llx (talker), %d, %d, %d, %s ]", RESPONSE_RECEIVED, end_station_entity_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, acmp_cmd_status_value_to_name(status)); } else { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_ERROR, "[ RESPONSE_RECEIVED, 0x%016llx (talker), %s, %s, %s, %s, %d ]", end_station_entity_id, acmp_cmd_value_to_name(msg_type), "NULL", "NULL", acmp_cmd_status_value_to_name(status), seq_id ); acmp_recv_resp_err = true; } // add notification of get_tx_state command to obserber if (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) { subject_data_elem elem; elem.listener_id = listener_id; elem.listener_index = node_acmpdu.listener_unique_id; elem.tarker_id = end_stream_id; elem.tarker_index = node_acmpdu.talker_unique_id; elem.ctrl_msg.data_type = JDKSAVDECC_SUBTYPE_ACMP; elem.ctrl_msg.msg_type = msg_type; elem.ctrl_msg.msg_resp_status = status;// -1 means timeout status. elem.data_frame = NULL;// set data frame elem.data_frame_len = 0; set_subject_data( elem, &gconnector_subjector ); notify_observer( &gconnector_subjector ); } } else if((notification_flag == CMD_WITH_NOTIFICATION) && ((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))) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id( frame, ZERO_OFFSET_IN_PAYLOAD ); struct jdksavdecc_eui64 _tarker_id = jdksavdecc_acmpdu_get_talker_entity_id( frame, ZERO_OFFSET_IN_PAYLOAD ); uint64_t tarker_id = jdksavdecc_uint64_get( &_tarker_id, 0 ); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); if( (status == ACMP_STATUS_SUCCESS) &&\ ((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE) || \ (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE)))// udpate system descriptor connect list { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, " [ RESPONSE_RECEIVED: %d 0x%016llx (listener)-0x%016llx(tarker), %d, %d, %d, %s ]", RESPONSE_RECEIVED, end_station_entity_id, tarker_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, acmp_cmd_status_value_to_name(status)); elem.connect_flag = (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE)?true:false; elem.listener_id = end_station_entity_id; elem.listener_index = node_acmpdu.listener_unique_id; elem.tarker_id = tarker_id; elem.tarker_index = node_acmpdu.talker_unique_id; elem.ctrl_msg.data_type = JDKSAVDECC_SUBTYPE_ACMP; elem.ctrl_msg.msg_type = msg_type; elem.ctrl_msg.msg_resp_status = status; elem.data_frame = NULL;// set data frame elem.data_frame_len = 0; set_subject_data( elem, &gconnector_subjector ); notify_observer( &gconnector_subjector ); } else if( (status == ACMP_STATUS_SUCCESS) && \ (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE)) { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, "[ RESPONSE_RECEIVED: %d 0x%016llx (listener), %d, %d, %d, %s ]", RESPONSE_RECEIVED, end_station_entity_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, acmp_cmd_status_value_to_name(status)); elem.listener_id = end_station_entity_id; elem.listener_index = node_acmpdu.listener_unique_id; elem.tarker_id = tarker_id; elem.tarker_index = node_acmpdu.talker_unique_id; elem.ctrl_msg.data_type = JDKSAVDECC_SUBTYPE_ACMP; elem.ctrl_msg.msg_type = msg_type; elem.ctrl_msg.msg_resp_status = status; elem.data_frame = NULL;// set data frame elem.data_frame_len = 0; set_subject_data( elem, &gconnector_subjector ); notify_observer( &gconnector_subjector ); } else if( status != ACMP_STATUS_SUCCESS ) { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_ERROR, "[ 0x%016llx (listener), %s, %s, %s, %s, %d ]", end_station_entity_id, acmp_cmd_value_to_name(msg_type), "NULL", "NULL", acmp_cmd_status_value_to_name(status), seq_id); elem.connect_flag = false; elem.listener_id = end_station_entity_id; elem.listener_index = node_acmpdu.listener_unique_id; elem.tarker_id = tarker_id; elem.tarker_index = node_acmpdu.talker_unique_id; elem.ctrl_msg.data_type = JDKSAVDECC_SUBTYPE_ACMP; elem.ctrl_msg.msg_type = msg_type; elem.ctrl_msg.msg_resp_status = status; elem.data_frame = NULL;// set data frame elem.data_frame_len = 0; set_subject_data( elem, &gconnector_subjector ); notify_observer( &gconnector_subjector ); acmp_recv_resp_err = true; } } else if((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) || (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE)) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_talker_entity_id(frame, ZERO_OFFSET_IN_PAYLOAD); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, "[RESPONSE_RECEIVED, 0x%016llx (talker), %s, %s, %s, %s, %d]", end_station_entity_id, acmp_cmd_value_to_name(msg_type), "NULL", "NULL", acmp_cmd_status_value_to_name(status), seq_id); } else { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id(frame, ZERO_OFFSET_IN_PAYLOAD); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, "[ COMMAND_SENT, 0x%016llx listener, %s, %s, %s, %s, %d ]", end_station_entity_id, acmp_cmd_value_to_name(msg_type), "NULL", "NULL", acmp_cmd_status_value_to_name(status), seq_id ); } return 0; }
void acmp_inflight_station_timeouts( inflight_plist acmp_sta, inflight_plist hdr ) { bool is_retried = false; inflight_plist acmp_pstation = NULL; uint8_t *frame = NULL; uint16_t frame_len = 0; uint32_t interval_time = 0; if( acmp_sta != NULL ) { acmp_pstation = acmp_sta; is_retried = is_inflight_cmds_retried( acmp_pstation ); frame = acmp_pstation->host_tx.inflight_frame.frame; frame_len = acmp_pstation->host_tx.inflight_frame.inflight_frame_len; } else { acmp_machine_debug( "noting to be proccessed by aecp timeout" ); return; } assert( frame && acmp_sta != NULL ); if( is_retried ) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id( frame, ZERO_OFFSET_IN_PAYLOAD ); struct jdksavdecc_eui64 _end_station_tarker_id = jdksavdecc_acmpdu_get_talker_entity_id( frame, ZERO_OFFSET_IN_PAYLOAD ); uint64_t end_station_entity_id = jdksavdecc_uint64_get( &_end_station_entity_id, 0 ); uint64_t tarker_id = jdksavdecc_uint64_get( &_end_station_tarker_id, 0 ); uint32_t msg_type = jdksavdecc_common_control_header_get_control_data( frame, 0 ); if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_ERROR, " [ COMMAND TIMEOUT: 0x%016llx, %s, %s,%d ]", end_station_entity_id, acmp_cmd_value_to_name(msg_type), "NULL", acmp_pstation->host_tx.inflight_frame.seq_id); struct jdksavdecc_acmpdu node_acmpdu; jdksavdecc_acmpdu_read( &node_acmpdu, frame, ZERO_OFFSET_IN_PAYLOAD, frame_len ); subject_data_elem elem; elem.connect_flag = false; elem.listener_id = end_station_entity_id; elem.listener_index = node_acmpdu.listener_unique_id; elem.tarker_id = tarker_id; elem.tarker_index = node_acmpdu.talker_unique_id; elem.ctrl_msg.data_type = JDKSAVDECC_SUBTYPE_ACMP; elem.ctrl_msg.msg_type = msg_type; elem.ctrl_msg.msg_resp_status = -1;// -1 means timeout status. elem.data_frame = NULL;// set data frame elem.data_frame_len = 0; set_subject_data( elem, &gconnector_subjector ); notify_observer( &gconnector_subjector ); // free inflight command node in the system release_heap_space( &acmp_pstation->host_tx.inflight_frame.frame); delect_inflight_dblist_node( &acmp_pstation ); is_inflight_timeout = true; // 设置超时 acmp_machine_debug( "is_inflight_timeout = %d", is_inflight_timeout ); } else { if (NULL != gp_log_imp) gp_log_imp->log.post_log_msg( &gp_log_imp->log, LOGGING_LEVEL_DEBUG, "[ acmp Date resend ]" ); transmit_acmp_packet_network( frame, frame_len, acmp_pstation, true, acmp_pstation->host_tx.inflight_frame.raw_dest.value, false, &interval_time ); } }
ssize_t transmit_acmp_packet_network( uint8_t* frame, uint16_t frame_len, inflight_plist resend_node, bool resend ,const uint8_t dest_mac[6], bool resp, uint32_t *interval_time ) { uint8_t sub_type = jdksavdecc_subtype_data_get_subtype(frame, ZERO_OFFSET_IN_PAYLOAD); uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ZERO_OFFSET_IN_PAYLOAD); uint16_t seq_id = jdksavdecc_acmpdu_get_sequence_id(frame, ZERO_OFFSET_IN_PAYLOAD); inflight_plist inflight_station = NULL; uint32_t timeout = get_acmp_timeout( msg_type ); assert( interval_time ); *interval_time = timeout; if( (frame_len > TRANSMIT_DATA_BUFFER_SIZE) || (frame_len <= 0) ) { acmp_machine_debug( "udp packet( size = %d )bigger than frame buf %d or little!", frame_len,TRANSMIT_DATA_BUFFER_SIZE ); return -1; } if(!resp )// not a response data { if( !resend )// data first send { inflight_station = create_inflight_dblist_new_node( &inflight_station ); if( NULL == inflight_station ) { acmp_machine_debug("inflight station node create failed!"); return -1; } memset(inflight_station, 0, sizeof(inflight_list)); inflight_station->host_tx.inflight_frame.frame = allot_heap_space( frame_len, &inflight_station->host_tx.inflight_frame.frame ); if( NULL != inflight_station->host_tx.inflight_frame.frame ) { memset(inflight_station->host_tx.inflight_frame.frame, 0, frame_len ); inflight_station->host_tx.inflight_frame.inflight_frame_len = frame_len; memcpy( inflight_station->host_tx.inflight_frame.frame, frame, frame_len); inflight_station->host_tx.inflight_frame.data_type = sub_type; //协议 inflight_station->host_tx.inflight_frame.seq_id = seq_id; memcpy(&inflight_station->host_tx.inflight_frame.raw_dest, dest_mac , 6 ); if( (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE ) || ( msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE )) inflight_station->host_tx.inflight_frame.notification_flag = CMD_WITHOUT_NOTIFICATION; else inflight_station->host_tx.inflight_frame.notification_flag = CMD_WITH_NOTIFICATION; inflight_station->host_tx.command_type = TRANSMIT_TYPE_ACMP; inflight_station->host_tx.flags.retried = 1; // meaning send once inflight_station->host_tx.flags.resend = false; inflight_timer_start(timeout, inflight_station ); // 将新建的inflight命令结点插入链表结尾中 if( acmp_inflight_guard != NULL ) insert_inflight_dblist_trail( acmp_inflight_guard, inflight_station ); } else { acmp_machine_debug("Err frame malloc !"); assert( NULL != inflight_station->host_tx.inflight_frame.frame ); if( NULL == inflight_station->host_tx.inflight_frame.frame ) return -1; } } else { acmp_machine_debug( " acmp seq id = %d, subtype = %d", seq_id, sub_type ); if( resend_node != NULL ) //already search it { resend_node->host_tx.flags.resend = true; resend_node->host_tx.flags.retried++ ; inflight_timer_state_avail( timeout, resend_node ); } else { acmp_machine_debug( "nothing to be resend!" ); assert(resend_node != NULL); if( resend_node == NULL ) return -1; } } } // ready to send uint8_t tx_frame[2048] = {0}; uint8_t ethertype[2] = {0x22, 0xf0}; int send_len = frame_len + ETHER_HDR_SIZE; if (send_len <= 2048) { if (dest_mac) { memcpy(tx_frame+0, dest_mac, 6); } else { memcpy(tx_frame+0, net.m_default_dest_mac, 6); } memcpy(tx_frame+6, net.m_my_mac, 6); memcpy(tx_frame+12, ethertype, 2); memcpy(tx_frame + ETHER_HDR_SIZE, frame, frame_len); controller_machine_1722_network_send(gp_controller_machine, tx_frame, send_len); } else send_len = -1; return (ssize_t)send_len; }
int acmp_controller_state_machine::callback(void *notification_id, uint32_t notification_flag, uint8_t *frame) { uint32_t msg_type = jdksavdecc_common_control_header_get_control_data(frame, ETHER_HDR_SIZE); uint16_t seq_id = jdksavdecc_acmpdu_get_sequence_id(frame, ETHER_HDR_SIZE); uint32_t status = jdksavdecc_common_control_header_get_status(frame, ETHER_HDR_SIZE); uint64_t end_station_entity_id; if((notification_flag == CMD_WITH_NOTIFICATION) && ((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) || (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE))) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_talker_entity_id(frame, ETHER_HDR_SIZE); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); notification_imp_ref->post_notification_msg(RESPONSE_RECEIVED, end_station_entity_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, status, notification_id); if(status != ACMP_STATUS_SUCCESS) { log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %s, %s, %d", end_station_entity_id, utility->acmp_cmd_value_to_name(msg_type), "NULL", "NULL", utility->acmp_cmd_status_value_to_name(status), seq_id); } } else if((notification_flag == CMD_WITH_NOTIFICATION) && ((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) || (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE))) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id(frame, ETHER_HDR_SIZE); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); notification_imp_ref->post_notification_msg(RESPONSE_RECEIVED, end_station_entity_id, (uint16_t)msg_type + CMD_LOOKUP, 0, 0, status, notification_id); if(status != ACMP_STATUS_SUCCESS) { log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %s, %s, %d", end_station_entity_id, utility->acmp_cmd_value_to_name(msg_type), "NULL", "NULL", utility->acmp_cmd_status_value_to_name(status), seq_id); } } else if((msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE) || (msg_type == JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE)) { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_talker_entity_id(frame, ETHER_HDR_SIZE); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "RESPONSE_RECEIVED, 0x%llx, %s, %s, %s, %s, %d", end_station_entity_id, utility->acmp_cmd_value_to_name(msg_type), "NULL", "NULL", utility->acmp_cmd_status_value_to_name(status), seq_id); } else { struct jdksavdecc_eui64 _end_station_entity_id = jdksavdecc_acmpdu_get_listener_entity_id(frame, ETHER_HDR_SIZE); end_station_entity_id = jdksavdecc_uint64_get(&_end_station_entity_id, 0); log_imp_ref->post_log_msg(LOGGING_LEVEL_DEBUG, "COMMAND_SENT, 0x%llx, %s, %s, %s, %s, %d", end_station_entity_id, utility->acmp_cmd_value_to_name(msg_type), "NULL", "NULL", utility->acmp_cmd_status_value_to_name(status), seq_id); } return 0; }