LINUX.ORG.RU

Кодировка USSD

 , ,


0

1

Как вы уже знаете, я автор Gnome Modem Manager. Решил наконец-то запилить корректную обработку русских USSD ответов, но не могу понять из какой кодировки перекодировать.

Если выводить ответ modemmanager как UTF8 строку, то:

1) Символы латиницы выводятся так как надо.

2) Вместо кириллицы выводится ерунда. Например вот такой ответ на запрос *111# у мегафона:

@¿@@B Ç$8òò$Δè@é@b@@B@ì$5òL!@ù£ΦèöΔh¥¡$@2@@! $£ÆèhΔ(C¡å@
@L£@è£Δè¿Δ C@ø$¡@(@¡ù@Δè.ΔhC@ø$:òx!¡ìA èè_ΔC@ø@
@T£@èAÇèù_ C¡å$:@(@@ì@Δè*ΔHD 

Вопрос: угадайте кодировку. Читал, что в USSD используется UCS2, но она не подошла - если из неё перекодировать то и из русских, и из английских букв получается ерунда.

★★★★★

Последнее исправление: KivApple (всего исправлений: 1)

Например вот такой ответ на запрос *111# у мегафона:

Покажи то же самое в шестнадцатиричном виде.

Deleted
()

Вот так всё работает в одном небольшом скрипте для модема ZTE MF100:

                if($st=~/^[0-9A-F]+$/i){
$st = pack(«H*», $st);
encode(«ucs-2»,$st); # mark that bytestring is in ucs2
from_to($st,«ucs-2»,«utf-8»); # actually recode
}
return $st;


Что и как перекодируете?

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

Вы, конечно, извините, но я код не понял. Что делает encode и pack.

ModemManager уже сам что-то перекодирует, потому что английские символы я получаю корректно. Выглядит код просто:

result = this.gsm_modem_ussd.Initiate(this.ussd_entry.text);

Этот result является string и его без изменений я присваиваю другому текстовому полю. GTK+ использует UTF-8 для всего. Но всё ломается, если есть русские символы и я получаю то, что есть в стартовом посте.

Перекодировать собираюсь вот так:

result = convert(this.gsm_modem_ussd.Initiate(this.ussd_entry.text), -1, "UTF8", "ИмяКодировки", null, null);

Параметр ИмяКодировки аналогичен заданию имени кодировки для вызова консольной команды iconv.

Варианта два:

1) Это всё одна и та же кодировка, просто для символов 0..127 коды совпаданию с UTF-8. В таком случае надо просто указать правильный параметр для convert.

2) Используются разные кодировки - ASCII для латиницы и что-то другое для кириллицы. В таком случае надо как-то понять, что в ответе была кириллица, а затем использовать convert только в этом случае.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от Deleted
[kiv@kiv-notebook ~]$ cat ussd-response.txt | hexdump -C
00000000  40 c2 bf 40 40 42 20 c3  87 24 38 c3 b2 c3 b2 24  |@..@@B ..$8....$|
00000010  ce 94 c3 a8 40 c3 a9 40  62 40 40 42 40 c3 ac 24  |....@..@b@@B@..$|
00000020  35 c3 b2 4c 21 40 c3 b9  c2 a3 ce a6 c3 a8 c3 b6  |5..L!@..........|
00000030  ce 94 68 c2 a5 c2 a1 24  40 32 40 40 21 20 24 c2  |..h....$@2@@! $.|
00000040  a3 c3 86 c3 a8 68 ce 94  28 43 c2 a1 c3 a5 40 0a  |.....h..(C....@.|
00000050  40 4c c2 a3 40 c3 a8 c2  a3 ce 94 c3 a8 c2 bf ce  |@L..@...........|
00000060  94 20 43 40 c3 b8 24 c2  a1 40 28 40 c2 a1 c3 b9  |. C@..$..@(@....|
00000070  40 ce 94 c3 a8 2e ce 94  68 43 40 c3 b8 24 3a c3  |@.......hC@..$:.|
00000080  b2 78 21 c2 a1 c3 ac 41  20 c3 a8 c3 a8 5f ce 94  |.x!....A ...._..|
00000090  43 40 c3 b8 40 0a 40 54  c2 a3 40 c3 a8 41 c3 87  |C@..@.@T..@..A..|
000000a0  c3 a8 c3 b9 5f 20 43 c2  a1 c3 a5 24 3a 40 28 40  |...._ C....$:@(@|
000000b0  40 c3 ac 40 ce 94 c3 a8  2a ce 94 48 44 20        |@..@....*..HD |
KivApple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Там нет base64, а просто перекодировать UTF16BE - получаю иероглифы

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

Через minicom зашли в модем ат-моманду, и смотри, что будет в ответ. Кто знает, что ты там набыдлокодил.

anonymous
()

теоретически должен существовать какой-то стандарт или спецификация для USSD, где будет указана кодировка для текста

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

Вообще не понятно что это. Это дамп прямо с порта модема, или через modemmanager? Если второе - возможно он уже каким-то неведомым образом обработал строку.

Я сейчас откопал свой Huawei E171 и попробовал через minicom:

+CSCS?
+CSCS: "UCS2"
OK

AT+CUSD=1,"*100#"
OK
+CUSD: 0,"04110430043B0430043D0441003A0034003604400020041104350437043B0438043C04380442043D044B043900200418043D044204350440043D043504420020043F043E00200420043E04410441043804380020002A003100310031002A0036003200380023",72
И далее:
$ printf $( echo "04110430043B0430043D0441003A0034003604400020041104350437043B0438043C04380442043D044B043900200418043D044204350440043D043504420020043F043E00200420043E04410441043804380020002A003100310031002A0036003200380023" | sed "s,\(..\),\\\\x\1,g" ) | iconv -f ucs-2be
Баланс:46р Безлимитный Интернет по России *111*628#

Deleted
()
Ответ на: комментарий от anonymous

Я имел ввиду что по той таблице не смог сориентироваться.

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

Это строка от ModemManager. Прямого доступа к модему я судя по всему не должен иметь, поэтому надо что-то придумать для этого варианта.

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

теоретически должен существовать какой-то стандарт или спецификация для USSD, где будет указана кодировка для текста

Я сейчас гуглил на эту тему. Оказалось, что стандарт есть: http://en.wikipedia.org/wiki/GSM_03.38. Но реальные масштабы бедствия я понял, только когда начал скачивать сами тексты стандартов и пытаться их читать 8).

Deleted
()
Ответ на: комментарий от KivApple

Это строка от ModemManager. Прямого доступа к модему я судя по всему не должен иметь, поэтому надо что-то придумать для этого варианта.

Посмотри как именно он обработал эту строку. И что-то мне подсказывает, что без модификации самого modemmanager'а не обойтись...

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

Там, на самом деле, все просто, но из стандартов нихрена не понятно.

В sms и ussd, в принципе, одинаковая схема - есть кодировка (DCS), иногда она в бинарном виде явно приходит (на новых модемах), иногда надо руками через AT интерфейс установить, какую хочется

На днях вот исправлял в одном RIL кодировку, портировал из старого часть функций

https://gitorious.org/~ast/replicant/asts-hardware_ril_samsung-ril/commit/98a...

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

Там, на самом деле, все просто, но из стандартов нихрена не понятно.

Похоже это общая беда почти всех стандартов 8).

Deleted
()
Ответ на: комментарий от alexst

И вот еще, декодирование UCS2

https://gitorious.org/~ast/replicant/asts-hardware_ril_samsung-ril/commit/4d2...

А вообще, можно почитать

https://gitorious.org/xdandroid/hardware_xdandroid-ril

Тут RIL для модемов в HTC Vogue/Diamond/Rhodium, классический AT протокол, и реализовано в былые славные времена все - смс, ussd, gprs. Если ОП захочет патчить ModemManager - это может пригодиться

alexst
()
Ответ на: комментарий от Deleted

Рекомендую посмотреть реализацию обработки USSD ответов в RIL подсистеме Android'a на некоторых телефонах.

Например здесь : http://www.gitorious.net/android-on-freerunner/platform_hardware_ril/blobs/47...

Начиная со строчки 3117.

Сам брал этот код, вроде бы с русским все было ок, но точно уже не вспомню.

Dead ★★★★
()

Если все еще помню, то кодировка зависит от SMS-центра, обрабатывающего запросы USSD, и ее трактовка может быть произвольной (??). Последнее лучше уточнить в описании протокола SMPP.

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

Наверное, SMPP тут ни причем. По хорошему это все скрыто за серверами. Надо брать уровнем выше. Что там? GSM? Вероятно, трактовка кодировки как-то прописана в их стандарте. Но в самом SMPP, через который уже обрабатывается USSD уровнем ниже, сама кодировка трактуется произвольно, если мне не изменяет память, хотя могу ошибаться.

dave ★★★★★
()

тут много ньюасов:
1) в отличие отвывода mironov_ivan, у тебя он какой-то совсем не текстовый. делаю вывод, что модем у тебя в PDU mode работает

2) кодировка зависит от сети и модема (несмотря на то, что чаще всего это ucs2) и от data coding scheme (dcs), которая приходит вместе с юссд ответом.

if TE character set other than «HEX» MT/TA converts GSM alphabet into current TE character set
if TE character set is «HEX»: MT/TA converts each 7‑bit character of GSM alphabet into two IRA character long hexadecimal number
if <dcs> indicates that 8‑bit data coding scheme is used: MT/TA converts each 8‑bit octet into two IRA character long hexadecimal number
if <dcs> indicates that 16-bit data coding scheme (UCS2) is used: MT/TA splits the 16 bits into two 8-bit octets. Each of those octets are converted as per the 8-bit data coding scheme, with the most significant octet first

специалисты рядом со мной предлагают тебе попробовать кодировку IRA

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

Это строка от Модем-Манаджера.

там стоит (char *) от бинарной строки после декодирования.

Посему, думаю, нужна обратная конвертация и декодирование как UCS2-BE, например.

Хотя в принципе кодировка ответа должна где-то храниться, но доступна ли она через интерфейс?

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

можно как нибудь так сделать:

$ dbus-send --system --print-reply --dest=org.freedesktop.ModemManager /org/freedesktop/ModemManager/Modems/0 org.freedesktop.ModemManager.Modem.Gsm.Ussd.Initiate string:*100# >file.dump

anonymous
()
Ответ на: комментарий от KivApple

Смотрел исходники Модем-манаджера, там плагин для HUAWEI недоработан.

Обработка reply идёт так:

bin = utils_hexstr2bin (reply, &bin_len); unpacked = gsm_unpack ((guint8*) bin, (bin_len * 8) / 7, 0, &unpacked_len); /* if the last character in a 7-byte block is padding, then drop it */ if ((bin_len % 7 == 0) && (unpacked[unpacked_len - 1] == 0x0d)) unpacked_len--; utf8 = (char*) mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len);

Последняя строка показывает, что бинарная строка преобразует в utf8 по кодировке

charset_gsm. Что, похоже, в той же, как и кодирование:

*scheme = MM_MODEM_GSM_USSD_SCHEME_7BIT;

Так что, видимо, поддержка иных кодировок ussd не предусмотрена. (пока?)

Алгоритм обратного преобразования, если кодировка ответа от оператора в UCS2, напрашивается сам. Сначала utf8 -> bin (по схеме gsm-7bit?), и потом по кодировке UCS2 (UCS2_BE) обратно в utf8. Но, возможна потеря информации при использовании 7 битного кода в плагине! И тогда, увы, финита. (я лично не пробовал, но чутьё слабых мест настораживает)

Согласен, что это только костыль для модемов HUAWEI. Лучше доработать плагин.

anonymous
()
10 ноября 2012 г.

я автор Gnome Modem Manager

Раз уж ты автор этого, то может подскажешь как его сконфигурять чтобы он не домогался до всего, что выглядит как последовательное усройство? Меня бы утроило хотябы для конкретных устройств его запретить. А то выбросить его из системы без нетворк-мэнэджера нельзя, а такое поведение очень бесит когда только что воткнутый, например, ГПС-приёмник оказывается заблокированным Модем-манагером и надо ждать пока тот к нему охладеет.

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

Я автор Gnome Modem Manager, а не Modem Manager. Моя программа лишь фронт-энд к нему и за работу с физическим устройством не отвечает.

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

Блин, назвал бы хоть GModemManagerGUI чтобы не вводить меня в заблуждение :)

anonymous
()
Ответ на: комментарий от KivApple

Я автор Gnome Modem Manager, а не Modem Manager. Моя программа лишь фронт-энд к нему и за работу с физическим устройством не отвечает.

Ну вот. А я-то подумал, что важный человек. Тьфу.

anonymous
()
27 февраля 2013 г.

USSD-запросы в Linux

Честно говоря я не праился. Побродив в интике нашел вот эту статью http://www.ionline.by/chasto-zadavaemye-voprosy-f-a-q/kak-nastroit-internet/m... Прога очень понравилась, тем более после того как я ей попользовался. На мой взгляд то что нужно обычному пользователю. Она не только USSD, но и с СМС работать умеет. Хорошая замена виндовым операторским приблудам.

Dark_Sarmat
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.