///|
pub fn version() -> String {
"0.1.0"
}
///|
pub fn default_dcp_identify_timeout_ms() -> Int {
400
}
///|
pub fn default_dcp_set_get_timeout_ms() -> Int {
1000
}
///|
pub fn default_dcp_set_get_max_retry_limit() -> Int {
2
}
///|
pub fn mandatory_set_usage_time_ms() -> Int {
400
}
///|
pub fn ip_address_change_bumpless() -> Bool {
false
}
///|
pub fn station_name_change_bumpless() -> Bool {
false
}
///|
pub fn recommended_ip_startup_time_ms() -> Int {
30000
}
///|
pub fn mandatory_ip_startup_time_ms() -> Int {
300000
}
///|
pub fn recommended_reset_to_factory_time_ms() -> Int {
30000
}
///|
pub fn mandatory_reset_to_factory_time_ms() -> Int {
300000
}
///|
pub fn recommended_ar_resource_release_timeout_ms() -> Int {
100
}
///|
pub fn mandatory_ar_resource_release_timeout_ms() -> Int {
1000
}
///|
pub fn recommended_autonegotiation_timeout_ms() -> Int {
3000
}
///|
pub fn mandatory_autonegotiation_timeout_ms() -> Int {
30000
}
///|
pub fn minimum_operational_link_speed_mbps() -> Int {
100
}
///|
pub fn required_operational_duplex_mode() -> String {
"full"
}
///|
pub fn diagnosis_link_state_mismatch_code() -> String {
"0x8000"
}
///|
pub fn diagnosis_mau_type_mismatch_code() -> String {
"0x8001"
}
///|
pub fn diagnosis_line_delay_mismatch_code() -> String {
"0x8002"
}
///|
pub fn autonegotiation_fault_requires_link_restart() -> Bool {
true
}
///|
pub fn pd_port_data_real_extended_record_index() -> String {
"0x8027"
}
///|
pub fn pd_port_data_real_record_index() -> String {
"0x802A"
}
///|
pub fn pd_port_data_check_record_index() -> String {
"0x802B"
}
///|
pub fn pd_port_statistic_record_index() -> String {
"0x8072"
}
///|
pub fn pd_interface_mrp_data_real_record_index() -> String {
"0x8050"
}
///|
pub fn pd_port_mrp_data_real_record_index() -> String {
"0x8054"
}
///|
pub fn pd_port_mrplc_data_real_record_index() -> String {
"0x8057"
}
///|
pub fn pd_interface_data_real_record_index() -> String {
"0x8080"
}
///|
pub fn pdev_data_record_index() -> String {
"0xF831"
}
///|
pub fn pd_real_data_record_index() -> String {
"0xF841"
}
///|
pub fn pd_port_data_check_supported_blocks() -> String {
"CheckPeers,CheckLineDelay,CheckMAUType,CheckLinkState,CheckSyncDifference,CheckMAUTypeDifference"
}
///|
pub fn maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound() -> Int {
65536
}
///|
pub fn mandatory_set_storage_time_ms() -> Int {
30000
}
///|
pub fn minimum_logbook_entries() -> Int {
16
}
///|
pub fn lldp_msg_tx_hold() -> Int {
4
}
///|
pub fn lldp_msg_tx_interval_ms() -> Int {
5000
}
///|
pub fn lldp_msg_tx_interval_positive_jitter_ms() -> Int {
1000
}
///|
pub fn lldp_tx_ttl_ms() -> Int {
21000
}
///|
pub fn lldp_tx_ttl_positive_jitter_ms() -> Int {
2000
}
///|
pub fn lldp_tx_now_on_change() -> Bool {
true
}
///|
pub fn lldp_minimum_neighbor_capacity() -> Int {
1
}
///|
pub fn lldp_recommended_neighbor_capacity() -> Int {
4
}
///|
pub fn pruning_mac_destination_support_recommended() -> Bool {
true
}
///|
pub fn lldp_system_capabilities_station_only_required() -> Bool {
true
}
///|
pub fn minimum_arp_cache_size() -> Int {
32
}
///|
pub fn arp_cache_timeout_ms() -> Int {
60000
}
///|
pub fn arp_response_timeout_ms() -> Int {
2000
}
///|
pub fn dns_request_timeout_ms() -> Int {
16000
}
///|
pub fn reject_dcp_set_requests_support() -> String {
"optional"
}
///|
pub fn snmp_service_optional() -> Bool {
true
}
///|
pub fn snmp_default_access_disabled() -> Bool {
true
}
///|
pub fn dhcp_service_optional() -> Bool {
true
}
///|
pub fn dhcp_subnet_mask_option_required() -> Bool {
true
}
///|
pub fn dhcp_gateway_option_required() -> Bool {
true
}
///|
pub fn dhcp_parameter_data_required_value() -> Int {
2
}
///|
pub fn dhcp_other_options_optional() -> Bool {
true
}
///|
pub fn snmp_explicit_enable_required() -> Bool {
true
}
///|
pub fn snmp_disabled_after_ar_abort() -> Bool {
true
}
///|
pub fn snmp_cim_interface_overrides_ar() -> Bool {
true
}
///|
pub fn snmp_community_public_access() -> String {
"read_only"
}
///|
pub fn snmp_community_private_access() -> String {
"read_write"
}
///|
pub fn recommended_snmp_set_timeout_ms() -> Int {
3000
}
///|
pub fn mandatory_snmp_set_timeout_ms() -> Int {
10000
}
///|
pub fn recommended_snmp_get_timeout_ms() -> Int {
3000
}
///|
pub fn mandatory_snmp_get_timeout_ms() -> Int {
10000
}
///|
pub fn recommended_snmp_get_next_timeout_ms() -> Int {
3000
}
///|
pub fn mandatory_snmp_get_next_timeout_ms() -> Int {
10000
}
///|
pub fn recommended_snmp_mib_update_time_ms() -> Int {
500
}
///|
pub fn mandatory_snmp_mib_update_time_ms() -> Int {
3000
}
///|
pub fn snmp_feature_mib2_required() -> Bool {
true
}
///|
pub fn snmp_feature_lldp_mib_required() -> Bool {
true
}
///|
pub fn snmp_feature_ieee_8021as_mib_optional() -> Bool {
true
}
///|
pub fn snmp_feature_bridge_mib_optional() -> Bool {
true
}
///|
pub fn snmp_feature_pno_mib_optional() -> Bool {
true
}
///|
pub fn set_usage_time_probeability() -> String {
"active_dcp_poll"
}
///|
pub fn set_usage_time_probeability_class() -> String {
"automatic_now"
}
///|
pub fn ip_startup_time_probeability() -> String {
"active_dcp_poll"
}
///|
pub fn ip_startup_time_probeability_class() -> String {
"automatic_now"
}
///|
pub fn reset_to_factory_time_probeability() -> String {
"active_reset_poll"
}
///|
pub fn reset_to_factory_time_probeability_class() -> String {
"requires_reset_workflow"
}
///|
pub fn ar_resource_release_time_probeability() -> String {
"ar_session_trace"
}
///|
pub fn ar_resource_release_time_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn autonegotiation_time_probeability() -> String {
"link_state_trace"
}
///|
pub fn autonegotiation_time_probeability_class() -> String {
"requires_link_state_capture"
}
///|
pub fn pd_port_data_real_probeability() -> String {
"record_read_pdportdatareal"
}
///|
pub fn pd_port_data_real_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_interface_data_real_probeability() -> String {
"record_read_pdinterfacedatareal"
}
///|
pub fn pd_interface_data_real_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_interface_mrp_data_real_probeability() -> String {
"record_read_pdinterfacemrpdatareal"
}
///|
pub fn pd_interface_mrp_data_real_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_port_mrp_data_real_probeability() -> String {
"record_read_pdportmrpdatareal"
}
///|
pub fn pd_port_mrp_data_real_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_port_mrplc_data_real_probeability() -> String {
"record_read_pdportmrplcdatareal"
}
///|
pub fn pd_port_mrplc_data_real_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pdev_data_probeability() -> String {
"record_read_pdevdata"
}
///|
pub fn pdev_data_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_real_data_probeability() -> String {
"record_read_pdrealdata"
}
///|
pub fn pd_real_data_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn pd_port_statistic_probeability() -> String {
"record_read_pdportstatistic"
}
///|
pub fn pd_port_statistic_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn lldp_neighbor_probeability() -> String {
"passive_lldp_capture"
}
///|
pub fn lldp_neighbor_probeability_class() -> String {
"requires_packet_capture"
}
///|
pub fn logbook_data_probeability() -> String {
"record_read_logbookdata"
}
///|
pub fn logbook_data_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn snmp_default_state_probeability() -> String {
"record_read_cimsnmpreal"
}
///|
pub fn snmp_default_state_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn snmp_timeout_probeability() -> String {
"active_snmp_roundtrip"
}
///|
pub fn snmp_timeout_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn snmp_mib_update_probeability() -> String {
"active_snmp_polling"
}
///|
pub fn snmp_mib_update_probeability_class() -> String {
"requires_protocol_extension"
}
///|
pub fn dhcp_option_support_probeability() -> String {
"startup_trace_or_vendor_record"
}
///|
pub fn dhcp_option_support_probeability_class() -> String {
"indirect_or_vendor_specific"
}
///|
pub fn dhcp_runtime_state_probeability() -> String {
"indirect_ip_observation"
}
///|
pub fn dhcp_runtime_state_probeability_class() -> String {
"indirect_only"
}
///|
pub fn encode_dcp_identify_request(
source_mac : StringView,
destination_mac? : StringView = "01:0E:CF:00:00:00",
xid? : Int = 16909060,
) -> Bytes raise @frame.FrameError {
let request = @dcp.IdentifyRequest::{
destination: @frame.MacAddress::from_hex(destination_mac),
source: @frame.MacAddress::from_hex(source_mac),
xid,
}
@dcp.encode_identify_request(request)
}
///|
pub fn encode_dcp_identify_request_hex(
source_mac : StringView,
destination_mac? : StringView = "01:0E:CF:00:00:00",
xid? : Int = 16909060,
) -> String raise @frame.FrameError {
@frame.bytes_to_hex(
encode_dcp_identify_request(source_mac, destination_mac~, xid~),
)
}
///|
pub fn encode_dcp_get_request(
source_mac : StringView,
destination_mac : StringView,
selectors? : StringView = "all",
xid? : Int = 16909060,
) -> Bytes raise @frame.FrameError {
@dcp.encode_get_request(@dcp.GetRequest::{
destination: @frame.MacAddress::from_hex(destination_mac),
source: @frame.MacAddress::from_hex(source_mac),
xid,
blocks: @dcp.parse_get_request_blocks(selectors),
})
}
///|
pub fn encode_dcp_get_request_hex(
source_mac : StringView,
destination_mac : StringView,
selectors? : StringView = "all",
xid? : Int = 16909060,
) -> String raise @frame.FrameError {
@frame.bytes_to_hex(
encode_dcp_get_request(source_mac, destination_mac, selectors~, xid~),
)
}
///|
pub fn encode_dcp_set_name_request(
source_mac : StringView,
destination_mac : StringView,
station_name : String,
xid? : Int = 16909060,
is_persistent? : Bool = false,
) -> Bytes raise @frame.FrameError {
@dcp.encode_set_name_request(
@frame.MacAddress::from_hex(destination_mac),
@frame.MacAddress::from_hex(source_mac),
xid,
station_name,
is_persistent~,
)
}
///|
pub fn encode_dcp_set_name_request_hex(
source_mac : StringView,
destination_mac : StringView,
station_name : String,
xid? : Int = 16909060,
is_persistent? : Bool = false,
) -> String raise @frame.FrameError {
@frame.bytes_to_hex(
encode_dcp_set_name_request(
source_mac,
destination_mac,
station_name,
xid~,
is_persistent~,
),
)
}
///|
pub fn encode_dcp_set_ip_request(
source_mac : StringView,
destination_mac : StringView,
address : StringView,
mask : StringView,
gateway : StringView,
xid? : Int = 16909060,
is_persistent? : Bool = false,
) -> Bytes raise @frame.FrameError {
@dcp.encode_set_ip_request(
@frame.MacAddress::from_hex(destination_mac),
@frame.MacAddress::from_hex(source_mac),
xid,
@frame.IPv4Address::from_text(address),
@frame.IPv4Address::from_text(mask),
@frame.IPv4Address::from_text(gateway),
is_persistent~,
)
}
///|
pub fn encode_dcp_set_ip_request_hex(
source_mac : StringView,
destination_mac : StringView,
address : StringView,
mask : StringView,
gateway : StringView,
xid? : Int = 16909060,
is_persistent? : Bool = false,
) -> String raise @frame.FrameError {
@frame.bytes_to_hex(
encode_dcp_set_ip_request(
source_mac,
destination_mac,
address,
mask,
gateway,
xid~,
is_persistent~,
),
)
}
///|
pub fn summarize_dcp_response_hex(packet_hex : StringView) -> String raise {
format_device_summary(
@dcp.summarize_response(
@dcp.parse_response(@frame.bytes_from_hex(packet_hex)),
),
)
}
///|
fn[T] fixture_merge_optional(left : T?, right : T?) -> T? {
match right {
Some(_) => right
None => left
}
}
///|
fn fixture_merge_device_summary(
current : @dcp.DeviceSummary,
incoming : @dcp.DeviceSummary,
) -> @dcp.DeviceSummary {
let options = current.options.copy()
for pair in incoming.options {
if !options.any(existing => existing == pair) {
options.push(pair)
}
}
@dcp.DeviceSummary::{
source: current.source,
station_name: fixture_merge_optional(
current.station_name,
incoming.station_name,
),
vendor_name: fixture_merge_optional(
current.vendor_name,
incoming.vendor_name,
),
alias_name: fixture_merge_optional(current.alias_name, incoming.alias_name),
vendor_id: fixture_merge_optional(current.vendor_id, incoming.vendor_id),
device_id: fixture_merge_optional(current.device_id, incoming.device_id),
device_instance: fixture_merge_optional(
current.device_instance,
incoming.device_instance,
),
oem_vendor_id: fixture_merge_optional(
current.oem_vendor_id,
incoming.oem_vendor_id,
),
oem_device_id: fixture_merge_optional(
current.oem_device_id,
incoming.oem_device_id,
),
ip_address: fixture_merge_optional(current.ip_address, incoming.ip_address),
subnet_mask: fixture_merge_optional(
current.subnet_mask,
incoming.subnet_mask,
),
gateway: fixture_merge_optional(current.gateway, incoming.gateway),
is_device: current.is_device || incoming.is_device,
is_controller: current.is_controller || incoming.is_controller,
is_multidevice: current.is_multidevice || incoming.is_multidevice,
is_supervisor: current.is_supervisor || incoming.is_supervisor,
options,
device_initiative: fixture_merge_optional(
current.device_initiative,
incoming.device_initiative,
),
control_response: fixture_merge_optional(
current.control_response,
incoming.control_response,
),
}
}
///|
fn fixture_upsert_device_summary(
summaries : Array[@dcp.DeviceSummary],
summary : @dcp.DeviceSummary,
) -> Unit {
let existing_index = summaries.search_by(item => item.source == summary.source)
match existing_index {
Some(index) =>
summaries[index] = fixture_merge_device_summary(summaries[index], summary)
None => summaries.push(summary)
}
}
///|
pub fn summarize_dcp_response_hexes(
packet_hexes : Array[String],
) -> String raise {
let summaries : Array[@dcp.DeviceSummary] = []
for packet_hex in packet_hexes {
fixture_upsert_device_summary(
summaries,
@dcp.summarize_response(
@dcp.parse_response(@frame.bytes_from_hex(packet_hex[:])),
),
)
}
if summaries.is_empty() {
"No devices discovered."
} else {
summaries.map(summary => format_device_summary(summary)).join("\n\n")
}
}
///|
pub fn format_dcp_response_overview(response : @dcp.DcpResponse) -> String {
let lines : Array[String] = []
let summary = @dcp.summarize_response(response)
let nonzero_blocks = response.blocks.filter(block => {
@dcp.response_block_info(block) != 0
})
lines.push("frame_id=" + response.frame_id.to_string())
lines.push("service_id=" + response.service_id.to_int().to_string())
lines.push("service_type=" + response.service_type.to_int().to_string())
lines.push(
"service_type_label=" +
@dcp.response_service_type_label(response.service_type),
)
lines.push("xid=" + response.xid.to_string())
lines.push("source=" + response.source.to_hex())
lines.push("block_count=" + response.blocks.length().to_string())
lines.push(
"blocks=" +
response.blocks.map(block => @dcp.response_block_name(block)).join(","),
)
lines.push("nonzero_block_count=" + nonzero_blocks.length().to_string())
if nonzero_blocks.length() > 0 {
lines.push(
"nonzero_blocks=" +
nonzero_blocks
.map(block => {
@dcp.response_block_name(block) +
":" +
@dcp.response_block_info(block).to_string() +
":" +
@dcp.response_block_info_label(@dcp.response_block_info(block))
})
.join(","),
)
}
match summary.station_name {
Some(name) => lines.push("station_name=" + name)
None => ()
}
match summary.vendor_name {
Some(name) => lines.push("vendor_name=" + name)
None => ()
}
match summary.alias_name {
Some(name) => lines.push("alias_name=" + name)
None => ()
}
match summary.vendor_id {
Some(value) => lines.push("vendor_id=" + value.to_string())
None => ()
}
match summary.device_id {
Some(value) => lines.push("device_id=" + value.to_string())
None => ()
}
match summary.device_instance {
Some(value) => lines.push("device_instance=" + value.to_string())
None => ()
}
match summary.oem_vendor_id {
Some(value) => lines.push("oem_vendor_id=" + value.to_string())
None => ()
}
match summary.oem_device_id {
Some(value) => lines.push("oem_device_id=" + value.to_string())
None => ()
}
match summary.device_initiative {
Some(value) => lines.push("device_initiative=" + value.to_string())
None => ()
}
match summary.control_response {
Some(data) => {
lines.push(
"control_failed_option=" + data.failed_option.to_int().to_string(),
)
lines.push(
"control_failed_suboption=" + data.failed_suboption.to_int().to_string(),
)
lines.push("control_block_error=" + data.block_error.to_int().to_string())
lines.push(
"control_block_error_label=" +
@dcp.control_response_error_label(data.block_error),
)
}
None => ()
}
if summary.options.length() > 0 {
lines.push(
"device_options=" +
summary.options
.map(pair => {
pair.option.to_int().to_string() +
":" +
pair.suboption.to_int().to_string()
})
.join(","),
)
}
lines.push("is_device=" + summary.is_device.to_string())
lines.push("is_controller=" + summary.is_controller.to_string())
lines.push("is_multidevice=" + summary.is_multidevice.to_string())
lines.push("is_supervisor=" + summary.is_supervisor.to_string())
lines.join("\n")
}
///|
pub fn describe_dcp_response_hex(packet_hex : StringView) -> String raise {
format_dcp_response_overview(
@dcp.parse_response(@frame.bytes_from_hex(packet_hex)),
)
}
///|
pub fn format_device_summary(summary : @dcp.DeviceSummary) -> String {
let lines : Array[String] = []
let vendor_id = match summary.vendor_id {
Some(id) => id.to_string()
None => ""
}
let device_id = match summary.device_id {
Some(id) => id.to_string()
None => ""
}
let device_instance = match summary.device_instance {
Some(value) => value.to_string()
None => ""
}
let oem_vendor_id = match summary.oem_vendor_id {
Some(value) => value.to_string()
None => ""
}
let oem_device_id = match summary.oem_device_id {
Some(value) => value.to_string()
None => ""
}
let ip_address = match summary.ip_address {
Some(ip) => ip.to_text()
None => ""
}
let subnet_mask = match summary.subnet_mask {
Some(ip) => ip.to_text()
None => ""
}
let gateway = match summary.gateway {
Some(ip) => ip.to_text()
None => ""
}
let device_initiative = match summary.device_initiative {
Some(value) => value.to_string()
None => ""
}
let control_block_error_label = match summary.control_response {
Some(data) => @dcp.control_response_error_label(data.block_error)
None => ""
}
lines.push("source=" + summary.source.to_hex())
lines.push("station_name=" + summary.station_name.unwrap_or(""))
lines.push("vendor_name=" + summary.vendor_name.unwrap_or(""))
lines.push("alias_name=" + summary.alias_name.unwrap_or(""))
lines.push("vendor_id=" + vendor_id)
lines.push("device_id=" + device_id)
lines.push("device_instance=" + device_instance)
lines.push("oem_vendor_id=" + oem_vendor_id)
lines.push("oem_device_id=" + oem_device_id)
lines.push("ip_address=" + ip_address)
lines.push("subnet_mask=" + subnet_mask)
lines.push("gateway=" + gateway)
lines.push("is_device=" + summary.is_device.to_string())
lines.push("is_controller=" + summary.is_controller.to_string())
lines.push("is_multidevice=" + summary.is_multidevice.to_string())
lines.push("is_supervisor=" + summary.is_supervisor.to_string())
lines.push(
"device_options=" +
summary.options
.map(pair => {
pair.option.to_int().to_string() +
":" +
pair.suboption.to_int().to_string()
})
.join(","),
)
lines.push("device_initiative=" + device_initiative)
lines.push("control_block_error_label=" + control_block_error_label)
lines.join("\n")
}
///|
fn format_gsd_summary(summary : @gsd.GsdSummary) -> String {
[
"vendor_id=" + summary.vendor_id,
"device_id=" + summary.device_id,
"vendor_name=" + summary.vendor_name,
"main_family=" + summary.main_family,
"product_family=" + summary.product_family,
"order_number=" + summary.order_number,
"device_access_point_id=" + summary.device_access_point_id,
"dns_compatible_name=" + summary.dns_compatible_name,
].join("\n")
}
///|
fn normalize_fixture_bool_text(text : String) -> String {
let trimmed = text.trim().to_owned()
if trimmed == "true" ||
trimmed == "TRUE" ||
trimmed == "Enabled" ||
trimmed == "enabled" ||
trimmed == "yes" ||
trimmed == "YES" {
"true"
} else if trimmed == "false" ||
trimmed == "FALSE" ||
trimmed == "Disabled" ||
trimmed == "disabled" ||
trimmed == "no" ||
trimmed == "NO" {
"false"
} else {
trimmed
}
}
///|
fn normalize_mrp_role_text(text : String) -> String {
let trimmed = text.trim().to_owned()
if trimmed == "disabled" ||
trimmed == "Disabled" ||
trimmed == "Media Redundancy disabled" ||
trimmed == "mrp_disabled" {
"disabled"
} else if trimmed == "client" ||
trimmed == "Client" ||
trimmed == "Media Redundancy Client" ||
trimmed == "mrp_client" {
"client"
} else if trimmed == "manager" ||
trimmed == "Manager" ||
trimmed == "Media Redundancy Manager" ||
trimmed == "mrp_manager" {
"manager"
} else if trimmed == "auto_manager" ||
trimmed == "manager_auto" ||
trimmed == "Media Redundancy Manager (Auto manager negotiation)" {
"auto_manager"
} else if trimmed == "" {
"unknown"
} else {
trimmed
}
}
///|
fn normalize_mrp_ring_state_text(text : String) -> String {
let trimmed = text.trim().to_owned()
if trimmed == "closed" ||
trimmed == "Closed" ||
trimmed == "ring_closed" ||
trimmed == "Ring Closed" {
"ring_closed"
} else if trimmed == "open" ||
trimmed == "Open" ||
trimmed == "ring_open" ||
trimmed == "Ring Open" {
"ring_open"
} else if trimmed == "" {
"unknown"
} else {
trimmed
}
}
///|
fn fixture_number_is_zero_like(text : String) -> Bool {
let trimmed = text.trim().to_owned()
trimmed == "0" ||
trimmed == "00" ||
trimmed == "0x0" ||
trimmed == "0x00" ||
trimmed == "0x0000"
}
///|
fn normalize_mrpic_role_text(text : String) -> String {
let trimmed = text.trim().to_owned()
if trimmed == "0" ||
trimmed == "0x00" ||
trimmed == "unassigned" ||
trimmed == "none" ||
trimmed == "No role assigned" {
"unassigned"
} else if trimmed == "1" ||
trimmed == "0x01" ||
trimmed == "MIC" ||
trimmed == "mic" ||
trimmed == "MRP Interconnection Client (MIC)" {
"mic"
} else if trimmed == "2" ||
trimmed == "0x02" ||
trimmed == "MIM" ||
trimmed == "mim" ||
trimmed == "MRP Interconnection Manager (MIM)" {
"mim"
} else if trimmed == "" {
"unknown"
} else {
trimmed
}
}
///|
fn normalize_mrpic_state_text(text : String) -> String {
let trimmed = text.trim().to_owned()
if trimmed == "0" ||
trimmed == "0x00" ||
trimmed == "open" ||
trimmed == "Open" ||
trimmed == "MRP Interconnection open" ||
trimmed == "interconnection_open" {
"interconnection_open"
} else if trimmed == "1" ||
trimmed == "0x01" ||
trimmed == "closed" ||
trimmed == "Closed" ||
trimmed == "MRP Interconnection closed" ||
trimmed == "interconnection_closed" {
"interconnection_closed"
} else if trimmed == "" {
"unknown"
} else {
trimmed
}
}
///|
fn fixture_lines(text : String) -> Array[String] {
text.split("\n").to_array().map(raw => raw.trim().to_owned())
}
///|
pub fn trace_link_state_autonegotiation(trace_text : String) -> String {
let mut local_port_id = ""
let mut autonegotiation_state = "unknown"
let mut link_state = "unknown"
let mut negotiated_mau_type = ""
let mut speed_mbps = "0"
let mut duplex_mode = "unknown"
let mut observed_autonegotiation_ms = "0"
let mut capture_source = ""
let mut restart_detected = "false"
let mut stable_after_link_up = "false"
for line in fixture_lines(trace_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"local_port_id" => local_port_id = value
"autonegotiation_state" => autonegotiation_state = value
"link_state" => link_state = value
"negotiated_mau_type" => negotiated_mau_type = value
"speed_mbps" => speed_mbps = value
"duplex_mode" => duplex_mode = value
"observed_autonegotiation_ms" => observed_autonegotiation_ms = value
"capture_source" => capture_source = value
"restart_detected" =>
restart_detected = normalize_fixture_bool_text(value)
"stable_after_link_up" =>
stable_after_link_up = normalize_fixture_bool_text(value)
_ => ()
}
}
let observed_value = @string.parse_int(observed_autonegotiation_ms[:]) catch {
_ => 0
}
let speed_value = @string.parse_int(speed_mbps[:]) catch { _ => 0 }
let recommended_timeout_ms = recommended_autonegotiation_timeout_ms()
let mandatory_timeout_ms = mandatory_autonegotiation_timeout_ms()
let link_ready = (link_state == "up" || link_state == "UP") &&
speed_value >= minimum_operational_link_speed_mbps() &&
(duplex_mode == required_operational_duplex_mode() || duplex_mode == "FULL")
let physical_contract = if link_ready {
"meets_minimum"
} else {
"below_minimum"
}
let compliance = if stable_after_link_up != "true" {
"not_stable"
} else if observed_value <= recommended_timeout_ms {
"recommended"
} else if observed_value <= mandatory_timeout_ms {
"mandatory_only"
} else {
"out_of_spec"
}
[
"trace_method=link_state_trace",
"local_port_id=" + local_port_id,
"autonegotiation_state=" + autonegotiation_state,
"link_state=" + link_state,
"negotiated_mau_type=" + negotiated_mau_type,
"speed_mbps=" + speed_mbps,
"duplex_mode=" + duplex_mode,
"observed_autonegotiation_ms=" + observed_autonegotiation_ms,
"capture_source=" + capture_source,
"restart_detected=" + restart_detected,
"stable_after_link_up=" + stable_after_link_up,
"recommended_timeout_ms=" + recommended_timeout_ms.to_string(),
"mandatory_timeout_ms=" + mandatory_timeout_ms.to_string(),
"minimum_speed_mbps=" + minimum_operational_link_speed_mbps().to_string(),
"required_duplex_mode=" + required_operational_duplex_mode(),
"fault_requires_link_restart=" +
autonegotiation_fault_requires_link_restart().to_string(),
"link_ready=" + link_ready.to_string(),
"physical_contract=" + physical_contract,
"compliance=" + compliance,
].join("\n")
}
///|
pub fn trace_link_state_port_diagnosis(trace_text : String) -> String {
let mut local_port_id = ""
let mut expected_mau_type = ""
let mut observed_mau_type = ""
let mut expected_link_state = "up"
let mut observed_link_state = "unknown"
let mut expected_line_delay_ns = ""
let mut observed_line_delay_ns = ""
let mut speed_mbps = "0"
let mut duplex_mode = "unknown"
for line in fixture_lines(trace_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"local_port_id" => local_port_id = value
"expected_mau_type" => expected_mau_type = value
"observed_mau_type" => observed_mau_type = value
"expected_link_state" => expected_link_state = value
"observed_link_state" => observed_link_state = value
"expected_line_delay_ns" => expected_line_delay_ns = value
"observed_line_delay_ns" => observed_line_delay_ns = value
"speed_mbps" => speed_mbps = value
"duplex_mode" => duplex_mode = value
_ => ()
}
}
let speed_value = @string.parse_int(speed_mbps[:]) catch { _ => 0 }
let expected_delay = @string.parse_int(expected_line_delay_ns[:]) catch {
_ => 0
}
let observed_delay = @string.parse_int(observed_line_delay_ns[:]) catch {
_ => 0
}
let observed_link_up = observed_link_state == "up" ||
observed_link_state == "UP"
let expected_link_up = expected_link_state == "up" ||
expected_link_state == "UP"
let link_mismatch = expected_link_up && !observed_link_up
let mau_mismatch = expected_mau_type != "" &&
observed_mau_type != "" &&
expected_mau_type != observed_mau_type
let line_delay_mismatch = expected_delay > 0 &&
observed_delay > expected_delay
let physical_ready = observed_link_up &&
speed_value >= minimum_operational_link_speed_mbps() &&
(duplex_mode == required_operational_duplex_mode() || duplex_mode == "FULL")
let diagnosis_code = if link_mismatch {
diagnosis_link_state_mismatch_code()
} else if mau_mismatch || !physical_ready {
diagnosis_mau_type_mismatch_code()
} else if line_delay_mismatch {
diagnosis_line_delay_mismatch_code()
} else {
"none"
}
let diagnosis_label = match diagnosis_code {
"0x8000" => "link_state_mismatch"
"0x8001" => "mau_type_mismatch"
"0x8002" => "line_delay_mismatch"
_ => "no_fault"
}
[
"trace_method=link_state_trace",
"local_port_id=" + local_port_id,
"expected_mau_type=" + expected_mau_type,
"observed_mau_type=" + observed_mau_type,
"expected_link_state=" + expected_link_state,
"observed_link_state=" + observed_link_state,
"expected_line_delay_ns=" + expected_line_delay_ns,
"observed_line_delay_ns=" + observed_line_delay_ns,
"speed_mbps=" + speed_mbps,
"duplex_mode=" + duplex_mode,
"minimum_speed_mbps=" + minimum_operational_link_speed_mbps().to_string(),
"required_duplex_mode=" + required_operational_duplex_mode(),
"link_state_mismatch_code=" + diagnosis_link_state_mismatch_code(),
"mau_type_mismatch_code=" + diagnosis_mau_type_mismatch_code(),
"line_delay_mismatch_code=" + diagnosis_line_delay_mismatch_code(),
"physical_ready=" + physical_ready.to_string(),
"diagnosis_code=" + diagnosis_code,
"diagnosis_label=" + diagnosis_label,
].join("\n")
}
///|
pub fn read_pd_port_data_real(record_text : String) -> String {
let mut local_port_id = ""
let mut port_state = "unknown"
let mut boundary_state = "unknown"
let mut link_state = "unknown"
let mut mau_type = ""
let mut speed_mbps = "0"
let mut duplex_mode = "unknown"
let mut line_delay_ns = "0"
let mut peer_count = "0"
let mut check_peers = "false"
let mut check_line_delay = "false"
let mut check_mau_type = "false"
let mut check_link_state = "false"
let mut check_sync_difference = "false"
let mut check_mau_type_difference = "false"
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"local_port_id" => local_port_id = value
"port_state" => port_state = value
"boundary_state" => boundary_state = value
"link_state" => link_state = value
"mau_type" => mau_type = value
"speed_mbps" => speed_mbps = value
"duplex_mode" => duplex_mode = value
"line_delay_ns" => line_delay_ns = value
"peer_count" => peer_count = value
"check_peers" => check_peers = normalize_fixture_bool_text(value)
"check_line_delay" =>
check_line_delay = normalize_fixture_bool_text(value)
"check_mau_type" => check_mau_type = normalize_fixture_bool_text(value)
"check_link_state" =>
check_link_state = normalize_fixture_bool_text(value)
"check_sync_difference" =>
check_sync_difference = normalize_fixture_bool_text(value)
"check_mau_type_difference" =>
check_mau_type_difference = normalize_fixture_bool_text(value)
_ => ()
}
}
let speed_value = @string.parse_int(speed_mbps[:]) catch { _ => 0 }
let peer_value = @string.parse_int(peer_count[:]) catch { _ => 0 }
let link_up = link_state == "up" || link_state == "UP"
let physical_ready = link_up &&
speed_value >= minimum_operational_link_speed_mbps() &&
(duplex_mode == required_operational_duplex_mode() || duplex_mode == "FULL")
let active_check_blocks : Array[String] = []
if check_peers == "true" {
active_check_blocks.push("CheckPeers")
}
if check_line_delay == "true" {
active_check_blocks.push("CheckLineDelay")
}
if check_mau_type == "true" {
active_check_blocks.push("CheckMAUType")
}
if check_link_state == "true" {
active_check_blocks.push("CheckLinkState")
}
if check_sync_difference == "true" {
active_check_blocks.push("CheckSyncDifference")
}
if check_mau_type_difference == "true" {
active_check_blocks.push("CheckMAUTypeDifference")
}
let topology_status = if peer_value > 0 {
"peer_present"
} else {
"peer_missing"
}
[
"record_method=record_read_pdportdatareal",
"local_port_id=" + local_port_id,
"record_index_real_extended=" + pd_port_data_real_extended_record_index(),
"record_index_real=" + pd_port_data_real_record_index(),
"record_index_check=" + pd_port_data_check_record_index(),
"supported_check_blocks=" + pd_port_data_check_supported_blocks(),
"port_state=" + port_state,
"boundary_state=" + boundary_state,
"link_state=" + link_state,
"mau_type=" + mau_type,
"speed_mbps=" + speed_mbps,
"duplex_mode=" + duplex_mode,
"line_delay_ns=" + line_delay_ns,
"peer_count=" + peer_count,
"minimum_speed_mbps=" + minimum_operational_link_speed_mbps().to_string(),
"required_duplex_mode=" + required_operational_duplex_mode(),
"physical_ready=" + physical_ready.to_string(),
"topology_status=" + topology_status,
"check_peers=" + check_peers,
"check_line_delay=" + check_line_delay,
"check_mau_type=" + check_mau_type,
"check_link_state=" + check_link_state,
"check_sync_difference=" + check_sync_difference,
"check_mau_type_difference=" + check_mau_type_difference,
"active_check_blocks=" + active_check_blocks.join(","),
].join("\n")
}
///|
pub fn read_pd_port_statistic(record_text : String) -> String {
let mut slot_number = ""
let mut subslot_number = ""
let mut local_port_id = ""
let mut counter_status = "0"
let mut if_in_octets = "0"
let mut if_out_octets = "0"
let mut if_in_discards = "0"
let mut if_out_discards = "0"
let mut if_in_errors = "0"
let mut if_out_errors = "0"
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"slot_number" => slot_number = value
"subslot_number" => subslot_number = value
"local_port_id" => local_port_id = value
"counter_status" => counter_status = value
"if_in_octets" => if_in_octets = value
"if_out_octets" => if_out_octets = value
"if_in_discards" => if_in_discards = value
"if_out_discards" => if_out_discards = value
"if_in_errors" => if_in_errors = value
"if_out_errors" => if_out_errors = value
_ => ()
}
}
let counter_status_value = @string.parse_int(counter_status[:]) catch {
_ => 0
}
let invalid_counters : Array[String] = []
if counter_status_value.land(1) != 0 {
invalid_counters.push("ifInOctets")
}
if counter_status_value.land(2) != 0 {
invalid_counters.push("ifOutOctets")
}
if counter_status_value.land(4) != 0 {
invalid_counters.push("ifInDiscards")
}
if counter_status_value.land(8) != 0 {
invalid_counters.push("ifOutDiscards")
}
if counter_status_value.land(16) != 0 {
invalid_counters.push("ifInErrors")
}
if counter_status_value.land(32) != 0 {
invalid_counters.push("ifOutErrors")
}
let traffic_state = if if_in_octets != "0" || if_out_octets != "0" {
"active"
} else {
"idle"
}
[
"record_method=record_read_pdportstatistic",
"slot_number=" + slot_number,
"subslot_number=" + subslot_number,
"local_port_id=" + local_port_id,
"record_index=" + pd_port_statistic_record_index(),
"counter_status=" + counter_status,
"if_in_octets=" + if_in_octets,
"if_out_octets=" + if_out_octets,
"if_in_discards=" + if_in_discards,
"if_out_discards=" + if_out_discards,
"if_in_errors=" + if_in_errors,
"if_out_errors=" + if_out_errors,
"invalid_counter_count=" + invalid_counters.length().to_string(),
"invalid_counters=" + invalid_counters.join(","),
"traffic_state=" + traffic_state,
].join("\n")
}
///|
pub fn read_pd_port_mrp_data_real(record_text : String) -> String {
let mut slot_number = ""
let mut subslot_number = ""
let mut local_port_id = ""
let mut mrp_instance = ""
let mut mrp_domain_uuid = ""
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"slot_number" => slot_number = value
"subslot_number" => subslot_number = value
"local_port_id" => local_port_id = value
"mrp_instance" => mrp_instance = value
"mrp_domain_uuid" => mrp_domain_uuid = value
_ => ()
}
}
let domain_uuid_present = mrp_domain_uuid != ""
let instance_scope = if mrp_instance == "" {
"default"
} else {
"instance_specific"
}
let domain_assignment = if domain_uuid_present { "bound" } else { "unbound" }
let mrp_digest_state = if domain_uuid_present && mrp_instance != "" {
"instance_bound"
} else if domain_uuid_present {
"bound"
} else if mrp_instance != "" {
"instance_unbound"
} else {
"unbound"
}
[
"record_method=record_read_pdportmrpdatareal",
"slot_number=" + slot_number,
"subslot_number=" + subslot_number,
"local_port_id=" + local_port_id,
"mrp_instance=" + mrp_instance,
"record_index=" + pd_port_mrp_data_real_record_index(),
"mrp_domain_uuid=" + mrp_domain_uuid,
"domain_uuid_present=" + domain_uuid_present.to_string(),
"instance_scope=" + instance_scope,
"domain_assignment=" + domain_assignment,
"mrp_digest_state=" + mrp_digest_state,
].join("\n")
}
///|
pub fn read_pd_port_mrplc_data_real(record_text : String) -> String {
let mut slot_number = ""
let mut subslot_number = ""
let mut local_port_id = ""
let mut mrpic_domain_id = ""
let mut mrpic_role = ""
let mut mrp_version = ""
let mut mrpic_domain_name = ""
let mut mrpic_topchg_t = ""
let mut mrpic_topnr_max = ""
let mut mrpic_link_status_change_t = ""
let mut mrpic_link_status_nrmax = ""
let mut mrpic_lnkdown_t = ""
let mut mrpic_lnkup_t = ""
let mut mrpic_lnknr_max = ""
let mut mrpic_start_delay = ""
let mut mrpic_mic_position = ""
let mut mrpic_state = ""
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"slot_number" => slot_number = value
"subslot_number" => subslot_number = value
"local_port_id" => local_port_id = value
"mrpic_domain_id" => mrpic_domain_id = value
"mrpic_role" => mrpic_role = value
"mrp_version" => mrp_version = value
"mrpic_domain_name" => mrpic_domain_name = value
"mrpic_topchg_t" => mrpic_topchg_t = value
"mrpic_topnr_max" => mrpic_topnr_max = value
"mrpic_link_status_change_t" => mrpic_link_status_change_t = value
"mrpic_link_status_nrmax" => mrpic_link_status_nrmax = value
"mrpic_lnkdown_t" => mrpic_lnkdown_t = value
"mrpic_lnkup_t" => mrpic_lnkup_t = value
"mrpic_lnknr_max" => mrpic_lnknr_max = value
"mrpic_start_delay" => mrpic_start_delay = value
"mrpic_mic_position" => mrpic_mic_position = value
"mrpic_state" => mrpic_state = value
_ => ()
}
}
let normalized_role = normalize_mrpic_role_text(mrpic_role)
let normalized_state = normalize_mrpic_state_text(mrpic_state)
let domain_defined = mrpic_domain_id != "" &&
!fixture_number_is_zero_like(mrpic_domain_id)
let mim_params_present = mrpic_topchg_t != "" ||
mrpic_topnr_max != "" ||
mrpic_link_status_change_t != "" ||
mrpic_link_status_nrmax != "" ||
(mrpic_start_delay != "" && normalized_role == "mim")
let mic_params_present = mrpic_lnkdown_t != "" ||
mrpic_lnkup_t != "" ||
mrpic_lnknr_max != "" ||
mrpic_mic_position != "" ||
(mrpic_start_delay != "" && normalized_role == "mic")
let state_present = mrpic_state != ""
let parameter_set = if mim_params_present && mic_params_present {
"mim_and_mic"
} else if mim_params_present {
"mim"
} else if mic_params_present {
"mic"
} else {
"none"
}
let mrpic_health = if normalized_state == "interconnection_closed" {
"interconnection_closed"
} else if normalized_state == "interconnection_open" {
"interconnection_open"
} else if !state_present {
"state_unreported"
} else {
"state_other"
}
let mrpic_readiness = if normalized_role == "unassigned" {
"unassigned"
} else if mrpic_health == "interconnection_closed" {
"redundant"
} else if mrpic_health == "interconnection_open" {
"degraded"
} else if parameter_set != "none" {
"configured"
} else {
"unknown"
}
let mrpic_digest_state = if normalized_role == "unassigned" {
"unassigned"
} else if mrpic_health == "interconnection_closed" ||
mrpic_health == "interconnection_open" {
normalized_role + "_" + mrpic_health
} else if parameter_set != "none" {
normalized_role + "_configured"
} else {
normalized_role + "_unknown"
}
let mrpic_domain_assignment = if domain_defined {
"defined"
} else {
"undefined"
}
[
"record_method=record_read_pdportmrplcdatareal",
"slot_number=" + slot_number,
"subslot_number=" + subslot_number,
"local_port_id=" + local_port_id,
"record_index=" + pd_port_mrplc_data_real_record_index(),
"mrpic_domain_id=" + mrpic_domain_id,
"mrpic_domain_defined=" + domain_defined.to_string(),
"mrpic_role=" + mrpic_role,
"mrpic_role_normalized=" + normalized_role,
"mrp_version=" + mrp_version,
"mrpic_domain_name=" + mrpic_domain_name,
"mrpic_topchg_t=" + mrpic_topchg_t,
"mrpic_topnr_max=" + mrpic_topnr_max,
"mrpic_link_status_change_t=" + mrpic_link_status_change_t,
"mrpic_link_status_nrmax=" + mrpic_link_status_nrmax,
"mrpic_lnkdown_t=" + mrpic_lnkdown_t,
"mrpic_lnkup_t=" + mrpic_lnkup_t,
"mrpic_lnknr_max=" + mrpic_lnknr_max,
"mrpic_start_delay=" + mrpic_start_delay,
"mrpic_mic_position=" + mrpic_mic_position,
"mrpic_state=" + mrpic_state,
"mim_params_present=" + mim_params_present.to_string(),
"mic_params_present=" + mic_params_present.to_string(),
"state_present=" + state_present.to_string(),
"parameter_set=" + parameter_set,
"mrpic_domain_assignment=" + mrpic_domain_assignment,
"mrpic_health=" + mrpic_health,
"mrpic_readiness=" + mrpic_readiness,
"mrpic_digest_state=" + mrpic_digest_state,
].join("\n")
}
///|
pub fn read_pd_interface_mrp_data_real(record_text : String) -> String {
let mut slot_number = ""
let mut subslot_number = ""
let mut mrp_instance = ""
let mut mrp_domain_uuid = ""
let mut mrp_role = ""
let mut mrp_version = ""
let mut mrp_domain_name = ""
let mut mrp_manager_prio = ""
let mut mrp_topchg_t = ""
let mut mrp_topnr_max = ""
let mut mrp_tstshort_t = ""
let mut mrp_tstdefault_t = ""
let mut mrp_tstnr_max = ""
let mut mrp_lnkdown_t = ""
let mut mrp_lnkup_t = ""
let mut mrp_lnknr_max = ""
let mut mrp_ring_state = ""
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"slot_number" => slot_number = value
"subslot_number" => subslot_number = value
"mrp_instance" => mrp_instance = value
"mrp_domain_uuid" => mrp_domain_uuid = value
"mrp_role" => mrp_role = value
"mrp_version" => mrp_version = value
"mrp_domain_name" => mrp_domain_name = value
"mrp_manager_prio" => mrp_manager_prio = value
"mrp_topchg_t" => mrp_topchg_t = value
"mrp_topnr_max" => mrp_topnr_max = value
"mrp_tstshort_t" => mrp_tstshort_t = value
"mrp_tstdefault_t" => mrp_tstdefault_t = value
"mrp_tstnr_max" => mrp_tstnr_max = value
"mrp_lnkdown_t" => mrp_lnkdown_t = value
"mrp_lnkup_t" => mrp_lnkup_t = value
"mrp_lnknr_max" => mrp_lnknr_max = value
"mrp_ring_state" => mrp_ring_state = value
_ => ()
}
}
let normalized_role = normalize_mrp_role_text(mrp_role)
let normalized_ring_state = normalize_mrp_ring_state_text(mrp_ring_state)
let manager_params_present = mrp_manager_prio != "" ||
mrp_topchg_t != "" ||
mrp_topnr_max != "" ||
mrp_tstshort_t != "" ||
mrp_tstdefault_t != "" ||
mrp_tstnr_max != ""
let client_params_present = mrp_lnkdown_t != "" ||
mrp_lnkup_t != "" ||
mrp_lnknr_max != ""
let ring_state_present = mrp_ring_state != ""
let parameter_set = if manager_params_present && client_params_present {
"manager_and_client"
} else if manager_params_present {
"manager"
} else if client_params_present {
"client"
} else {
"none"
}
let ring_health = if normalized_ring_state == "ring_closed" {
"ring_closed"
} else if normalized_ring_state == "ring_open" {
"ring_open"
} else if !ring_state_present {
"ring_state_unreported"
} else {
"ring_state_other"
}
let mrp_readiness = if normalized_role == "disabled" {
"disabled"
} else if ring_health == "ring_closed" {
"redundant"
} else if ring_health == "ring_open" {
"degraded"
} else if parameter_set != "none" {
"configured"
} else {
"unknown"
}
let mrp_digest_state = if normalized_role == "disabled" {
"disabled"
} else if ring_health == "ring_closed" || ring_health == "ring_open" {
normalized_role + "_" + ring_health
} else if parameter_set != "none" {
normalized_role + "_configured"
} else {
normalized_role + "_unknown"
}
[
"record_method=record_read_pdinterfacemrpdatareal",
"slot_number=" + slot_number,
"subslot_number=" + subslot_number,
"mrp_instance=" + mrp_instance,
"record_index=" + pd_interface_mrp_data_real_record_index(),
"mrp_domain_uuid=" + mrp_domain_uuid,
"mrp_role=" + mrp_role,
"mrp_role_normalized=" + normalized_role,
"mrp_version=" + mrp_version,
"mrp_domain_name=" + mrp_domain_name,
"mrp_manager_prio=" + mrp_manager_prio,
"mrp_topchg_t=" + mrp_topchg_t,
"mrp_topnr_max=" + mrp_topnr_max,
"mrp_tstshort_t=" + mrp_tstshort_t,
"mrp_tstdefault_t=" + mrp_tstdefault_t,
"mrp_tstnr_max=" + mrp_tstnr_max,
"mrp_lnkdown_t=" + mrp_lnkdown_t,
"mrp_lnkup_t=" + mrp_lnkup_t,
"mrp_lnknr_max=" + mrp_lnknr_max,
"mrp_ring_state=" + mrp_ring_state,
"manager_params_present=" + manager_params_present.to_string(),
"client_params_present=" + client_params_present.to_string(),
"ring_state_present=" + ring_state_present.to_string(),
"parameter_set=" + parameter_set,
"mrp_ring_health=" + ring_health,
"mrp_readiness=" + mrp_readiness,
"mrp_digest_state=" + mrp_digest_state,
].join("\n")
}
///|
pub fn read_pd_interface_data_real(record_text : String) -> String {
let mut slot_number = ""
let mut subslot_number = ""
let mut chassis_id = ""
let mut mac_address = ""
let mut ip_parameter_value = ""
let mut ip_address = ""
let mut subnet_mask = ""
let mut standard_gateway = ""
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"slot_number" => slot_number = value
"subslot_number" => subslot_number = value
"chassis_id" => chassis_id = value
"mac_address" => mac_address = value
"ip_parameter_value" => ip_parameter_value = value
"ip_address" => ip_address = value
"subnet_mask" => subnet_mask = value
"standard_gateway" => standard_gateway = value
_ => ()
}
}
let parameter_assignment = if ip_parameter_value ==
dhcp_parameter_data_required_value().to_string() {
"dhcp"
} else if ip_parameter_value == "" {
"unknown"
} else {
"static_or_vendor_specific"
}
let address_complete = ip_address != "" &&
subnet_mask != "" &&
standard_gateway != ""
[
"record_method=record_read_pdinterfacedatareal",
"slot_number=" + slot_number,
"subslot_number=" + subslot_number,
"record_index=" + pd_interface_data_real_record_index(),
"chassis_id=" + chassis_id,
"mac_address=" + mac_address,
"ip_parameter_value=" + ip_parameter_value,
"ip_address=" + ip_address,
"subnet_mask=" + subnet_mask,
"standard_gateway=" + standard_gateway,
"parameter_assignment=" + parameter_assignment,
"address_complete=" + address_complete.to_string(),
].join("\n")
}
///|
pub fn read_pdev_data(record_text : String) -> String {
let mut has_pd_ir_data = "false"
let mut has_pd_sync_data = "false"
let mut has_pd_ir_subframe_data = "false"
let mut has_pd_time_data = "false"
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"has_pd_ir_data" => has_pd_ir_data = normalize_fixture_bool_text(value)
"has_pd_sync_data" =>
has_pd_sync_data = normalize_fixture_bool_text(value)
"has_pd_ir_subframe_data" =>
has_pd_ir_subframe_data = normalize_fixture_bool_text(value)
"has_pd_time_data" =>
has_pd_time_data = normalize_fixture_bool_text(value)
_ => ()
}
}
let present_components : Array[String] = []
if has_pd_ir_data == "true" {
present_components.push("PD IR Data")
}
if has_pd_sync_data == "true" {
present_components.push("PD Sync Data")
}
if has_pd_ir_subframe_data == "true" {
present_components.push("PD IR Subframe Data")
}
if has_pd_time_data == "true" {
present_components.push("PD Time Data")
}
[
"record_method=record_read_pdevdata",
"record_index=" + pdev_data_record_index(),
"related_pd_real_data_record_index=" + pd_real_data_record_index(),
"has_pd_ir_data=" + has_pd_ir_data,
"has_pd_sync_data=" + has_pd_sync_data,
"has_pd_ir_subframe_data=" + has_pd_ir_subframe_data,
"has_pd_time_data=" + has_pd_time_data,
"present_component_count=" + present_components.length().to_string(),
"present_components=" + present_components.join(","),
].join("\n")
}
///|
fn fixture_value(record_text : String, wanted_key : String) -> String {
for line in fixture_lines(record_text) {
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
if key == wanted_key {
return value
}
}
""
}
///|
fn pd_real_data_sections(record_text : String) -> Array[String] {
let sections : Array[String] = []
let current_lines : Array[String] = []
for raw_line in record_text.split("\n").to_array() {
let line = raw_line.trim().to_owned()
if line == "" {
if !current_lines.is_empty() {
sections.push(current_lines.join("\n"))
current_lines.clear()
}
continue
}
if line == "[submodule]" || line == "---" {
if !current_lines.is_empty() {
sections.push(current_lines.join("\n"))
current_lines.clear()
}
continue
}
if line[:].has_prefix("#") {
continue
}
current_lines.push(line)
}
if !current_lines.is_empty() {
sections.push(current_lines.join("\n"))
}
sections
}
///|
pub fn read_pd_real_data(record_text : String) -> String {
let sections = pd_real_data_sections(record_text)
let mut port_submodule_count = 0
let mut port_mrp_submodule_count = 0
let mut port_mrplc_submodule_count = 0
let mut interface_submodule_count = 0
let mut interface_mrp_submodule_count = 0
let mut statistic_submodule_count = 0
let mut unsupported_submodule_count = 0
let mut physical_ready_port_count = 0
let mut bound_port_mrp_count = 0
let mut closed_port_mrplc_count = 0
let mut address_complete_interface_count = 0
let mut ring_closed_interface_mrp_count = 0
let mut active_statistic_submodule_count = 0
let submodule_kinds : Array[String] = []
let submodule_digests : Array[String] = []
for section in sections {
let kind = fixture_value(section, "kind")
let slot_number = fixture_value(section, "slot_number")
let subslot_number = fixture_value(section, "subslot_number")
let location = if slot_number != "" || subslot_number != "" {
slot_number + "/" + subslot_number
} else {
fixture_value(section, "local_port_id")
}
if kind == "pd_port_data_real" {
port_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_port_data_real(section)
if fixture_value(summary, "physical_ready") == "true" {
physical_ready_port_count += 1
}
submodule_digests.push(
location + ":" + kind + ":" + fixture_value(summary, "topology_status"),
)
} else if kind == "pd_port_mrp_data_real" {
port_mrp_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_port_mrp_data_real(section)
if fixture_value(summary, "domain_assignment") == "bound" {
bound_port_mrp_count += 1
}
submodule_digests.push(
location + ":" + kind + ":" + fixture_value(summary, "mrp_digest_state"),
)
} else if kind == "pd_port_mrplc_data_real" {
port_mrplc_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_port_mrplc_data_real(section)
if fixture_value(summary, "mrpic_health") == "interconnection_closed" {
closed_port_mrplc_count += 1
}
submodule_digests.push(
location +
":" +
kind +
":" +
fixture_value(summary, "mrpic_digest_state"),
)
} else if kind == "pd_interface_mrp_data_real" {
interface_mrp_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_interface_mrp_data_real(section)
if fixture_value(summary, "mrp_ring_health") == "ring_closed" {
ring_closed_interface_mrp_count += 1
}
submodule_digests.push(
location + ":" + kind + ":" + fixture_value(summary, "mrp_digest_state"),
)
} else if kind == "pd_interface_data_real" {
interface_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_interface_data_real(section)
if fixture_value(summary, "address_complete") == "true" {
address_complete_interface_count += 1
}
submodule_digests.push(
location +
":" +
kind +
":" +
fixture_value(summary, "parameter_assignment"),
)
} else if kind == "pd_port_statistic" {
statistic_submodule_count += 1
submodule_kinds.push(kind)
let summary = read_pd_port_statistic(section)
if fixture_value(summary, "traffic_state") == "active" {
active_statistic_submodule_count += 1
}
submodule_digests.push(
location + ":" + kind + ":" + fixture_value(summary, "traffic_state"),
)
} else if kind != "" {
unsupported_submodule_count += 1
submodule_kinds.push(kind)
submodule_digests.push(location + ":" + kind + ":unsupported")
}
}
[
"record_method=record_read_pdrealdata",
"record_index=" + pd_real_data_record_index(),
"submodule_count=" + sections.length().to_string(),
"port_submodule_count=" + port_submodule_count.to_string(),
"port_mrp_submodule_count=" + port_mrp_submodule_count.to_string(),
"port_mrplc_submodule_count=" + port_mrplc_submodule_count.to_string(),
"interface_submodule_count=" + interface_submodule_count.to_string(),
"interface_mrp_submodule_count=" + interface_mrp_submodule_count.to_string(),
"statistic_submodule_count=" + statistic_submodule_count.to_string(),
"unsupported_submodule_count=" + unsupported_submodule_count.to_string(),
"physical_ready_port_count=" + physical_ready_port_count.to_string(),
"bound_port_mrp_count=" + bound_port_mrp_count.to_string(),
"closed_port_mrplc_count=" + closed_port_mrplc_count.to_string(),
"address_complete_interface_count=" +
address_complete_interface_count.to_string(),
"ring_closed_interface_mrp_count=" +
ring_closed_interface_mrp_count.to_string(),
"active_statistic_submodule_count=" +
active_statistic_submodule_count.to_string(),
"submodule_kinds=" + submodule_kinds.join(","),
"submodule_digests=" + submodule_digests.join(","),
].join("\n")
}
///|
pub fn trace_ar_resource_release_time(trace_text : String) -> String {
let mut session_handle = ""
let mut arep = ""
let mut release_reason = ""
let mut trigger_event = ""
let mut observed_release_ms = "0"
let mut release_confirmed = "false"
let mut trace_source = ""
let mut transition_count = "1"
for line in fixture_lines(trace_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"session_handle" => session_handle = value
"arep" => arep = value
"release_reason" => release_reason = value
"trigger_event" => trigger_event = value
"observed_release_ms" => observed_release_ms = value
"release_confirmed" =>
release_confirmed = normalize_fixture_bool_text(value)
"trace_source" => trace_source = value
"transition_count" => transition_count = value
_ => ()
}
}
let observed_value = @string.parse_int(observed_release_ms[:]) catch {
_ => 0
}
let recommended_release_ms = recommended_ar_resource_release_timeout_ms()
let mandatory_release_ms = mandatory_ar_resource_release_timeout_ms()
let compliance = if release_confirmed != "true" {
"not_confirmed"
} else if observed_value <= recommended_release_ms {
"recommended"
} else if observed_value <= mandatory_release_ms {
"mandatory_only"
} else {
"out_of_spec"
}
[
"trace_method=ar_session_trace",
"session_handle=" + session_handle,
"arep=" + arep,
"release_reason=" + release_reason,
"trigger_event=" + trigger_event,
"observed_release_ms=" + observed_release_ms,
"release_confirmed=" + release_confirmed,
"trace_source=" + trace_source,
"transition_count=" + transition_count,
"recommended_release_ms=" + recommended_release_ms.to_string(),
"mandatory_release_ms=" + mandatory_release_ms.to_string(),
"compliance=" + compliance,
].join("\n")
}
///|
pub fn measure_snmp_roundtrip(sample_text : String) -> String {
let mut operation = "get"
let mut target_ip = ""
let mut community = ""
let mut oid = ""
let mut observed_ms = "0"
let mut retries = "0"
let mut timeout_budget_ms = ""
let mut packet_loss = "false"
for line in fixture_lines(sample_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"operation" => operation = value
"target_ip" => target_ip = value
"community" => community = value
"oid" => oid = value
"observed_ms" => observed_ms = value
"retries" => retries = value
"timeout_budget_ms" => timeout_budget_ms = value
"packet_loss" => packet_loss = normalize_fixture_bool_text(value)
_ => ()
}
}
let observed_value = @string.parse_int(observed_ms[:]) catch { _ => 0 }
let recommended_timeout_ms = match operation {
"set" => recommended_snmp_set_timeout_ms()
"get_next" => recommended_snmp_get_next_timeout_ms()
_ => recommended_snmp_get_timeout_ms()
}
let mandatory_timeout_ms = match operation {
"set" => mandatory_snmp_set_timeout_ms()
"get_next" => mandatory_snmp_get_next_timeout_ms()
_ => mandatory_snmp_get_timeout_ms()
}
let compliance = if observed_value <= recommended_timeout_ms {
"recommended"
} else if observed_value <= mandatory_timeout_ms {
"mandatory_only"
} else {
"out_of_spec"
}
[
"measurement_method=active_snmp_roundtrip",
"operation=" + operation,
"target_ip=" + target_ip,
"community=" + community,
"oid=" + oid,
"observed_ms=" + observed_ms,
"retries=" + retries,
"timeout_budget_ms=" + timeout_budget_ms,
"packet_loss=" + packet_loss,
"recommended_timeout_ms=" + recommended_timeout_ms.to_string(),
"mandatory_timeout_ms=" + mandatory_timeout_ms.to_string(),
"compliance=" + compliance,
].join("\n")
}
///|
pub fn measure_snmp_mib_update(sample_text : String) -> String {
let mut target_ip = ""
let mut community = ""
let mut oid = ""
let mut poll_interval_ms = ""
let mut observed_update_ms = "0"
let mut timeout_budget_ms = ""
let mut update_detected = "false"
let mut sample_count = "1"
for line in fixture_lines(sample_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"target_ip" => target_ip = value
"community" => community = value
"oid" => oid = value
"poll_interval_ms" => poll_interval_ms = value
"observed_update_ms" => observed_update_ms = value
"timeout_budget_ms" => timeout_budget_ms = value
"update_detected" => update_detected = normalize_fixture_bool_text(value)
"sample_count" => sample_count = value
_ => ()
}
}
let observed_value = @string.parse_int(observed_update_ms[:]) catch { _ => 0 }
let recommended_update_ms = recommended_snmp_mib_update_time_ms()
let mandatory_update_ms = mandatory_snmp_mib_update_time_ms()
let compliance = if update_detected != "true" {
"not_detected"
} else if observed_value <= recommended_update_ms {
"recommended"
} else if observed_value <= mandatory_update_ms {
"mandatory_only"
} else {
"out_of_spec"
}
[
"measurement_method=active_snmp_polling",
"target_ip=" + target_ip,
"community=" + community,
"oid=" + oid,
"poll_interval_ms=" + poll_interval_ms,
"observed_update_ms=" + observed_update_ms,
"timeout_budget_ms=" + timeout_budget_ms,
"update_detected=" + update_detected,
"sample_count=" + sample_count,
"recommended_update_ms=" + recommended_update_ms.to_string(),
"mandatory_update_ms=" + mandatory_update_ms.to_string(),
"compliance=" + compliance,
].join("\n")
}
///|
pub fn observe_dhcp_runtime_state(observation_text : String) -> String {
let mut source = ""
let mut station_name = ""
let mut current_ip = ""
let mut previous_ip = ""
let mut subnet_mask = ""
let mut gateway = ""
let mut lease_source = "unknown"
let mut renewed = "false"
let mut changed_by_dcp = "false"
let mut observed_reboot = "false"
let mut ip_conflict = "false"
let mut address_observed_count = "1"
for line in fixture_lines(observation_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"source" => source = value
"station_name" => station_name = value
"current_ip" => current_ip = value
"previous_ip" => previous_ip = value
"subnet_mask" => subnet_mask = value
"gateway" => gateway = value
"lease_source" => lease_source = value
"renewed" => renewed = normalize_fixture_bool_text(value)
"changed_by_dcp" => changed_by_dcp = normalize_fixture_bool_text(value)
"observed_reboot" => observed_reboot = normalize_fixture_bool_text(value)
"ip_conflict" => ip_conflict = normalize_fixture_bool_text(value)
"address_observed_count" => address_observed_count = value
_ => ()
}
}
let runtime_state = if lease_source == "dhcp" || renewed == "true" {
"dhcp_active"
} else if changed_by_dcp == "true" {
"dcp_override_observed"
} else if lease_source == "static" {
"static_observed"
} else {
"unknown"
}
[
"observation_method=indirect_ip_observation",
"source=" + source,
"station_name=" + station_name,
"current_ip=" + current_ip,
"previous_ip=" + previous_ip,
"subnet_mask=" + subnet_mask,
"gateway=" + gateway,
"lease_source=" + lease_source,
"renewed=" + renewed,
"changed_by_dcp=" + changed_by_dcp,
"observed_reboot=" + observed_reboot,
"ip_conflict=" + ip_conflict,
"address_observed_count=" + address_observed_count,
"required_parameter_data_value=" +
dhcp_parameter_data_required_value().to_string(),
"required_subnet_mask_option=" +
dhcp_subnet_mask_option_required().to_string(),
"required_gateway_option=" + dhcp_gateway_option_required().to_string(),
"other_options_optional=" + dhcp_other_options_optional().to_string(),
"runtime_state=" + runtime_state,
].join("\n")
}
///|
pub fn read_logbook_data(record_text : String) -> String {
let entries : Array[String] = []
let mut source = ""
let mut slot = ""
let mut subslot = ""
let mut block_version_low = "0"
let mut actual_local_timestamp = ""
let mut time_timestamp = ""
let mut entry_local_timestamp = ""
let mut entry_aruuid = ""
let mut entry_pniostatus = ""
let mut entry_detail = ""
fn flush_logbook_entry(
entries : Array[String],
entry_local_timestamp : String,
entry_aruuid : String,
entry_pniostatus : String,
entry_detail : String,
) -> Unit {
if entry_local_timestamp == "" &&
entry_aruuid == "" &&
entry_pniostatus == "" &&
entry_detail == "" {
return
}
entries.push(
"local_timestamp=" +
entry_local_timestamp +
"|aruuid=" +
entry_aruuid +
"|pniostatus=" +
entry_pniostatus +
"|entry_detail=" +
entry_detail,
)
}
for line in fixture_lines(record_text) {
if line == "" || line == "---" {
flush_logbook_entry(
entries, entry_local_timestamp, entry_aruuid, entry_pniostatus, entry_detail,
)
entry_local_timestamp = ""
entry_aruuid = ""
entry_pniostatus = ""
entry_detail = ""
continue
}
if line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"source" => source = value
"slot" => slot = value
"subslot" => subslot = value
"block_version_low" => block_version_low = value
"actual_local_timestamp" => actual_local_timestamp = value
"time_timestamp" => time_timestamp = value
"entry_local_timestamp" => entry_local_timestamp = value
"entry_aruuid" => entry_aruuid = value
"entry_pniostatus" => entry_pniostatus = value
"entry_detail" => entry_detail = value
_ => ()
}
}
flush_logbook_entry(
entries, entry_local_timestamp, entry_aruuid, entry_pniostatus, entry_detail,
)
let lines : Array[String] = []
lines.push("record_index=0xF830")
lines.push("scope=device")
lines.push("source=" + source)
lines.push("slot=" + slot)
lines.push("subslot=" + subslot)
lines.push("block_version_low=" + block_version_low)
lines.push("minimum_entry_capacity=" + minimum_logbook_entries().to_string())
lines.push("ring_buffer=true")
lines.push("whole_buffer_read=true")
if block_version_low == "0" {
lines.push("actual_local_timestamp=" + actual_local_timestamp)
} else {
lines.push("time_timestamp=" + time_timestamp)
}
lines.push("entry_count=" + entries.length().to_string())
for index, entry in entries {
lines.push("entry_" + (index + 1).to_string() + "=" + entry)
}
lines.join("\n")
}
///|
pub fn read_cimsnmp_real(record_text : String) -> String {
let mut source = ""
let mut slot = ""
let mut subslot = ""
let mut snmp_disabled = snmp_default_access_disabled().to_string()
let mut public_community_access = snmp_community_public_access()
let mut private_community_access = snmp_community_private_access()
let mut configuration_owner = "cim"
let mut supported_mib2 = snmp_feature_mib2_required().to_string()
let mut supported_lldp = snmp_feature_lldp_mib_required().to_string()
let mut supported_ieee_8021as = snmp_feature_ieee_8021as_mib_optional().to_string()
let mut supported_bridge = snmp_feature_bridge_mib_optional().to_string()
let mut supported_pno = snmp_feature_pno_mib_optional().to_string()
for line in fixture_lines(record_text) {
if line == "" || line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"source" => source = value
"slot" => slot = value
"subslot" => subslot = value
"snmp_disabled" => snmp_disabled = normalize_fixture_bool_text(value)
"public_community_access" => public_community_access = value
"private_community_access" => private_community_access = value
"configuration_owner" => configuration_owner = value
"supported_mib2" => supported_mib2 = normalize_fixture_bool_text(value)
"supported_lldp" => supported_lldp = normalize_fixture_bool_text(value)
"supported_ieee_8021as" =>
supported_ieee_8021as = normalize_fixture_bool_text(value)
"supported_bridge" =>
supported_bridge = normalize_fixture_bool_text(value)
"supported_pno" => supported_pno = normalize_fixture_bool_text(value)
_ => ()
}
}
[
"record_index=0x8201",
"source=" + source,
"slot=" + slot,
"subslot=" + subslot,
"snmp_disabled=" + snmp_disabled,
"public_community_access=" + public_community_access,
"private_community_access=" + private_community_access,
"configuration_owner=" + configuration_owner,
"explicit_enable_required=" + snmp_explicit_enable_required().to_string(),
"reverts_after_ar_abort=" + snmp_disabled_after_ar_abort().to_string(),
"cim_interface_overrides_ar=" +
snmp_cim_interface_overrides_ar().to_string(),
"supported_mib2=" + supported_mib2,
"supported_lldp=" + supported_lldp,
"supported_ieee_8021as=" + supported_ieee_8021as,
"supported_bridge=" + supported_bridge,
"supported_pno=" + supported_pno,
].join("\n")
}
///|
pub fn capture_lldp_neighbors(capture_text : String) -> String {
let entries : Array[String] = []
let local_ports : Array[String] = []
let mut local_port = ""
let mut chassis_id = ""
let mut port_id = ""
let mut source_mac = ""
let mut system_name = ""
let mut management_address = ""
fn flush_entry(
entries : Array[String],
local_ports : Array[String],
local_port : String,
chassis_id : String,
port_id : String,
source_mac : String,
system_name : String,
management_address : String,
) -> Unit {
if local_port == "" &&
chassis_id == "" &&
port_id == "" &&
source_mac == "" &&
system_name == "" &&
management_address == "" {
return
}
if local_port != "" {
local_ports.push(local_port)
}
entries.push(
"local_port=" +
local_port +
"|chassis_id=" +
chassis_id +
"|port_id=" +
port_id +
"|source_mac=" +
source_mac +
"|system_name=" +
system_name +
"|management_address=" +
management_address,
)
}
for line in fixture_lines(capture_text) {
if line == "" || line == "---" {
flush_entry(
entries, local_ports, local_port, chassis_id, port_id, source_mac, system_name,
management_address,
)
local_port = ""
chassis_id = ""
port_id = ""
source_mac = ""
system_name = ""
management_address = ""
continue
}
if line[:].has_prefix("#") {
continue
}
let parts = line.split("=").to_array()
if parts.length() < 2 {
continue
}
let key = parts[0].trim().to_owned()
let value = parts[1].trim().to_owned()
match key {
"local_port" => local_port = value
"chassis_id" => chassis_id = value
"port_id" => port_id = value
"source_mac" => source_mac = value
"system_name" => system_name = value
"management_address" => management_address = value
_ => ()
}
}
flush_entry(
entries, local_ports, local_port, chassis_id, port_id, source_mac, system_name,
management_address,
)
let lines : Array[String] = []
lines.push("neighbor_count=" + entries.length().to_string())
lines.push(
"minimum_neighbor_capacity=" + lldp_minimum_neighbor_capacity().to_string(),
)
lines.push(
"recommended_neighbor_capacity=" +
lldp_recommended_neighbor_capacity().to_string(),
)
lines.push("local_ports=" + local_ports.join(","))
for index, entry in entries {
lines.push("neighbor_" + (index + 1).to_string() + "=" + entry)
}
lines.join("\n")
}
///|
pub fn standard_baseline_report() -> String {
[
"default_dcp_identify_timeout_ms=" +
default_dcp_identify_timeout_ms().to_string(),
"default_dcp_set_get_timeout_ms=" +
default_dcp_set_get_timeout_ms().to_string(),
"default_dcp_set_get_max_retry_limit=" +
default_dcp_set_get_max_retry_limit().to_string(),
"ip_address_change_bumpless=" + ip_address_change_bumpless().to_string(),
"station_name_change_bumpless=" + station_name_change_bumpless().to_string(),
"mandatory_set_usage_time_ms=" + mandatory_set_usage_time_ms().to_string(),
"recommended_ip_startup_time_ms=" +
recommended_ip_startup_time_ms().to_string(),
"mandatory_ip_startup_time_ms=" + mandatory_ip_startup_time_ms().to_string(),
"recommended_reset_to_factory_time_ms=" +
recommended_reset_to_factory_time_ms().to_string(),
"mandatory_reset_to_factory_time_ms=" +
mandatory_reset_to_factory_time_ms().to_string(),
"recommended_ar_resource_release_timeout_ms=" +
recommended_ar_resource_release_timeout_ms().to_string(),
"mandatory_ar_resource_release_timeout_ms=" +
mandatory_ar_resource_release_timeout_ms().to_string(),
"recommended_autonegotiation_timeout_ms=" +
recommended_autonegotiation_timeout_ms().to_string(),
"mandatory_autonegotiation_timeout_ms=" +
mandatory_autonegotiation_timeout_ms().to_string(),
"minimum_operational_link_speed_mbps=" +
minimum_operational_link_speed_mbps().to_string(),
"required_operational_duplex_mode=" + required_operational_duplex_mode(),
"autonegotiation_fault_requires_link_restart=" +
autonegotiation_fault_requires_link_restart().to_string(),
"pd_port_statistic_record_index=" + pd_port_statistic_record_index(),
"pd_port_mrp_data_real_record_index=" + pd_port_mrp_data_real_record_index(),
"pd_port_mrplc_data_real_record_index=" +
pd_port_mrplc_data_real_record_index(),
"pd_interface_mrp_data_real_record_index=" +
pd_interface_mrp_data_real_record_index(),
"pd_interface_data_real_record_index=" +
pd_interface_data_real_record_index(),
"pdev_data_record_index=" + pdev_data_record_index(),
"pd_real_data_record_index=" + pd_real_data_record_index(),
"pd_port_data_real_extended_record_index=" +
pd_port_data_real_extended_record_index(),
"pd_port_data_real_record_index=" + pd_port_data_real_record_index(),
"pd_port_data_check_record_index=" + pd_port_data_check_record_index(),
"pd_port_data_check_supported_blocks=" +
pd_port_data_check_supported_blocks(),
"mandatory_set_storage_time_ms=" +
mandatory_set_storage_time_ms().to_string(),
"maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound=" +
maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound().to_string(),
"diagnosis_link_state_mismatch_code=" + diagnosis_link_state_mismatch_code(),
"diagnosis_mau_type_mismatch_code=" + diagnosis_mau_type_mismatch_code(),
"diagnosis_line_delay_mismatch_code=" + diagnosis_line_delay_mismatch_code(),
"minimum_logbook_entries=" + minimum_logbook_entries().to_string(),
"pruning_mac_destination_support_recommended=" +
pruning_mac_destination_support_recommended().to_string(),
"lldp_system_capabilities_station_only_required=" +
lldp_system_capabilities_station_only_required().to_string(),
"lldp_msg_tx_hold=" + lldp_msg_tx_hold().to_string(),
"lldp_msg_tx_interval_ms=" + lldp_msg_tx_interval_ms().to_string(),
"lldp_msg_tx_interval_positive_jitter_ms=" +
lldp_msg_tx_interval_positive_jitter_ms().to_string(),
"lldp_tx_ttl_ms=" + lldp_tx_ttl_ms().to_string(),
"lldp_tx_ttl_positive_jitter_ms=" +
lldp_tx_ttl_positive_jitter_ms().to_string(),
"lldp_tx_now_on_change=" + lldp_tx_now_on_change().to_string(),
"lldp_minimum_neighbor_capacity=" +
lldp_minimum_neighbor_capacity().to_string(),
"lldp_recommended_neighbor_capacity=" +
lldp_recommended_neighbor_capacity().to_string(),
"minimum_arp_cache_size=" + minimum_arp_cache_size().to_string(),
"arp_cache_timeout_ms=" + arp_cache_timeout_ms().to_string(),
"arp_response_timeout_ms=" + arp_response_timeout_ms().to_string(),
"dns_request_timeout_ms=" + dns_request_timeout_ms().to_string(),
"reject_dcp_set_requests_support=" + reject_dcp_set_requests_support(),
"snmp_service_optional=" + snmp_service_optional().to_string(),
"snmp_default_access_disabled=" + snmp_default_access_disabled().to_string(),
"snmp_explicit_enable_required=" +
snmp_explicit_enable_required().to_string(),
"snmp_disabled_after_ar_abort=" + snmp_disabled_after_ar_abort().to_string(),
"snmp_cim_interface_overrides_ar=" +
snmp_cim_interface_overrides_ar().to_string(),
"snmp_community_public_access=" + snmp_community_public_access(),
"snmp_community_private_access=" + snmp_community_private_access(),
"recommended_snmp_set_timeout_ms=" +
recommended_snmp_set_timeout_ms().to_string(),
"mandatory_snmp_set_timeout_ms=" +
mandatory_snmp_set_timeout_ms().to_string(),
"recommended_snmp_get_timeout_ms=" +
recommended_snmp_get_timeout_ms().to_string(),
"mandatory_snmp_get_timeout_ms=" +
mandatory_snmp_get_timeout_ms().to_string(),
"recommended_snmp_get_next_timeout_ms=" +
recommended_snmp_get_next_timeout_ms().to_string(),
"mandatory_snmp_get_next_timeout_ms=" +
mandatory_snmp_get_next_timeout_ms().to_string(),
"recommended_snmp_mib_update_time_ms=" +
recommended_snmp_mib_update_time_ms().to_string(),
"mandatory_snmp_mib_update_time_ms=" +
mandatory_snmp_mib_update_time_ms().to_string(),
"snmp_feature_mib2_required=" + snmp_feature_mib2_required().to_string(),
"snmp_feature_lldp_mib_required=" +
snmp_feature_lldp_mib_required().to_string(),
"snmp_feature_ieee_8021as_mib_optional=" +
snmp_feature_ieee_8021as_mib_optional().to_string(),
"snmp_feature_bridge_mib_optional=" +
snmp_feature_bridge_mib_optional().to_string(),
"snmp_feature_pno_mib_optional=" +
snmp_feature_pno_mib_optional().to_string(),
"dhcp_service_optional=" + dhcp_service_optional().to_string(),
"dhcp_subnet_mask_option_required=" +
dhcp_subnet_mask_option_required().to_string(),
"dhcp_gateway_option_required=" + dhcp_gateway_option_required().to_string(),
"dhcp_parameter_data_required_value=" +
dhcp_parameter_data_required_value().to_string(),
"dhcp_other_options_optional=" + dhcp_other_options_optional().to_string(),
].join("\n")
}
///|
pub fn standard_baseline_grouped_report() -> String {
[
[
"[dcp_defaults]",
"default_dcp_identify_timeout_ms=" +
default_dcp_identify_timeout_ms().to_string(),
"default_dcp_set_get_timeout_ms=" +
default_dcp_set_get_timeout_ms().to_string(),
"default_dcp_set_get_max_retry_limit=" +
default_dcp_set_get_max_retry_limit().to_string(),
].join("\n"),
[
"[behavior]",
"ip_address_change_bumpless=" + ip_address_change_bumpless().to_string(),
"station_name_change_bumpless=" +
station_name_change_bumpless().to_string(),
"mandatory_set_usage_time_ms=" + mandatory_set_usage_time_ms().to_string(),
"recommended_ip_startup_time_ms=" +
recommended_ip_startup_time_ms().to_string(),
"mandatory_ip_startup_time_ms=" +
mandatory_ip_startup_time_ms().to_string(),
"recommended_reset_to_factory_time_ms=" +
recommended_reset_to_factory_time_ms().to_string(),
"mandatory_reset_to_factory_time_ms=" +
mandatory_reset_to_factory_time_ms().to_string(),
"recommended_ar_resource_release_timeout_ms=" +
recommended_ar_resource_release_timeout_ms().to_string(),
"mandatory_ar_resource_release_timeout_ms=" +
mandatory_ar_resource_release_timeout_ms().to_string(),
"recommended_autonegotiation_timeout_ms=" +
recommended_autonegotiation_timeout_ms().to_string(),
"mandatory_autonegotiation_timeout_ms=" +
mandatory_autonegotiation_timeout_ms().to_string(),
"minimum_operational_link_speed_mbps=" +
minimum_operational_link_speed_mbps().to_string(),
"required_operational_duplex_mode=" + required_operational_duplex_mode(),
"autonegotiation_fault_requires_link_restart=" +
autonegotiation_fault_requires_link_restart().to_string(),
"pd_port_statistic_record_index=" + pd_port_statistic_record_index(),
"pd_port_mrp_data_real_record_index=" +
pd_port_mrp_data_real_record_index(),
"pd_port_mrplc_data_real_record_index=" +
pd_port_mrplc_data_real_record_index(),
"pd_interface_mrp_data_real_record_index=" +
pd_interface_mrp_data_real_record_index(),
"pd_interface_data_real_record_index=" +
pd_interface_data_real_record_index(),
"pdev_data_record_index=" + pdev_data_record_index(),
"pd_real_data_record_index=" + pd_real_data_record_index(),
"pd_port_data_real_extended_record_index=" +
pd_port_data_real_extended_record_index(),
"pd_port_data_real_record_index=" + pd_port_data_real_record_index(),
"pd_port_data_check_record_index=" + pd_port_data_check_record_index(),
"pd_port_data_check_supported_blocks=" +
pd_port_data_check_supported_blocks(),
"mandatory_set_storage_time_ms=" +
mandatory_set_storage_time_ms().to_string(),
].join("\n"),
[
"[diagnosis_and_lldp]",
"maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound=" +
maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound().to_string(),
"diagnosis_link_state_mismatch_code=" +
diagnosis_link_state_mismatch_code(),
"diagnosis_mau_type_mismatch_code=" + diagnosis_mau_type_mismatch_code(),
"diagnosis_line_delay_mismatch_code=" +
diagnosis_line_delay_mismatch_code(),
"minimum_logbook_entries=" + minimum_logbook_entries().to_string(),
"pruning_mac_destination_support_recommended=" +
pruning_mac_destination_support_recommended().to_string(),
"lldp_system_capabilities_station_only_required=" +
lldp_system_capabilities_station_only_required().to_string(),
"lldp_msg_tx_hold=" + lldp_msg_tx_hold().to_string(),
"lldp_msg_tx_interval_ms=" + lldp_msg_tx_interval_ms().to_string(),
"lldp_msg_tx_interval_positive_jitter_ms=" +
lldp_msg_tx_interval_positive_jitter_ms().to_string(),
"lldp_tx_ttl_ms=" + lldp_tx_ttl_ms().to_string(),
"lldp_tx_ttl_positive_jitter_ms=" +
lldp_tx_ttl_positive_jitter_ms().to_string(),
"lldp_tx_now_on_change=" + lldp_tx_now_on_change().to_string(),
"lldp_minimum_neighbor_capacity=" +
lldp_minimum_neighbor_capacity().to_string(),
"lldp_recommended_neighbor_capacity=" +
lldp_recommended_neighbor_capacity().to_string(),
].join("\n"),
[
"[network]",
"minimum_arp_cache_size=" + minimum_arp_cache_size().to_string(),
"arp_cache_timeout_ms=" + arp_cache_timeout_ms().to_string(),
"arp_response_timeout_ms=" + arp_response_timeout_ms().to_string(),
"dns_request_timeout_ms=" + dns_request_timeout_ms().to_string(),
"reject_dcp_set_requests_support=" + reject_dcp_set_requests_support(),
].join("\n"),
[
"[snmp]",
"snmp_service_optional=" + snmp_service_optional().to_string(),
"snmp_default_access_disabled=" +
snmp_default_access_disabled().to_string(),
"snmp_explicit_enable_required=" +
snmp_explicit_enable_required().to_string(),
"snmp_disabled_after_ar_abort=" +
snmp_disabled_after_ar_abort().to_string(),
"snmp_cim_interface_overrides_ar=" +
snmp_cim_interface_overrides_ar().to_string(),
"snmp_community_public_access=" + snmp_community_public_access(),
"snmp_community_private_access=" + snmp_community_private_access(),
"recommended_snmp_set_timeout_ms=" +
recommended_snmp_set_timeout_ms().to_string(),
"mandatory_snmp_set_timeout_ms=" +
mandatory_snmp_set_timeout_ms().to_string(),
"recommended_snmp_get_timeout_ms=" +
recommended_snmp_get_timeout_ms().to_string(),
"mandatory_snmp_get_timeout_ms=" +
mandatory_snmp_get_timeout_ms().to_string(),
"recommended_snmp_get_next_timeout_ms=" +
recommended_snmp_get_next_timeout_ms().to_string(),
"mandatory_snmp_get_next_timeout_ms=" +
mandatory_snmp_get_next_timeout_ms().to_string(),
"recommended_snmp_mib_update_time_ms=" +
recommended_snmp_mib_update_time_ms().to_string(),
"mandatory_snmp_mib_update_time_ms=" +
mandatory_snmp_mib_update_time_ms().to_string(),
"snmp_feature_mib2_required=" + snmp_feature_mib2_required().to_string(),
"snmp_feature_lldp_mib_required=" +
snmp_feature_lldp_mib_required().to_string(),
"snmp_feature_ieee_8021as_mib_optional=" +
snmp_feature_ieee_8021as_mib_optional().to_string(),
"snmp_feature_bridge_mib_optional=" +
snmp_feature_bridge_mib_optional().to_string(),
"snmp_feature_pno_mib_optional=" +
snmp_feature_pno_mib_optional().to_string(),
].join("\n"),
[
"[dhcp]",
"dhcp_service_optional=" + dhcp_service_optional().to_string(),
"dhcp_subnet_mask_option_required=" +
dhcp_subnet_mask_option_required().to_string(),
"dhcp_gateway_option_required=" +
dhcp_gateway_option_required().to_string(),
"dhcp_parameter_data_required_value=" +
dhcp_parameter_data_required_value().to_string(),
"dhcp_other_options_optional=" + dhcp_other_options_optional().to_string(),
].join("\n"),
].join("\n\n")
}
///|
pub fn standard_baseline_markdown_report() -> String {
[
"## DCP Defaults\n- default_dcp_identify_timeout_ms: " +
default_dcp_identify_timeout_ms().to_string() +
"\n- default_dcp_set_get_timeout_ms: " +
default_dcp_set_get_timeout_ms().to_string() +
"\n- default_dcp_set_get_max_retry_limit: " +
default_dcp_set_get_max_retry_limit().to_string(),
"## Behavior\n- ip_address_change_bumpless: " +
ip_address_change_bumpless().to_string() +
"\n- station_name_change_bumpless: " +
station_name_change_bumpless().to_string() +
"\n- mandatory_set_usage_time_ms: " +
mandatory_set_usage_time_ms().to_string() +
"\n- recommended_ip_startup_time_ms: " +
recommended_ip_startup_time_ms().to_string() +
"\n- mandatory_ip_startup_time_ms: " +
mandatory_ip_startup_time_ms().to_string() +
"\n- recommended_reset_to_factory_time_ms: " +
recommended_reset_to_factory_time_ms().to_string() +
"\n- mandatory_reset_to_factory_time_ms: " +
mandatory_reset_to_factory_time_ms().to_string() +
"\n- recommended_ar_resource_release_timeout_ms: " +
recommended_ar_resource_release_timeout_ms().to_string() +
"\n- mandatory_ar_resource_release_timeout_ms: " +
mandatory_ar_resource_release_timeout_ms().to_string() +
"\n- recommended_autonegotiation_timeout_ms: " +
recommended_autonegotiation_timeout_ms().to_string() +
"\n- mandatory_autonegotiation_timeout_ms: " +
mandatory_autonegotiation_timeout_ms().to_string() +
"\n- minimum_operational_link_speed_mbps: " +
minimum_operational_link_speed_mbps().to_string() +
"\n- required_operational_duplex_mode: " +
required_operational_duplex_mode() +
"\n- autonegotiation_fault_requires_link_restart: " +
autonegotiation_fault_requires_link_restart().to_string() +
"\n- pd_port_statistic_record_index: " +
pd_port_statistic_record_index() +
"\n- pd_port_mrp_data_real_record_index: " +
pd_port_mrp_data_real_record_index() +
"\n- pd_port_mrplc_data_real_record_index: " +
pd_port_mrplc_data_real_record_index() +
"\n- pd_interface_mrp_data_real_record_index: " +
pd_interface_mrp_data_real_record_index() +
"\n- pd_interface_data_real_record_index: " +
pd_interface_data_real_record_index() +
"\n- pdev_data_record_index: " +
pdev_data_record_index() +
"\n- pd_real_data_record_index: " +
pd_real_data_record_index() +
"\n- pd_port_data_real_extended_record_index: " +
pd_port_data_real_extended_record_index() +
"\n- pd_port_data_real_record_index: " +
pd_port_data_real_record_index() +
"\n- pd_port_data_check_record_index: " +
pd_port_data_check_record_index() +
"\n- pd_port_data_check_supported_blocks: " +
pd_port_data_check_supported_blocks() +
"\n- mandatory_set_storage_time_ms: " +
mandatory_set_storage_time_ms().to_string(),
"## Diagnosis And LLDP\n- maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound: " +
maximum_diagnosis_data_per_submodule_octets_exclusive_upper_bound().to_string() +
"\n- diagnosis_link_state_mismatch_code: " +
diagnosis_link_state_mismatch_code() +
"\n- diagnosis_mau_type_mismatch_code: " +
diagnosis_mau_type_mismatch_code() +
"\n- diagnosis_line_delay_mismatch_code: " +
diagnosis_line_delay_mismatch_code() +
"\n- minimum_logbook_entries: " +
minimum_logbook_entries().to_string() +
"\n- lldp_msg_tx_interval_ms: " +
lldp_msg_tx_interval_ms().to_string() +
"\n- lldp_tx_ttl_ms: " +
lldp_tx_ttl_ms().to_string(),
"## Network\n- minimum_arp_cache_size: " +
minimum_arp_cache_size().to_string() +
"\n- arp_cache_timeout_ms: " +
arp_cache_timeout_ms().to_string() +
"\n- arp_response_timeout_ms: " +
arp_response_timeout_ms().to_string() +
"\n- dns_request_timeout_ms: " +
dns_request_timeout_ms().to_string(),
"## SNMP\n- snmp_service_optional: " +
snmp_service_optional().to_string() +
"\n- snmp_default_access_disabled: " +
snmp_default_access_disabled().to_string() +
"\n- recommended_snmp_set_timeout_ms: " +
recommended_snmp_set_timeout_ms().to_string() +
"\n- mandatory_snmp_set_timeout_ms: " +
mandatory_snmp_set_timeout_ms().to_string(),
"## DHCP\n- dhcp_service_optional: " +
dhcp_service_optional().to_string() +
"\n- dhcp_parameter_data_required_value: " +
dhcp_parameter_data_required_value().to_string() +
"\n- dhcp_other_options_optional: " +
dhcp_other_options_optional().to_string(),
].join("\n\n")
}
///|
pub fn probeability_matrix_report() -> String {
[
"metric=set_usage_time|method=" +
set_usage_time_probeability() +
"|class=" +
set_usage_time_probeability_class(),
"metric=ip_startup_time|method=" +
ip_startup_time_probeability() +
"|class=" +
ip_startup_time_probeability_class(),
"metric=reset_to_factory_time|method=" +
reset_to_factory_time_probeability() +
"|class=" +
reset_to_factory_time_probeability_class(),
"metric=ar_resource_release_time|method=" +
ar_resource_release_time_probeability() +
"|class=" +
ar_resource_release_time_probeability_class(),
"metric=autonegotiation_time|method=" +
autonegotiation_time_probeability() +
"|class=" +
autonegotiation_time_probeability_class(),
"metric=pd_port_statistic|method=" +
pd_port_statistic_probeability() +
"|class=" +
pd_port_statistic_probeability_class(),
"metric=pd_port_mrp_data_real|method=" +
pd_port_mrp_data_real_probeability() +
"|class=" +
pd_port_mrp_data_real_probeability_class(),
"metric=pd_port_mrplc_data_real|method=" +
pd_port_mrplc_data_real_probeability() +
"|class=" +
pd_port_mrplc_data_real_probeability_class(),
"metric=pd_real_data|method=" +
pd_real_data_probeability() +
"|class=" +
pd_real_data_probeability_class(),
"metric=pd_interface_mrp_data_real|method=" +
pd_interface_mrp_data_real_probeability() +
"|class=" +
pd_interface_mrp_data_real_probeability_class(),
"metric=pd_interface_data_real|method=" +
pd_interface_data_real_probeability() +
"|class=" +
pd_interface_data_real_probeability_class(),
"metric=pdev_data|method=" +
pdev_data_probeability() +
"|class=" +
pdev_data_probeability_class(),
"metric=pd_port_data_real|method=" +
pd_port_data_real_probeability() +
"|class=" +
pd_port_data_real_probeability_class(),
"metric=lldp_neighbor_state|method=" +
lldp_neighbor_probeability() +
"|class=" +
lldp_neighbor_probeability_class(),
"metric=logbook_data|method=" +
logbook_data_probeability() +
"|class=" +
logbook_data_probeability_class(),
"metric=snmp_default_state|method=" +
snmp_default_state_probeability() +
"|class=" +
snmp_default_state_probeability_class(),
"metric=snmp_timeout|method=" +
snmp_timeout_probeability() +
"|class=" +
snmp_timeout_probeability_class(),
"metric=snmp_mib_update|method=" +
snmp_mib_update_probeability() +
"|class=" +
snmp_mib_update_probeability_class(),
"metric=dhcp_option_support|method=" +
dhcp_option_support_probeability() +
"|class=" +
dhcp_option_support_probeability_class(),
"metric=dhcp_runtime_state|method=" +
dhcp_runtime_state_probeability() +
"|class=" +
dhcp_runtime_state_probeability_class(),
].join("\n")
}
// ── Alarm facade ────────────────────────────────────────────────
///|
pub fn encode_alarm_cr_block_req() -> Bytes {
@alarm.encode_alarm_cr_block_req(@alarm.AlarmCRBlockReq::default())
}
///|
pub fn parse_alarm_cr_block_res(
data : Bytes,
offset : Int,
) -> @alarm.AlarmCRBlockRes raise @frame.FrameError {
@alarm.parse_alarm_cr_block_res(data, offset)
}
///|
pub fn parse_alarm_notification(
data : Bytes,
offset : Int,
) -> @alarm.AlarmNotification raise @frame.FrameError {
@alarm.parse_alarm_notification(data, offset)
}
///|
pub fn format_alarm_notification(alarm : @alarm.AlarmNotification) -> String {
@alarm.format_alarm_notification(alarm)
}
// ── RPC/DCE facade ──────────────────────────────────────────────
///|
pub fn encode_dce_header(header : @rpc.DceHeader) -> Bytes {
@rpc.encode_dce_header(header)
}
///|
pub fn parse_dce_header(
data : Bytes,
offset : Int,
) -> @rpc.DceHeader raise @frame.FrameError {
@rpc.parse_dce_header(data, offset)
}
///|
pub fn format_dce_header(header : @rpc.DceHeader) -> String {
@rpc.format_dce_header(header)
}
// ── AR/IOCR facade ──────────────────────────────────────────────
///|
pub fn encode_ar_block_req(req : @ar.ARBlockReq) -> Bytes {
@ar.encode_ar_block_req(req)
}
///|
pub fn parse_ar_block_res(
data : Bytes,
offset : Int,
) -> @ar.ARBlockRes raise @frame.FrameError {
@ar.parse_ar_block_res(data, offset)
}
///|
pub fn encode_iocr_block_req(req : @ar.IOCRBlockReq) -> Bytes {
@ar.encode_iocr_block_req(req)
}
///|
pub fn parse_iocr_block_res(
data : Bytes,
offset : Int,
) -> @ar.IOCRBlockRes raise @frame.FrameError {
@ar.parse_iocr_block_res(data, offset)
}
// ── IO Data Exchange facade ─────────────────────────────────────
///|
pub fn encode_cyclic_frame(frame : @io.IoCyclicFrame) -> Bytes {
@io.encode_cyclic_frame(frame)
}
///|
pub fn parse_cyclic_frame(
data : Bytes,
offset : Int,
data_length : Int,
) -> @io.IoCyclicFrame raise @frame.FrameError {
@io.parse_cyclic_frame(data, offset, data_length)
}
///|
pub fn parse_iam0(
data : Bytes,
offset : Int,
) -> @io.IAndM0 raise @frame.FrameError {
@io.parse_iam0(data, offset)
}
///|
pub fn format_iam0(iam0 : @io.IAndM0) -> String {
@io.format_iam0(iam0)
}
// ── Record Read/Write facade ────────────────────────────────────
///|
pub fn encode_iod_read_req_header(req : @record.IODReadReqHeader) -> Bytes {
@record.encode_iod_read_req_header(req)
}
///|
pub fn encode_iod_write_req_header(req : @record.IODWriteReqHeader) -> Bytes {
@record.encode_iod_write_req_header(req)
}
///|
pub fn encode_iod_control_req(req : @record.IODControlReq) -> Bytes {
@record.encode_iod_control_req(req)
}
///|
pub fn parse_iod_control_req(
data : Bytes,
offset : Int,
) -> @record.IODControlReq raise @frame.FrameError {
@record.parse_iod_control_req(data, offset)
}
// ── PROFIdrive facade ───────────────────────────────────────────
///|
pub fn encode_profidrive_param_request(req : @profidrive.ParamRequest) -> Bytes {
@profidrive.encode_param_request(req)
}
///|
pub fn parse_profidrive_param_response(
data : Bytes,
offset : Int,
) -> @profidrive.ParamResponse raise @frame.FrameError {
@profidrive.parse_param_response(data, offset)
}
///|
pub fn format_profidrive_param_request(
req : @profidrive.ParamRequest,
) -> String {
@profidrive.format_param_request(req)
}
// ── SNMP facade ─────────────────────────────────────────────────
///|
pub fn build_snmp_get_request(
community : String,
request_id : Int,
oid : String,
) -> @snmp.SnmpMessage {
@snmp.build_get_request(community, request_id, oid)
}
///|
pub fn build_snmp_get_next_request(
community : String,
request_id : Int,
oid : String,
) -> @snmp.SnmpMessage {
@snmp.build_get_next_request(community, request_id, oid)
}
///|
pub fn format_snmp_message(msg : @snmp.SnmpMessage) -> String {
@snmp.format_snmp_message(msg)
}
// ── LLDP facade ─────────────────────────────────────────────────
///|
pub fn parse_lldp_tlvs(
data : Bytes,
offset : Int,
) -> Array[@lldp.LldpTlv] raise @frame.FrameError {
@lldp.parse_lldp_tlvs(data, offset)
}
///|
pub fn extract_lldp_neighbor(tlvs : Array[@lldp.LldpTlv]) -> @lldp.LldpNeighbor {
@lldp.extract_neighbor(tlvs)
}
///|
pub fn format_lldp_neighbor(n : @lldp.LldpNeighbor) -> String {
@lldp.format_neighbor(n)
}
// ── DHCP facade ─────────────────────────────────────────────────
///|
pub fn build_dhcp_discover(
mac : Bytes,
xid : Int,
hostname? : String = "",
) -> @dhcp.DhcpMessage {
@dhcp.build_discover(mac, xid, hostname~)
}
///|
pub fn encode_dhcp_message(msg : @dhcp.DhcpMessage) -> Bytes {
@dhcp.encode_dhcp_message(msg)
}
///|
pub fn parse_dhcp_message(
data : Bytes,
) -> @dhcp.DhcpMessage raise @frame.FrameError {
@dhcp.parse_dhcp_message(data)
}
///|
pub fn format_dhcp_message(msg : @dhcp.DhcpMessage) -> String {
@dhcp.format_dhcp_message(msg)
}
///|
pub fn probeability_matrix_markdown_report() -> String {
[
"| Metric | Method | Class |",
"| --- | --- | --- |",
"| set_usage_time | " +
set_usage_time_probeability() +
" | " +
set_usage_time_probeability_class() +
" |",
"| ip_startup_time | " +
ip_startup_time_probeability() +
" | " +
ip_startup_time_probeability_class() +
" |",
"| reset_to_factory_time | " +
reset_to_factory_time_probeability() +
" | " +
reset_to_factory_time_probeability_class() +
" |",
"| ar_resource_release_time | " +
ar_resource_release_time_probeability() +
" | " +
ar_resource_release_time_probeability_class() +
" |",
"| autonegotiation_time | " +
autonegotiation_time_probeability() +
" | " +
autonegotiation_time_probeability_class() +
" |",
"| pd_port_statistic | " +
pd_port_statistic_probeability() +
" | " +
pd_port_statistic_probeability_class() +
" |",
"| pd_port_mrp_data_real | " +
pd_port_mrp_data_real_probeability() +
" | " +
pd_port_mrp_data_real_probeability_class() +
" |",
"| pd_port_mrplc_data_real | " +
pd_port_mrplc_data_real_probeability() +
" | " +
pd_port_mrplc_data_real_probeability_class() +
" |",
"| pd_real_data | " +
pd_real_data_probeability() +
" | " +
pd_real_data_probeability_class() +
" |",
"| pd_interface_mrp_data_real | " +
pd_interface_mrp_data_real_probeability() +
" | " +
pd_interface_mrp_data_real_probeability_class() +
" |",
"| pd_interface_data_real | " +
pd_interface_data_real_probeability() +
" | " +
pd_interface_data_real_probeability_class() +
" |",
"| pdev_data | " +
pdev_data_probeability() +
" | " +
pdev_data_probeability_class() +
" |",
"| pd_port_data_real | " +
pd_port_data_real_probeability() +
" | " +
pd_port_data_real_probeability_class() +
" |",
"| lldp_neighbor_state | " +
lldp_neighbor_probeability() +
" | " +
lldp_neighbor_probeability_class() +
" |",
"| logbook_data | " +
logbook_data_probeability() +
" | " +
logbook_data_probeability_class() +
" |",
"| snmp_default_state | " +
snmp_default_state_probeability() +
" | " +
snmp_default_state_probeability_class() +
" |",
"| snmp_timeout | " +
snmp_timeout_probeability() +
" | " +
snmp_timeout_probeability_class() +
" |",
"| snmp_mib_update | " +
snmp_mib_update_probeability() +
" | " +
snmp_mib_update_probeability_class() +
" |",
"| dhcp_option_support | " +
dhcp_option_support_probeability() +
" | " +
dhcp_option_support_probeability_class() +
" |",
"| dhcp_runtime_state | " +
dhcp_runtime_state_probeability() +
" | " +
dhcp_runtime_state_probeability_class() +
" |",
].join("\n")
}
///|
pub fn acquisition_channel_skeleton_report() -> String {
[
"class=requires_protocol_extension|metric=ar_resource_release_time|channel=ar_session_trace|planned_api=trace_ar_resource_release_time|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_link_state_capture|metric=autonegotiation_time|channel=link_state_trace|planned_api=trace_link_state_autonegotiation|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_port_statistic|channel=record_read_pdportstatistic|planned_api=read_pd_port_statistic|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_port_mrp_data_real|channel=record_read_pdportmrpdatareal|planned_api=read_pd_port_mrp_data_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_port_mrplc_data_real|channel=record_read_pdportmrplcdatareal|planned_api=read_pd_port_mrplc_data_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_real_data|channel=record_read_pdrealdata|planned_api=read_pd_real_data|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_interface_mrp_data_real|channel=record_read_pdinterfacemrpdatareal|planned_api=read_pd_interface_mrp_data_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_interface_data_real|channel=record_read_pdinterfacedatareal|planned_api=read_pd_interface_data_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pdev_data|channel=record_read_pdevdata|planned_api=read_pdev_data|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=pd_port_data_real|channel=record_read_pdportdatareal|planned_api=read_pd_port_data_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=indirect_only|metric=dhcp_runtime_state|channel=indirect_ip_observation|planned_api=observe_dhcp_runtime_state|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=logbook_data|channel=record_read_logbookdata|planned_api=read_logbook_data|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=snmp_default_state|channel=record_read_cimsnmpreal|planned_api=read_cimsnmp_real|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=snmp_timeout|channel=active_snmp_roundtrip|planned_api=measure_snmp_roundtrip|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_protocol_extension|metric=snmp_mib_update|channel=active_snmp_polling|planned_api=measure_snmp_mib_update|planned_inputs=fixture_text|status=offline_fixture_ready",
"class=requires_packet_capture|metric=lldp_neighbor_state|channel=passive_lldp_capture|planned_api=capture_lldp_neighbors|planned_inputs=fixture_text|status=offline_fixture_ready",
].join("\n")
}
///|
pub fn acquisition_channel_skeleton_markdown_report() -> String {
[
"| Class | Metric | Channel | Planned API | Planned Inputs | Status |", "| --- | --- | --- | --- | --- | --- |",
"| requires_protocol_extension | ar_resource_release_time | ar_session_trace | trace_ar_resource_release_time | fixture_text | offline_fixture_ready |",
"| requires_link_state_capture | autonegotiation_time | link_state_trace | trace_link_state_autonegotiation | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_port_statistic | record_read_pdportstatistic | read_pd_port_statistic | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_port_mrp_data_real | record_read_pdportmrpdatareal | read_pd_port_mrp_data_real | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_port_mrplc_data_real | record_read_pdportmrplcdatareal | read_pd_port_mrplc_data_real | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_real_data | record_read_pdrealdata | read_pd_real_data | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_interface_mrp_data_real | record_read_pdinterfacemrpdatareal | read_pd_interface_mrp_data_real | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_interface_data_real | record_read_pdinterfacedatareal | read_pd_interface_data_real | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pdev_data | record_read_pdevdata | read_pdev_data | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | pd_port_data_real | record_read_pdportdatareal | read_pd_port_data_real | fixture_text | offline_fixture_ready |",
"| indirect_only | dhcp_runtime_state | indirect_ip_observation | observe_dhcp_runtime_state | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | logbook_data | record_read_logbookdata | read_logbook_data | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | snmp_default_state | record_read_cimsnmpreal | read_cimsnmp_real | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | snmp_timeout | active_snmp_roundtrip | measure_snmp_roundtrip | fixture_text | offline_fixture_ready |",
"| requires_protocol_extension | snmp_mib_update | active_snmp_polling | measure_snmp_mib_update | fixture_text | offline_fixture_ready |",
"| requires_packet_capture | lldp_neighbor_state | passive_lldp_capture | capture_lldp_neighbors | fixture_text | offline_fixture_ready |",
].join("\n")
}
///|
pub fn parse_gsdml_summary_text(xml_text : String) -> String raise {
let summary = @gsd.parse_gsdml_summary(xml_text)
format_gsd_summary(summary)
}
// ── GSD detail facade ───────────────────────────────────────────
///|
pub fn parse_gsdml_detail_text(xml_text : String) -> String raise {
let detail = @gsd.parse_gsdml_detail(xml_text)
@gsd.format_gsd_detail(detail)
}
// ── PROFIdrive controller facade ────────────────────────────────
///|
pub fn profidrive_stw1_for_state(target : @profidrive.DriveState) -> Int {
@profidrive.stw1_for_transition(target)
}
///|
pub fn profidrive_state_from_zsw1(zsw1 : Int) -> String {
@profidrive.drive_state_label(@profidrive.drive_state_from_zsw1(zsw1))
}
///|
pub fn profidrive_format_telegram(tg : @profidrive.TelegramData) -> String {
@profidrive.format_telegram(tg)
}
///|
pub fn profidrive_pnu_label_ext(pnu : Int) -> String {
@profidrive.pnu_label_ext(pnu)
}
// ── Security facade ─────────────────────────────────────────────
///|
pub fn security_format_info(
mode : @security.SecurityMode,
alg : @security.AeadAlgorithm,
) -> String {
@security.format_security_info(mode, alg)
}
///|
pub fn security_encode_header(sd : @security.SecurityData) -> Bytes {
@security.encode_security_data(sd)
}
///|
pub fn security_parse_header(
data : Bytes,
offset : Int,
) -> @security.SecurityData raise {
@security.parse_security_data(data, offset)
}
///|
pub fn security_format_header(sd : @security.SecurityData) -> String {
@security.format_security_data(sd)
}
// ── Alarm hex facade ────────────────────────────────────────────
///|
pub fn decode_alarm_notification_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
let notif = @alarm.parse_alarm_notification(data, 0)
@alarm.format_alarm_notification(notif)
}
// ── RPC hex facade ──────────────────────────────────────────────
///|
pub fn decode_rpc_header_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
let hdr = @rpc.parse_dce_header(data, 0)
@rpc.format_dce_header(hdr)
}
// ── AR hex facade ───────────────────────────────────────────────
///|
pub fn format_ar_block_req_default(station_name : String) -> String {
let req = @ar.ARBlockReq::default(
@rpc.Uuid::empty(),
@frame.MacAddress::broadcast(),
station_name,
)
@ar.format_ar_block_req(req)
}
///|
pub fn format_iocr_block_req_default(frame_id : Int) -> String {
let req = @ar.IOCRBlockReq::default_input(frame_id)
@ar.format_iocr_block_req(req)
}
// ── IO hex facade ───────────────────────────────────────────────
///|
pub fn decode_io_cyclic_frame_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
// frame_id(2) + payload(N) + cycle_counter(2) + data_status(1) + transfer_status(1)
let payload_len = data.length() - 6
guard payload_len >= 0 else {
raise @frame.FrameError::InvalidMacLength(data.length())
}
let frame = @io.parse_cyclic_frame(data, 0, payload_len)
let lines : Array[String] = []
lines.push("frame_id=0x" + @frame.uint16_to_hex(frame.frame_id))
lines.push("cycle_counter=" + frame.cycle_counter.to_string())
lines.push(
"data_status=0x" + @frame.uint16_to_hex(frame.data_status.to_int()),
)
let data_status = @io.decode_data_status(frame.data_status)
lines.push("data_status_state=" + data_status.state)
lines.push("data_status_redundancy=" + data_status.redundancy)
lines.push("data_status_data_valid=" + data_status.data_valid)
lines.push("data_status_provider_state=" + data_status.provider_state)
lines.push("data_status_station_problem=" + data_status.station_problem)
lines.push("data_status_ignore=" + data_status.ignore)
lines.push(
"transfer_status=0x" + @frame.uint16_to_hex(frame.transfer_status.to_int()),
)
lines.push("payload_length=" + frame.payload.length().to_string())
lines.join("\n")
}
///|
pub fn decode_iam0_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
let iam0 = @io.parse_iam0(data, 0)
@io.format_iam0(iam0)
}
// ── Record hex facade ───────────────────────────────────────────
///|
pub fn encode_record_read_hex(slot : Int, subslot : Int, index : Int) -> String {
let req = @record.IODReadReqHeader::{
seq_number: 0,
ar_uuid: @rpc.Uuid::empty(),
api: 0,
slot_number: slot,
subslot_number: subslot,
index,
record_data_length: 0,
}
@frame.bytes_to_hex(@record.encode_iod_read_req_header(req), separator="")
}
///|
pub fn format_record_read_req(slot : Int, subslot : Int, index : Int) -> String {
let req = @record.IODReadReqHeader::{
seq_number: 0,
ar_uuid: @rpc.Uuid::empty(),
api: 0,
slot_number: slot,
subslot_number: subslot,
index,
record_data_length: 0,
}
@record.format_iod_read_req(req)
}
// ── SNMP hex facade ─────────────────────────────────────────────
///|
pub fn encode_snmp_get_hex(oid : String, community : String) -> String {
let msg = @snmp.build_get_request(community, 1, oid)
@frame.bytes_to_hex(@snmp.encode_snmp_message(msg), separator="")
}
// ── LLDP hex facade ─────────────────────────────────────────────
///|
pub fn decode_lldp_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
let tlvs = @lldp.parse_lldp_tlvs(data, 0)
let neighbor = @lldp.extract_neighbor(tlvs)
@lldp.format_neighbor(neighbor)
}
// ── DHCP hex facade ─────────────────────────────────────────────
///|
pub fn decode_dhcp_hex(hex : StringView) -> String raise {
let data = @frame.bytes_from_hex(hex)
let msg = @dhcp.parse_dhcp_message(data)
@dhcp.format_dhcp_message(msg)
}
///|
pub fn encode_dhcp_discover_hex(
mac : StringView,
hostname : String,
) -> String raise {
let mac_addr = @frame.MacAddress::from_hex(mac)
let mac_bytes = mac_addr.octets()
let msg = @dhcp.build_discover(mac_bytes, 0x12345678, hostname~)
@frame.bytes_to_hex(@dhcp.encode_dhcp_message(msg), separator="")
}