-- SPDX-License-Identifier: GPL-3.0-or-later ------------------------------------------------------------------------ -- pla-util - A power line adapter utility -- Copyright (C) 2016-2023 John Serock -- -- This file is part of pla-util. -- -- pla-util is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- pla-util is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . ------------------------------------------------------------------------ with Ada.Command_Line; with Ada.Strings; with Ada.Strings.Fixed; with Ada.Strings.Maps; with Ada.Text_IO; with Config; with GNAT.Directory_Operations; with GNAT.Formatted_String; with HFID_Strings; with Pla_Util_Config; with Power_Line_Adapter_Sets; with Power_Line_Adapters; use GNAT.Formatted_String; use type Ada.Text_IO.Count; use type Power_Line_Adapters.NID_Type; package body Console is package Chip_Id_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.Chip_Id_Type); package Data_Rate_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.Data_Rate_Type); package Hardware_Version_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.Hardware_Version_Type); package Network_Count_Text_IO is new Ada.Text_IO.Integer_IO (Num => Power_Line_Adapters.Network_Count_Type); package NID_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.NID_Type); package Param_Config_Version_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.Param_Config_Version_Type); package Partial_Version_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.Partial_Version_Type); package SNID_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.SNID_Type); package TEI_Text_IO is new Ada.Text_IO.Modular_IO (Num => Power_Line_Adapters.TEI_Type); function Chip_Id_Format is new GNAT.Formatted_String.Mod_Format (Int => Power_Line_Adapters.Chip_Id_Type, Put => Chip_Id_Text_IO.Put); function Hardware_Version_Format is new GNAT.Formatted_String.Mod_Format (Int => Power_Line_Adapters.Hardware_Version_Type, Put => Hardware_Version_Text_IO.Put); function NID_Format is new GNAT.Formatted_String.Mod_Format (Int => Power_Line_Adapters.NID_Type, Put => NID_Text_IO.Put); App_Name : constant String := GNAT.Directory_Operations.Base_Name (Ada.Command_Line.Command_Name); Separator_Character_Mapping : constant Ada.Strings.Maps.Character_Mapping := Ada.Strings.Maps.To_Mapping (From => "-", To => "_"); Syntax_Error : exception; procedure Check_DAK (Network_Device_Name : String; Passphrase : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is Is_Match : constant Boolean := Commands.Check_DAK (Network_Device_Name => Network_Device_Name, Passphrase => Passphrase, PLA_MAC_Address => PLA_MAC_Address); begin if Is_Match then Ada.Text_IO.Put_Line (Item => "Device Access Key matches"); else Ada.Text_IO.Put_Line (Item => "Device Access Key does not match"); end if; end Check_DAK; procedure Check_NMK (Network_Device_Name : String; Passphrase : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is Is_Match : constant Boolean := Commands.Check_NMK (Network_Device_Name => Network_Device_Name, Passphrase => Passphrase, PLA_MAC_Address => PLA_MAC_Address); begin if Is_Match then Ada.Text_IO.Put_Line (Item => "Network Membership Key matches"); else Ada.Text_IO.Put_Line (Item => "Network Membership Key does not match"); end if; end Check_NMK; procedure Discover (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is Adapters : constant Power_Line_Adapter_Sets.Set := Commands.Discover (Network_Device_Name => Network_Device_Name, PLA_MAC_Address => PLA_MAC_Address); begin for Adapter of Adapters loop Ada.Text_IO.Put_Line (Item => Adapter.Image); end loop; end Discover; procedure Get_Capabilities (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is separate; procedure Get_Discover_List (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is separate; procedure Get_HFID (Network_Device_Name : String; HFID_Level : Commands.HFID_Level_Type; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is HFID : HFID_Strings.Bounded_String; begin HFID := Commands.Get_HFID (Network_Device_Name => Network_Device_Name, HFID_Level => HFID_Level, PLA_MAC_Address => PLA_MAC_Address); Ada.Text_IO.Put_Line (Item => HFID_Strings.To_String (Source => HFID)); end Get_HFID; function Get_HFID_Level (HFID_Level_Text : String) return Commands.HFID_Level_Type is begin return Commands.HFID_Level_Type'Value (HFID_Level_Text); exception when Constraint_Error => raise Syntax_Error with "Invalid HFID level """ & HFID_Level_Text & '"'; end Get_HFID_Level; procedure Get_Id_Info (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is Column_2 : constant := 22; Id_Info : constant Power_Line_Adapters.Id_Info_Type := Commands.Get_Id_Info (Network_Device_Name => Network_Device_Name, PLA_MAC_Address => PLA_MAC_Address); begin Ada.Text_IO.Put (Item => "HomePlug AV Version:"); Ada.Text_IO.Set_Col (To => Column_2); Ada.Text_IO.Put_Line (Item => Image (HPAV_Version => Id_Info.Homeplug_AV_Version)); Ada.Text_IO.Put (Item => "MCS:"); Ada.Text_IO.Set_Col (To => Column_2); Ada.Text_IO.Put_Line (Item => Id_Info.MCS'Image); end Get_Id_Info; procedure Get_Network_Info (Network_Device_Name : String; Network_Scope : Commands.Network_Scope_Type; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is separate; function Get_Network_Scope (Network_Scope_Text : String) return Commands.Network_Scope_Type is begin return Commands.Network_Scope_Type'Value (Network_Scope_Text); exception when Constraint_Error => raise Syntax_Error with "Invalid network scope """ & Network_Scope_Text & '"'; end Get_Network_Scope; procedure Get_Network_Stats (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is separate; function Get_PLA_MAC_Address (MAC_Address_Image : String) return MAC_Addresses.MAC_Address_Type is begin return MAC_Addresses.Value (MAC_Address_Image => MAC_Address_Image); exception when Constraint_Error => raise MAC_Addresses.MAC_Address_Error with "Invalid MAC address '" & MAC_Address_Image & "'"; end Get_PLA_MAC_Address; procedure Get_Station_Info (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is separate; function Image (Chip_Id : Power_Line_Adapters.Chip_Id_Type) return String is begin return "0x" & (-(Chip_Id_Format (Format => +"%08x", Var => Chip_Id))); end Image; function Image (Hardware_Version : Power_Line_Adapters.Hardware_Version_Type) return String is begin return "0x" & (-(Hardware_Version_Format (Format => +"%08x", Var => Hardware_Version))); end Image; function Image (HPAV_Version : Power_Line_Adapters.HPAV_Version_Type) return String is begin case HPAV_Version is when Power_Line_Adapters.HPAV_1_1 => return "1.1"; when Power_Line_Adapters.HPAV_2_0 => return "2.0"; when Power_Line_Adapters.Not_HPAV => return "Not a HomePlug AV device"; end case; end Image; function Image (NID : Power_Line_Adapters.NID_Type) return String is begin return -(NID_Format (Format => +"%014x", Var => NID)) & " (" & Security_Level (NID => NID) & ')'; end Image; function Image (Signal_Level : Power_Line_Adapters.Signal_Level_Type) return String is begin case Signal_Level is when 0 => return "not available"; when 1 => return Integer'Image ((Integer (Signal_Level) + 1) * (-5)) & " dB < SL <= 0 dB"; when 15 => return "SL <= -75 dB"; when others => return Integer'Image ((Integer (Signal_Level) + 1) * (-5)) & " dB < SL <= " & Integer'Image (Integer (Signal_Level) * (-5)) & " dB"; end case; end Image; function Image (Uptime : Power_Line_Adapters.Uptime_Type) return String is Days : Natural; Hours : Natural; Minutes : Natural; Seconds : Natural; Remainder : Natural; use type Power_Line_Adapters.Uptime_Type; begin Days := Natural (Uptime / 86400); Remainder := Natural (Uptime rem 86400); Hours := Remainder / 3600; Remainder := Remainder rem 3600; Minutes := Remainder / 60; Seconds := Remainder rem 60; return -(+"%u %02u:%02u:%02u" & Days & Hours & Minutes & Seconds); end Image; procedure Process_Command_Line is separate; procedure Reset (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is begin Commands.Reset (Network_Device_Name => Network_Device_Name, PLA_MAC_Address => PLA_MAC_Address); Ada.Text_IO.Put_Line (Item => "Device was reset to factory defaults"); end Reset; procedure Restart (Network_Device_Name : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is begin Commands.Restart (Network_Device_Name => Network_Device_Name, PLA_MAC_Address => PLA_MAC_Address); Ada.Text_IO.Put_Line (Item => "Device was restarted"); end Restart; function Security_Level (NID : Power_Line_Adapters.NID_Type) return String is begin return (if (NID and 16#10_0000_0000_0000#) = 0 then "SL-SC" else "SL-HS"); end Security_Level; procedure Set_HFID (Network_Device_Name : String; HFID : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is begin Commands.Set_HFID (Network_Device_Name => Network_Device_Name, HFID => HFID_Strings.To_Bounded_String (Source => HFID, Drop => Ada.Strings.Error), PLA_MAC_Address => PLA_MAC_Address); Ada.Text_IO.Put_Line (Item => "User HFID set"); end Set_HFID; procedure Set_NMK (Network_Device_Name : String; Passphrase : String; PLA_MAC_Address : MAC_Addresses.MAC_Address_Type) is begin Commands.Set_NMK (Network_Device_Name => Network_Device_Name, Passphrase => Passphrase, PLA_MAC_Address => PLA_MAC_Address); Ada.Text_IO.Put_Line (Item => "Network Membership Key set"); end Set_NMK; procedure Show_Help is separate; procedure Show_Version is begin Ada.Text_IO.Put_Line (Item => App_Name & " " & Pla_Util_Config.Crate_Version); end Show_Version; function To_Command (Source : String) return Commands.Command_Type is Command : Commands.Command_Type; Command_Name : constant String := Ada.Strings.Fixed.Translate (Source => Source, Mapping => Separator_Character_Mapping); begin Command := Commands.Command_Type'Value (Command_Name); return Command; exception when Constraint_Error => raise Syntax_Error with "Invalid command '" & Source & "'"; end To_Command; end Console;