tree checksum vpatch file split hunks
all signers: diana_coman
antecedents:
press order:
smg_comms_genesis | diana_coman |
patch:
(0 . 0)(1 . 2)
5 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.
6
-(0 . 0)(1 . 1)
11 obj
-(0 . 0)(1 . 24)
16 -- S.MG, 2018
17 -- prototype implementation of S.MG communication protocol
18 -- http://trilema.com/2018/euloras-communication-protocol-restated/
19
20 project SMG_comms is
21 for Languages use ("Ada");
22
23 for Source_Dirs use ("src");
24 for Ignore_Source_Sub_Dirs use (".svn", ".git", "@*");
25
26 for Object_Dir use "obj";
27 for Exec_Dir use ".";
28
29 for Main use ("test_comms.adb");
30
31 package Builder is
32 for Executable ("test_comms.adb") use "test_comms";
33 end Builder;
34
35 package Compiler is
36 for Default_Switches ("Ada") use ("-O2");
37 end Compiler;
38
39 end SMG_comms;
-(0 . 0)(1 . 69)
44 -- S.MG, 2018
45 -- prototype implementation of S.MG communication protocol
46
47 with SMG_comms_types; use SMG_comms_types;
48 with System; use System; -- endianness
49 with Ada.Exceptions;
50 with Ada.Streams; use Ada.Streams;
51
52 package body SMG_comms_types is
53
54 -- to and from network format (i.e. big endian, stream_element_array)
55 procedure ToNetworkFormat(
56 Item : in Octet_Array;
57 Buffer : out Stream_Element_Array) is
58 begin
59 if Item'Length /= Buffer'Length then
60 raise Constraint_Error with "Item and Buffer lengths do NOT match!";
61 end if;
62
63 if Default_Bit_Order = Low_Order_First then
64 for I in 0 .. Item'Length - 1 loop
65 Buffer( Buffer'Last - Stream_Element_Offset(I) ) := Stream_Element(Item(Item'First + I));
66 end loop;
67 else
68 for I in 0 .. Item'Length - 1 loop
69 Buffer( Buffer'First + Stream_Element_Offset(I) ) := Stream_Element(Item(Item'First + I));
70 end loop;
71 end if;
72 end ToNetworkFormat;
73
74 procedure FromNetworkFormat(
75 Buffer : in Stream_Element_Array;
76 Item : out Octet_Array) is
77 begin
78 if Item'Length /= Buffer'Length then
79 raise Constraint_Error with "Buffer and Item length do NOT match!";
80 end if;
81
82 if Default_Bit_Order = Low_Order_First then
83 for I in 0 .. Buffer'Length - 1 loop
84 Item( Item'Last - I ) :=
85 Unsigned_8( Buffer( Buffer'First + Stream_Element_Offset( I ) ) );
86 end loop;
87 else
88 for I in 0 .. Buffer'Length - 1 loop
89 Item( Item'First + I ) :=
90 Unsigned_8( Buffer( Buffer'First + Stream_Element_Offset( I ) ) );
91 end loop;
92 end if;
93 end FromNetworkFormat;
94
95 -- Integer_8
96 procedure ToNetworkFormat(
97 Item : in Integer_8;
98 Buffer : out Stream_Element_Array) is
99 begin
100 ToNetworkFormat( Cast( Item ), Buffer );
101 end ToNetworkFormat;
102
103 procedure FromNetworkFormat(
104 Buffer : in Stream_Element_Array;
105 Item : out Integer_8) is
106 octets: Octets_1;
107 begin
108 FromNetworkFormat(Buffer, octets);
109 Item := Cast( octets );
110 end FromNetworkFormat;
111
112 end SMG_comms_types;
-(0 . 0)(1 . 52)
117 -- S.MG, 2018
118 -- prototype implementation of S.MG communication protocol
119
120 with Ada.Streams; use Ada.Streams;
121 with Interfaces; use Interfaces; -- Integer_n and Unsigned_n
122 with Ada.Unchecked_Conversion; -- converting int/uint to array of octets
123
124 package SMG_comms_types is
125 -- basic types with guaranteed lengths
126 type Octet_Array is array(Natural range <>) of Unsigned_8;
127
128 subtype Octets_1 is Octet_Array( 1 .. 1 );
129 subtype Octets_2 is Octet_Array( 1 .. 2 );
130 subtype Octets_4 is Octet_Array( 1 .. 4 );
131 subtype Octets_8 is Octet_Array( 1 .. 8 );
132
133 subtype Message is Octet_Array( 1 .. 512 );
134 subtype RSAMessage is Octet_Array( 1 .. 245 );
135
136 -- blind, unchecked casts ( memcpy style )
137 function Cast is new Ada.Unchecked_Conversion( Integer_8, Octets_1 );
138 function Cast is new Ada.Unchecked_Conversion( Octets_1, Integer_8 );
139
140 function Cast is new Ada.Unchecked_Conversion( Integer_16, Octets_2 );
141 function Cast is new Ada.Unchecked_Conversion( Octets_2, Integer_16 );
142
143 function Cast is new Ada.Unchecked_Conversion( Integer_32, Octets_4 );
144 function Cast is new Ada.Unchecked_Conversion( Octets_4, Integer_32 );
145
146 function Cast is new Ada.Unchecked_Conversion( Integer_64, Octets_8 );
147 function Cast is new Ada.Unchecked_Conversion( Octets_8, Integer_64 );
148
149 -- to and from streams for network communications - general
150 procedure ToNetworkFormat(
151 Item : in Octet_Array;
152 Buffer : out Stream_Element_Array);
153
154 procedure FromNetworkFormat(
155 Buffer : in Stream_Element_Array;
156 Item : out Octet_Array);
157
158 -- specific, convenience methods for the basic types
159 -- Integer_8
160 procedure ToNetworkFormat(
161 Item : in Integer_8;
162 Buffer : out Stream_Element_Array);
163
164 procedure FromNetworkFormat(
165 Buffer : in Stream_Element_Array;
166 Item : out Integer_8);
167
168 end SMG_comms_types;
-(0 . 0)(1 . 87)
173 -- S.MG, 2018
174 -- prototype implementation of S.MG communication protocol
175
176 with GNAT.Sockets; use GNAT.Sockets;
177 with Ada.Text_IO; use Ada.Text_IO;
178 with Ada.Streams; use Ada.Streams;
179 with Interfaces; use Interfaces;
180
181 with SMG_comms_types; use SMG_comms_types;
182
183 procedure test_comms is
184 Port_No : constant := 2222;
185
186 task type Client is
187 entry Send;
188 end Client;
189
190 task type Server is
191 entry Listen;
192 entry Ready;
193 end Server;
194
195 task body Client is
196 Sock: Socket_Type;
197 Address: Sock_Addr_Type;
198 Data: Ada.Streams.Stream_Element_Array(1..10) := (others => 42);
199 Last: Ada.Streams.Stream_Element_Offset;
200 N : Integer_8 := -36;
201 begin
202 accept Send; -- task WILL block here until asked to send
203 Address.Port := Port_No;
204 Address.Addr := Inet_Addr("127.0.0.1");
205 Create_Socket(Sock, Family_Inet, Socket_Datagram);
206
207 ToNetworkFormat( N, Data(1..1));
208
209 Send_Socket(Sock, Data, Last, Address);
210 Put_Line("Client sent data " & "last: " & Last'Img);
211 end Client;
212
213 task body Server is
214 Sock: Socket_Type;
215 Address, From: Sock_Addr_Type;
216 Data: Ada.Streams.Stream_Element_Array(1..512);
217 Last: Ada.Streams.Stream_Element_Offset;
218 N : Integer_8;
219 begin
220 accept Listen; -- wait to be started!
221 Put_Line("Server started!");
222 -- create UDP socket
223 Create_Socket( Sock, Family_Inet, Socket_Datagram );
224
225 -- set options on UDP socket
226 Set_Socket_Option( Sock, Socket_Level, (Reuse_Address, True));
227 Set_Socket_Option( Sock, Socket_Level, (Receive_Timeout, Timeout => 10.0));
228
229 -- set address and bind
230 Address.Addr := Any_Inet_Addr;
231 Address.Port := Port_No;
232 Bind_Socket( Sock, Address );
233
234 accept Ready; -- server IS ready, when here
235 -- receive on socket
236 begin
237 Receive_Socket( Sock, Data, Last, From );
238 Put_Line("last: " & Last'Img);
239 Put_Line("from: " & Image(From.Addr));
240 Put_Line("data is:");
241 for I in Data'First .. Last loop
242 FromNetworkFormat(Data(I..I), N);
243 Put_Line(N'Image);
244 end loop;
245 exception
246 when Socket_Error =>
247 Put_Line("Socket error! (timeout?)");
248 end; -- end of receive
249
250 end Server;
251
252 S: Server;
253 C: Client;
254 begin
255 S.Listen;
256 S.Ready; -- WAIT for server to be ready!
257 C.Send; -- client is started only after server!
258 end test_comms;
259