[Из песочницы] Мифический PCM Capture Extraction Tool: извлекаем звук без обращения в TAC

6ec2147a08bd49f2aec758f0e15f84e3.jpg
Недоступный простым смертным мифический ресурс pcet.cisco.com

Читатель, сталкивавшийся с необходимостью заниматься захватом данных PCM на маршрутизаторах Cisco ISR, легко находит исчерпывающее пошаговое руководство по данной теме, но непременно спотыкается о пункт «полученный файл следует отправить в TAC для дальнейшего извлечения звука». Можно ли обойтись без этого?

Предыстория


Телефонную станцию заказчика требовалось подключить как к одному известному SIP-оператору (публичный IP-адрес), так и к SIP-серверу провайдера, предоставлявшего местную связь (частный IP-адрес). К сожалению, станции этой модели не могут одновременно подключаться к SIP-серверам за NAT’ом и к таковым в частной сети, поскольку обход NAT подменой адресов в них включается для всех SIP-транков без исключения. В качестве маршрутизатора клиент использовал Cisco 2811. Поскольку у заказчика в АТС имелась свободная плата потока ISDN PRI, задачу решили приобретением в указанный маршрутизатор платы потока E1 и голосового процессора. Были выполнены соответствующие настройки (везде использовался кодек G.711 A-law) — и все заработало.

Проблема


Ситуация стандартная — все работало замечательно, но в один прекрасный день перестало. Сотрудники заказчика начали обращаться с жалобами на некий сигнал во время разговора, «как будто кто-то кнопку на телефоне нажал». Данный сигнал был довольно быстро идентифицирован как DTMF-тон, который мог прозвучать в начале, середине или конце разговора, а то и несколько раз в продолжение такового. Оставалось выяснить, кто в этом виноват (или что виновато) и как ситуацию исправить.

Следует сказать, что состав используемого оборудования предоставляет впечатляющий набор инструментов для тестирования и отладки. Кроме всего спектра отладочных возможностей Cisco есть весьма полезный инструмент трассировки ISDN в реальном времени, входящий в состав консоли управления используемой АТС. К сожалению, в этом случае ничего не помогало, «поймать» данный сигнал, то есть сопоставить его с отладочной информацией, никак не получалось в силу крайней нерегулярности его появления. Изучение всей информации по данному вопросу привело к ряду документов по захвату PCM на оборудовании Cisco.

Сообщается, что маршрутизаторы серий 2900, 3900, 3900e и шлюзы VG350 позволяют это делать легко и просто, причем в результате получается файл, содержащий голосовые данные, пригодные для непосредственного импорта в аудиоредакторы.

К огромному сожалению, маршрутизатор заказчика серии 2800 не имел чести принадлежать к перечисленным благородным семействам и таковыми возможностями не обладал. В IOS с версиями ниже 15.2(2)T1 (для маршрутизатора заказчика такая версия ПО никогда не будет выпущена, ибо End of Support) для захвата PCM требовалось выполнить ряд команд. Если событие ожидаемое, то можно дождаться его и произвести запись:

voice hpi capture buffer 51200000
voice hpi capture destination flash:pcm.dat

test voice port x/x/x pcm-dump caplog fff duration xxx

Или же можно записывать вообще все подряд до тех пор, пока не произойдет интересующее событие (осторожно, возможно переполнение памяти flash!):
dial-peer voice x voip/pots
 pcm-dump caplog fff duration xxx

При этом создается файл с голосовой и отладочной информацией, который может быть извлечен из памяти flash и скопирован на TFTP-сервер.

Еще одна проблема, в каком-то смысле похуже первой


Вот тут началось самое интересное. Многочисленные граждане, озадачившиеся захватом PCM, изливали на форумах технической поддержки свое негодование — мол, я сделал дамп, импортировал его в аудиоредактор и так и эдак, все равно получается какая-то фигня! Что я делаю неправильно? На это другие граждане им отвечали, что ситуация совершенно нормальная, извлечь из оного файла вожделенный звук могут только могущественные специалисты TAC при помощи мифического инструмента PCM Capture Extraction Tool, доступного по ссылке pcet.cisco.com. Думаю, не я один, посмотрев замечательный обучающий видеоролик на Youtube, пытался перейти по данной ссылке и был жестоко унижен, ибо это невозможно для простых смертных. Якобы необходимость вовлечения TAC связана не с техническими, а с правовыми аспектами (интересно, чем в правовом аспекте ISR G2 отличается от ISR?) — дескать, такое декодирование с какой-то точки зрения можно считать незаконным прослушиванием, и вообще декодер меняется слишком часто, версию используемого DSP определить трудно, etc. Удалось найти и мнение, высказанное предположительно от лица нерусскоязычного инженера TAC — мол, мы о механизме не задумываемся, а файл просто загружаем в систему через форму на страничке. Есть ряд ограничений на имя и размер, но в результате получаем .WAV-Файлы, а также некоторую отладочную информацию. В виде распространяемого дистрибутива данный инструмент не существует, и вообще основная трудность — заполучить сами .DAT-Файлы, так что вы, уважаемые заказчики, сии файлы заполучите и перешлите нам, а уж мы извлечем из них все, что надо и не надо.

Однако вовлечь в решение вопроса инженеров TAC в данном случае не получилось — помните, что оборудование в статусе End of Support? Соответственно, никаких сервисных контрактов и никакой поддержки. Правда, инженеры TAC порадовали меня, сообщив, что мое желание самостоятельно решить данную задачу, то есть разобраться в структуре файла и извлечь хранимую там информацию, нарушением чего бы то ни было не является и в случае успеха меня за это ничего пожизненно не лишат. И на том, как говорится, спасибо.

Начал с того, что загрузил один из полученных файлов в шестнадцатеричный редактор. Увиденное не слишком порадовало, хотя там и были знакомые слова («C2800NM-ADVENTERPRISEK9-M, 15.1(4)M10, IP|SLA|IPv6|IS-IS|FIREWALL|VOICE|PLUS|QoS|HA|NAT|MPLS|VPN|LE» и »28.3.14», последнее представляет собой значение DSPWARE VERSION из вывода команды show voice dsp detail). Кроме того, была заметна, так сказать, структура и периодичность. На этом этапе я решил вернуться к рассмотрению команды test voice port:

C2811#test voice port 0/3/0:15.1 pcm-dump  ?
  caplog   Print to caplog, please enable banjo logger
  console  Print to console, possible flood console
  disable  Disable the message dump

Во всех найденных описаниях внимание уделяется исключительно параметру caplog. Почему же заслуженную консоль так незаслуженно обошли вниманием? Это следует исправить:
C2811#test voice port 0/3/0:15.1 pcm-dump console ?
  <1-7>  PCM stream index. Bit0:R_in=0x01 Bit1:S_in=0x02 Bit2:S_out=0x04

Тут все более или менее понятно. Следующий параметр кодирует номера потоков PCM, которые требуется захватить. Поток R_in содержит аудиоданные, передающиеся из VoIP в PSTN. Поток S_in содержит аудиоданные, передающиеся из PSTN в VoIP ДО обработки DSP. Поток S_out содержит аудиоданные, передающиеся из PSTN в VoIP ПОСЛЕ обработки DSP. Номера потоков можно складывать, получая любые желаемые комбинации — можно захватывать любой один, любые два или же сразу все три потока одновременно. Впрочем, не вижу причин, по которым имеет смысл захватывать не все три потока данных сразу — разве что с целью разобраться в структуре поступающей в консоль информации. При этом можно запустить бессрочный захват (не забываем о том, что на карте flash должно быть достаточно свободного места) с последующей ручной остановкой:
test voice port 0/3/0:15.1 pcm-dump console 1

[разговор]
test voice port 0/3/0:15.1 pcm-dump disable

Можно сразу указать требуемую продолжительность в секундах:
C2811#test voice port 0/3/0:15.1 pcm-dump console 1 duration ?
  <0-255>  capturing time in sec

Захват трех каналов в консоли выглядит примерно так:
047581: Jan 19 11:52:15.491:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
047582: Jan 19 11:52:15.495:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 00 00 07 00 09 00 0E 00 0E 00 0D 00 0D 00 03 FF FC 00 00 00 04 00 02 00 00 FF F9 00 03 00 0B 00 04 00 0B 00 0C 00 01 00 00 00 01 FF FE 00 06 00 02 00 03 00 07 00 06 00 00 00 05 FF FD 00 02 00 07 00 03 00 04 00 08 FF FF 00 02 00 04 FF FF FF F8 FF F5 FF F3 FF FA FF F8 FF F1 FF F1 FF F2 FF F4 FF EF FF EF FF EE FF F0 FF F8 FF FB FF F4 FF F3 FF FA FF F4 FF F2 FF F8 FF FF 00 04 FF FB FF F5 FF F1 FF FC FF FD FF FE FF F6 FF F3 FF F2 FF ED FF EA FF EB FF F7 FF F5 FF F2 FF F2 FF F6 FF FC
047583: Jan 19 11:52:15.499:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 01 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08

[и еще очень много похожих сообщений]

Захват одного канала:

027761: Jan 15 00:59:53.549:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00

[и еще очень много похожих сообщений]

Выполним следующие команды:

test voice port 0/3/0:15.1 pcm-dump con 1 duration 10
test voice port 0/3/0:15.1 pcm-dump dis

test voice port 0/3/0:15.1 pcm-dump con 2 duration 10
test voice port 0/3/0:15.1 pcm-dump dis

test voice port 0/3/0:15.1 pcm-dump con 4 duration 10
test voice port 0/3/0:15.1 pcm-dump dis

test voice port 0/3/0:15.1 pcm-dump con 7 duration 10
test voice port 0/3/0:15.1 pcm-dump dis

Вернемся к рассмотрению структуры полученных текстовых сообщений. Файл для R_in:
047648: Jan 19 12:10:48.525:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 00 00 18 00 28 00 28 00 18 00 28 00 28 00 18 00 28 00 18 00 18 00 18 00 18 00 08 00 18 00 18 00 08 00 18 00 08 FF F8 00 08 FF F8 FF E8 FF E8 FF E8 FF E8 FF E8 FF E8 FF E8 FF E8 FF D8 FF D8 FF E8 FF E8 FF E8 FF E8 FF D8 FF E8 FF E8 FF E8 FF E8 FF E8 FF F8 00 08 00 08 FF F8 FF F8 FF F8 FF F8 FF F8 FF F8 FF F8 FF F8 00 08 00 08 FF F8 00 08 00 08 00 08 00 08 00 18 00 08 00 18 00 18 00 18 00 18 00 18 00 18 00 08 00 18 00 18 00 18 00 18 00 08 00 08 00 08 00 08 00 18 00 18 FF F8 00 08

[…]
048647: Jan 19 12:10:58.517:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 00 00 08 00 08 FF E8 FF F8 FF E8 FF F8 FF F8 FF E8 FF E8 FF E8 FF E8 FF F8 FF E8 00 08 FF F8 FF F8 FF F8 FF F8 00 18 FF F8 00 08 00 08 FF F8 FF F8 FF E8 FF F8 FF E8 FF F8 FF E8 FF F8 FF F8 FF F8 FF F8 FF E8 FF D8 FF F8 FF E8 FF E8 FF E8 FF E8 FF F8 FF F8 FF D8 FF E8 FF E8 FF F8 FF E8 FF F8 FF F8 FF E8 FF F8 FF F8 FF E8 FF E8 FF F8 FF E8 FF E8 00 08 FF F8 FF F8 FF F8 FF F8 FF F8 FF E8 FF E8 FF F8 FF E8 00 08 FF F8 00 18 00 08 00 08 FF E8 00 08 00 08 00 08 00 08 00 18 00 08 00 08

Шестизначное число перед датой представляет собой уникальный идентификатор, всего у нас присутствует ровно одна тысяча сообщений с номерами от 047648 до 048647 включительно.

Файл для S_in:

050234: Jan 19 12:12:58.636:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 01 FF E8 FD 90 FE F8 FF B8 02 B0 01 C8 FF 48 03 D0 FE 98 08 40 FD F0 FD 70 FF D8 FD D0 00 C8 FC D0 04 E0 FA E0 02 10 04 A0 F9 E0 02 90 FD F0 FE A8 00 B8 02 50 02 70 FE E8 02 90 FD 90 00 F8 04 60 FA 60 00 A8 FC D0 02 30 01 E8 FD D0 03 50 FA 20 FF D8 01 78 FF 28 03 90 01 08 FB E0 01 78 FF 98 FE C8 FF A8 FF 38 06 A0 FA A0 00 A8 04 A0 FD 10 00 E8 FE 08 00 B8 FE D8 FD B0 01 98 01 78 01 D8 00 38 FF C8 FF 08 00 28 01 58 FE B8 01 D8 FE E8 FE 08 01 C8 FF 68 FF A8 00 08 00 38 FF 28 FE 48

[…]
051233: Jan 19 12:13:08.624:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 01 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 08 00 18 00 08 00 08 00 08 00 18 00 18 00 18 00 18 00 18 00 18 00 08 00 08 FF F8 FF F8 FF F8 FF E8 FF E8 FF E8 FF D8 FF E8 FF D8 FF D8 FF D8 FF E8 FF E8 FF E8 FF F8 FF F8 00 08 00 18 00 08 00 08 00 18 00 18 00 18 00 18 00 18 00 08 00 08 00 08 00 08 00 08 FF F8 00 08 FF F8 00 08 00 08 00 08 FF F8 FF F8 FF F8 FF F8 00 08 00 08 00 08 00 08 FF F8 00 08 00 08 00 08 00 18 00 08 00 18 00 18 FF F8 FF F8 FF F8 FF F8 FF F8 FF E8 FF E8

Тоже одна тысяча сообщений ровно.

Файл для S_out:

051234: Jan 19 12:14:00.396:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 02 00 06 FF F6 00 76 00 F6 00 36 FF C6 00 68 FF F8 FF 88 00 78 FF A8 FE B8 00 18 00 98 FF 98 FF C8 01 38 FF 98 FF 18 01 58 00 58 FE F6 FF A8 01 A8 00 E8 00 38 00 18 FF 08 FE 56 FF 06 00 A6 00 86 00 E6 FF 86 FF 58 FF D8 00 18 00 86 00 26 00 66 FF F6 FF E6 FF 56 00 56 00 76 FE F6 FF E6 00 16 FF C6 FF B6 FF C6 00 86 FF B6 FF 76 FF F6 00 A6 00 36 FF E6 00 88 00 08 00 38 FF E8 FF F6 00 18 00 3A 00 8A 00 2A FF BA FF 5A FF D8 00 18 00 58 00 5A FF 7A FF AA FF E8 00 18 00 18 FF C8 FF F8

[…]
052233: Jan 19 12:14:10.388:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 02 00 C0 01 8C FD 52 01 00 01 C2 FE E8 FE BE 01 3E 01 60 FF 4E FE 56 FE 44 02 0E 02 14 FF E8 FF 46 FF B4 FE F6 01 64 00 C2 FC D2 03 84 00 84 FC BC FD E8 01 5E 04 66 FD B6 FE 62 00 60 FF C6 01 6E 00 50 FE AA FE AC 01 3C 02 2C FC E8 00 16 01 3E 00 38 00 EC FF 26 FF 40 00 26 01 30 00 22 00 20 FF 74 FE 9C 01 A8 01 16 FF A8 FD EE FF 84 01 E0 FE 9C 00 64 FF A4 00 7A 01 96 FE BC FF 44 00 86 FF E0 FE F8 01 8A FF 22 FF 00 02 12 00 5A FE 70 00 18 00 B0 FE D6 01 B6 FE 1A FF E6 02 6E FE 22

Одна тысяча сообщений ровно.

Файл для всех потоков:

052234: Jan 19 12:15:02.576:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 00 00 08 00 38 00 78 00 B8 00 18 00 18 FF F8 FF C8 FF F8 FF E8 FF B8 FF 58 00 08 FF 98 FF A8 00 58 00 48 00 08 FF 88 FF C8 00 28 00 48 00 68 00 98 00 68 00 A8 00 B8 00 18 FF 98 FF 68 FF C8 FF A8 FF 88 FF 78 FF 58 00 38 FF C8 FF 78 00 48 00 48 00 38 00 88 01 78 00 78 FF D8 00 38 FF A8 FF 78 FF E8 00 28 FF A8 FF 98 00 88 00 A8 00 18 FF 88 FF E8 00 78 FF E8 FF B8 00 58 00 58 FF 48 FF C8 00 48 00 08 FF C8 00 38 00 78 FF D8 00 28 00 68 00 18 FF B8 FF 78 FF C8 00 68 00 38 FF D8 FF A8

[…]
055211: Jan 19 12:15:12.516:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 01 FF A8 01 28 FE 28 00 18 FF 78 FE E8 01 A8 00 08 02 10 00 48 FE C8 00 28 00 98 00 38 FF 68 FF 18 FE C8 00 A8 FF 68 01 98 00 08 FF C8 01 18 00 B8 FF E8 FF 08 FF F8 FE 18 00 28 FF 68 FE F8 00 E8 00 78 00 F8 00 78 FE E8 00 78 FE D8 00 48 01 A8 00 E8 00 B8 FF F8 FF C8 FF 58 FF 08 00 C8 FF B8 FF 58 01 D8 FE 78 00 08 FF 38 FE 28 FF E8 00 C8 FF 88 01 48 00 D8 00 68 00 08 FF 68 FF D8 00 68 FF B8 FF 58 00 78 00 08 00 68 FF A8 01 18 FE 58 00 18 00 28 FF E8 00 F8 00 28 01 08 00 B8 FE E8
055212: Jan 19 12:15:12.520:  len=172, ch_id=1, pak_id=143, proc_id=0, <==  Payload:  00 07 00 02 FF AC 01
055234: Jan 19 12:15:32.851: %ISDN-6-DISCONNECT: Interface Serial0/3/0:0  disconnected from 2606699 , call lasted 372 seconds

Тут картина несколько отличается. Очевидно, что для трех потоков сообщений будет в три раза больше, чем для одного. Однако во взятом для примера логе полных сообщений всего-навсего 2978 штук, плюс одно обрезанное в самом конце. Некоторые источники указывают на то, что в случаях, когда диагностические сообщения поступают в буфер быстрее, чем маршрутизатор может выводить их в лог, некоторые сообщения могу теряться целиком или частично.

Можно обратить внимание, что в каждом сообщении данные начинаются одной и той же последовательностью байтов (R_in: 00 07 00 00, S_in: 00 07 00 01, S_out: 00 07 00 02; файл для всех потоков содержит сообщения со всеми указанными последовательностями).

Очевидно, эти четыре байта представляют собой некий служебный заголовок, который при рассмотрении можно смело не принимать в расчет, поскольку он просто указывает на поток, которому принадлежит сообщение. Данное предположение неплохо согласуется с тем, что для десятисекундного интервала в лог попадает тысяча сообщений со 160 байтами полезной информации каждое, то есть 160000 байтов полезной информации. При частоте дискретизации 8000 Герц, временном интервале 10 секунд и при глубине дискретизации 16 бит для одного звукового канала (моно) получается именно такой объем данных.

Первая грубая обработка


При помощи текстового редактора, поддерживающего регулярные выржения, и регулярного выражения (…:).*(<== Payload: 00 07 00 01 ) удаляю строки (050234: Jan 19 12:12:58.636: len=172, ch_id=1, pak_id=143, proc_id=0, <== Payload: 00 07 00 01 ) из соответствующего файла. Происходит ровно 1000 замен. После преобразования ASCII данных в двоичные в шестнадцатеричном редакторе (вставка в файл буфера ASCII-HEX) получаем файл размером ровно 160000 байтов.

Необходимо отметить, что при этом происходит следующее. В лог маршрутизатора данные попадают в том же порядке, в котором они хранятся в его памяти (порядок big-endian). То есть, например, значение 0×1234 хранится в двух последовательных ячейках: 12 34. В таком виде мы и копируем текст в буфер, в том же порядке байты попадают в двоичный файл.

Посмею напомнить читателю, что в памяти персональных компьютеров с x86-процессорами принят порядок записи от младшего байта к старшему (англ. little-endian, дословно: «остроконечный»), в связи с чем иногда его называют интеловский порядок (по названию фирмы-создателя архитектуры x86).

В то же время стандартным для протоколов TCP/IP является байтовый порядок от старшего к младшему (англ. big-endian, дословно: «тупоконечный»). Он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому порядок байтов от старшего к младшему часто называют сетевым порядком байтов (англ. network byte order). Этот порядок байтов используется не только процессорами IBM 360/370/390, Motorola 68000, SPARC (отсюда третье название — порядок байтов Motorola, Motorola byte order), но и процессорами некоторых маршрутизаторов Cisco.

Далее производится импорт полученного RAW-файл в аудиоредактор. В итоге удается получить корректный звуковой файл при указании следующих параметров: Signed 16 bit, Big-endian, 1 канал (моно), частота 8000 Гц.

Все слышно!

Это, безусловно, первый маленький успех. Его следует развить — попробовать разобраться со структурой .DAT файла, после чего всяк желающий сможет написать на своем любимом языке программирования собственную программу, которая будет извлекать из данного файла звук.

При ближайшем рассмотрении файла обнаружил, что в файле также чередуются последовательности 00 07 00 0X, смещенные на F4 байтов друг относительно друга. Двухбайтовое слово со значением 00 F4 (big-endian, не забываем это) присутствует во всех случаях со смещением -0×0E относительно последовательности 00 07 00 0X. Можно предположить, что оно относится к заголовку пакета данных и указывает размер текущего пакета (смещение заголовка следующего пакета по отношению к заголовку текущего пакета).

Рассмотрев последний голосовой пакет в файле, можно заметить, что за F4 байтов от конца файла присутствует последовательность 00 00 00 00. Предположим, что она обозначает начало пакета. Таким образом, слово со значением 00 F4 находится по смещению 0×42 от начала голосового пакета. В то же время для каждого голосового пакета в файле между последовательностями 00 07 00 0X и 00 00 00 00 помещается ровно 0xA0, то есть 160 байтов информации, что неплохо согласуется с зависимостями, установленными в ходе анализа текстового лога. Можно предположить, что это 160 байт полезной нагрузки — голосовых данных. На иллюстрациях я выделяю данные байты пурпурным цветом, дабы указать на их важность.

Проанализируем заголовки:

54878a7820a1435985401253969275c6.jpg

Голубым выделено предполагаемое положение идентификаторов len, ch_id, pak_id, proc_id (Вспомним текстовый лог: 792308: Jan 22 16:30:42.458: len=172, ch_id=1, pak_id=143, proc_id=0, <== Payload:), оранжевое значение в проанализированных пакетах совпадает с ch_id.

Значение 172=0xAC, расположенное по смещению 0×48, соответствует размеру порции данных начиная от этого смещения и до конца пакета.

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

71a44f52ecda427a81971fa710cb7018.jpg

Обнаруживаются две завершающиеся нулем строки, содержащие текстовую информацию о маршрутизаторе (на рисунке выделены желто-зеленым цветом):

1) текст 28.3.14 (соответствует DSPWARE VERSION из вывода команды show voice dsp detail) находится со смещением 0×5С от начала файла;

2) текст C2800NM-ADVENTERPRISEK9-M, 15.1(4)M10, IP|SLA|IPv6|IS-IS|FIREWALL|VOICE|PLUS |QoS|HA|NAT|MPLS|VPN|LE) находится со смещением 0xC0 от начала файла.

Можно также попытаться отыскать в данном файле какие-то частные значения, относящиеся к конкретному маршрутизатору (типа MAC’ов и серийных номеров) или пакету (CRC). Пока же не следует углубляться в изыскания, поскольку эти данные для нас особого интереса не представляют.

По смещению 0×42 в файле содержится слово 01 24, а по смещению 0×0124 начинается первый голосовой пакет. Это могло бы быть совпадением, однако проверка на ряде файлов позволяет сделать вывод, что закономерность подтверждается для всех файлов и пакетов в них. Это соблюдается и для неизвестного назначения и содержания пакетов, явно не содержащих голос.

Итак, структура голосового пакета:

packet_sign		[0x00]	0x04 байта	всегда 	00 00 00 00
UNKNOWN			[0x04] 	0x3E байтов		
packet_size		[0x42]	0x02	байта
UNKNOWN			[0x44] 	0x04	байта	всегда 	00 00 00 00
len				[0x48]	0x02 байта
ch_id			[0x4A]	0x02 байта
pak_id			[0x4C]	0x02 байта
proc_id			[0x4E]	0x02 байта
UNKNOWN			[0x50] 	0x02 байта	всегда 	00 07
stream_id			[0x52]	0x02 байта	R_in		00 00
									S_in		00 01
									S_out	00 02
raw_data			[0x54]	0xA0 байтов

Вооружившись изложенным, всяк желающий может самостоятельно на своем любимом языке программирования написать программу, формирующую из DAT-файла файлы, содержащие голос — хоть RAW для последующего импорта в аудиоредактор и обработки, хоть сразу WAV.

Итог


Разумеется, это лишь частное решение, не претендующее на полноту. Например, при использовании кодеков, отличных от G.711, идентифицировать и распаковать звуковые данные будет существенно сложнее. Наверняка проявятся и другие побочные эффекты. По этим причинам я не публикую код, при помощи которого достигалась автоматизация обработки входных данных.

Данные предположения позволили без проблем разделить по каналам файл с данными PCM, полученный на диалпире и содержащий несколько одновременных разговоров с различными ch_id. Благодаря этому удалось отследить и идентифицировать проблемный DTMF, который был всему причиной.

К тому же маршрутизатору, как выяснилось, был подключен по SIP китайский GSM-шлюз. Абоненты АТС слышали тоны только при звонках через данный шлюз. Удалось выявить, что шлюз, на котором включен RFC2833, передает странные (не вполне понятно, откуда они берутся — то ли генерируются самим шлюзом, то ли приходят из сети оператора, но точно не от удаленного абонента) пакеты, которые маршрутизатор (на котором, в свою очередь, тоже включен RFC2833) воспринимает как RTP NTE, после чего отправляет в поток полноценный тон, который слышат абоненты АТС и для обнаружения которого были проделаны все те манипуляции, которые легли в основу данного материала.

Поскольку шлюз в силу своей предельной дешевизны не позволяет выполнять сбор отладочной информации и установить степень его вины не представлялось возможным, было на всякий случай произведено обновление прошивки шлюза до актуальной версии. Это не помогло, сигнал продолжал появляться. Далее было произведено переключение шлюза в режим SIP INFO (на маршрутизаторах Cisco ISR данный режим всегда включен). Пока жалобы отсутствуют.

Комментарии (0)

© Habrahabr.ru