LINUX.ORG.RU

Загадочный huawei E173

 ,


0

1

Долгое время жила машинка с ядром 2.6.36 и huawei E173. Работал на ней smsd (gammu-1.33) используя /dev/ttyUSB0.

При этом перловый скрипт для выполнения ussd запросов исправно работал на /dev/ttyUSB2. Скрипт приходилось использовать из-за того, что ответ на ussd запрос приходит в UTF-16BE, что приводит gammu в недоумение.

Сдохла мать ( вспухли кондеры ). Переставили модем на свежее железо со свежим ядром (3.12), а там перестал работать скрипт!

На комманду «AT» ответ «OK» приходит на /dev/ttyUSB2, а ответ на «AT+CUSD=1,AA180C3602,15» приходит на /dev/ttyUSB0 !^%$#^%$@!

Что это баг в ядре или есть какие-то патчики ?

★★★★★

[user@workstation ~]$ uname -a
Linux workstation 3.14.1-1-ARCH #1 SMP PREEMPT Mon Apr 14 20:40:47 CEST 2014 x86_64 GNU/Linux
[user@workstation ~]$ lsusb | grep E173
Bus 002 Device 006: ID 12d1:1436 Huawei Technologies Co., Ltd. E173 3G Modem (modem-mode)
[user@workstation ~]$ huawei-ussd -i *102#
USSD REPLY: Баланс 0.00 р. Какая завтра погода? Узнайте по номеру 0970! 3р/д,7дн.беспл.
[user@workstation ~]$ cat $(which huawei-ussd)
#!/usr/bin/perl

use Getopt::Std;
use Device::Gsm::Pdu;
use Text::Iconv;

# defaults
$opt_r = "/dev/ttyUSB2";
$opt_s = "/dev/ttyUSB0";
$conv = Text::Iconv->new('utf16be','utf8');

my $USAGE = <<__EOU;

Usage: $0 [-r input_port] [-s output_port] [-n] [-h] [-v] [-w] [-i] ussd_msg

Description:
  Send and receive 7-bit PDU-encoded USSD messages.
  Written and tested for Huawei E1550 GSM/UMTS USB modem.

Options:
  -r port   Port to receive data from. Default: $opt_r
  -s port   Port to send AT commands to. Default: $opt_s
  -n        Do not send any data to port. Useful with -v.
  -h        Print this help.
  -v        Be verbose.
  -i        Use iconv [from utf16be to utf8] to reply
  -w        reply workaround (try it if script can not decode reply)
  -z        Do not encode request to 7bit PDU
__EOU

sub HELP_MESSAGE {print "$USAGE\n"; exit;}
sub VERSION_MESSAGE {};
getopts ('r:s:hnvwiz');
HELP_MESSAGE() and exit if (! $ARGV[0]) or defined($opt_h);
my $ussd_req ='';
print "USSD MSG: $ARGV[0]\n" if $opt_v;
if (! $opt_z) {
	$ussd_req = Device::Gsm::Pdu::encode_text7($ARGV[0]);
	$ussd_req =~ s/^..//;
}
else {
	$ussd_req = ($ARGV[0]);
}

print "PDU ENCODED: $ussd_req\n" if $opt_v;

my $ussd_reply;
if (! $opt_n) {
    open (SENDPORT, '+<', $opt_s) or die "Can't open '$opt_s': $!\n";
    print 'Sending AT+CUSD=1,',$ussd_req,",15\r\n" if $opt_v;
    print SENDPORT 'AT+CUSD=1,',$ussd_req,",15\r\n";
    close SENDPORT;
    open (RCVPORT, $opt_r) or die "Can't open '$opt_r': $!\n";
    print "Waiting for USSD reply...\n" if $opt_v;
    while (<RCVPORT>) {
        chomp;
        die "USSD ERROR\n" if $_ eq "+CUSD: 2";
        if (/^\+CUSD: 0,\"([A-F0-9]+)\"/) {
            $ussd_reply = $1;
            print "PDU USSD REPLY: $ussd_reply\n" if $opt_v;
            last;
        }
        print "Got unknown USSD message: $_\n" if /^\+CUSD:/ and $opt_v;
    }
}

if ($ussd_reply) {
    $iconved_reply = $conv->convert(pack('H*', $ussd_reply));
    $decoded_ussd_reply = $opt_w ? pack('H*', $ussd_reply) : Device::Gsm::Pdu::decode_text7('00'.$ussd_reply);
    print STDOUT "USSD REPLY: ".($opt_i ? $iconved_reply: $decoded_ussd_reply)."\n";
}
else
{
    print "No USSD reply!\n";
}
Deleted
()
Ответ на: комментарий от Deleted

Ты невнимательно прочитал мой вопрос.

ussd запрос замечательно выполняется на /dev/ttyUSB0, но это неинтересно, т.к. на /dev/ttyUSB0 живет smsd.

Раньше ответы на запросы посылаемые в /dev/ttyUSB2 приходили на /dev/ttyUSB2, а сейчас она приходят в /dev/ttyUSB0 !

куда копать ?

Как кастыль - раз в сутки останавливать smsd и выпонять ussd, но это же моветон!

vel ★★★★★
() автор топика
9 апреля 2016 г.
Ответ на: комментарий от vel

Ты невнимательно прочитал мой вопрос.

Ты, кстати, невнимательно скрипт прочитал. Скрипт этот получает через $opt_r = "/dev/ttyUSB2", это вот шлёт он через $opt_s = "/dev/ttyUSB0". Но твоя фраза навела на мысль попробовать и слать через ttyUSB2. В общем, всё работает с вариантом

$opt_r = "/dev/ttyUSB2";
$opt_s = "/dev/ttyUSB2";
Ядро 3.14.65, Huawei E169. Есть, правда, один косяк: изредка виснет навечно. Надо добавить
$SIG{ALRM} = sub { die "Timeout" };
alarm 10;
Для варианта периодической проверки сойдёт - ну не проверит один раз.

А если проблема есть, я бы не в ядре граблю предположил, а в модеме.

AS ★★★★★
()
Ответ на: комментарий от AS

Продолжим некропостинг :)

Проблема в ядре! В 2.6 оно отвечало там, где был запрос, а на 3.х и 4.х - на первом свободном порту. Я почти на 100% уверен, что если я подниму ppp на этом модеме (USB0), то ответы будут приходить на USB2.

Я уже пару раз проходил через «git bisect» на kernel.org с разницей более чем на 2000 коммитов и эту проблему я не уже не собираюсь фиксить самостоятельно.

vel ★★★★★
() автор топика
Ответ на: комментарий от vel

Продолжим некропостинг :)

Для меня не очень - как раз пригодился на днях. Заодно вот дописал про $SIG{ALRM}, может пригодится кому - как раз основная причина некропоста. :-)

В 2.6 оно отвечало там, где был запрос, а на 3.х и 4.х - на первом свободном порту.

У меня всегда отвечает в ttyUSB2. Если поменять $opt_r = "/dev/ttyUSB2" на ttyUSB0, ответа я не вижу. В $opt_s работает и ttyUSB0, и ttyUSB2. Странно, если оно от ядра зависит.

AS ★★★★★
()
Последнее исправление: AS (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.