Hello
Our goal was to send status sms via the vty interface. But all of our
sms were cropped. In contrast sms from one MS to another MS are
displayed correctly (despite the fact, that the text at the database
contains several '@' at the end / the user_data contains several
zero-octets). Therefore i have inspect the code and found several bugs.
The main problem is that the "user_data_len" is not correctly used. As
per GSM 03.40, 9.2.3.16 TP‑User‑Data‑Length (TP‑UDL):
"If the TP‑User‑Data is coded using the GSM 7 bit default alphabet, the
TP‑User‑Data‑Length field gives an integer representation of the number
of septets within the TP‑User‑Data field to follow."
Currently the "user_data_len" contains the number of octets (returned
from gsm_7bit_encode(...) at gsm_utils.c (libosmocore)).
The big problem here is that this information is not unique, e.g.:
1.) 46 non-extension characters + 1 extension character => (46 * 7 bit +
(1 * (2 * 7 bit))) / 8 bit = 42 octets
2.) 47 non-extension characters => (47 * 7 bit) / 8 bit = 41,125 = 42 octets
3.) 48 non-extension characters => (48 * 7 bit) / 8 bit = 42 octects
But the MS has to know the correct "user_data_len" to decode the correct
number of characters.
For this reason i updated the gsm_7bit_encode() function to return the
correct number of septets. However sometimes it is needed to know the
correct number of octets (e.g. at gsm_04_11.c: gsm340_gen_tpdu(...)) =>
i added a function to gsm_utils.c named:
uint8_t get_octet_len(const uint8_t sept_len)
I have also fixed the problem, that the sms are wrongly stored /
displayed on the database. But the solution on the function
*sms_from_result(...) (at db.c) is not really "beautiful". This is
because there exists no "user_data_len" field at the database. To store
the right value for "user_data_len" (which is further needed) i have to
get the length from the "text" field. Unfortunately this is not enough.
If the text contains extension characters like {[]} etc. then the
"user_data_len" has to be bigger because these characters needs two
septets. Therefore i use a switch statement so search for these
characters. A better solution for that is to store the right
"user_data_len" to the database (on the encoding / decoding procedure).
But i don't know if this is a suitable solution for all of you (because
you have to change your database structure etc.).
Best Regards
Dennis Wehrle