Some documentation on the LogicSniffer client.
The client will be entirely OSGi-based. Reasons to chose for this is that all projects are loosely coupled and can be upgraded individually. In addition, OSGi provides the ability to load/unload native libraries for the correct operating system out of the box.
A description of the current projects is given in the following paragraphs.
Provides the serial I/O routines for communicating with serial devices, such as the LogicSniffer. It integrates the native libraries for various operating systems. Currently, the following operating systems are supported:
- Windows 32/64 bits;
- Linux 32/64 bits;
- Mac OSX 32/64 bits.
Provides the common API (maybe "common API" would be a better name?) shared between the client, tools and devices. This project does nothing on its own but provides some common code for the rest of the projects.
The idea is to have only interfaces in the API-project, but this is currently not the case. For example the AnnotatedData implementation is used by several other projects, and is a concrete class instead of an interface. To really solve this, one would need an additional project that provides common implementations.
Provides the actual UI of the client and forms the "glue" between devices, tools and UI. The client project is more or less an empty "shell" that allows devices and tools to be added dynamically. The UI is entirely Swing based.
Provides support for the actual devices, such as the LogicSniffer and a testing device. A device contains everything to actually work with the device, from low-level communications to configuration UI and interfacing logic with the rest of the client.
Provides analysis, measurement and other tools that can provide additional information about captured data. Most of the current tools do some "heavy" processing of data, which should be done in the background to keep the UI responsive. To make writing such tools easier, a "base" tool is provided which provides most of the boilerplate code.
Provides the export functionality from the diagram to various output formats. The exporters get access to the complete diagram, which can result in a very memory consuming export. No limitations are enforced from the platform.
Provides a small "bootstrap" for the OSGi container. This project is the only non-OSGi project. It provides the only "main" method in all projects and this main should start the OSGi container with some predefined configuration and let the OSGi container do the remainder of the work. Currently, Felix 3.0 is used as OSGi container.
Provides a logging "bridge" for Java's native logging functionality and OSGi Logging service. It allows classes to log using Java's native logging functionality (java.util.logging) which will be redirected to a OSGi log service under water.
Provides some common utilities that are shared among all other projects.
For storing captured data to files, the OLS uses the data format as used by the original sump client. The format is plain text, and rather easy to parse.
If a line starts with a semicolon (;), it will be regarded as a header, or metadata. These headers contain information about the actual sample data, such as sample rate, capture length, and so on. If a line does not start with a semicolon, but contains only hexadecimal digits and one at-sign (@), it will be regarded as sample data. All other lines are to be ignored.
Headers start with a semicolon and are always a single line (so, terminated with carriage- return and/or line-feed). Headers contain of a key-value pair separated by a colon (:). The format of a header is:
;<name>: <value>
In which the <name></name> is a predefined header name (case sensitive!), and the <value></value> an arbritary value for that particular header.
The following headers are understood by the current client:
- Size: (Integer, mandatory) defines the absolute number of samples the file contains;
- Rate: (Integer, mandatory) defines the original sample rate, in Hertz, at which the data was taken;
- Channels: (Integer, mandatory) defines the number of channels in the sample data, should be 8, 16, 24 or 32;
- EnabledChannels: (Integer, optional) defines which channel groups are enabled (unused at the moment);
- Compressed: (Boolean, mandatory) should always be set to true;
- AbsoluteLength: (Integer, mandatory) defines the total number of samples taken. Can be used together with the sample rate to determine the total capture time;
- CursorEnabled: (Boolean, optional) defines whether or not cursors are to be enabled;
- Cursor0..Cursor9: (Long integer, optional) defines the time values of the individual cursors (up to ten).
Sample data are always a single line (similar as headers) consisting of hexadecimal digits (0-9, a-f, A-F) and an at-sign (@). The format of sample data is:
<sample></sample>@<sample></sample>
In which the <sample></sample> is the decimal (base 10) representation of the absolute sample number, and <sample></sample> the hexadecimal (base 16) representation of the sample value itself.
Note that the Size header must match the total count of sample data.
The OLS client is extensible at several points. The following extension types are defined:
- devices, denoting physical devices the OLS client can talk to;
- tools, denoting tools that perform certain actions on sample data;
- exporters, denoting functionality to export sample data to a certain format, such as images;
- importers, denoting functionality to import external data formats and represent them as sample data. This extension point is not yet available.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&#10;" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> &lt;modelversion&gt;4.0.0&lt;/modelversion&gt;
&lt;name&gt;My Funky Exporter&lt;/name&gt; &lt;groupid&gt;nl.lxtreme.ols.export&lt;/groupid&gt; &lt;artifactid&gt;funky&#45;exporter&lt;/artifactid&gt; &lt;packaging&gt;bundle&lt;/packaging&gt; &lt;version&gt;1.0.0&lt;/version&gt;
&lt;dependencies&gt; &amp;lt;dependency&amp;gt; &amp;amp;lt;groupid&amp;amp;gt;nl.lxtreme.ols&amp;amp;lt;/groupid&amp;amp;gt; &amp;amp;lt;artifactid&amp;amp;gt;api&amp;amp;lt;/artifactid&amp;amp;gt; &amp;amp;lt;version&amp;amp;gt;1.0.3&amp;amp;lt;/version&amp;amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;amp;lt;groupid&amp;amp;gt;nl.lxtreme.ols&amp;amp;lt;/groupid&amp;amp;gt; &amp;amp;lt;artifactid&amp;amp;gt;util&amp;amp;lt;/artifactid&amp;amp;gt; &amp;amp;lt;version&amp;amp;gt;1.0.5&amp;amp;lt;/version&amp;amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;amp;lt;groupid&amp;amp;gt;org.osgi&amp;amp;lt;/groupid&amp;amp;gt; &amp;amp;lt;artifactid&amp;amp;gt;org.osgi.core&amp;amp;lt;/artifactid&amp;amp;gt; &amp;amp;lt;version&amp;amp;gt;4.2.0&amp;amp;lt;/version&amp;amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;amp;lt;groupid&amp;amp;gt;org.osgi&amp;amp;lt;/groupid&amp;amp;gt; &amp;amp;lt;artifactid&amp;amp;gt;org.osgi.compendium&amp;amp;lt;/artifactid&amp;amp;gt; &amp;amp;lt;version&amp;amp;gt;4.2.0&amp;amp;lt;/version&amp;amp;gt; &amp;lt;/dependency&amp;gt; &lt;/dependencies&gt;
&lt;build&gt; &amp;lt;plugins&amp;gt; &amp;amp;lt;plugin&amp;amp;gt; &amp;amp;amp;lt;groupid&amp;amp;amp;gt;org.apache.felix&amp;amp;amp;lt;/groupid&amp;amp;amp;gt; &amp;amp;amp;lt;artifactid&amp;amp;amp;gt;maven&amp;amp;amp;#45;bundle&amp;amp;amp;#45;plugin&amp;amp;amp;lt;/artifactid&amp;amp;amp;gt; &amp;amp;amp;lt;extensions&amp;amp;amp;gt;true&amp;amp;amp;lt;/extensions&amp;amp;amp;gt; &amp;amp;amp;lt;configuration&amp;amp;amp;gt; &amp;amp;amp;amp;lt;instructions&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;OLS&amp;amp;amp;amp;#45;Exporter&amp;amp;amp;amp;gt;1.0&amp;amp;amp;amp;amp;lt;/ols&amp;amp;amp;amp;#45;exporter&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;OLS&amp;amp;amp;amp;#45;ExporterClass&amp;amp;amp;amp;gt;nl.lxtreme.ols.export.funky.MyFunkyExporter&amp;amp;amp;amp;amp;lt;/ols&amp;amp;amp;amp;#45;exporterclass&amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;/instructions&amp;amp;amp;amp;gt; &amp;amp;amp;lt;/configuration&amp;amp;amp;gt; &amp;amp;lt;/plugin&amp;amp;gt; &amp;lt;/plugins&amp;gt; &lt;/build&gt; </project>
There are several "section" in the POM-file (denoted with whitespace), the first one is the project information itself, containing of a name, group identifier, version and so on. The second section is the list of dependencies. Most of the times the four dependencies listed above are enough. The last section is are the build instructions, which instruct Maven how the resulting JAR file should look like. Actually, it instructs how to MANIFEST.MF file of the resulting JAR should look like. While most of this is rather static, special care needs to be taken for the tags OLS-Exporter and OLS-ExporterClass. These are specific to the OLS-client, and are verbatimely written to the MANIFEST.MF file, like:
... OLS-Exporter: 1.0 OLS-ExporterClass: nl.lxtreme.ols.export.funky.MyFunkyExporter ...
Upon startup of the OLS-client, the manifests of all JARs are scanned for line starting with "OLS-". If found, it will be regarded as a potential extension point. The lines above tell the OLS-client two things:
- the JAR contains one or more exporter extensions;
- the main class of this exporter extension is nl.lxtreme.ols.export.funky.MyFunkyExporter. Note
OLS-ExporterClass: my.first.package.MyExporter1, my.other.package2.MyExporter2
NOTE: both mentioned lines are needed! If one of them is omitted from the resulting JAR file, it will be considered an invalid extension and the results are not (well) defined!