diff -uNr a/smg_comms/manifest b/smg_comms/manifest --- a/smg_comms/manifest false +++ b/smg_comms/manifest 865132e483b57dcf86c4beb6f0123019747cbcb3745f8e297103d0e931af958d9a4e57f213b6b41ba8b7ad0fcd6b0dd0967150243d24a9bc24c5f6fc6a365b1c @@ -0,0 +1,2 @@ +532398 smg_comms_genesis diana_coman The first seed of an implementation of S.MG's communication protocol for Eulora: definitions for basic types, methods to/from network format, basic client/server test running locally on the same machine. + diff -uNr a/smg_comms/obj/README b/smg_comms/obj/README --- a/smg_comms/obj/README false +++ b/smg_comms/obj/README 50f9b127e6ae2019779520d8998bea7f559496b1847c7c66b6ce6a6f3fc20db67d45f1fbf7a9318c86ebba0694db73de168f409d8328a751f3104c1474a83a0d @@ -0,0 +1 @@ +obj diff -uNr a/smg_comms/smg_comms.gpr b/smg_comms/smg_comms.gpr --- a/smg_comms/smg_comms.gpr false +++ b/smg_comms/smg_comms.gpr 7ca4898ea436586cb87f25161c03b7118cd3f7ff3805079ea8e73a523b2a6f97b0e698256954ab2c3fcfcbd2db8d6fe1545d618054cdb04072cd3d784f17be2f @@ -0,0 +1,24 @@ + -- S.MG, 2018 + -- prototype implementation of S.MG communication protocol + -- http://trilema.com/2018/euloras-communication-protocol-restated/ + +project SMG_comms is + for Languages use ("Ada"); + + for Source_Dirs use ("src"); + for Ignore_Source_Sub_Dirs use (".svn", ".git", "@*"); + + for Object_Dir use "obj"; + for Exec_Dir use "."; + + for Main use ("test_comms.adb"); + + package Builder is + for Executable ("test_comms.adb") use "test_comms"; + end Builder; + + package Compiler is + for Default_Switches ("Ada") use ("-O2"); + end Compiler; + +end SMG_comms; diff -uNr a/smg_comms/src/smg_comms_types.adb b/smg_comms/src/smg_comms_types.adb --- a/smg_comms/src/smg_comms_types.adb false +++ b/smg_comms/src/smg_comms_types.adb 59000f9e3569f550c5994913e7ba3cdb6cbb964deb307a47676b5feba9220f70b0bef3f187b22a4e69948037e6a046ed91001bcb66adab6eeee42199a0e84208 @@ -0,0 +1,69 @@ + -- S.MG, 2018 + -- prototype implementation of S.MG communication protocol + +with SMG_comms_types; use SMG_comms_types; +with System; use System; -- endianness +with Ada.Exceptions; +with Ada.Streams; use Ada.Streams; + +package body SMG_comms_types is + + -- to and from network format (i.e. big endian, stream_element_array) + procedure ToNetworkFormat( + Item : in Octet_Array; + Buffer : out Stream_Element_Array) is + begin + if Item'Length /= Buffer'Length then + raise Constraint_Error with "Item and Buffer lengths do NOT match!"; + end if; + + if Default_Bit_Order = Low_Order_First then + for I in 0 .. Item'Length - 1 loop + Buffer( Buffer'Last - Stream_Element_Offset(I) ) := Stream_Element(Item(Item'First + I)); + end loop; + else + for I in 0 .. Item'Length - 1 loop + Buffer( Buffer'First + Stream_Element_Offset(I) ) := Stream_Element(Item(Item'First + I)); + end loop; + end if; + end ToNetworkFormat; + + procedure FromNetworkFormat( + Buffer : in Stream_Element_Array; + Item : out Octet_Array) is + begin + if Item'Length /= Buffer'Length then + raise Constraint_Error with "Buffer and Item length do NOT match!"; + end if; + + if Default_Bit_Order = Low_Order_First then + for I in 0 .. Buffer'Length - 1 loop + Item( Item'Last - I ) := + Unsigned_8( Buffer( Buffer'First + Stream_Element_Offset( I ) ) ); + end loop; + else + for I in 0 .. Buffer'Length - 1 loop + Item( Item'First + I ) := + Unsigned_8( Buffer( Buffer'First + Stream_Element_Offset( I ) ) ); + end loop; + end if; + end FromNetworkFormat; + + -- Integer_8 + procedure ToNetworkFormat( + Item : in Integer_8; + Buffer : out Stream_Element_Array) is + begin + ToNetworkFormat( Cast( Item ), Buffer ); + end ToNetworkFormat; + + procedure FromNetworkFormat( + Buffer : in Stream_Element_Array; + Item : out Integer_8) is + octets: Octets_1; + begin + FromNetworkFormat(Buffer, octets); + Item := Cast( octets ); + end FromNetworkFormat; + +end SMG_comms_types; diff -uNr a/smg_comms/src/smg_comms_types.ads b/smg_comms/src/smg_comms_types.ads --- a/smg_comms/src/smg_comms_types.ads false +++ b/smg_comms/src/smg_comms_types.ads a2253e5b8f18b3f3d7d9f7d0198761771470d53dc72986c9be61b9809f101290f7def2f92970dd973e523e567a84375a25ffae2c7a80f227ae49542b75f9b259 @@ -0,0 +1,52 @@ + -- S.MG, 2018 + -- prototype implementation of S.MG communication protocol + +with Ada.Streams; use Ada.Streams; +with Interfaces; use Interfaces; -- Integer_n and Unsigned_n +with Ada.Unchecked_Conversion; -- converting int/uint to array of octets + +package SMG_comms_types is + -- basic types with guaranteed lengths + type Octet_Array is array(Natural range <>) of Unsigned_8; + + subtype Octets_1 is Octet_Array( 1 .. 1 ); + subtype Octets_2 is Octet_Array( 1 .. 2 ); + subtype Octets_4 is Octet_Array( 1 .. 4 ); + subtype Octets_8 is Octet_Array( 1 .. 8 ); + + subtype Message is Octet_Array( 1 .. 512 ); + subtype RSAMessage is Octet_Array( 1 .. 245 ); + + -- blind, unchecked casts ( memcpy style ) + function Cast is new Ada.Unchecked_Conversion( Integer_8, Octets_1 ); + function Cast is new Ada.Unchecked_Conversion( Octets_1, Integer_8 ); + + function Cast is new Ada.Unchecked_Conversion( Integer_16, Octets_2 ); + function Cast is new Ada.Unchecked_Conversion( Octets_2, Integer_16 ); + + function Cast is new Ada.Unchecked_Conversion( Integer_32, Octets_4 ); + function Cast is new Ada.Unchecked_Conversion( Octets_4, Integer_32 ); + + function Cast is new Ada.Unchecked_Conversion( Integer_64, Octets_8 ); + function Cast is new Ada.Unchecked_Conversion( Octets_8, Integer_64 ); + + -- to and from streams for network communications - general + procedure ToNetworkFormat( + Item : in Octet_Array; + Buffer : out Stream_Element_Array); + + procedure FromNetworkFormat( + Buffer : in Stream_Element_Array; + Item : out Octet_Array); + + -- specific, convenience methods for the basic types + -- Integer_8 + procedure ToNetworkFormat( + Item : in Integer_8; + Buffer : out Stream_Element_Array); + + procedure FromNetworkFormat( + Buffer : in Stream_Element_Array; + Item : out Integer_8); + +end SMG_comms_types; diff -uNr a/smg_comms/src/test_comms.adb b/smg_comms/src/test_comms.adb --- a/smg_comms/src/test_comms.adb false +++ b/smg_comms/src/test_comms.adb abf3a0700182a7622a7468465c37f038b72818ddd9500efe683a923e7ca8f020c08a236bfdb0bce0c0d65fbc2425d90251688e21b834b1ef8ef5982c6f94071c @@ -0,0 +1,87 @@ + -- S.MG, 2018 + -- prototype implementation of S.MG communication protocol + +with GNAT.Sockets; use GNAT.Sockets; +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Streams; use Ada.Streams; +with Interfaces; use Interfaces; + +with SMG_comms_types; use SMG_comms_types; + +procedure test_comms is + Port_No : constant := 2222; + + task type Client is + entry Send; + end Client; + + task type Server is + entry Listen; + entry Ready; + end Server; + + task body Client is + Sock: Socket_Type; + Address: Sock_Addr_Type; + Data: Ada.Streams.Stream_Element_Array(1..10) := (others => 42); + Last: Ada.Streams.Stream_Element_Offset; + N : Integer_8 := -36; + begin + accept Send; -- task WILL block here until asked to send + Address.Port := Port_No; + Address.Addr := Inet_Addr("127.0.0.1"); + Create_Socket(Sock, Family_Inet, Socket_Datagram); + + ToNetworkFormat( N, Data(1..1)); + + Send_Socket(Sock, Data, Last, Address); + Put_Line("Client sent data " & "last: " & Last'Img); + end Client; + + task body Server is + Sock: Socket_Type; + Address, From: Sock_Addr_Type; + Data: Ada.Streams.Stream_Element_Array(1..512); + Last: Ada.Streams.Stream_Element_Offset; + N : Integer_8; + begin + accept Listen; -- wait to be started! + Put_Line("Server started!"); + -- create UDP socket + Create_Socket( Sock, Family_Inet, Socket_Datagram ); + + -- set options on UDP socket + Set_Socket_Option( Sock, Socket_Level, (Reuse_Address, True)); + Set_Socket_Option( Sock, Socket_Level, (Receive_Timeout, Timeout => 10.0)); + + -- set address and bind + Address.Addr := Any_Inet_Addr; + Address.Port := Port_No; + Bind_Socket( Sock, Address ); + + accept Ready; -- server IS ready, when here + -- receive on socket + begin + Receive_Socket( Sock, Data, Last, From ); + Put_Line("last: " & Last'Img); + Put_Line("from: " & Image(From.Addr)); + Put_Line("data is:"); + for I in Data'First .. Last loop + FromNetworkFormat(Data(I..I), N); + Put_Line(N'Image); + end loop; + exception + when Socket_Error => + Put_Line("Socket error! (timeout?)"); + end; -- end of receive + + end Server; + + S: Server; + C: Client; +begin + S.Listen; + S.Ready; -- WAIT for server to be ready! + C.Send; -- client is started only after server! +end test_comms; +