Skip to content

Commit 317f86a

Browse files
dstarke-siemensgregkh
authored andcommitted
tty: n_gsm: fix wrong signal octets encoding in MSC
n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. The value of the modem status command (MSC) frame contains an address field, control signal and optional break signal octet. The address field is encoded as described in chapter 5.2.1.2 with only one octet (may be extended to more in future versions of the standard). Whereas the control signal and break signal octet are always one byte each. This is strange at first glance as it makes the EA bit redundant. However, the same two octets are also encoded as header in convergence layer type 2 as described in chapter 5.5.2. No header length field is given and the only way to test if there is an optional break signal octet is via the EA flag which extends the control signal octet with a break signal octet. Now it becomes obvious how the EA bit for those two octets shall be encoded in the MSC frame. The current implementation treats the signal octet different for MSC frame and convergence layer type 2 header even though the standard describes it for both in the same way. Use the EA bit to encode the signal octets not only in the convergence layer type 2 header but also in the MSC frame in the same way with either 1 or 2 bytes in case of an optional break signal. Adjust the receiving path accordingly in gsm_control_modem(). Fixes: 3ac06b9 ("tty: n_gsm: Fix for modems with brk in modem status control") Cc: [email protected] Signed-off-by: Daniel Starke <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 398867f commit 317f86a

File tree

1 file changed

+5
-13
lines changed

1 file changed

+5
-13
lines changed

drivers/tty/n_gsm.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,6 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
10941094
{
10951095
unsigned int addr = 0;
10961096
unsigned int modem = 0;
1097-
unsigned int brk = 0;
10981097
struct gsm_dlci *dlci;
10991098
int len = clen;
11001099
int slen;
@@ -1124,17 +1123,8 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
11241123
return;
11251124
}
11261125
len--;
1127-
if (len > 0) {
1128-
while (gsm_read_ea(&brk, *dp++) == 0) {
1129-
len--;
1130-
if (len == 0)
1131-
return;
1132-
}
1133-
modem <<= 7;
1134-
modem |= (brk & 0x7f);
1135-
}
11361126
tty = tty_port_tty_get(&dlci->port);
1137-
gsm_process_modem(tty, dlci, modem, slen);
1127+
gsm_process_modem(tty, dlci, modem, slen - len);
11381128
if (tty) {
11391129
tty_wakeup(tty);
11401130
tty_kref_put(tty);
@@ -2963,8 +2953,10 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
29632953
int len = 2;
29642954

29652955
modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */
2966-
modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
2967-
if (brk) {
2956+
if (!brk) {
2957+
modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
2958+
} else {
2959+
modembits[1] = gsm_encode_modem(dlci) << 1;
29682960
modembits[2] = (brk << 4) | 2 | EA; /* Length, Break, EA */
29692961
len++;
29702962
}

0 commit comments

Comments
 (0)