Coding Mask Calculation

From SubPos
Jump to navigation Jump to search

To increase compatibility of the SubPos coding in a large array of different access points and Wi-Fi receiver APIs, the coding mask consists of an "ASCII Mask" and an "Invalid Character" mask. During coding, the ASCII mask is calculated before the Invalid Character mask, and upon decoding, they occur in the reverse order.

The human readable tag at the start of the coded SSID is excluded from these mask calculations and should always be a valid character for any access point.

ASCII Mask

This mask converts all characters to ASCII since some access points don't use UTF8.

The ASCII Mask is a 3x7bit mask, with each 7 bits being stored in the lower bits of a byte (24 bits total; so we don't have to ASCII Mask the mask) that corresponds to bytes 4 to 24 (indexed 1) of the SSID. Each bit represents whether the corresponding byte is greater than 0x7F. If the byte is greater, this byte has its most significant bit set to 0 in the original array and the mask bit is set. On decode, if this bit is set, the most significant bit is set back to 1.

The following ASCII Mask bits correspond to bytes in the SSID:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
not used byte 4 byte 5 byte 6 byte 7 byte 8 byte 9 byte 10 not used byte 11 byte 12 byte 13 byte 14 byte 15 byte 16 byte 17 not used byte 18 byte 19 byte 20 byte 21 byte 22 byte 23 byte 24

Invalid Character Mask

This mask is used to convert and mask characters out that might be invalid for certain access points. For example, the most common invalid characters are:

LF    - 0x0A
CR    - 0x0D
"     - 0x22	
+     - 0x2B
null  - 0x00
space - 0x20

The Invalid Character Mask is a 4x7bit mask, with each 7 bits being stored in the lower bits of a byte (32 bits total; so we don't have to ASCII Mask the mask). Each bit represents whether the corresponding byte was originally an invalid character byte. If the original byte is one from an invalid list (this can be different for each access point and the decoder will still be able to decode it), this byte gets incremented by 1 in the original array and the mask bit for that corresponding byte is set. On decode, if this bit is set, the corresponding byte in the SSID gets decremented by 1. If two invalid characters are next to each other in the ASCII table for a certain access point, this access point is not supported.

The following Invalid Character Mask bits correspond to bytes in the SSID:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
not used byte 4 byte 5 byte 6 byte 7 byte 8 byte 9 byte 10 not used byte 11 byte 12 byte 13 byte 14 byte 15 byte 16 byte 17 not used byte 18 byte 19 byte 20 byte 21 byte 22 byte 23 byte 24 not used byte 25 (ASCII mask) byte 26 (ASCII mask) byte 27 (ASCII mask)

The last 4 bits are used to apply the coding mask to the mask itself. When checking the last byte of the coding mask, the final bit is set if that byte is invalid (which modifies/increments the byte itself). On decode, this last byte is self referencing and the byte is decremented if the bit is set (set the bit to 0).

29 30 31 32
byte 28 (Invalid Char mask) byte 29 (Invalid Char mask) byte 30 (Invalid Char mask) byte 31 (Invalid Char mask)

Implementation

C (reference design) - https://github.com/subpos/ssid_coder/blob/master/coder/ssid_coder.c
Javascript (encoder only) - https://github.com/subpos/ssid_coder/blob/master/coder/ssid_coder.js
Java (decoder only) - https://github.com/subpos/subpos_android_api/blob/master/SPSData.java