Native library

libmisbcore is a KLV/MISB metadata encoder and decoder, compiled as a self-contained native library (Native AOT form factor). It enables easy integration of the MisbCore library into cross-platform C/C++ applications.

Samples MisbCoreNative sample apps.

System Requirements

OS: Linux (x64, arm64) / Windows x64.

Installation

Library Version Download link
libmisbcore linux-x64 v3.0.0 libmisbcore_v3.0.0_amd64.deb
libmisbcore linux-arm64 v3.0.0 libmisbcore_v3.0.0_arm64.deb
libmisbcore win-x64 v3.0.0 libmisbcore_v3.0.0_win-x64.zip
libmisbcore C demo app v3.0.0 libmisbcore_-demo.zip

Install with the .deb file (x64)

wget -O ./libmisbcore.deb https://github.com/impleotv/misbcore-native-lib-release/releases/download/v3.0.0/libmisbcore_v3.0.0_amd64.deb  
sudo dpkg -i ./libmisbcore.deb  
rm ./libmisbcore.deb

Install with the .deb file (arm64)

wget -O ./libmisbcore.deb https://github.com/impleotv/misbcore-native-lib-release/releases/download/v3.0.0/libmisbcore_v3.0.0_arm64.deb 
sudo dpkg -i ./libmisbcore.deb  
rm ./libmisbcore.deb

Check with dpkg:

dpkg -l | grep libmisbcore

You should see a line like:

ii libmisbcore 3.0.0 amd64 Native MISB 601 core processing library

Show detailed status of the package:

dpkg -s libmisbcore

To remove the library:

sudo apt remove libmisbcore

or

sudo dpkg -r libmisbcore

Windows

Copy libmisbcore.dll to your current directory or add its location to your system's PATH environment variable.

Using libmisbcore

To use the library, you must first load it:

#ifdef _WIN32
    #define funcAddr GetProcAddress
    const char* PathToLibrary = "libmisbcore.dll";
    HINSTANCE handle = LoadLibraryA((char*)PathToLibrary);
#else
    #define funcAddr dlsym
    const char* PathToLibrary = "libmisbcore.so";
    void* handle = dlopen((char*)PathToLibrary, RTLD_LAZY);
#endif

Reading the nodeinfo

    getNodeInfoFunc GetNodeInfo = (getNodeInfoFunc)funcAddr(handle, (char *)"GetNodeInfo");
    char *nodeInfo = GetNodeInfo();
    printf("The NodeInfo: %s \n", nodeInfo);

License activation

    activateFunc Activate = (activateFunc)funcAddr(handle, (char *)"Activate");
    bool fValid = Activate((char *)PathToLicenseFile, (char *)LicenseKey);
    printf("Activate. License %s\n", fValid ? "Valid" : "Invalid. Demo mode.\n");

Encoding RAW KLV buffer

Now, let's create a very simple MISB 601 Local set packet (sample data from MISB ST 0601.16a).

const char* jspnPckt = R"({
    2: '2008-10-24T00:13:29.913',
    3: 'MISSION01',
    13: 60.176822966978335,
    14: 128.42675904204452,
    15: 14190.7195,
    16: 144.571298,
    65: 13
})";

Next, define a simple structure to hold the resulting buffer and its length, then call the Encode method, passing the string as an argument.

struct PcktBuffer
{
  char* buffer;
    int length;
};

typedef PcktBuffer (*encodeFunc)(char*);

encodeFunc encode601Pckt = (encodeFunc)funcAddr(handle, (char*)"Encode");

// Encode json packet to data buffer
PcktBuffer pcktBuf = encode601Pckt((char*)(jspnPckt));

Note: the Encode function returns a pointer to internally allocated memory. It is automatically deallocated during the next Encode call, so you may need to copy this buffer depending on your scenario.

The resulting buffer is a raw KLV containing all mandatory parts of the packet:

  • The UAS Local Set 16-Byte UL “Key”
  • Packet length
  • Packet data payload
  • Checksum

This buffer can be injected into STANAG4609 multiplex:

Encoded buffer

Timestamps

If you don't provide the mandatory Tag 2 timestamp, MisbCore automatically adds the current time. Time can be specified as a long value as defined in the MISB601 standard (e.g., "2": 1638730169255332) or as an ISO 8601 string (e.g., "2": "2021-12-16T13:44:54").

Decoding RAW KLV buffer

To decode the data buffer:

typedef char* (*decodeFunc)(char*, int len);

decodeFunc decodeKlvBuffer = (decodeFunc)funcAddr(handle, (char*)"Decode");

// Decode the buffer back to json. 
char* json = decodeKlvBuffer((char*)buf, len);

Here is the result:

{
  "2": "2008-10-24T00:13:29.913Z",
  "3": "MISSION01",
  "13": 60.176822967,
  "14": 128.426759042,
  "15": 14190.72,
  "16": 144.5713,
  "65": 13,
  "1": 53482
}

Converting to a detailed human-readable format

This method may be used for presentation, when you need some additional information, like tag full name in addition to the tag number and more suitable value formatting.

typedef char* (*toDetailedFunc)(char*);
toDetailedFunc toDetailed = (toDetailedFunc)funcAddr(handle, (char*)"ToDetailed");

char* detailedJsonStr = toDetailed((char*)jsonPckt);
printf("Convert a compact json format to human readable, detailed json: \n %s", detailedJsonStr);

The resulting string will be something like this:

{
  "003. Mission ID": "MISSION01",
  "004. Platform Tail Number": "AF-101",
  "005. Platform Heading Angle": "159.974365°",
  "006. Platform Pitch Angle": "-0.43°",
  "007. Platform Roll Angle": "3.41°",
  "008. Platform True Airspeed": "147 m/s",
  "009. Platform Indicated Airspeed": "159 m/s",
  "010. Platform Designation": "MQ1-B",
  "011. Image Source Sensor": "EO",
  "012. Image Coordinate System": "WGS-84",
  "013. Sensor Latitude": "60° 10' 36.563'' N",
  "014. Sensor Longitude": "128° 25' 36.333'' E",
  "015. Sensor True Altitude": "14190.7195 m",
  "016. Sensor Horizontal field of View": "144.571298°",
  "017. Sensor Vertical Field of View": "152.643626°",
  "018. Sensor Relative Azimuth Angle": "160.7192°",
  "019. Sensor Relative Elevation Angle": "-168.7923°"
  ...
}

Cleaning up

To free internally allocated memory, call CleanUp method:

typedef void (*cleanUpFunc)();

cleanUpFunc cleanUp = (cleanUpFunc)funcAddr(handle, (char*)"CleanUp");
cleanUp();

Using multiple instances

You can obtain multiple encoder/decoder instances. To do so, use the following methods:

typedef PcktBuffer (*instanceEncodeFunc)(int id, char*);
typedef char* (*instanceDecodeFunc)(int id, char*, int len);
typedef void (*instanceCleanUpFunc)(int id);

The only difference from the default mode is that you must provide an instance id as an argument.

Note: In non-default mode, the instance is created and activated on the first call to instanceEncodeFunc or instanceDecodeFunc.

Here is an example of using instance with id=1.

PcktBuffer pcktBuf = encode601Pckt(1, (char*)(jspnPckt)); 
char* json = decodeKlvBuffer(1, (char*)(pcktBuf.buffer), pcktBuf.length);

Demo mode

Please note that if not activated, the library will work in demo mode processing only tags < 15 (and tag 65).
To activate the license, call Activate method:

const char* PathToLicenseFile = "/home/user/Licenses/Impleo/MisbCoreNativeLicense.lic";
const char* LicenseKey = "AF596BF0-BBAB142B-1B905B24-8DA51BED";
typedef bool (*activateFunc)(char*, char*);

activateFunc Activate = (activateFunc)funcAddr(handle, (char*)"Activate");
bool fValid = Activate((char*)PathToLicenseFile, (char*)LicenseKey);

Demo app

A simple demo application (a CMake project) demonstrating basic functionality is available for download - libmisbcore_-demo.zip

Getting help

To get help with libmisbcore, please contact us at support@impleotv.com.