Using the Gnome and KDE Secret Service API in Ada Read more

by Java 2 Ada

The Gnome and KDE desktop environments have designed a shared service API to allow applications to protect, retrieve and manage their secret data such as passwords and private keys. The Secret Service API defines the mechanisms and operations that can be used by applications to use the service.

The libsecret is the C library that gives access to the Secret Service API. The Ada Libsecret is an Ada binding for the C library. The Ada binding does not allow to access and use all of the functionalities implemented by the C library but it implements the most useful operations allowing to store, retrieve and delete some application secret data.

Understanding the Secret Service API

At first glance, the Secret Service API is not easy to use. Each secret is stored together with lookup attributes and a label. Lookup attributes are formed of key/value pairs. The label is the user friendly name that desktop key manager will use to display some information to the end user.

ada-libsecret-dbus.png

The Secret Service API is implemented by a keyring manager such as gnome-keyring-daemon or kwalletd. This is a daemon that is started when a user opens a desktop session. It manages the application secrets and protects their access. The secret database can be locked in which case the access to secrets is forbidden. Unlocking is possible but requires authentication by the user (in most cases a dialog popup window opens and asks to unlock the keyring).

When a client application wishes to retrieve one of its secret, it builds the lookup attributes that correspond to the secret to retrieve. The lookup attributes are not encrypted and they are not part of the secret. The client application uses the D-Bus IPC mechanism to ask the keyring manager for the secret. The keyring manager will manage for unlocking the database by asking the user to confirm the access. The keyring manager will then look in its database for the secret associated with the lookup attributes.

Note that the label cannot be used as a key to retrieve the secret since the same label can be associated with different lookup attributes.

Using the Ada Secret Service API

Setting up the project

After building and installing the Ada Libsecret library you will add the following line to your GNAT project file:

with "secret";

This definition will give you access to the Secret package and will handle the build and link support to use the libsecret C library.

Setting the lookup attributes

Attributes are defined by the Secret.Attributes package which provides the Map type that represents the lookup attributes. First, you will add the following with clause:

with Secret.Attributes;

to make available the operations and types provided by the package. Then, you will declare the attributes instance by using:

   List : Secret.Attributes.Map;

At this stage, the lookup attributes are empty and you can check that by using the Is_Null function that will return True in that case. You must now add at least one key/value pair in the attributes by using the Insert procedure:

   List.Insert ("secret-tool", "key-password");
   List.Insert ("user", "joe");

Applications are free about what attributes they use. The attributes have to be unique so that the application can identify and retrieve them. For example, the svn command uses two attributes to store the password to authenticate to svn remote repositories: domain and user. The domain represents the server URL and the user represents the user name to use for the connection. By using these two attributes, it is possible to store several passwords for different svn accounts.

Storing a secret

To store a secret, we will use the operations and types from the Secret.Services and Secret.Values packages. The following definitions:

with Secret.Services;
with Secret.Values;

will bring such definitions to the program. The secret service is represented by the Service_Type type and we will declare an instance of it as follows:

   Service : Secret.Services.Service_Type;

This service instance is a proxy to the Secret Service API and it communicates to the gnome-keyring-daemon by using the D-Bus protocol.

The secret value itself is represented by the Secret_Type and we can define and create such secret by using the Create function as follows:

   Value : Secret.Values.Secret_Type := Secret.Values.Create ("my-secret");

Storing the secret is done by the Store operation which associates the secret value to the lookup attributes and a label. As explained before, the lookup attributes represent the unique key to identify the secret. The label is used to give a user friendly name to the association. This label is used by the desktop password and key manager to give information to the user.

   Service.Store (List, "Secret tool password", Value);

Retreiving a secret

Retreiving a secret follows the same steps but involves using the Lookup function that returns the secret value from the lookup attributes. Care must be made to provide the same lookup attributes that were used during the store phase.

   Value : Secret.Values.Secret_Type := Service.Lookup (List);

The secret value should be checked by using the Is_Null function to verify that the value was found. The secret value itself is accessed by using the Get_Value function.

   if not Value.Is_Null then
      Ada.Text_IO.Put_Line (Value.Get_Value);
   end if;

Conclusion

By using the Ada Secret Service API, Ada applications can now securely store private information and protect resources for their users. The API is fairly simple and can be used to store OAuth access tokens, database passwords, and more...

Read the Ada Libsecret Documentation to learn more about the API.


Software I2C master implementation Read more

by Tero Koskinen on AVR/Ada

Some time ago I was spending evening with a friend and it came up that I had not ever written software I2C master routines, even though I have used I2C quite much in various projects.

So, to correct this omission, we armed ourselves with the I2C specification, sit down for few hours, and composed together a simple C implementation for I2C master using GPIO pins.

The code was for Atmel SAMD21 and as such could not be used with AVR-Ada. This led me to rewrite the code in Ada.

I abstracted the core logic into a generic package, which can be used on any platform as long as few procedures are provided by the user:

generic
   with procedure Pull_SDA_Down;
   with procedure Release_SDA_Up;
   with procedure Pull_SCL_Down;
   with procedure Release_SCL_Up;
   with procedure Delay_T_HD_STA; -- 4.0
   with procedure Delay_T_SU_STO; -- 4.0
   with procedure Delay_T_Buf; -- 4.7..5
   with procedure Delay_T_Low_Half; -- 2.4
   with procedure Delay_T_High; -- 5
   with function SDA_State return Boolean;
package Soft_I2C is

   type Byte_Array is
     array (Interfaces.Unsigned_8 range <>) of Interfaces.Unsigned_8;

   type Error_Status is
     (SOFT_I2C_OK,
      SOFT_I2C_NACK,
      SOFT_I2C_FAILED);

   procedure Start;
   procedure Stop;
   procedure Write_Byte (Byte : Interfaces.Unsigned_8;
                         Status : out Error_Status);
   procedure Read_Byte (Byte : out Interfaces.Unsigned_8; Ack : Boolean);

   procedure Write (Address : Interfaces.Unsigned_8; Bytes : Byte_Array;
                    Status  : out Error_Status);

   procedure Read (Address : Interfaces.Unsigned_8; Bytes : in out Byte_Array);
end Soft_I2C;

The user need to provide GPIO pin manipulation procedures/functions:

with procedure Pull_SDA_Down;
with procedure Release_SDA_Up;
with procedure Pull_SCL_Down;
with procedure Release_SCL_Up;
...
with function SDA_State return Boolean;

And procedures which implement the required delays between pin changes:

with procedure Delay_T_HD_STA; -- 4.0 usecs
with procedure Delay_T_SU_STO; -- 4.0 usecs
with procedure Delay_T_Buf; -- 4.7..5 usecs
with procedure Delay_T_Low_Half; -- 2.4 usecs
with procedure Delay_T_High; -- 5 usecs

An implementation for AVR-Ada and Arduino UNO (atmega328p) is provided in uno_i2c.ads and uno_i2c.adb.

TMP102 temperature sensor

Following example code shows how to read TMP102 temperature sensor value using the package:

procedure Test_I2C is
   use type Interfaces.Unsigned_8;

   TMP102_Address : constant := 16#90#;
   Data : Uno_I2C.I2C.Byte_Array (1..2) := (0, 0);
   Cmd : Uno_I2C.I2C.Byte_Array (1..1) := (1 => 16#00#);
   Status : Uno_I2C.I2C.Error_Status;
   Temp_Value : Integer;
begin
   AVR.UART.Init (103);
   loop
      Data := (0, 0);
      Uno_I2C.Write (Address => TMP102_Address, Bytes => Cmd, Status => Status);
      Uno_I2C.Read (Address => TMP102_Address, Bytes => Data);
      Temp_Value := Integer (Data (1)) * 256;
      Temp_Value := Temp_Value + Integer (Data (2));
      Temp_Value := Temp_Value / 256; -- Basically we ignore the second byte

      AVR.UART.Put ("T:");

      if Temp_Value > 0 then
         Data (1) := Interfaces.Unsigned_8 (Temp_Value);
      else
         AVR.UART.Put ("-");
         Data (1) := Interfaces.Unsigned_8 (-Temp_Value);
      end if;
      AVR.UART.Put (Data (1), Base => 10);
      AVR.UART.Put (" C");
      AVR.UART.CRLF;
      delay 2.0;
   end loop;
end Test_I2C;

Full code is available under ISC license at my arduino-blog Bitbucket repository.

As usual, some caveats:

  • Code doesn't implement all I2C master features, like clock stretching.
  • The example code for Arduino UNO uses 80kHz I2C bus speed. Faster is not possible easily.
  • Read and Write procedures expect 8-bit I2C addresses.

Pasta! Read more

by Gautier de Montmollin

My first online game (I mean, as an author)...

Pasta! is a match-3 puzzle game.
Free of charge, no in-app payment.
Link on the image or here.
Work in permanent progress.
20 levels available so far.
Under the hood: Gnoga.

Enjoy! Caution: high-carb, addictive contents!

Free tools and libraries updates Read more

by AdaIC

Here are some recent updates to our Free Tools and Libraries page:

June 8, 2017: Added ArchiCheck, an architecture checking tool.
May 19, 2017: Added Gnat Math Extensions, extensions to the standard vector and matrix operations.
Added Ada LZMA, an Ada binding for liblzma compression library.
Added Ada Database Objects, an Ada library that provides object relational mapping to access a database.
Added Ada Wiki, a library for a wiki engine.
September 30, 2016: Added X-Cleaner, a Windows tool to securely erase data.
August 11, 2016: Added PUGIXML Ada, a set of Ada bindings to PUGIXML, a lightweight XML processing library.
Added ZStd for Ada, Ada bindings to ZStandard, a new lossless compression algorithm.
July 19, 2016: Added Libsodium-ada, a set of thick Ada bindings to libsodium. Libsodium is a portable implementation of the NaCl encryption, hashing, and authentication library.
(This post will be periodically updated – Webmaster.)

GDB vs macOS Sierra Read more

by Forward in Code

We probably feel downhearted if we need to use the debugger to find out what's wrong with our Ada code.

Under those circumstances, we feel even more frustrated if the debugger doesn't work!

This is exactly what has happened with gdb and macOS Sierra.

Read more »

Porting PN532 routines from AVR-Ada to GNAT ARM Read more

by Tero Koskinen

Olimex STM32-E407 with PN532 breakout board

If you have followed my Arduino blog you know that I have written some time ago PN532 routines for AVR-Ada.

Now, to play with Ada_Drivers_Library, I decided to port my PN532 routines to ARM Cortex-M4 using STM32F4 board (STM32-E407) from Olimex.

The porting process was relatively smooth, as I already had separated SPI/I2C bus related communication from other logic. I mostly had to replace my AVR-Ada specific logging routines with ones for ARM/STM32.

The biggest problems I had with STM32-E407 board, which doesn't have its own board definition in Ada_Drivers_Library / embedded-runtimes repo.

With following tweaks to embedded-runtimes I got the board (and its UART/SPI peripherals) working:

diff --git a/bsps/stm32f4/bsp/s-bbbopa.ads b/bsps/stm32f4/bsp/s-bbbopa.ads
index 95c65e5..98668ea 100644
--- a/bsps/stm32f4/bsp/s-bbbopa.ads
+++ b/bsps/stm32f4/bsp/s-bbbopa.ads
@@ -37,12 +37,12 @@ package System.BB.Board_Parameters is
    -- Hardware clock --
    --------------------

-   Main_Clock_Frequency : constant := 168_000_000;
+   Main_Clock_Frequency : constant := 144_000_000;
    --  Optimal frequency of the system clock. Note that the STM32F411 can go
    --  up to 200 MHz, but all other STM32F40x and STM32F41x MCUs can only do
    --  168 MHz.

-   HSE_Clock_Frequency : constant := 8_000_000;
+   HSE_Clock_Frequency : constant := 12_000_000;
    --  Frequency of High Speed External clock.

    FLASH_Latency : constant := 5;
diff --git a/bsps/stm32f4/bsp/setup_pll.adb b/bsps/stm32f4/bsp/setup_pll.adb
index 59c0363..96e4aff 100644
--- a/bsps/stm32f4/bsp/setup_pll.adb
+++ b/bsps/stm32f4/bsp/setup_pll.adb
@@ -51,7 +51,7 @@ procedure Setup_Pll is
    LSI_Enabled     : constant Boolean := True;  -- use low-speed internal clock

    Activate_PLL       : constant Boolean := True;
-   Activate_Overdrive : constant Boolean := True;
+   Activate_Overdrive : constant Boolean := False;
    Activate_PLLI2S    : constant Boolean := False;

    pragma Compile_Time_Error (not (if Activate_PLL then HSE_Enabled),

Basically, I decreased the clock speed a little and corrected the HSE clock frequency (because the Olimex board uses 12MHz crystal).

In theory, STM32F407 on the Olimex board should be able to run at 168MHz, but for some reason the clock speed calculation algorithm used in embedded-runtimes worked only up to 144MHz.

Anyway, the code is now available under my Github account in my Ada_Drivers_Library fork.

There are some caveats though:

  • Reading NFC-enabled Yubikeys do not seem to work, although they work with AVR-Ada version
  • Likewise, there are some problems with NFC tag emulation

I suspect that they are some timing related errors as PN532 is sometimes quite sensitive to timings. In addition, in my AVR-Ada code I have used quite short timeout values for calls and they might be calculated incorrectly on ARM.


Ada Prehistory Unearthed Read more

by AdaIC

The president of the ARA, Ben Brosgol, has unearthed a part of Ada Prehistory, a document from June 1976 titled “A Common Programming Language for the Department of Defense – Background and Technical Requirements”. We’ve posted it in the AdaIC archives in the Policy and History section. You can access it directly at http://archive.adaic.com/pol-hist/history/Fisher-P-1191.pdf. (Warning: this is a 7.5 megabyte file.)

This report is a very early description of the process that led to Ada: it predates the language design competition. (Ben, for those of you who don’t know, was a principal designer for the runner-up language – Red – in that language design competition. Red was an interesting language in its own right.)


Rest API Benchmark comparison between Ada and Java Read more

by Java 2 Ada

Arcadius Ahouansou from Menelic.com made an interesting benchmark to compare several Java Web servers: Java REST API Benchmark: Tomcat vs Jetty vs Grizzly vs Undertow, Round 3. His benchmark is not as broad as the TechEmpower Benchmark but it has the merit to be simple to understand and it can be executed very easily by everyone. I decided to make a similar benchmark for Ada Web servers with the same REST API so that it would be possible to compare Ada and Java implementations.

The goal is to benchmark the following servers and have an idea of how they compare with each others:

The first three are implemented in Ada and the last one in Java.

REST Server Implementation

The implementation is different for each server but they all implement the same REST GET operation accessible from the /api base URL. They return the same JSON content:

{"greeting":"Hello World!"}

Below is an extract of the server implementation for each server.

AWS Rest API Server

function Get_Api (Request : in AWS.Status.Data) return AWS.Response.Data is
begin
   return AWS.Response.Build ("application/json", "{""greeting"":""Hello World!""}");
end Get_Api;

ASF Rest API Server

procedure Get (Req    : in out ASF.Rest.Request'Class;
               Reply  : in out ASF.Rest.Response'Class;
               Stream : in out ASF.Rest.Output_Stream'Class) is
begin
   Stream.Start_Document;
   Stream.Write_Entity ("greeting", "Hello World!");
   Stream.End_Document;
end Get;

EWS Rest API Server

function Get (Request : EWS.HTTP.Request_P) return EWS.Dynamic.Dynamic_Response'Class is
   Result : EWS.Dynamic.Dynamic_Response (Request);
begin
   EWS.Dynamic.Set_Content_Type (Result, To => EWS.Types.JSON);
   EWS.Dynamic.Set_Content (Result, "{""greeting"":""Hello World!""}");
   return Result;
end Get;

Java Rest API Server

@Produces(APPLICATION_JSON_UTF8_VALUE)
@Path("/api")
@Component
public class ApiResource {
  public static final String RESPONSE = "{\"greeting\":\"Hello World!\"}";
  
  @GET
  public Response test() {
      return ok(RESPONSE).build();
  }
}

Benchmark Strategy and Results

The Ada and Java servers are started on the same host (one at a time), a Linux Ubuntu 14.04 64-bit powered by an Intel i7-33770S CPU @3.10Ghz with 8-cores. The benchmark is made by using Siege executed on a second computer running Linux Ubuntu 15.04 64-bit powered by an Intel i7-4720HQ CPU @2.60Ghz with 8-cores. Client and server hosts are connected through a Gigabit Ethernet link.

Siege makes an intensive use of network connections which results in exhaustion of TCP/IP port to connect to the server. This is due to the TCP TIME_WAIT that prevents the TCP/IP port from being re-used for future connections. To avoid such exhaustion, the network stack is tuned on both the server and the client hosts with the sysctl commands:

sudo sysctl -w net.ipv4.tcp_tw_recycle=1
sudo sysctl -w net.ipv4.tcp_tw_reuse=1

The benchmark tests are executed by running the run-load-test.sh script and then making GNUplot graphs using plot-perf.gpi script. The benchmark gives the number of REST requests which are made per second for different level of concurrency.

  • The Embedded Web Server targets embedded platforms and it uses only one task to serve requests. Despite this simple configuration, it gets some honorable results as it reaches 8000 requests per second.
  • The Ada Server Faces provides an Ada implementation of Java Server Faces. It uses the Ada Web Server. The benchmark shows a small overhead (arround 4%).
  • The Ada Web Server is the fastest server in this configuration. As for the Ada Server Faces it is configured to only have 8 tasks that serve requests. Increasing the number of tasks does not bring better performance.
  • The Java Grizzly server is the faster Java server reported by Arcadius's benchmark. It uses 62 threads. It appears to serve 7% less requests than the Ada Web Server.

ada-rest-api-benchmark.png

On the memory side, the process Resident Set Size (RSS) is measured once the benchmark test ends and graphed below. The Java Grizzly server uses arround 580 Mb, followed by Ada Server Faces that uses 5.6Mb, Ada Web Server 3.6Mb and the EWS only 1 Mb.

ada-rest-api-memory.png

Conclusion and References

The Ada Web Server has comparable performance with the Java Grizzly server (it is even a little bit faster). But as far a memory is concerned, Ada has a serious advantage since it cuts the memory size by a factor of 100. Ada has other advantages that make it an alternative choice for web development (safety, security, realtime capabilities, ...).

Sources of the benchmarks are available in the following two GitHub repositories:


Atlas 1.0.0 the Ada Web Application demonstrator available as Docker image Read more

by Java 2 Ada

Atlas is a small application intended to show various features provided by the Ada Web Application framework. The application features:

  • A small blogging system,
  • A question and answer area,
  • A complete wiki system,
  • A document and image storage space,
  • Authentication with Google+ or Facebook.

atlas-mashup.png

Atlas is now available as a Docker image so that you can easily try it.

What is Docker ?

Docker is a container platform that allows to run applications on the host but within an isolated environment. The container has its own libraries, its own network, its own root file system but it shares the same running Linux kernel as the host. Docker is based on Linux containers which provides kernel namespaces and cgroups. Docker provides a lot of abstractions that simplifies the creation, startup and management of containers.

To learn more about Docker, you may have a look at the Get started with Docker documentation.

Using the Atlas Docker image

The Atlas Docker image is available at the Docker Hub cloud-based registry service. This registry allows you to get and synchronize your local Docker images easily by pulling them from the cloud.

Assuming that you have installed Docker, you can pull the Atlas Docker image by using the following command:

  sudo docker pull ciceron/atlas

Beware that the Docker image is a 64-bit image so it runs only on Linux x86_64 hosts. Once you have obtained the image, you can create the container and start it as follows:

  sudo docker run --name atlas -p 8080:8080 ciceron/atlas

and then point your browser to http://localhost:8080/atlas/index.html The -p 8080:8080 option tells Docker to expose the TCP/IP port 8080 from the container to the host so that you can access the web application.

The application will first display some installation page that allows you to choose the database, configure the mail server and the Google and Facebook connexions (most of the default values should be correct).

To stop and cleanup the docker container, you can use the following commands:

  sudo docker stop atlas
  sudo docker rm atlas

Learning more about Ada Web Application

You may read the following tutorials to lean more about the technical details about setting up and building an Ada Web Application:


Ada with a side of JSON Read more

by Thomas Løcke Rambling

So, you've got Ada and you need to handle some JSON data, but you're not quite sure if there are tools available, or if you're going to have to come up with a homegrown solution. Well, as luck will have it, you need look no further than to the excellent GNATColl library from libre.adacore.com:

The GNAT Component Collection is a suite of reusable software components and utilities. It has been used by AdaCore in developing the GNAT tool set, the GPS Integrated Development Environment, and GNAT Tracker, its web-based customer support interface.

There's a lot of really nice stuff in GNATColl, but today I'll focus on the very new and shiny JSON features. Actually, at the time of writing, the GNATColl JSON facilities are so new that they haven't even made it into the GNATColl manual yet, but that's not really a problem, since they are so very easy to grasp.

But before we can get cracking on the actual Ada code, we need to install GNATColl. My personal preference is to go with the latest development snapshot:



Obviously you should take a look at the configure options, so you don't end up trying to compile features you don't want/need. Also it's worth noting that if you want to be sure of success, then it's probably best to use the GNAT GPL compiler from AdaCore. Once you've made it work with that, you can start experimenting with the FSF GCC compiler. I've compiled GNATColl with GCC 4.6.2, so I can at least attest to the fact that GNATColl compiled with that specific version at the time of writing.

So, now that we have GNATColl available, lets get down and dirty with some JSON.

Step one is to initialize an empty JSON_Value variable:



Running that should give you this output:

Yes, Penguin is a JSON object

The Create_Object call is where the magic is at. This gives us an empty JSON object, to which we can add values using the Set_Field procedure. The Kind function returns the kind of JSON_Value we're dealing with. There are 7 kinds:



It should be obvious what kinds of data the different types contain.

So, currently we've got an empty Penguin JSON object, next step is naming the cute little fellow. Add this to the JSON_Fun program:



And voila! We've got a penguin named Linux. Amazing stuff eh? In the above snippet we encounter two key subprograms in the GNATCOLL.JSON package: Set_Field and Get. The former adds data to a JSON_Value object, while the latter retrieves data. There are Set_Field and Get subprograms for all the available JSON_Value_Type's.

Moving on, lets give our penguin some parents. As we all know, Linux got a lot of parents, but we'll settle on adding three of those to a JSON_Array:



Woah! Lots of new stuff going on here. Lets take it from the top. First we declare a new JSON_Array object: Parents. We then append JSON_Value objects to Parents using the Append procedure, which takes a JSON_Array as its first parameter and a JSON_Value as its second. If you've programmed for more than 2 weeks, you should already have guessed that the value of the second parameter is appended to the JSON_Array given as the first parameter. There's an alternative method: Using the "&" function. It's slower, but to some the code is more readable:



I personally like the Append approach, but you can use whatever floats your boat. Naturally you can append both JSON_Value's and JSON_Array's.

Next we have the Create function. There's a series of Create functions in the GNATCOLL.JSON package, each returning a JSON_Value containing the data given in its sole parameter. In our case we give Create a String, so it returns a JSON_Value where the JSON_Value_Type is JSON_String_Type.

The Length (Parents) call returns the amount (Natural) of items in the Parents array, and in the loop we make use of that number to set the range. It would've been nice to not have to define the lower bound of the range with an actual number. I would've much preferred something like Parents'Range, but hey, you can't have it all.

In the loop we stumble on a less than pretty construction:



Gaggle! Lots of Get'ing going on there. But before you tear your hair out in frustration, lets take a look at the specification for the two Get functions used here:



Aha! Suddenly everything makes sense again. One could argue that readability could've been improved slighty, had the innermost call been named differently, but since that's not the case, we're just going to have to live with Get'ing twice.

Finally we output the JSON we've created:



Executing the program results in this:

Yes, Penguin is a JSON object
Our Penguin is named Linux
Linux got 3 parents.
They are:
Linus Torvalds
Alan Cox
Greg Kroah-Hartman
{"parents":["Linus Torvalds", "Alan Cox", "Greg Kroah-Hartman"], "name":"Linux"}

Amazing! Now, just as there's a Write function for turning a JSON object into a String, there's also a Read function to turn a JSON String into a JSON_Value object:



We Read the JSON String generated by the Write (Penguin) call into our newly declared Pingu object. The Filename parameter gives a file to where error messages are written, in case the given JSON String is mangled in some way. The two Set_Field calls overwrite the name and parents fields with new values (another famous penguin!), and finally we output the new JSON String, adding this to the previous output:

{"parents":"Otmar Gutmann", "name":"Pingu"}

Neat eh?

Using the Map_JSON_Object procedure it is also possible to iterate a JSON_Value object:



So as you can see, you can do most everything with the tools available in GNATCOLL.JSON - there is though one thing I feel is missing: Facilities to delete fields in a JSON_Value object, but I'm sure these will come as the package matures.

For the sake of completeness, here's the full listing of our penguin example:



I hope you've enjoyed reading this short introduction to the GNATCOLL.JSON package. Ada and JSON is a pretty good match, so if you don't need or want all the complexities of XML, then give JSON a chance. The tools are available and they are pretty good.

Consolidated RM available in EMACS info format Read more

by AdaIC

The consolidated Ada Reference manual is now available in EMACS info format, through the efforts of Stephen Leake. Find out more at his site — http://stephe-leake.org/ada/arm.html. The consolidated Ada 2012 Reference manual includes the original third edition (Ada 2012) and the corrections from Technical Corrigendum 1.

Tracking down a Program_Error Read more

by Forward in Code

A StackOverflow question about a Storage_Error exception when trying to implement a FastCGI example in Ada prompted me to investigate.

Read more »

Two Compilers for FreeBSD ARM64 Read more

by DragonLace

Last week, a new cross-compiler based on GnatDroid was introduced into the FreeBSD Ports Collection. The host machine for this compiler is x86 FreeBSD or DragonFly while the target is aarch64--freebsd (FreeBSD/ARM64).

See Freshports GnatCross AArch64

This cross compiler was then used to bootstrap a native FSF GCC 6.3.1 with Ada frontend on FreeBSD/ARM64 (based on the 64-bit ARMv8 architecture). It passes every test in the GCC testsuite thanks to FreeBSD-specific signal frame unwinder I wrote that will be pushed to upstream to the GNU GCC project.

See Freshports GCC6-AUX

The existing GCC6-AUX port was updated to support aarch64, increasing the number of platforms to four:

  • FreeBSD i386
  • FreeBSD x86-64
  • FreeBSD aarch64
  • DragonFly x86-64

In related pkgsrc news, lang/gcc5-aux was upgraded from vesion 5.1 to 5.4 and lang/gcc6-aux (version 6.2) was introduced at the end of 2016. They support FreeBSD, DragonFly, and SunOS, but are limited to x86 architecture.


Ahven status update, January 2017 Read more

by Tero Koskinen

Even though I didn't manage to make any Ahven releases in year 2016 and the build job for Ahven as been failing for 6 months or so, I haven't completely abandoned it.

I added some performance tests and converted from Bounded_String usage to Unbounded_Strings. This helped with memory consumption for simple tests.

One of my long term plans has been to create functional tests for Ahven. Currently, Ahven is tested only by its own unit tests and that isn't enough.

My first option was to use cram for these functional tests, but recently I have started to think if the tests should be done using Robot Framework.

I also played a little with Gource and visualized Ahven's full Mercurial commit history (20MB video).

And made Ahven's homepage accessible via https.


Retrospective 2016 Read more

by Gautier de Montmollin

  • Ada PDF Writer. First release in 2016. Link here.
  • AZip 2.0. First release with standard Deflate compression format and a recompression tool for squeezing Zip archives smaller, with an automatic algorithm picking depending on data types. Link here.
  • Excel Writer. Internationalization and zoom factor added. Link here.
  • GID (Generic Image Decoder). Maintenance release. Added a chart reverse-engineering tool. Link here.
  • GLOBE_3D. Added multi-texturing (specular textures added for shiny effects). Uses GID for decoding textures (broad choice of image formats). Added Wavefront object format importer. Link here.
  • Mathpaqs. Maintenance release. The Copula package can use a vector of pseudo-random generators instead of a single generator. Link here.
  • Zip-Ada. Added a "true" - and original - Deflate algorithm which scans the LZ-compressed data stream for setting up compression blocks, but without losing too much time doing so (Taillaule algorithm). Added an original LZMA algorithm which uses floating-point calculations for probability estimates of encoding variants. On some data formats (such as raw camera image data or mobile device data) this algorithm outpaces all existing LZMA-based compressions on the SqueezeChart benchmark! Link to Zip-Ada here.
Oh, perhaps it's worthwhile to remind it: all of this software is fully in Ada. With the exception of AZip, it builds "out-of-the box" on at least two independent Ada toolsets: AdaCore GNAT, and PTC ObjectAda.

Simple UDP Echo Server on STM32F746 Read more

by Java 2 Ada

Writing a simple UDP server in Ada for a STM32F746 ARM controller is now easy with the use of the Ada Embedded Network stack. The article describes through a simple UDP echo server the different steps for the implementation of an UDP server.

Overview

The Echo server listens to the UDP port 7 on the Ethernet network and it sends back the received packet to the sender: this is the RFC 862 Echo protocol. Our application follows that RFC but it also maintains a list of the last 10 messages that have been received. The list is then displayed on the STM32 display so that we get a visual feedback of the received messages.

The Echo server uses the DHCP client to get and IPv4 address and the default gateway. We will see how that DHCP client is integrated in the application.

The application has two tasks. The main task loops to manage the refresh of the STM32 display and also to perform some network housekeeping such as the DHCP client management and ARP table management. The second task is responsible for waiting Ethernet packets, analyzing them to handle ARP, ICMP and UDP packets.

Through this article, you will see:

  1. How the STM32 board and network stack are initialized,
  2. How the board gets an IPv4 address using DHCP,
  3. How to implement the UDP echo server,
  4. How to build and test the echo server.

Initialization

STM32 Board Initialization

First of all, the STM32 board must be initialized. There is no random generator available in the Ada Ravenscar profile and we need one for the DHCP protocol for the XID generation. The STM32 provides a hardware random generator that we are going to use. The Initialize_RNG must be called once during the startup and before any network operation is called.

We will use the display to list the messages that we have received. The Display instance must be initialized and the layer configured.

with HAL.Bitmap;
with STM32.RNG.Interrupts;
with STM32.Board;
...
   STM32.RNG.Interrupts.Initialize_RNG;
   STM32.Board.Display.Initialize;
   STM32.Board.Display.Initialize_Layer (1, HAL.Bitmap.ARGB_1555);
Network stack initialization

The network stack will need some memory to receive and send network packets. As described in Using the Ada Embedded Network STM32 Ethernet Driver, we allocate the memory by using the SDRAM.Reserve function and the Add_Region procedure to configure the network buffers that will be available.

An instance of the STM32 Ethernet driver must be declared in a package. The instance must be aliased because the network stack will need to get an access to it.

with Interfaces;
with Net.Buffers;
with Net.Interfaces.STM32;
with STM32.SDRAM;
...
   NET_BUFFER_SIZE : constant Interfaces.Unsigned_32 := Net.Buffers.NET_ALLOC_SIZE * 256;
   Ifnet : aliased Net.Interfaces.STM32.STM32_Ifnet;

The Ethernet driver is initialized by calling the Initialize procedure. By doing so, the Ethernet receive and transmit rings are configured and we are ready to receive and transmit packets. On its side the Ethernet driver will also reserve some memory by using the Reserve and Add_Region operations. The buffers allocated will be used for the Ethernet receive ring.

   Net.Buffers.Add_Region (STM32.SDRAM.Reserve (Amount => NET_BUFFER_SIZE), NET_BUFFER_SIZE);
   Ifnet.Initialize;

The Ethernet driver configures the MII transceiver and enables interrupts for the receive and transmit rings.

Getting the IPv4 address with DHCP

At this stage, the network stack is almost ready but it does not have any IPv4 address. We are going to use the DHCP protocol to automatically get an IPv4 address, get the default gateway and other network configuration such as the DNS server. The DHCP client uses a UDP socket on port 68 to send and receive DHCP messages. Such DHCP client is provided by the Net.DHCP package and we need to declare an instance of it. The DHCP client is based on the UDP socket support that we are going to use for the echo server. The DHCP client instance must be declared aliased because the UDP socket layer need to get an access to it to propagate the DHCP packets that are received.

with Net.DHCP;
...
   Dhcp : aliased Net.DHCP.Client;

The DHCP client instance must be initialized and the Ethernet driver interface must be passed as parameter to correctly configure and bind the UDP socket. After the Initialize procedure is called, the DHCP state machine is ready to enter into action. We don't have an IPv4 address after the procedure returns.

   Dhcp.Initialize (Ifnet'Access);

The DHCP client is using an asynchronous implementation to maintain the client state according to RFC 2131. For this it has two important operations that are called by tasks in different contexts. First the Process procedure is responsible for sending requests to the DHCP server and to manage the timeouts used for the retransmissions, renewal and lease expiration. The Process procedure sends the DHCPDISCOVER and DHCPREQUEST messages. On the other hand, the Receive procedure is called by the network stack to handle the DHCP packets sent by the DHCP server. The Receive procedure gets the DHCPOFFER and DHCPACK messages.

Getting an IPv4 address with the DHCP protocol can take some time and must be repeated continuously due to the DHCP lease expiration. This is why the DHCP client must not be stopped and should continue forever.

Refer to the DHCP documentation to learn more about this process.

UDP Echo Server

Logger protected type

The echo server will record the message that are received. The message is inserted in the list by the receive task and it is read by the main task. We use the an Ada protected type to protect the list from concurrent accesses.

Each message is represented by the Message record which has an identifier that is unique and incremented each time a message is received. To avoid dynamic memory allocation the list of message is fixed and is represented by the Message_List array. The list itself is managed by the Logger protected type.

type Message is record
   Id      : Natural := 0;
   Content : String (1 .. 80) := (others => ' ');
end record;
type Message_List is array (1 .. 10) of Message;

protected type Logger is
   procedure Echo (Content : in Message);
   function Get return Message_List;
private
   Id   : Natural := 0;
   List : Message_List;
end Logger;

The Logger protected type provides the Echo procedure to insert a message to the list and the Get function to retrieve the list of messages.

Server Declaration

The UDP Echo Server uses the UDP socket support provided by the Net.Sockets.UDP package. The UDP package defines the Socket abstract type which represents the UDP endpoint. The Socket type is abstract because it defines the Receive procedure that must be implemented. The Receive procedure will be called by the network stack when a UDP packet for the socket is received.

The declaration of our echo server is the following:

with Net.Buffers;
with Net.Sockets;
...
   type Echo_Server is new Net.Sockets.UDP.Socket with record
      Count    : Natural := 0;
      Messages : Logger;
   end record;

It holds a counter of message as well as the messages in the Logger protected type.

The echo server must implement the Receive procedure:

overriding
procedure Receive (Endpoint : in out Echo_Server;
                   From     : in Net.Sockets.Sockaddr_In;
                   Packet   : in out Net.Buffers.Buffer_Type);

The network stack will call the Receive procedure each time a UDP packet for the socket is received. The From parameter will contain the IPv4 address and UDP port of the client that sent the UDP packet. The Packet parameter contains the received UDP packet.

Server Implementation

Implementing the server is very easy because we only have to implement the Receive procedure (we will leave the Logger protected type implementation as an exercise to the reader).

First we use the Get_Data_Size function to get the size of our packet. The function is able to return different sizes to take into account one or several protocol headers. We want to know the size of our UDP packet, excluding the UDP header. We tell Get_Data_Size we want to get the UDP_PACKET size. This size represents the size of the echo message sent by the client.

   Msg    : Message;
   Size   : constant Net.Uint16 := Packet.Get_Data_Size (Net.Buffers.UDP_PACKET);
   Len    : constant Natural
        := (if Size > Msg.Content'Length then Msg.Content'Length else Natural (Size));

Having the size we truncate it so that we get a string that fits in our message. We then use the Get_String procedure to retrieve the echo message in a string. This procedure gets from the packet a number of characters that corresponds to the string length passed as parameter.

   Packet.Get_String (Msg.Content (1 .. Len));

The Buffer_Type provides other Get operations to extract data from the packet. It maintains a position in the buffer that tells the Get operation the location to read in the packet and each Get updates the position according to what was actually read. There are also several Put operations intended to be used to write and build the packet before sending it. We are not going to use them because the echo server has to return the original packet as is. Instead, we have to tell what is the size of the packet that we are going to send. This is done by the Set_Data_Size procedure:

   Packet.Set_Data_Size (Size);

Here we want to give the orignal size so that we return the full packet.

Now we can use the Send procedure to send the packet back to the client. We use the client IPv4 address and UDP port represented by From as the destination address. The Send procedure returns a status that tells whether the packet was successfully sent or queued.

Status : Net.Error_Code;
...
   Endpoint.Send (To => From, Packet => Packet, Status => Status);
Server Initialization

Now that the Echo_Server type is implemented, we have to make a global instance of it and bind it to the UDP port 7 that corresponds to the UDP echo protocol. The port number must be defined in network byte order (as in Unix Socket API) and this is why it is converted using the To_Network function. We don't know our IPv4 address and by using 0 we tell the UDP stack to use the IPv4 address that is configured on the Ethernet interface.

Server : aliased Echo_Server;
...
   Server.Bind (Ifnet'Access, (Port => Net.Headers.To_Network (7),
                               Addr => (others => 0)));

Main loop and receive task

As explained in the overview, we need several tasks to handle the display, network housekeeping and reception of Ethernet packets. To make it simple the display, ARP table management and DHCP client management will be handled by the main task. The reception of Ethernet packet will be handled by a second task. It is possible to use a specific task for the ARP management and another one for the DHCP but there is no real benefit in doing so for our simple echo server.

The main loop repeats calls to the ARP Timeout procedure and the DHCP Process procedure. The Process procedure returns a delay that we are supposed to wait but we are not going to use it for this example. The main loop simply looks as follows:

Dhcp_Timeout : Ada.Real_Time.Time_Span;
...
   loop
      Net.Protos.Arp.Timeout (Ifnet);
      Dhcp.Process (Dhcp_Timeout);
      ...
      delay until Ada.Real_Time.Clock + Ada.Real_Time.Milliseconds (500);
   end loop;

The receive task was described in the previous article Using the Ada Embedded Network STM32 Ethernet Driver. The task is declared at package level as follows:

   task Controller with
     Storage_Size => (16 * 1024),
     Priority => System.Default_Priority;

And the implementation loops to receive packets from the Ethernet driver and calls either the ARP Receive procedure, the ICMP Receive procedure or the UDP Input procedure. The complete implementation can be found in the receive.adb file.

Building and testing the server

To build the UDP echo server and have it run on the STM32 board is a three step process:

  1. First, you will use the arm-eabi-gnatmake command with the echo GNAT project. After successful build, you will get the echo ELF binary image in obj/stm32f746disco/echo.
  2. Then, the ELF image must be converted to binary by extracting the ELF sections that must be put on the flash. This is done by running the arm-eabi-objcopy command.
  3. Finaly, the binary image produced by arm-eabi-objcopy must be put on the flash using the st-util utility. You may have to press the reset button on the board so that the st-util is able to take control of the board; then release the reset button to let st-util the flash the image.

To help in this process, you can use the Makefile and simply run the following make targets:

make echo
make flash-echo

Once the echo application is running, it displays some banner with the information of the DHCP state machine. Once the IPv4 address is obtained, it is displayed with the gateway and the DNS. Take that IPv4 address and use the following command to send message and have them written on the display:

echo -n 'Hello! Ada is great!' | socat - UDP:192.168.1.156:7

(replace 192.168.1.156 with the IPv4 address displayed on the board).

ada-enet-hello.png

The above message was printed with the following script:

#!/bin/sh
IP=$1
FILE=$2
while IFS='' read -r line ; do
  echo -n "$line" | socat - UDP:$IP:7
done < $FILE

and a text file generated with the UNIX System V banner utility.

References

Sources of the article are available in Github https://github.com/stcarrez/ada-enet and you may browse the following files and documentation:


GID release #06 - with Recurve, a chart data recovery tool Read more

by Gautier de Montmollin

GID means Generic Image Decoder, a free, open-source library that can be found here.

The latest release features a couple of new application examples, among them a tool called Recurve for retrieving data from an image with plotted curves. Typically you come across a chart on a web site and would like to get the corresponding data, for reworking them in Excel - perhaps you want to spot specific values, or compare two curves that were not originally on the same chart, or use the data for further calculation. Sometimes the data is not available from the web site - and even less if the chart is from a PDF or a scanned newspaper page.

Fortunately, Recurve will do the painful job of retrieving the data points for you. It will detect gridlines and filter them out, then track the curves by matching their respective colours.

An example here:
Mortgage rates in Switzerland - 2004 to now. Chart is from the Comparis web site


GLOBE_3D Release 2016-07-05 - "Blender edition" Read more

by Gautier de Montmollin

GLOBE_3D is a GL Object Based 3D engine realized with the Ada programming language.
URL: http://globe3d.sf.net

Latest additions:
  • Use of Generic Image Decoder (GID) in GL.IO; now most image formats are supported for textures and other bitmaps to be used with GLOBE_3D (or any GL app)
  • New Wavefront format (.obj / .mtl) importer
  • Doom 3 / Quake 4 map importer more complete
  • Unified GNAT project file (.gpr), allowing to selected the target Operating System (Windows, Linux, Mac) and compilation mode (fast, debug, small) for demos, tools, etc.
  • Project file for ObjectAda 9.1+ updated
The first two points facilitate the import of 3D models from software such as Blender.
Here is an example:
Click to enlarge
Coincidentally, the Wavefront file format so simple that you can also write 3D models "by hand" in that format. An example made in an Excel sheet is provided along with the importer, in the ./tools/wavefront directory.

Click to enlarge
Enjoy!

GLOBE_3D: most image formats now available for textures Read more

by Gautier de Montmollin

The texture loader in GL.IO was around 15 years old and supported only the Targa (.tga) format for textures, plus a few sub-formats of Windows bitmaps (.bmp).
In order to make things easy when dealing with various models, e.g. those imported from Blender, the old code for reading images has been wiped out and the loader is using now GID for the job, supporting JPEG or PNG in addition. For instance the Blender model below is using the JPEG format for textures.

Futuristic Combat Jet (hi poly version) by Dennis Haupt (DennisH2010)

The following Blender model has a single PNG texture projected on a complicated surface called a Mandelbulb (never heard of before!) :

Mandelbulb 3D Panorama 3 by DennisH2010


GLOBE_3D is a GL Object Based 3D engine realized with the Ada programming language.

URL: http://globe3d.sf.net/


AVR-Ada 1.2.2 RPMs for Fedora 25 Read more

by Tero Koskinen on AVR/Ada

Sparkfun DIY Arduino with ftdi cable

I have been slacking with Fedora AVR-Ada rpm binaries, but finally I found some time to make new binary rpms. These binaries are for Fedora 25 (x86_64), which will be released later in this month. I generated them on Fedora 25 (Server) Beta, but they should work on the released Fedora 25 version also.

Like always, create file /etc/yum.repos.d/fedora-adalanguage.repo with contents:

[fedora-adalanguage]
name=Tero's Fedora RPM repository for Ada packages
baseurl=http://fedora.ada-language.com/repo/$releasever/$basearch
enabled=1

And run:

sudo dnf install avr-ada --nogpgcheck

Notes:

  • The used GCC version is 4.9.2.
  • Instead of using normal .spec files + rpmbuild, I build the binaries with my custom build script and fpm (for installation, you need only dnf).
  • The installation happens to /opt/avr-ada-122
  • The RPMs are unofficial in every possible way and they are not endorsed by Fedora or AVR-Ada projects.