-- Message reader & writers for SMG Communication Protocol -- This part effectively serializes/deserializes game data structures -- for transmission between client and server. -- Note that messages themeselves are simply arrays of octets. -- (see also raw_types.ads/adb and packing.ads/adb for related parts) -- NB: message ids and padding as per protocol spec are handled HERE ONLY. -- Relies on: -- RNG (for random padding) -- CRC32 (for CRC calculations) -- Raw_Types -- Data_Structs -- S.MG, 2018 with Raw_Types; with RNG; with CRC32; with Data_Structs; use Data_Structs; with Interfaces; package Messages is -- exception raised when given message to read fails sanity checks Invalid_Msg: exception; ---------------------- -- Serpent Messages -- ---------------------- -------------------------Keys---------------------------------------- -- Writes a Serpent Keyset to the given Serpent Message -- -- Keyset - the set of keys to write to message -- Counter - the message count procedure Write_SKeys_SMsg( Keyset : in Serpent_Keyset; Counter : in Interfaces.Unsigned_16; Msg : out Raw_Types.Serpent_Msg); -- Reads a Serpent Keyset from the given Serpent Message -- The opposite of Write_SKeys_SMsg above -- Raises Invalid_Message exception if given message fails sanity checks procedure Read_SKeys_SMsg( Msg : in Raw_Types.Serpent_Msg; Counter : out Interfaces.Unsigned_16; Keyset : out Serpent_Keyset); ------------------------Keys Management------------------------------ -- Writes a Key Management structure to the given Serpent Message -- -- KMgm - the keys management structure to write to message -- Counter - the message count procedure Write_KMgm_SMsg( KMgm : in Keys_Mgm; Counter : in Interfaces.Unsigned_16; Msg : out Raw_Types.Serpent_Msg); -- Reads a Key management structure from the given Serpent Message -- The opposite of Write_KMgm_SMsg above -- Raises Invalid_Message exception if given message fails sanity checks procedure Read_KMgm_SMsg( Msg : in Raw_Types.Serpent_Msg; Counter : out Interfaces.Unsigned_16; KMgm : out Keys_Mgm); ----------------- File Transfer ---------------------- -- Writes the given File Chunk to a File Transfer type of message -- Chunk - chunk of file to write; contains counter, filename, content procedure Write_File_Transfer( Chunk : in File_Chunk; Msg : out Raw_Types.Serpent_Msg); -- The opposite of Write_File_Transfer method above. -- Chunk will contain the counter, filename and content procedure Read_File_Transfer( Msg : in Raw_Types.Serpent_Msg; Chunk : out File_Chunk); ----------------- File Request ---------------------- -- Writes a message to request the files specified through their names -- Written parameter will hold the number of filenames actually written -- NB: this can be less than the number of filenames provided! -- When Written < FR.F_No, the FIRST Written filenames were written; the rest -- did not fit into the message and it's up to caller to decide what to do. procedure Write_File_Request( FR : in Filenames; Counter : in Interfaces.Unsigned_16; Msg : out Raw_Types.Serpent_Msg; Written : out Natural); -- Reads a request for files; the opposite of Write_File_Request above -- Raises Invalid_Msg exception if the provided message fails checks. procedure Read_File_Request( Msg : in Raw_Types.Serpent_Msg; Counter : out Interfaces.Unsigned_16; FR : out Filenames); ------------------ -- RSA Messages -- ------------------ -------------------------Keys---------------------------------------- -- Writes a Serpent Keyset to the given RSA Message -- -- Keyset - the set of keys to write to message -- Counter - the message count procedure Write_SKeys_RMsg( Keyset : in Serpent_Keyset; Counter : in Interfaces.Unsigned_16; Msg : out Raw_Types.RSA_Msg); -- Reads a Serpent Keyset from the given RSA Message -- The opposite of Write_SKeys_RMsg above -- Raises Invalid_Message exception if given message fails sanity checks procedure Read_SKeys_RMsg( Msg : in Raw_Types.RSA_Msg; Counter : out Interfaces.Unsigned_16; Keyset : out Serpent_Keyset); ------------------------Keys Management------------------------------ -- Writes a Key Management structure to the given RSA Message -- -- KMgm - the keys management structure to write to message -- Counter - the message count procedure Write_KMgm_RMsg( KMgm : in Keys_Mgm; Counter : in Interfaces.Unsigned_16; Msg : out Raw_Types.RSA_Msg); -- Reads a Key management structure from the given RSA Message -- The opposite of Write_KMgm_SMsg above -- Raises Invalid_Msg exception if given message fails sanity checks procedure Read_KMgm_RMsg( Msg : in Raw_Types.RSA_Msg; Counter : out Interfaces.Unsigned_16; KMgm : out Keys_Mgm); -- String to Octets conversion -- NB: Str'Length has to be EQUAL to Octets'Length! procedure String_To_Octets(Str: in String; O: out Raw_Types.Octets); -- Octets to string conversion -- NB: Str'Length has to be EQUAL to Octets'Length! procedure Octets_To_String(O: in Raw_Types.Octets; Str: out String); private -- if native is little endian, does nothing; -- if native is big endian, it flips the input's octets. -- (strictly for arrays of octets) procedure Cast_LE( LE: in out Raw_Types.Octets ); -- separator used for list of filenames F_Sep: constant String := ";"; --as string Sep: constant Interfaces.Unsigned_8 := 16#3B#; -- ascii code -- protocol message types IDs, fixed as per protocol specification -- Serpent messages end in "S_Type" -- RSA messages end in "R_Type" -- Character action types end in "A_Type" -- Serpent message types SKeys_S_Type : constant Interfaces.Unsigned_8 := 1; Key_Mgm_S_Type : constant Interfaces.Unsigned_8 := 2; File_Transfer_S_Type : constant Interfaces.Unsigned_8 := 3; File_Req_S_Type : constant Interfaces.Unsigned_8 := 4; Client_Action_S_Type : constant Interfaces.Unsigned_8 := 5; World_Bulletin_S_Type: constant Interfaces.Unsigned_8 := 6; Obj_Request_S_Type : constant Interfaces.Unsigned_8 := 7; Obj_Info_S_Type : constant Interfaces.Unsigned_8 := 8; -- RSA message types RKeys_R_Type : constant Interfaces.Unsigned_8 := 251; SKeys_R_Type : constant Interfaces.Unsigned_8 := 157; Key_Mgm_R_Type : constant Interfaces.Unsigned_8 := 233; -- Character action types Lock_A_Type : constant Interfaces.Unsigned_8 := 0; Make_A_Type : constant Interfaces.Unsigned_8 := 1; Explore_A_Type : constant Interfaces.Unsigned_8 := 2; Exchange_A_Type : constant Interfaces.Unsigned_8 := 3; Attack_A_Type : constant Interfaces.Unsigned_8 := 4; Repair_A_Type : constant Interfaces.Unsigned_8 := 5; Move_A_Type : constant Interfaces.Unsigned_8 := 6; Train_A_Type : constant Interfaces.Unsigned_8 := 7; -- internal read/write of Serpent Keys -- those are called by both interface methods for RSA and Serpent messages -- NB: caller HAS TO provide ENOUGH space in Msg AND valid Type_ID -- Msg will be padded with random octets until full length. procedure Write_SKeys( Keyset : in Serpent_Keyset; Counter : in Interfaces.Unsigned_16; Type_ID : in Interfaces.Unsigned_8; Msg : out Raw_Types.Octets); -- NB: caller has to ensure that Msg is a valid RSA or Serpent message procedure Read_SKeys( Msg : in Raw_Types.Octets; Counter : out Interfaces.Unsigned_16; Keyset : out Serpent_Keyset); -- internal read/write of Key Management structures -- those are called by both interface methods for RSA and Serpent messages -- NB: caller HAS TO provide ENOUGH space in Msg AND valid Type_ID -- Msg will be padded with random octets until full length. procedure Write_KMgm( KMgm : in Keys_Mgm; Counter : in Interfaces.Unsigned_16; Type_ID : in Interfaces.Unsigned_8; Msg : out Raw_Types.Octets); -- NB: caller has to ensure that Msg is a valid RSA or Serpent message procedure Read_KMgm( Msg : in Raw_Types.Octets; Counter : out Interfaces.Unsigned_16; KMgm : out Keys_Mgm); -- helper methods to read/write a value on 16 bits (using Cast_LE as needed) -- Writing a 16-bits value to the given Octets at specified position. -- NB: Caller has to make sure Pos <= Msg'Last -1 ; NO check here! -- Msg - the array of octets into which the value is to be written -- Pos - the position in Msg at which to write the value; -- NB: Pos will be increased by 2 after the write! -- U16 - the value to write procedure Write_U16( Msg: in out Raw_Types.Octets; Pos: in out Natural; U16: in Interfaces.Unsigned_16); -- Reading a 16-bits value from the given Octets at specified position. -- NB: Caller has to make sure Pos <= Msg'Last -1 ; NO check here! -- Pos - the position in Msg from which to read the value; -- NB: Pos will be increased by 2 after the read! -- The opposite of Write_U16 above. procedure Read_U16( Msg: in Raw_Types.Octets; Pos: in out Natural; U16: out Interfaces.Unsigned_16); end Messages;