Что вижу - о том пою (aragont) wrote,
Что вижу - о том пою
aragont

Categories:

Это сообщение EMS! Посмотрите его на телефоне.

Юлька любит во время путешествий отправлять родным и друзьям стихотворные СМСки - СтихМСки.
Известно, что длина СМСки на русском языке не может превышать 70 символов (а у буржуев 160 :{ ). Стишок в такой объем не помещается, и СМСка разбивается на несколько. Хозяйственная Юлька выработала особый стихотворный размер, заполняющий ровно две или три СМСки, не оставляя пустым ни один оплаченный байт.

Потихоньку память аппарата заполняется и через несколько путешествий возникает вопрос: как бы стереть СМСки, но сохранить стихи?

Во времена наших первых телефонов проблема решалась абсолютно нетехнологичным способом - Юлька садилась за компьютер, включала телефон и тупо перепечатывала все СМСки в Ворде. Потом телефон поменялся, у него появился USB-шнурок для подключения к компьютеру, но тут нас ждала новая засада. Саммсунговская программа управления телефонами Samsung PC Studio напрочь отказалась показывать длинные СМСки. До 70 символов пожалуйста, а если длиннее, то программа выдаёт издевательский текст: "Это сообщение EMS! Посмотрите его на телефоне." На телефоне я его и раньше читал, а теперь хочу на компьютере!

Юлька человек простой - она готова перепечатывать полсотни СМС раз в полгода, а меня эта ситуация немного заела. В начале я даже собирался написать специальную программу с окошечками, которая бы все читала и показывала, а потом обошёлся подручными средствами и маленьким скриптом, запускающимся из командной строки.

Что нужно: Телефон Samsung (не смартофон. У Юльки SGH-J700), Samsung PC Studio, подходящей к телефону версии, микрософтовская утилита portmon.exe с сайта Sysinternals и скриптовый язык Python.

При подключении по USB телефон, на самом деле, прикидывается модемом, подключенным к COM-порту. Работа Виндоуз с COM-портами не отличается особой устойчивостью, поэтому может потребоваться определённый порядок запуска программ (например вначале запуск, а потом подключение телефона или наоборот), а иногда (при получении сообщения, что порт занят другой программой) перезагрузка.

"Мой компьютер" - правая клавиша мыши - "Управление" - "Диспетчер устройств"
Находим модем-телефон и номер порта, который ему назначен.
samsung1

Запускаем программу portmon.exe и настраиваем параметры записи. Если захватывать сообщения в текстовом виде, то 1024 байта вполне достаточно для записи СМС. Если захватывать в 16-ричном виде (HEX - смотри ниже), то значение надо увеличить до 2048.
samsung3
samsung4

В текстовом виде portmon заменяет все спецсимволы точками. К сожалению, русские буквы попадают в эту категорию и текст портится. Если нужны только длинные СМС (они кодируются цифрами и латинскими буквами), то можно этой настройкой пренебречь. Если хочется скачать все, надо включить запись 16-ричных кодов символов (HEX).
samsung-hex

Наконец, надо выбрать порт для наблюдения. Записать данные в файл можно будет потом, нажав на иконку с дискетой в левом углу, а можно включить запись на лету, нажать значок дискеты с красной меткой.
samsung2

Когда запись началась, можно запустить PC Studio и выбрать Message Manager, который автоматически начнёт закачку СМС с телефона
samsung5

samsung6

В файле должно сохраниться примерно следующее

HEX версия:

1622 0.00000000 ConMgr.exe IRP_MJ_READ ss_mdm1 Length 8192
1613 0.19396684 SUCCESS
1623 0.00000000 ConMgr.exe IOCTL_SERIAL_GET_COMMSTATUS ss_mdm1
1623 0.00001028 SUCCESS
1624 0.00000000 ConMgr.exe IOCTL_SERIAL_WAIT_ON_MASK ss_mdm1
1624 0.00068652 SUCCESS
1622 0.01683736 TIMEOUT Length 369: 0D 0A 2B 43 4D 47 52 3A 20 22 53 54 4F 20 53 45 4E 54 22 2C 22 2B 37 39 31 32 32 37 32 32 32 32 32 22 2C 22 38 31 32 22 2C 31 34 35 2C 36 35 2C 30 2C 32 35 2C 22 2B 37 39 32 32 32 39 30 39 30 39 30 22 2C 32 35 35 2C 31 34 30 0D 0A 30 35 30 30 30 33 31 42 30 33 30 31 30 34 31 43 30 34 34 42 30 30 32 30 30 34 33 32 30 34 34 37 30 34 33 35 30 34 34 30 30 34 33 30 30 30 32 30 30 34 33 32 30 30 32 30 30 34 33 45 30 34 34 32 30 34 33 35 30 34 33 42 30 34 34 43 30 30 32 30 30 30 41 42 30 34 32 31 30 34 33 30 30 34 33 34 30 34 33 41 30 34 33 45 30 30 42 42 30 30 32 30 30 34 33 46 30 34 33 45 30 34 34 31 30 34 33 35 30 34 33 42 30 34 33 38 30 34 33 42 30 34 33 38 30 34 34 31 30 34 34 46 30 30 32 43 30 34 33 38 30 30 32 30 30 34 33 44 30 34 33 30 30 30 32 30 30 34 33 41 30 34 34 30 30 34 33 35 30 34 33 43 30 34 33 42 30 34 34 43 30 30 32 30 30 34 33 44 30 34 33 30 30 30 32 30 30 34 31 44 30 34 33 45 30 34 33 32 30 34 33 33 30 34 33 45 30 34 34 30 30 34 33 45 30 34 33 34 30 34 34 31 30 34 33 41 30 34 33 38 30 34 33 39 30 30 32 30 30 34 33 46 30 34 33 45 30 34 33 34 2C 33 2C 30 0D 0A 0D 0A 4F 4B 0D 0A
1625 0.00000000 ConMgr.exe IRP_MJ_READ ss_mdm1 Length 8192
1626 0.00000000 ConMgr.exe IOCTL_SERIAL_GET_COMMSTATUS ss_mdm1
1626 0.00000936 SUCCESS


Текстовая версия с испорченной короткой СМС и закодированной длинной:

765 0.00001476 SUCCESS
766 0.00000000 ConMgr.exe IOCTL_SERIAL_WAIT_ON_MASK ss_mdm0
764 0.01981044 TIMEOUT Length 168: ..+CMGR: "STO SENT","+79166058222","191",145,1,0,25,"+79222909090",0,89...................... ................ ........ ............ .... ..................! ;))),3,0..
766 0.00057872 SUCCESS


780 0.00000000 ConMgr.exe IRP_MJ_READ ss_mdm0 Length 8192
781 0.00000000 ConMgr.exe IOCTL_SERIAL_GET_COMMSTATUS ss_mdm0
781 0.00000800 SUCCESS
782 0.00000000 ConMgr.exe IOCTL_SERIAL_WAIT_ON_MASK ss_mdm0
780 0.00078032 TIMEOUT Length 360: ..+CMGR: "STO SENT","+79166058222","191",145,65,0,25,"+79222909090",0,84..050003E30201042F0020043E043F044F0442044C00200432002000AB0433043E043D0446043000BB00200438043304400430044E003A0020044100200432043E0441043A0440043504410435043D044C044F0020043704300433043E04400430044E002004320020041404360435043C0435044204350020043D04300020043104350440043504330443002E,3,0..
782 0.00081992 SUCCESS


Программа для извлечения текста СМС из файла приведена ниже. Структура данных описана в комментариях. Запускается из командной строки через интерпретатор Pyton'а, с указанием входного и выходного файла в качестве параметров. Выходной файл записывается в виноузовской кодировке cp1251. После минимальных исправлений (убрать комментарии на русском, вычеркнуть в начале программы fout = open(sys.argv[2],"w") и заменить в последней строке fout.write на sys.stdout.write, в двух местах заменить 'cp1251' на 'utf_8') можно запустить программу в онлайн интерпетаторе - http://www.compileonline.com/execute_python_online.php

>python samsungems.py Portmon.log sms.txt


# -*- coding: utf8 -*-
import binascii
import array
import sys


if len(sys.argv) != 3:
    sys.stderr.write("Usage: "+sys.argv[0]+" <infile> <outfile>\n")
    sys.exit(1)
f = open(sys.argv[1])
lines = f.readlines()
f.close()

fout = open(sys.argv[2],"w")
outlines = list()

for line in lines:
    # Отбрасываем строки не содержащие входных даных
    if line.find("TIMEOUT") == -1 :
        continue
    if line.find("TIMEOUT  Length 0:") != -1 :
        continue

    # Отрезаем заголовок, вставленный PORTMONом
    line=line[line.find(":")+1:]

    # Считаем, что 0D 0A - признак захвата данных в HEX
    # Текст захваченный без HEX отчасти искажен.
    # так, символы конца строки заменены на две точки
    if line.find("0D 0A") != -1 :
        line="".join(line.split()).decode("hex")
        sep="\r\n"
    else :
        sep=".." 

    # СМС, в зависимости от того отправлены они или приняты,  помечены как
    # "STO SENT" "STO UNSENT" и "REC READ"
    if line.find("+CMGR: \"STO") == -1 and line.find("+CMGR: \"REC") == -1:
        continue

    sublines=line.split(sep)

    fields=sublines[1].split(',')
    #После тела СМС есть ещё два числовых поля, но мы на них внимания не обращаем
    msgtxt=sublines[2]
    phone=fields[1]

     принятых СМС есть поле с датой, в отправленных нет
    # поэтому нумерация полей сдвигается
    if fields[0].find("+CMGR: \"STO") >= 0 :
        inout="STO"
        enc=fields[4]
    else :
        inout="REC"
        enc=fields[6]

    # enc < 64 - используется простой текстовый формат в UTF-8
    # enc >= 64 используется кодирование в формат PDU + запись в HEX
    #    Выделяются поля - тип заголовка (12 или 24 символа)
    #    Уникальный идентификатор СМС + номер фрагмента в этой СМС
    #    Сам текст хранится в UTF-16 + HEX запись
    if int(enc) >= 64 :
        thead=int(msgtxt[1])
        msgid=msgtxt[4:10]
        msgnum=msgtxt[10:12]
        if thead == 5:
            htext=msgtxt[12:]
        if thead == 9:
            htext=msgtxt[24:]
        htext=htext.split(',')[0]
        # при захвате в HEX и потери части данных возможны ошибки при декодировании
        try:
            text=htext.decode("hex").decode('utf_16_be').encode('cp1251')
        except:
            text="Wrong string"
    else :
        # фиктивный идентификатор для некодированных сообщений
        msgid=msgtxt
        msgnum="0"
        text=msgtxt.decode('utf_8').encode('cp1251')

    outlines.append((phone,msgid,msgnum,inout,text))

outlines.sort()
msgid=0
msgnum=0
for line in outlines:
    if line[1] != msgid:
        msgid=line[1]
        fout.write("\n"+line[0]+" "+line[3]+" "+line[4])
    else :
        fout.write(line[4])
Tags: Юлькино, программы, рецепты
Subscribe

Recent Posts from This Journal

  • От сумы и до тюрьмы

    Личный опыт показывает, что в каждом городе, в котором есть психиатрическая больница, для нее придумано народное название, которое потом попадает в…

  • О похоронном деле

    Так получилось, что последние две недели я несколько раз заглядывал на Ивановское кладбище. Среди могил время от времени появляются объекты,…

  • Как снимать историю

    Когда у меня появился первый цифровой фотоаппарат, я тут же начал фотографировать родной город, чтобы сохранить память об изменениях в нём хотя бы…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 2 comments