diff --git a/eRINA_STM32F7/src/rina/namespace_manager.adb b/eRINA_STM32F7/src/rina/namespace_manager.adb new file mode 100644 index 0000000..bc912dd --- /dev/null +++ b/eRINA_STM32F7/src/rina/namespace_manager.adb @@ -0,0 +1,82 @@ +with Ada.Numerics.Discrete_Random; + +package body Namespace_Manager is + -- instantiate IPCP to App Names map when NSM created inside a DIF + IPCP_To_App_Names : IPCP_Map; + + -- Get IPCP address from app name + function Get_IPCP_Address + (Self : Namespace_Manager; App_Name : Application_Name) + return IPCP_Address + is + Curr_Name : Application_Name; + begin + -- for now, linear O(n) + for IPCP in IPCP_To_App_Names.Iterate loop + Curr_Name := IPCP_To_App_Names (IPCP); + if Curr_Name = App_Name then + return IPCP; + end if; + end loop; + -- Make user handle error + raise Application_Name_Non_Existent; + end Get_IPCP_Address; + + -- Get the app name from IPCP Address + function Get_Application_Name + (IPCP_Addr : IPCP_Address) return Application_Name + is + begin + -- desired route + if IPCP_To_App_Names.Contains (IPCP_Addr) then + return IPCP_To_App_Names (IPCP_Addr); + end if; + -- Make user handle error + raise Application_Name_Non_Existent; + end Get_Application_Name; + + -- store application name with corresponding ipcp address + procedure Assign_Application_Name (App_Name : Application_Name) is + IPCP_Addr : IPCP_Address; + IPCP_Assigned : Boolean; + Pos : Cursor; + IPCP_Alloc_Retry_Count : Integer := IPCP_Address'Last + 1; + begin + -- allocate an unassigned IPCP Address + IPCP_Addr := Allocate_IPCP_Address; + -- Insert IPCP address into map + IPCP_To_App_Names.Insert (IPCP_Addr, App_Name, Pos, IPCP_Assigned); + + -- double check that app name was actually inserted + while IPCP_Assigned /= True and IPCP_Alloc_Retry_Count > 0 loop + -- retry only as many times as there are addresses + IPCP_Addr := Allocate_IPCP_Address; + IPCP_To_App_Names.Insert (IPCP_Addr, App_Name, Pos, IPCP_Assigned); + -- decrement counter + IPCP_Alloc_Retry_Count := IPCP_Alloc_Retry_Count - 1; + end loop; + end Assign_Application_Name; + + -- helper to allocate new IPCP address + function Allocate_IPCP_Address return IPCP_Address is + -- Instantiate Random number with range of IPCP Addrs + package Random_Addr is new Ada.Numerics.Discrete_Random (IPCP_Address); + use Random_Addr; + Gen : Generator; + Addr : IPCP_Address; + Addr_Already_Assigned : Boolean; + begin + Reset + (Gen); -- seed random number generator with new seed every invocation + Addr := Random (Gen); -- choose pseudo random IPCP addr number + -- check if IPCP Addr already allocated + Addr_Already_Assigned := IPCP_To_App_Names.Contains (Addr); + while Addr_Already_Assigned loop + Addr := Random (Gen); -- choose pseudo random IPCP addr number + Addr_Already_Assigned := + IPCP_To_App_Names.Contains (Addr); -- check again + end loop; + return Addr; + end Allocate_IPCP_Address; + +end Namespace_Manager; diff --git a/eRINA_STM32F7/src/rina/namespace_manager.ads b/eRINA_STM32F7/src/rina/namespace_manager.ads new file mode 100644 index 0000000..abd8291 --- /dev/null +++ b/eRINA_STM32F7/src/rina/namespace_manager.ads @@ -0,0 +1,42 @@ +with Names; use Names; +with Ada.Strings.Hash; +with Ada.Containers.Hashed_Maps; use Ada.Containers; + +package Namespace_Manager is + -- Possible errors + Application_Name_Non_Existent : exception; + Application_Name_Already_Assigned : exception; + + -- IPCP address maps to Application name + type Application_Name is + new Names_String; -- The endpoint to send and be sent from + + type IPCP_Address is + new Integer range 0 .. 255; -- IPCP address range is 1 byte + + -- Map of app names to IPCP addrs + package IPCP_To_App is new Ada.Containers.Hashed_Maps + (Key_Type => IPCP_Address, Element_Type => Application_Name, + Hash => Integer.Hash, Equivalent_Keys => "="); + + subtype IPCP_Map is + IPCP_To_App.Map; -- so we don't have to .Map everytime created + + -- Allow getting assigned names + -- and addresses given one or the other + function Get_IPCP_Address + (Self : Namespace_Manager; App_Name : Application_Name) + return IPCP_Address; + + function Get_Application_Name + (Self : Namespace_Manager; IPCP_Add : IPCP_Address) + return Application_Name; + + -- Allow assigning names to IPCP's + procedure Assign_Application_Name (App_Name : Application_Name); + +private + -- Pseudo-randomly choose IPCP address + function Allocate_IPCP_Address return IPCP_Address; + +end Namespace_Manager;