# PSON: A Serialization Format for IoT Sensor Networks
## 3 PSON: Thinger.io Data Serialization Format  
PSON is an object serialization specification similar to JSON but specifically created for microcontrollers. It improves JSON in encoding/decoding complexity and generates a more compact representation over the wire. It also extends JSON by allowing any arbitrary binary information to be encoded, which is not permitted by the standard JSON schema. Thus, JSON handles different data types, which are referenced in the following as the wire type:  
* [noitemsep,topsep=0 pt]
* Unsigned: represents unsigned integers;
* Signed: represents signed integers;
* Float: represents both IEEE 754 simple and double precision;
* Discrete: represents discrete values, such as true, false, or null;
* String: represents a UTF-8 string;
* Bytes: represents a byte array;
* Map: represents key-value pairs of objects;
* Array: represents a sequence of objects. To represent this kind of heterogeneous information, JSON messages are encoded as series of header-value pairs. Headers indicate the type of data, and the value represents the actual value. Therefore, a decoder needs to read the header to retrieve the actual data type and determine how to decode the upcoming value. A header is a fixed single byte composed of two fields: the wire type and the header payload. The wire type is encoded in the first 3 MSB (most significant bits), while the payload header is kept on the remaining 5 LSB (less significant bits). Figure 1 represents this structure. The wire-type field of the header has a clear role in describing the value type, i.e., a number, a float, a string, an object, etc. On the other side, the header payload is 5-bit general-purpose storage that is used to optimize the serialization size. In this case, 5 bits allows up to 32 different values to be specified, which, in JSON, is used for different purposes:  
* [noitemsep,topsep=0 pt]
* Represent small signed/unsigned integers (0-30);
* Indicate whether the floating point value is an IEEE 754 with simple or double precision;
* Discern between true, false, and nulls;
* Indicate the string size (up to 30 characters);
* Indicate the byte array size (up to 30 bytes);
* Indicate the number of elements in a map (up to 30 elements);
* Indicate the number of elements in an array (up to 30 elements). Thus, a header contains the wire type and, under some circumstances, the actual value or size of the upcoming object/array, resulting in an efficient encoding representation. This is especially useful in the embedded ecosystem, where payloads tend to be small due to network and battery constraints. If an integer, length, size, or number of elements does not fit in the 5-bit storage (it is greater than 30), then it is flagged with a \(0x1f\) (31) value in the header payload, and in this case, the actual value is represented by a varint number following the header. Varints, also known as Little Endian Base 128 (LEB128) [41], allow small numbers to be stored in a single byte while also allowing the encoding of arbitrarily long numbers. Each byte in LEB128, except for the last byte, has the MSB set, and this indicates that there are further bytes to come. The lower 7 bits of each byte are used to store the two's complement representation of the number in groups of 7 bits, starting with the least significant group. The conventions used for encoding all different types are summarized in Table 1, along with their binary representations. Figure 2 presents an example of the complete encoding of a JSON document to the JSON format. In this example, a map is encoded with two keys. A map wire-type is encoded by convention with a header starting with \(0b110\ldots\). The remaining bits are used for the header payload, which contains the number of elements  
Figure 1: JSON data header composed of both wire type (3 bits) and header payload (5 bits). in the map. Thus, the header value is encoded as \(0b11000010\), which is \(0 xC2\), as shown in the figure.