Thoughts on the current state of ASN.1 and XML technologies.

Improved TBCD and BCD Support for Java/C#

Our next release of ASN1C (v 7.3) will include improved support for TBCD and BCD strings for Java and C#.  In short, for these types, the toString/ToString function will return the TBCD/BCD interpretation of the octets, rather than merely their hexadecimal representation.  This also improves the print functionality.

TBCD stands for Telephony Binary-coded Decimal and BCD stands for Binary-coded Decimal.  So, what are TBCD and BCD strings?  They are OCTET STRINGS in which a series of digits or telephony digits are encoded, using one nibble (4 bits) per digit.  There isn’t an authoritative definition, but there are a few standards out there that provide definitions of TBCD or BCD and these are what we’ve followed, as described below.

As you will see in the following descriptions, TBCD and BCD strings are similar.  The differences are 1) the set of digit characters and 2) the ordering of the nibbles within the bytes.

TBCD Strings

For TBCD, we follow 3GPP 29.002.  This is also the document that happens to be referenced in the section on TBCD in the Wikipedia entry for BCD.  Here is how 29.002 defines TBCD:

TBCD-STRING ::= OCTET STRING
-- This type (Telephony Binary Coded Decimal String) is used to
-- represent several digits from 0 through 9, *, #, a, b, c, two
-- digits per octet, each digit encoded 0000 to 1001 (0 to 9),
-- 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used
-- as filler when there is an odd number of digits.
-- bits 8765 of octet n encoding digit 2n
-- bits 4321 of octet n encoding digit 2(n-1) +1

To summarize the characteristics for 3GPP 29.002 TBCD-STRING:
• Uses characters 0-9,*,#,a-c.
• F nibble is used as filler when there is an odd number of digits.
• The low nibble contains the first digit.

Note that 3GPP 24.008 §10.5.4.7 “Called party BCD number” specifies the same encoding, though it simply refers to it as “BCD”.  24.008 also calls for BCD in §10.5.1.4 “Mobile Identity” (for the  IMSI, IMEI and IMEISV), (presumably) meaning BCD as defined in §10.5.4.7, i.e. TBCD.

BCD Strings

For BCD, we have followed the TAP3 (GSM TD.57) specification of BCD.  Here is how they define BCD:

-- The BCDString data type (Binary Coded Decimal String) is used to represent 
-- several digits from 0 through 9, a, b, c, d, e. 
-- Two digits are encoded per octet. The four leftmost bits of the octet represent 
-- the first digit while the four remaining bits represent the following digit. 
-- A single f must be used as a filler when the total number of digits to be 
-- encoded is odd. 
-- No other filler is allowed.

To summarize the characteristics of TAP3 BCDString:

• Uses characters 0-9,a-e.
• F nibble is used as filler when there is an odd number of digits.
• The high nibble contains the first digit.

ITU-T Q.825 TBCD-STRING

Q.825 was another candidate for a definition of TBCD strings.  At this point, we haven’t added special support for it.  This section merely points out the differences between Q.825 TBCD-STRING and 3GPP 29.002 TBCD-STRING.  The differences are:

  • In Q.825, TBCD-STRING is defined as part of an OCTET STRING, not as a standalone type.  Prior to the TBCD-STRING content, the OCTET STRING contains an odd/even indicator octet, and, in some cases, another octet.
  • Q.825 orders the nibbles differently.
  • Q.825 uses the F nibble to mark the end of the TBCD string (“end of pulsing signal-ST”)
  • Q.825 uses the 0 nibble as filler when there is an odd number of digits.  So, in some cases, a zero nibble is merely filler, but in other cases it is a ‘0’ digit.  [Note: we’re not sure why Q.825 specifies that filler is required when there is an odd number of digits; it seem it should be required when there is an even number of digits.  By our reading, “123” would map to 0x123F (no filler), while “1234” would map to 0x12340F (filler).]

 

No Comments

New 5G NR (New Radio) 3GPP/LTE APIs available

We have added the new 3GPP/LTE 5G NR (New Radio) ASN.1 API’s for use with ASN1C.  These 5G API’s are extended sample programs that contain the complete ASN.1 specifications extracted from the relevant 3GPP 5G standard documents.  The API’s are available at the following URL (“LTE ASN.1 APIs” tab):

http://www.obj-sys.com/lte_3gpp_apis.php

There are API’s available for 3GPP release 15 of the different 5G AP specification types.  API’s are currently available for LTE-RRC 5G NR, E1AP 5G NR, F1AP 5G NR, NGAP 5G NR, and XnAP 5G NR LTE ASN.1 specifications.

Additionally, the existing 3GPP LTE APIs (such as S1AP, e.g.) have been updated to their latest releases (rel 14 or 15).

Finally, support for specification TS 24.501 (NAS protocol for 5G Systems) has been added to the NAS DLL.  Support for the SDK add-on will be included in the next release of ASN1C.

No Comments

Using -prttostrm (print-to-stream) vs -prttostr (print-to-string) in generated C code

The capability to print the contents of binary-encoded data in a human-readable form has always been an often used feature of our code generation products.  We have had since the beginning the standard -print code generation option for generating code that would print the contents of generated data structures to standard output.  These are straight-forward and simple to use.  But it was not long after that users wanted a way to print to other mediums, most commonly to a text buffer (i.e character array) so that the printed data could be sent to other places, for example, a display window within a GUI.

For this, the “print-to-string” capability was added.  The command-line option -prttostr was added for this purpose and the generated functions allowed a text buffer and size to be passed to receive the printed data.

This worked OK and was fine for printing small amounts of data.  But what we found was that users frequently wanted to print very large data structures using this capability and this led to very slow performance.  The primary reason for this was because in order to append to the buffer that was passed, the end of the string buffer had to be found and the only way to do this lacking any other state information was to make a call to the string length (strlen) run-time function.  If this was done over and over on a very large buffer containing a very large string, it quickly became a compute-intensive operation.

In order to remedy this, we introduced the “print-to-stream” capability.  This provided more flexibility in printing as a user-defined callback function could be declared that would be invoked to handle the printing of each individual data item.  Users could provide their own user-defined data structures to the callback functions making it possible to maintain state between operations.  One example of this would be in keeping track of where the end of a string buffer was after each print operation making the appending of additional data much faster.

We declared “print-to-string” to be deprecated in favor of the new “print-to-stream” capability, but what we have found 15 years down the road is print-to-string still being used.  A few possible reasons for this are 1) that is the way some users started doing it and did not want to change, and 2) it is simpler to use these functions as all that is necessary is to pass a string buffer directly to the function instead of having to design a callback function.

To address the latter point, as part of our next ASN1C release next year, we will provide a built-in callback function that can be used to model print-to-string using print-to-stream.  If users don’t want to wait that long, the code for the new callback is shown below:

void rtxPrintStreamToStringCB
(void* pPrntStrmInfo, const char* fmtspec, va_list arglist)
{
   OSRTStrBuf* bufp = (OSRTStrBuf*) pPrntStrmInfo;
   if (bufp->bufsize > bufp->endx) {
      vsnprintf (&bufp->strbuf[bufp->endx], bufp->bufsize - bufp->endx,
                 fmtspec, arglist);
      bufp->endx += strlen (&bufp->strbuf[bufp->endx]);
   }
}

The OSRTStrBuf structure is defined as follows:

typedef struct {
   char* strbuf;
   OSSIZE bufsize;
   OSSIZE endx;
} OSRTStrBuf;

The code can then be inserted into a C program to print a populated type structure:

OSRTStrBuf strBufDescr;
char strbuf[10240];
...
/* Set up print-to-stream callback to write to character string buffer */
strBufDescr.strbuf = strbuf;
strBufDescr.bufsize = sizeof(strbuf);
strBufDescr.endx = 0;

rtxSetPrintStream (&ctxt, &rtxPrintStreamToStringCB, (void*)&strBufDescr);

asn1PrtToStrm_<type> (&ctxt, "Data", &data);

In this code snippet, <type> would be replaced with the type name of the data structure to be printed. The result of the call would be the data printed to the strbuf character array. Be sure to create a large enough array to hold all of the printed data. If not large enough, the data will be truncated.

No Comments

XBinder Version 2.6 Release

We recently released a new major version of our XBinder XML Schema Compiler product.  XBinder generates C, C++, Java, or C# code from XML Schema (XSD) definitions, making it easier to create and consume compliant XML documents in a programmatic way.

New features in this release include the following:

    • Generation of C/C++ Code to Better Support 64-bit Architectures
    • Generation of Visual Studio Projects for 64-bits
    • Ability to Use Qt Types
    • Use of Newer Versions of Visual Studio for Windows
    • XML Validation in XBinder Editor
    • Generation of Visual Studio Projects in XBinder Editor

A full list of changes, and additional details on the above changes, are available in the release notes.

No Comments

V2X API Updates

The V2X ASN.1 encode/decode API provides functions for encoding and decoding messages defined in the SAE International Dedicated Short Range Communications (DSRC) Message Set Dictionary J2735 standard and equivalent ETSI standards – CAM and DENM.  An updated version of the API is now available for download from the V2X API product page on our web-site.  The updated API was built with ASN1C v7.2.2 and adds the following new features:

  • Generated XER (XML) and JSON code was added making it possible to output binary data to these formats and conversely decode data in these formats back to binary form.
  • The updated API contains generated “print-to-stream” functions rather than standard print functions.  This makes it possible to set up print callbacks to print to output devices or mediums other than stdout (for example, to a GUI display).
  • Versions of the C/C++ API have been added for Linux x86 32-bit and Linux ARM 32-bit platforms.

Also note that the name of the product has changed.  It was formerly known as V2X DLL, but the name was changed to V2X API as the former gave the impression it was a Windows-only product.

 

No Comments