<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Семён сохраняет полезное_)</title><subtitle>Канал о электронике и связи.
Демократии тут нет и не будет! Бан раздается за любое &quot;Ну очевидно, же&quot;</subtitle><author><name>Семён сохраняет полезное_)</name></author><id>https://teletype.in/atom/pole_sam</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/pole_sam?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/pole_sam?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-09-28T12:29:50.329Z</updated><entry><id>pole_sam:0Ddri2A1-yN</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/0Ddri2A1-yN?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Как из неуправляемого коммутатора сделали управляемый или как я купил очередную хрень и сделал из неё другую</title><published>2026-09-20T17:55:01.202Z</published><updated>2026-09-20T17:55:01.202Z</updated><summary type="html">Однажды мне попался на озоне медиаконвертер с 4 портами RJ-45(8P8C) и одним портом для оптики. Стоил он недорого(их и сейчас можно найти за 2 тысячи) и мне было интересно на чем он устроен и что можно из него сделать(а ещё если он будет вовсе глупый то использовать по прямому назначению). Так прошел год после покупки и у меня недоходили руки до него. Недавно время всё таки нашлось. Итак я сделал из медиаконвертера управляемый свитч.</summary><content type="html">
  &lt;p id=&quot;keJG&quot;&gt;Однажды мне попался на озоне медиаконвертер с 4 портами RJ-45(8P8C) и одним портом для оптики. Стоил он недорого(их и сейчас можно найти за 2 тысячи) и мне было интересно на чем он устроен и что можно из него сделать(а ещё если он будет вовсе глупый то использовать по прямому назначению). Так прошел год после покупки и у меня недоходили руки до него. Недавно время всё таки нашлось. Итак я сделал из медиаконвертера управляемый свитч.&lt;br /&gt;&lt;/p&gt;
  &lt;p id=&quot;S6uD&quot;&gt;Начнем с того что обнаружилось на плате медиаконвертера.&lt;/p&gt;
  &lt;p id=&quot;mVEF&quot;&gt;&lt;strong&gt;RTL8367S-CG&lt;/strong&gt; — управляемый коммутатор второго уровня, пять встроенных&lt;br /&gt;приёмопередатчиков на гигабит плюс два расширенных порта. На нашей плате&lt;br /&gt;наружу выведены четыре разъёма и один под оптику.&lt;/p&gt;
  &lt;p id=&quot;A5Cp&quot;&gt;Рядом с ним на плате стоит &lt;strong&gt;FT24C32A&lt;/strong&gt; — микросхема памяти на 32 килобита&lt;br /&gt;(4 КБ) с двухбайтовой адресацией, откликается на адрес &lt;code&gt;0x50&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;v1JM&quot;&gt;В качестве управляющей платы я взял &lt;strong&gt;WeAct STM32G431 Core Board.  &lt;/strong&gt;На плате стоит STM32G431CB, а в нем: Cortex-M4F на 170 МГц, 128 КБ флеш-памяти,&lt;br /&gt;32 КБ оперативной. Определение платы уже есть в дереве Zephyr под именем&lt;br /&gt;&lt;code&gt;weact_stm32g431_core&lt;/code&gt;, и в нём всё, что нужно. Ровно 48 МГц для USB — обязательное требование, и делитель Q подобран&lt;br /&gt;именно под него. Взят он потому-что был просто под рукой. И да для данной задачи это over. &lt;/p&gt;
  &lt;h2 id=&quot;3-выводы-коммутатора-и-выбор-режима&quot;&gt;Выводы коммутатора и выбор режима&lt;/h2&gt;
  &lt;p id=&quot;rRAU&quot;&gt;Самая ценная выкладка из документации на RTL8367S-CG была в том:&lt;/p&gt;
  &lt;p id=&quot;m3td&quot;&gt;&lt;strong&gt;Отдельных выводов MDC/MDIO у микросхемы нет.&lt;/strong&gt; Это те же две линии что и I2C. Какую из двух ролей они играют, задаёт состояние вывода &lt;strong&gt;&lt;code&gt;SMI_SEL&lt;/code&gt;&lt;/strong&gt;&lt;br /&gt;(совмещён с GPIO52, &lt;code&gt;LAN0LED0&lt;/code&gt;/&lt;code&gt;LED_CK&lt;/code&gt;) в момент сброса.&lt;/p&gt;
  &lt;p id=&quot;BH5e&quot;&gt;Второй страппинг: &lt;strong&gt;&lt;code&gt;EEPROM_MOD&lt;/code&gt;/&lt;code&gt;LAN4LED0&lt;/code&gt;&lt;/strong&gt; задаёт размер памяти —&lt;br /&gt;низкий уровень означает до 16 кбит (24C02…24C16), высокий — больше&lt;br /&gt;(24C32…24C256). У нас стоит 24C32, значит вывод должен быть в высоком&lt;br /&gt;состоянии.&lt;/p&gt;
  &lt;h2 id=&quot;4-служебный-протокол-realtek-smi&quot;&gt;Служебный протокол Realtek SMI&lt;/h2&gt;
  &lt;p id=&quot;UWuU&quot;&gt;Протокол внешне напоминает I²C, но им не является: у него свои условия&lt;br /&gt;начала и конца посылки. Поэтому аппаратный контроллер I²C использовать&lt;br /&gt;нельзя — обмен формируется программно.&lt;/p&gt;
  &lt;h3 id=&quot;код-команды&quot;&gt;Код команды&lt;/h3&gt;
  &lt;p id=&quot;xJyR&quot;&gt;Первый байт собирается из трёх частей:&lt;/p&gt;
  &lt;pre id=&quot;LGiJ&quot;&gt;  1011    +    100    +    К       =  1011 100К
  4 бита       3 бита      1 бит&lt;/pre&gt;
  &lt;p id=&quot;qHIO&quot;&gt;где &lt;code&gt;К&lt;/code&gt; — направление: 1 означает чтение, 0 — запись.&lt;/p&gt;
  &lt;h3 id=&quot;последовательность-чтения-регистра&quot;&gt;Последовательность чтения регистра&lt;/h3&gt;
  &lt;pre id=&quot;sxfh&quot;&gt;START
0xB9                → подтверждение
младший байт адреса → подтверждение
старший байт адреса → подтверждение
младший байт данных ← выдаём подтверждение (0)
старший байт данных ← выдаём отказ (1)
STOP&lt;/pre&gt;
  &lt;p id=&quot;Vdx5&quot;&gt;Запись отличается тем, что после старшего байта адреса передаются младший&lt;br /&gt;и старший байты данных, каждый с подтверждением.&lt;/p&gt;
  &lt;p id=&quot;gmak&quot;&gt;Порядок байт: &lt;strong&gt;младший вперёд&lt;/strong&gt; и для адреса, и для данных.&lt;/p&gt;
  &lt;h3 id=&quot;условия-начала-и-конца&quot;&gt;Условия начала и конца&lt;/h3&gt;
  &lt;p id=&quot;v2Kb&quot;&gt;Начало посылки отличается от I²C тем, что спад линии данных приходится&lt;br /&gt;на &lt;strong&gt;второй&lt;/strong&gt; такт, а не на первый:&lt;/p&gt;
  &lt;pre id=&quot;G39G&quot;&gt;SCK: __/‾‾\__/‾‾‾‾‾‾\__
SDA: ‾‾‾‾‾‾‾‾‾‾‾‾\_____/‾‾
         такт 1    такт 2&lt;/pre&gt;
  &lt;p id=&quot;z9Yr&quot;&gt;Конец посылки содержит несколько добавочных тактов - коммутатору нужно&lt;br /&gt;время завершить внутреннюю операцию.&lt;/p&gt;
  &lt;h3 id=&quot;самое-важное-способ-управления-линиями&quot;&gt;Самое важное: способ управления линиями&lt;/h3&gt;
  &lt;p id=&quot;uC8J&quot;&gt;&lt;strong&gt;Линии необходимо вести активно в оба уровня.&lt;/strong&gt; На открытом стоке, когда&lt;br /&gt;единицу отдаёт подтягивающий резистор, коммутатор &lt;strong&gt;не отвечает вовсе&lt;/strong&gt; -&lt;br /&gt;ни на одной скорости, ни при каком назначении выводов.&lt;/p&gt;
  &lt;h3 id=&quot;тайминги&quot;&gt;Тайминги&lt;/h3&gt;
  &lt;p id=&quot;e1wr&quot;&gt;Задержка между сменами уровней у Realtek - 1 микросекунда. У нас по&lt;br /&gt;умолчанию 2 мкс, и обмен устойчиво работает в диапазоне 1…10 мкс. Скорость&lt;br /&gt;на работоспособность не влияла: перебор от нулевой задержки до 100 мкс при&lt;br /&gt;открытом стоке не дал ни одного ответа.&lt;/p&gt;
  &lt;h2 id=&quot;5-открытие-доступа-к-регистрам&quot;&gt;5. Открытие доступа к регистрам&lt;/h2&gt;
  &lt;p id=&quot;0NNG&quot;&gt;Регистр номера чипа &lt;code&gt;0x1300&lt;/code&gt; упорно читался нулями, хотя соседние регистры&lt;br /&gt;отдавали осмысленные значения. Разгадка нашлась в исходниках изготовителя:&lt;br /&gt;при запуске он записывает особое значение в отдельный регистр.&lt;/p&gt;
  &lt;pre id=&quot;Nv2T&quot;&gt;записать 0x0249 в регистр 0x13C2&lt;/pre&gt;
  &lt;p id=&quot;I2tT&quot;&gt;Проверка на железе и тут!&lt;/p&gt;
  &lt;p id=&quot;ZHm7&quot;&gt;&lt;code&gt;0x6367&lt;/code&gt; - это и есть опознавательный номер RTL8367. Заодно опыт доказал,&lt;br /&gt;что &lt;strong&gt;запись в регистры работает&lt;/strong&gt;: записанное значение изменило поведение&lt;br /&gt;микросхемы.&lt;/p&gt;
  &lt;p id=&quot;xR3x&quot;&gt;Прошивка делает это сама при запуске, выждав перед этим три секунды —&lt;br /&gt;столько коммутатору нужно на собственную инициализацию после включения. Поймал при ребуте коммутатора по питанию.&lt;/p&gt;
  &lt;h2 id=&quot;6-карта-регистров&quot;&gt;6. Карта регистров&lt;/h2&gt;
  &lt;p id=&quot;G28i&quot;&gt;Официальный заголовок Realtek &lt;code&gt;rtl8367c_reg.h&lt;/code&gt; содержит около двадцати трёх&lt;br /&gt;тысяч строк определений. Переписывать это руками бессмысленно, поэтому&lt;br /&gt;карта построил разбором заголовка.&lt;/p&gt;
  &lt;p id=&quot;AhUW&quot;&gt;Привязка полей к регистрам делается по самому длинному совпадающему&lt;br /&gt;префиксу имени — иначе поля похоже названных регистров достаются не тем&lt;br /&gt;владельцам.&lt;/p&gt;
  &lt;h2 id=&quot;7-состояние-портов&quot;&gt;7. Состояние портов&lt;/h2&gt;
  &lt;p id=&quot;XwNx&quot;&gt;Один регистр на порт, начиная с &lt;code&gt;0x1352&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;KId1&quot;&gt;адрес = 0x1352 + номер порта&lt;/pre&gt;
  &lt;p id=&quot;98dx&quot;&gt;Расшифровка проверена вживую. При подключении кабеля регистр изменился&lt;br /&gt;так:&lt;/p&gt;
  &lt;pre id=&quot;1ENq&quot;&gt;было  0x00e0 = 0000 0000 1110 0000
стало 0x00f5 = 0000 0000 1111 0101
                          ↑  ↑ ↑ ↑
                          │  │ │ └─ бит 0: скорость 100 Мбит/с
                          │  │ └─── бит 2: полный дуплекс
                          │  └───── бит 4: появилась связь
                          └──────── биты 5-7 не изменились
&lt;/pre&gt;
  &lt;p id=&quot;xGPD&quot;&gt;Поднялись ровно три ожидаемых разряда, остальное осталось на месте.&lt;/p&gt;
  &lt;p id=&quot;CBbZ&quot;&gt;Соответствие разъёмов портам: физический разъём &lt;strong&gt;1&lt;/strong&gt; — это порт &lt;strong&gt;0&lt;/strong&gt;&lt;br /&gt;внутри микросхемы.&lt;/p&gt;
  &lt;h2 id=&quot;8-счётчики&quot;&gt;8. Счётчики&lt;/h2&gt;
  &lt;p id=&quot;OSY9&quot;&gt;Коммутатор ведёт 59 счётчиков на каждый порт. Они лежат не в обычных&lt;br /&gt;регистрах: нужно задать номер счётчика и забрать значение из окна.&lt;/p&gt;
  &lt;p id=&quot;DHom&quot;&gt;&lt;code&gt;0x1004 -&lt;/code&gt;номер нужного счётчика&lt;/p&gt;
  &lt;p id=&quot;FDxx&quot;&gt;&lt;code&gt;0x1005 -&lt;/code&gt;состояние, разряд 0 - занятость, разряд 1 - идёт сброс&lt;/p&gt;
  &lt;p id=&quot;uGkf&quot;&gt;&lt;code&gt;0x1000&lt;/code&gt;…&lt;code&gt;0x1003 -&lt;/code&gt;окно из четырёх регистров со значением&lt;/p&gt;
  &lt;h3 id=&quot;вычисление-номера&quot;&gt;Вычисление номера&lt;/h3&gt;
  &lt;pre id=&quot;aBEJ&quot;&gt;смещение = 0x7C × номер_порта
если номер_порта &amp;gt; 7: смещение += 68
для каждого предыдущего счётчика: смещение += его_длина
&lt;/pre&gt;
  &lt;p id=&quot;xaDz&quot;&gt;Длина счётчика — 4 регистра (64 разряда) для объёмов в байтах и&lt;br /&gt;2 регистра (32 разряда) для остальных. Шаг между наборами разных портов —&lt;br /&gt;&lt;code&gt;0x7C&lt;/code&gt;, то есть 124 регистра.&lt;/p&gt;
  &lt;h3 id=&quot;порядок-обращения&quot;&gt;Порядок обращения&lt;/h3&gt;
  &lt;ol id=&quot;9PSA&quot;&gt;
    &lt;li id=&quot;cMNX&quot;&gt;Прочитать &lt;code&gt;0x1004&lt;/code&gt;. Если там уже лежит нужный номер, записать другой —&lt;br /&gt;иначе коммутатор не станет обновлять окно.&lt;/li&gt;
    &lt;li id=&quot;TjIZ&quot;&gt;Записать &lt;code&gt;смещение &amp;gt;&amp;gt; 2&lt;/code&gt; в &lt;code&gt;0x1004&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;pMyW&quot;&gt;Дождаться сброса разряда занятости в &lt;code&gt;0x1005&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;j2fZ&quot;&gt;Прочитать окно. Для счётчика длиной 4 регистра чтение начинается&lt;br /&gt;с &lt;code&gt;0x1003&lt;/code&gt;, для длиной 2 — с &lt;code&gt;0x1000 + ((смещение + 1) mod 4)&lt;/code&gt;.&lt;br /&gt;Дальше адрес &lt;strong&gt;убывает&lt;/strong&gt;, а значение собирается сдвигом влево на 16.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;MOJg&quot;&gt;Отдельно стоит счётчик отброшенных изученных записей: он не привязан&lt;br /&gt;к порту и лежит по фиксированному смещению &lt;code&gt;0x420&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;9-виртуальные-сети&quot;&gt;9. Виртуальные сети&lt;/h2&gt;
  &lt;p id=&quot;1jb4&quot;&gt;Два уровня описания.&lt;/p&gt;
  &lt;h3 id=&quot;записи-членства-32-штуки-по-4-регистра&quot;&gt;Записи членства: 32 штуки по 4 регистра&lt;/h3&gt;
  &lt;pre id=&quot;OHLv&quot;&gt;адрес = 0x0728 + номер_записи × 4&lt;/pre&gt;
  &lt;p id=&quot;wrsL&quot;&gt;Раскладка по словам:&lt;/p&gt;
  &lt;p id=&quot;cRb1&quot;&gt;0 - маска портов-членов, 11 разрядов&lt;/p&gt;
  &lt;p id=&quot;x1ph&quot;&gt;1 - группа фильтрации, 4 разряда&lt;/p&gt;
  &lt;p id=&quot;Nj97&quot;&gt;2 - разряд 0 - приоритет включён, 1–3 - приоритет, 4 - учёт включён, 5–10 - номер счётчика&lt;/p&gt;
  &lt;p id=&quot;v8gk&quot;&gt;3 - номер сети, 13 разрядов&lt;/p&gt;
  &lt;h3 id=&quot;привязка-порта-к-записи&quot;&gt;Привязка порта к записи&lt;/h3&gt;
  &lt;pre id=&quot;oBqA&quot;&gt;адрес = 0x0700 + номер_порта / 2&lt;/pre&gt;
  &lt;p id=&quot;54Sx&quot;&gt;По два порта на регистр: порт с чётным номером в младшей половине, со&lt;br /&gt;следующим - в старшей. В каждой половине разряды 0–4 содержат номер&lt;br /&gt;записи членства, разряды 5–7 - приоритет.&lt;/p&gt;
  &lt;p id=&quot;HOlI&quot;&gt;Обратите внимание: порт ссылается &lt;strong&gt;не на номер сети напрямую&lt;/strong&gt;, а на&lt;br /&gt;номер записи членства.&lt;/p&gt;
  &lt;h3 id=&quot;таблица-на-4096-сетей-3-слова-на-запись&quot;&gt;Таблица на 4096 сетей: 3 слова на запись&lt;/h3&gt;
  &lt;p id=&quot;1BgD&quot;&gt;0 - разряды 0–7 - маска членов, 8–15 - маска портов без метки&lt;/p&gt;
  &lt;p id=&quot;IZyV&quot;&gt;1 - 0-3 группа фильтрации, 4 приоритет включён, 5–7 приоритет, 8 учёт включён, 9–13 номер счётчика, 14 раздельное изучение адресов&lt;/p&gt;
  &lt;p id=&quot;bvGy&quot;&gt;2 - 0-2 старшие разряды маски членов, 3–5 старшие разряды маски без метки, 6 старший разряд номера счётчика&lt;/p&gt;
  &lt;p id=&quot;9UVY&quot;&gt;Маски портов разрезаны между словами 0 и 2, потому что портов&lt;br /&gt;одиннадцать, а в байт помещается восемь.&lt;/p&gt;
  &lt;h2 id=&quot;10-доступ-к-внутренним-таблицам&quot;&gt;10. Доступ к внутренним таблицам&lt;/h2&gt;
  &lt;p id=&quot;8x1F&quot;&gt;Таблицы сетей, изученных адресов и правил разбора доступны через общее&lt;br /&gt;окно:&lt;/p&gt;
  &lt;p id=&quot;rJpy&quot;&gt;&lt;code&gt;0x0500 - &lt;/code&gt;вид таблицы и направление обращения&lt;/p&gt;
  &lt;p id=&quot;sggv&quot;&gt;&lt;code&gt;0x0501 - &lt;/code&gt;номер записи&lt;/p&gt;
  &lt;p id=&quot;dEzB&quot;&gt;&lt;code&gt;0x0510&lt;/code&gt;…&lt;code&gt;0x0519 - &lt;/code&gt;окно записи&lt;/p&gt;
  &lt;p id=&quot;3RNW&quot;&gt;&lt;code&gt;0x0520&lt;/code&gt;…&lt;code&gt;0x0529 - &lt;/code&gt;окно чтения&lt;/p&gt;
  &lt;p id=&quot;qJGJ&quot;&gt;Слово управления собирается так:&lt;/p&gt;
  &lt;pre id=&quot;Du3J&quot;&gt;команда = (направление &amp;lt;&amp;lt; 3) | вид_таблицы&lt;/pre&gt;
  &lt;p id=&quot;fzeH&quot;&gt;Правила разбора - 1&lt;/p&gt;
  &lt;p id=&quot;XfOR&quot;&gt;Действия разбора - 2&lt;/p&gt;
  &lt;p id=&quot;h1Kh&quot;&gt;Сети - 3&lt;/p&gt;
  &lt;p id=&quot;UclR&quot;&gt;Изученные адреса - 4&lt;/p&gt;
  &lt;p id=&quot;wdpP&quot;&gt;Группы рассылки  - 5&lt;/p&gt;
  &lt;p id=&quot;z10B&quot;&gt;Направление: 0 — чтение, 1 — запись.&lt;/p&gt;
  &lt;h2 id=&quot;11-прочие-подсистемы&quot;&gt;11. Прочие подсистемы&lt;/h2&gt;
  &lt;h3 id=&quot;зеркалирование-трафика&quot;&gt;Зеркалирование трафика&lt;/h3&gt;
  &lt;p id=&quot;8A8p&quot;&gt;Регистр &lt;code&gt;0x121C&lt;/code&gt;:&lt;/p&gt;
  &lt;p id=&quot;QYBD&quot;&gt;0–3 - порт-источник&lt;/p&gt;
  &lt;p id=&quot;RkY0&quot;&gt;4–7 - порт-приёмник копии&lt;/p&gt;
  &lt;p id=&quot;b3ii&quot;&gt;9 - копировать принятое&lt;/p&gt;
  &lt;p id=&quot;VuNp&quot;&gt;10 - копировать переданное&lt;/p&gt;
  &lt;p id=&quot;BkRd&quot;&gt;Дополнительно &lt;code&gt;0x12FB&lt;/code&gt; содержит маску портов-источников (11 разрядов).&lt;/p&gt;
  &lt;h3 id=&quot;изоляция-портов&quot;&gt;Изоляция портов&lt;/h3&gt;
  &lt;pre id=&quot;aP3G&quot;&gt;адрес = 0x08A2 + номер_порта&lt;/pre&gt;
  &lt;p id=&quot;rTTr&quot;&gt;Одиннадцатиразрядная маска: каким портам этот порт вправе пересылать&lt;br /&gt;кадры. Позволяет развести абонентов, не прибегая к виртуальным сетям.&lt;/p&gt;
  &lt;h3 id=&quot;ограничение-скорости&quot;&gt;Ограничение скорости&lt;/h3&gt;
  &lt;p id=&quot;drJY&quot;&gt;Приём -&lt;code&gt;0x000F + номер_порта × 2&lt;/code&gt;, два регистра&lt;/p&gt;
  &lt;p id=&quot;uELI&quot;&gt;Передача -&lt;code&gt;PORT&amp;lt;n&amp;gt;_EGRESSBW_CTRL0/1&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;banD&quot;&gt;Первый регистр хранит младшие 16 разрядов, второй — разряды 16–18. Счёт&lt;br /&gt;идёт в единицах по &lt;strong&gt;8 килобит в секунду&lt;/strong&gt;, поэтому заданное значение&lt;br /&gt;округляется вниз до кратного.&lt;/p&gt;
  &lt;h2 id=&quot;12-что-лежало-в-памяти-на-плате&quot;&gt;12. Что лежало в памяти на плате&lt;/h2&gt;
  &lt;p id=&quot;gwlP&quot;&gt;Содержимое микросхемы вычитано целиком — 4096 байт. Ожидалась таблица&lt;br /&gt;вида «адрес регистра — значение», которую коммутатор загружает при&lt;br /&gt;включении. Оказалось иное.&lt;/p&gt;
  &lt;p id=&quot;b3TV&quot;&gt;Начало образа:&lt;/p&gt;
  &lt;pre id=&quot;TaJr&quot;&gt;0000: b7 0d 02 0a 71 e4 f5 a8 d2 af 22 00 00 02 0c d3&lt;/pre&gt;
  &lt;p id=&quot;4xw0&quot;&gt;0x00 - &lt;code&gt;b7 0d - &lt;/code&gt;заголовок: &lt;code&gt;0x0DB7&lt;/code&gt; = 3511, длина&lt;/p&gt;
  &lt;p id=&quot;PU18&quot;&gt;0x02 -&lt;code&gt;02 0a 71 - LJMP 0x0A71&lt;/code&gt; — вектор сброса&lt;/p&gt;
  &lt;p id=&quot;0fvp&quot;&gt;0x05 - &lt;code&gt;e4 f5 a8 d2 af 22 - CLR A&lt;/code&gt; / &lt;code&gt;MOV IE,A&lt;/code&gt; / &lt;code&gt;SETB EA&lt;/code&gt; / &lt;code&gt;RET&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;LrZq&quot;&gt;0x0D - &lt;code&gt;02 0c d3 - LJMP 0x0CD3&lt;/code&gt; - вектор прерывания таймера&lt;/p&gt;
  &lt;p id=&quot;VeQs&quot;&gt;Это &lt;strong&gt;исполняемый код архитектуры 8051&lt;/strong&gt;. Если считать, что адресу&lt;br /&gt;&lt;code&gt;0x0000&lt;/code&gt; соответствует смещение 2, таблица векторов прерываний сходится&lt;br /&gt;идеально.&lt;/p&gt;
  &lt;p id=&quot;91ag&quot;&gt;Характерные команды по всему объёму: &lt;code&gt;e4&lt;/code&gt; (&lt;code&gt;CLR A&lt;/code&gt;), &lt;code&gt;90 xx xx&lt;/code&gt;&lt;br /&gt;(&lt;code&gt;MOV DPTR&lt;/code&gt;), &lt;code&gt;12 xx xx&lt;/code&gt; (&lt;code&gt;LCALL&lt;/code&gt;), &lt;code&gt;02&lt;/code&gt; (&lt;code&gt;LJMP&lt;/code&gt;), &lt;code&gt;22&lt;/code&gt; (&lt;code&gt;RET&lt;/code&gt;),&lt;br /&gt;&lt;code&gt;7f&lt;/code&gt;/&lt;code&gt;7e&lt;/code&gt;/&lt;code&gt;7d&lt;/code&gt; (загрузка регистров).&lt;/p&gt;
  &lt;p id=&quot;AFR0&quot;&gt;В конце образа: по смещению &lt;code&gt;0x0FE0&lt;/code&gt; — байты &lt;code&gt;d1 a1 cd a4 ca a1&lt;/code&gt;, которые&lt;br /&gt;в кодировке GB2312 складываются в иероглифы; по смещению &lt;code&gt;0x0FF6&lt;/code&gt; —&lt;br /&gt;&lt;code&gt;20 16 10 25&lt;/code&gt;, очень похоже на дату 25 октября 2016 года.&lt;/p&gt;
  &lt;h3 id=&quot;проверка-догадки&quot;&gt;Проверка догадки&lt;/h3&gt;
  &lt;p id=&quot;bpFr&quot;&gt;В открытой библиотеке для этого семейства нашёлся готовый образ памяти,&lt;br /&gt;причём именно для FT24C32A в корпусе SOIC8 — той же микросхемы:&lt;/p&gt;
  &lt;pre id=&quot;eLbH&quot;&gt;наш образ:  b7 0d 02 0a 71 e4 f5 a8 d2 af 22 00 00 02 0c d3
эталонный:  fc 09 02 07 37 e4 f5 a8 d2 af 22 00 00 02 09 44
            └──┬──┘ └───┬──┘ └────────┬───────┘ └─┬─┘ └──┬──┘
            заголовок  LJMP      одинаковый код  нули  LJMP
&lt;/pre&gt;
  &lt;p id=&quot;Ejt0&quot;&gt;Совпадает структура: заголовок с длиной, переход на начало программы,&lt;br /&gt;&lt;strong&gt;побайтово одинаковый&lt;/strong&gt; стартовый код, нули, вектор прерывания.&lt;br /&gt;Содержимое разное (другая версия прошивки, у эталона длина &lt;code&gt;0x09FC&lt;/code&gt; =&lt;br /&gt;2556), но формат тот же.&lt;/p&gt;
  &lt;p id=&quot;Nu2E&quot;&gt;&lt;strong&gt;ядро 8051 встроено в сам RTL8367S&lt;/strong&gt;, и в памяти лежит его&lt;br /&gt;прошивка. Коммутатор при включении сам вычитывает её по тем же линиям,&lt;br /&gt;выступая на шине ведущим.&lt;/p&gt;
  &lt;h2 id=&quot;13-архитектура-решения&quot;&gt;13. Архитектура решения&lt;/h2&gt;
  &lt;h3 id=&quot;почему-логика-на-компьютере&quot;&gt;Почему логика на компьютере&lt;/h3&gt;
  &lt;p id=&quot;zYGO&quot;&gt;Карта регистров содержит 4079 позиций. Реализовывать их обслуживание в&lt;br /&gt;прошивке значило бы перепрошивать плату ради каждой новой возможности.&lt;br /&gt;Поэтому разделение такое:&lt;/p&gt;
  &lt;p id=&quot;kzpN&quot;&gt;Прошивка на Zephyr v4.4.2 на STM32 - прозрачный мост к регистрам&lt;/p&gt;
  &lt;p id=&quot;LPj2&quot;&gt;Программа на Python - карта регистров, подсистемы, веб-интерфейс&lt;/p&gt;
  &lt;h3 id=&quot;машинный-протокол&quot;&gt;Машинный протокол&lt;/h3&gt;
  &lt;p id=&quot;DQNX&quot;&gt;У оболочки на плате два набора команд. Один для кожаных - с подписями и&lt;br /&gt;пояснениями. Второй для программы - со строгим ответом:&lt;/p&gt;
  &lt;p id=&quot;qA0o&quot;&gt;&lt;code&gt;m r &amp;lt;адрес&amp;gt; [кол-во] - &lt;/code&gt;прочитать подряд идущие регистры&lt;/p&gt;
  &lt;p id=&quot;ovUB&quot;&gt;&lt;code&gt;m w &amp;lt;адрес&amp;gt; &amp;lt;знач&amp;gt;… - &lt;/code&gt;записать подряд идущие регистры&lt;/p&gt;
  &lt;p id=&quot;0hji&quot;&gt;&lt;code&gt;m m &amp;lt;адрес&amp;gt; &amp;lt;маска&amp;gt; &amp;lt;знач&amp;gt; - &lt;/code&gt;изменить только отмеченные разряды&lt;/p&gt;
  &lt;p id=&quot;Qju6&quot;&gt;&lt;code&gt;m i - &lt;/code&gt;номер чипа, версия, режим&lt;/p&gt;
  &lt;p id=&quot;9uGF&quot;&gt;&lt;code&gt;m u - &lt;/code&gt;открыть доступ к регистрам&lt;/p&gt;
  &lt;p id=&quot;9U4Q&quot;&gt;&lt;code&gt;m s [мкс] - &lt;/code&gt;показать или задать полутакт шины&lt;/p&gt;
  &lt;p id=&quot;xAOc&quot;&gt;Ответ всегда одной строкой: &lt;code&gt;+ &amp;lt;значения&amp;gt;&lt;/code&gt; при успехе, &lt;code&gt;- &amp;lt;код&amp;gt;&lt;/code&gt; при&lt;br /&gt;отказе, все числа шестнадцатеричные. Пример:&lt;/p&gt;
  &lt;pre id=&quot;oE1r&quot;&gt;m r 1352 8
+ 00e0 00e0 00e0 00f5 0086 0000 0000 0000&lt;/pre&gt;
  &lt;p id=&quot;emck&quot;&gt;Команда изменения разрядов существует отдельно неспроста: читать и писать&lt;br /&gt;по очереди небезопасно, потому что между двумя обращениями регистр может&lt;br /&gt;изменить сам коммутатор. Прошивка делает это неделимо.&lt;/p&gt;
  &lt;h3 id=&quot;связь-с-платой&quot;&gt;Связь с платой&lt;/h3&gt;
  &lt;p id=&quot;zV0X&quot;&gt;Плата отдаётся системе как виртуальный последовательный порт с&lt;br /&gt;опознавательными признаками &lt;code&gt;2FE3:0001&lt;/code&gt; и названием &lt;code&gt;RTL8367S Manager&lt;/code&gt;.&lt;br /&gt;Программа ищет её по этим признакам, поэтому смена имени устройства&lt;br /&gt;(&lt;code&gt;/dev/ttyACM0&lt;/code&gt; против &lt;code&gt;/dev/ttyACM1&lt;/code&gt;) ни на что не влияет — а меняется&lt;br /&gt;оно охотно, поскольку рядом подключён отладчик.&lt;/p&gt;
  &lt;h2 id=&quot;источники&quot;&gt;Источники&lt;/h2&gt;
  &lt;ul id=&quot;UBEu&quot;&gt;
    &lt;li id=&quot;0HF6&quot;&gt;&lt;a href=&quot;https://www.unikeyic.com/media/datasheet/ee/09/56ff/ee/d621a0c96c0b0157c1ae4aae7c9cf12e.pdf&quot; target=&quot;_blank&quot;&gt;RTL8367S-CG, техническое описание&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Rd2w&quot;&gt;&lt;a href=&quot;https://github.com/shiroichiheisen/Realtek-Unmanaged-Switch-Arduino-Library&quot; target=&quot;_blank&quot;&gt;Realtek Unmanaged Switch Arduino Library&lt;/a&gt; — эталонная реализация обмена, карта регистров, образ памяти&lt;/li&gt;
    &lt;li id=&quot;gy9z&quot;&gt;&lt;a href=&quot;https://github.com/libc0607/Realtek_switch_hacking&quot; target=&quot;_blank&quot;&gt;Realtek_switch_hacking&lt;/a&gt; — первоисточник файлов изготовителя&lt;/li&gt;
    &lt;li id=&quot;sIHc&quot;&gt;&lt;a href=&quot;https://lwn.net/Articles/883059/&quot; target=&quot;_blank&quot;&gt;Драйверы realtek в ядре Linux&lt;/a&gt; — два независимых интерфейса управления&lt;/li&gt;
    &lt;li id=&quot;eMeL&quot;&gt;&lt;a href=&quot;https://www.kernel.org/doc/Documentation/devicetree/bindings/net/dsa/realtek-smi.txt&quot; target=&quot;_blank&quot;&gt;Описание привязки realtek-smi в Linux&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>pole_sam:ejN-g2kqhSy</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/ejN-g2kqhSy?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Трафик без data bearer: как передавать данные, если есть только служебный канал</title><published>2026-09-12T20:08:24.207Z</published><updated>2026-09-12T20:10:08.834Z</updated><summary type="html">Иногда бывает так: модем подключён, сеть есть, но привычного IP-интерфейса (ppp0, wwan0) — нет. Либо оператор заблокировал data bearer, либо устройство работает в режиме «только сигнализация». При этом диагностический порт (Qualcomm DIAG, Gobinet, QXDM) доступен, и через него идёт служебный трафик: NAS, RRC, SIB, paging.</summary><content type="html">
  &lt;p id=&quot;kdmc&quot;&gt;Иногда бывает так: модем подключён, сеть есть, но привычного IP-интерфейса (ppp0, wwan0) — нет. Либо оператор заблокировал data bearer, либо устройство работает в режиме «только сигнализация». При этом диагностический порт (Qualcomm DIAG, Gobinet, QXDM) доступен, и через него идёт служебный трафик: NAS, RRC, SIB, paging.&lt;/p&gt;
  &lt;p id=&quot;XMiJ&quot;&gt;В таких условиях можно организовать передачу пользовательских данных, используя служебный канал как транспорт. Ниже — рабочий подход, проверенный на Qualcomm MSM8916, USB-модемах и Android-устройствах с root.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;data-bearer&quot;&gt;Что доступно, если нет data bearer&lt;/h2&gt;
  &lt;p id=&quot;JOgZ&quot;&gt;Обычный сценарий работы модема:&lt;/p&gt;
  &lt;pre id=&quot;v2bg&quot;&gt;UE &amp;lt;--RRC/NAS--&amp;gt; eNB &amp;lt;--S1-AP--&amp;gt; MME
 |                              |
 +------IP (PPP/NCM/MBIM)------+&lt;/pre&gt;
  &lt;p id=&quot;zHLI&quot;&gt;При отсутствии data bearer IP-канал не поднимается. Но диагностический порт остаётся активным:&lt;/p&gt;
  &lt;pre id=&quot;rP35&quot;&gt;UE &amp;lt;--DIAG (USB/ADB)--&amp;gt; Host (Linux/Android)
       ^
       | сырые L2/L3 фреймы: BCCH, CCCH, DCCH, DTCH&lt;/pre&gt;
  &lt;p id=&quot;XVWm&quot;&gt;Через DIAG можно:&lt;/p&gt;
  &lt;ul id=&quot;0Dwg&quot;&gt;
    &lt;li id=&quot;hzNq&quot;&gt;принимать и декодировать служебные сообщения (NAS, RRC, SIB);&lt;/li&gt;
    &lt;li id=&quot;DtVx&quot;&gt;в некоторых случаях — инкапсулировать пользовательские данные в DTCH-подобные фреймы;&lt;/li&gt;
    &lt;li id=&quot;Y7c8&quot;&gt;использовать туннелирование поверх существующих сигнальных процедур.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Hdqc&quot;&gt;Инструментарий&lt;/h2&gt;
  &lt;p id=&quot;QRFb&quot;&gt;Для работы понадобятся:&lt;/p&gt;
  &lt;ul id=&quot;XjOj&quot;&gt;
    &lt;li id=&quot;An7J&quot;&gt;&lt;strong&gt;QCSuper&lt;/strong&gt; — утилита для захвата и декодирования радиофреймов с Qualcomm-модемов.github+1&lt;/li&gt;
    &lt;li id=&quot;22lu&quot;&gt;&lt;strong&gt;Wireshark&lt;/strong&gt; — для анализа pcap-файлов.&lt;/li&gt;
    &lt;li id=&quot;syGe&quot;&gt;&lt;strong&gt;ADB&lt;/strong&gt; (если модем встроен в Android) или &lt;strong&gt;USB-модем с DIAG-портом&lt;/strong&gt; (например, разлоченный Quectel).&lt;/li&gt;
    &lt;li id=&quot;xSC6&quot;&gt;&lt;strong&gt;socat / netcat&lt;/strong&gt; — для организации туннелей.&lt;/li&gt;
    &lt;li id=&quot;FLOI&quot;&gt;&lt;strong&gt;AT-команды&lt;/strong&gt; для включения диагностического режима.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;dDwo&quot;&gt;Включение диагностического порта&lt;/h2&gt;
  &lt;h2 id=&quot;usb--quectel-thales&quot;&gt;Для USB-модема (Quectel, Thales и др.)&lt;/h2&gt;
  &lt;pre id=&quot;qaes&quot;&gt;# Найти порт модема
mmcli -L

# Включить DIAG (Qualcomm)
mmcli -m &amp;lt;modem-index&amp;gt; --command=&amp;quot;AT$QCDMG&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;GjoP&quot;&gt;После этого появится устройство &lt;code&gt;/dev/ttyUSBx&lt;/code&gt; (обычно ttyUSB0 или ttyUSB2) — это и есть DIAG-порт.&lt;/p&gt;
  &lt;h2 id=&quot;android&quot;&gt;Для Android-устройства&lt;/h2&gt;
  &lt;pre id=&quot;liIv&quot;&gt;# Включить отладку по USB
adb devices

# Проверить доступ
adb shell

# Включить DIAG (требует root)
adb shell &amp;quot;su -c &amp;#x27;setprop sys.usb.config diag,adb&amp;#x27;&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;elwd&quot;&gt;На некоторых устройствах требуется прописать правило udev:&lt;/p&gt;
  &lt;pre id=&quot;RvFl&quot;&gt;# Узнать VID:PID
lsusb

# Создать правило
sudo nano /etc/udev/rules.d/51-android.rules
# Добавить строку:
SUBSYSTEM==&amp;quot;usb&amp;quot;, ATTR{idVendor}==&amp;quot;&amp;lt;VID&amp;gt;&amp;quot;, ATTR{idProduct}==&amp;quot;&amp;lt;PID&amp;gt;&amp;quot;, MODE=&amp;quot;0666&amp;quot;, GROUP=&amp;quot;plugdev&amp;quot;

# Перезагрузить правила
sudo udevadm control --reload-rules&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;qcsuper&quot;&gt;Захват трафика через QCSuper&lt;/h2&gt;
  &lt;h2 id=&quot;8HIu&quot;&gt;Базовый запуск&lt;/h2&gt;
  &lt;pre id=&quot;2rsj&quot;&gt;# Для USB-модема
qcsuper --usb-modem /dev/ttyUSB0 --wireshark-live --decrypt-nas --reassemble-sibs --include-ip-traffic

# Для Android через ADB
qcsuper --adb --wireshark-live --decrypt-nas --reassemble-sibs&lt;/pre&gt;
  &lt;p id=&quot;vM3L&quot;&gt;По умолчанию QCSuper показывает только сигнальные фреймы. Опция &lt;code&gt;--include-ip-traffic&lt;/code&gt; добавляет пользовательский IP-трафик, если он есть.&lt;/p&gt;
  &lt;h2 id=&quot;wireshark&quot;&gt;Что видно в Wireshark&lt;/h2&gt;
  &lt;ul id=&quot;ZkpU&quot;&gt;
    &lt;li id=&quot;7VCI&quot;&gt;&lt;strong&gt;BCCH&lt;/strong&gt; — широковещательные SIB (информация о соте);&lt;/li&gt;
    &lt;li id=&quot;C400&quot;&gt;&lt;strong&gt;PCCH&lt;/strong&gt; — paging;&lt;/li&gt;
    &lt;li id=&quot;GtZY&quot;&gt;&lt;strong&gt;CCCH/DCCH&lt;/strong&gt; — сигнальные сообщения (attach, authentication, bearer setup);&lt;/li&gt;
    &lt;li id=&quot;zNiw&quot;&gt;&lt;strong&gt;DTCH&lt;/strong&gt; — зашифрованный пользовательский трафик (если data bearer активен).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;4H5V&quot;&gt;Если data bearer отсутствует, DTCH будет пустым или отсутствовать. Но это не значит, что передача данных невозможна.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;m0XP&quot;&gt;Организация туннеля поверх служебного трафика&lt;/h2&gt;
  &lt;h2 id=&quot;MgZd&quot;&gt;Идея&lt;/h2&gt;
  &lt;p id=&quot;vi7D&quot;&gt;Поскольку прямой IP-канал недоступен, можно:&lt;/p&gt;
  &lt;ol id=&quot;F9m0&quot;&gt;
    &lt;li id=&quot;3A8G&quot;&gt;Инкапсулировать пользовательские данные в сигнальные сообщения (например, в NAS или RRC);&lt;/li&gt;
    &lt;li id=&quot;NChk&quot;&gt;Использовать существующий DTCH как транспорт, даже если он не поднимает PPP;&lt;/li&gt;
    &lt;li id=&quot;lU9v&quot;&gt;Организовать туннель между двумя устройствами, где одно выступает как «модем», а другое — как шлюз.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;socat&quot;&gt;Пример: туннель через socat&lt;/h2&gt;
  &lt;p id=&quot;Zxbg&quot;&gt;Предположим, у вас есть:&lt;/p&gt;
  &lt;ul id=&quot;gIPc&quot;&gt;
    &lt;li id=&quot;0CO4&quot;&gt;&lt;strong&gt;Устройство A&lt;/strong&gt; — модем с DIAG-портом (например, Raspberry Pi с USB-модемом);&lt;/li&gt;
    &lt;li id=&quot;byLr&quot;&gt;&lt;strong&gt;Устройство B&lt;/strong&gt; — шлюз с доступом в интернет.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;q9Gr&quot;&gt;На &lt;strong&gt;устройстве A&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;adKg&quot;&gt;# Открыть порт для ретрансляции DIAG-трафика
socat TCP-LISTEN:12345,reuseaddr,fork /dev/ttyUSB0,raw,echo=0&lt;/pre&gt;
  &lt;p id=&quot;kGFk&quot;&gt;На &lt;strong&gt;устройстве B&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;MgXo&quot;&gt;# Создать виртуальный COM-порт, подключённый к устройству A
socat PTY,link=/dev/virtualTTY0,raw,echo=0 TCP:&amp;lt;IP-устройства-A&amp;gt;:12345

# Запустить QCSuper с туннелированием
qcsuper --usb-modem /dev/virtualTTY0 --wireshark-live --include-ip-traffic&lt;/pre&gt;
  &lt;p id=&quot;yp0c&quot;&gt;Теперь можно захватывать трафик удалённо, а при необходимости — модифицировать его на лету (например, внедрять пользовательские данные в DTCH).&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;icmp-dns-http&quot;&gt;Обход блокировок: ICMP, DNS, HTTP-туннели&lt;/h2&gt;
  &lt;p id=&quot;Y121&quot;&gt;Если оператор блокирует обычный data bearer, но пропускает ICMP или DNS, можно использовать их как транспорт:&lt;/p&gt;
  &lt;h2 id=&quot;icmp--ping&quot;&gt;ICMP-туннель (ping)&lt;/h2&gt;
  &lt;pre id=&quot;y00N&quot;&gt;import socket, struct

def create_packet(id, data):
    ICMP_ECHO_REQUEST = 8
    header = struct.pack(&amp;#x27;bbHHh&amp;#x27;, ICMP_ECHO_REQUEST, 0, 0, id, 1)
    data = data + b&amp;quot;\x00&amp;quot; * ((len(data) % 2))
    # checksum calculation omitted for brevity
    return header + data

sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
packet = create_packet(1, b&amp;quot;Hello, world!&amp;quot;)
sock.sendto(packet, (&amp;quot;8.8.8.8&amp;quot;, 0))&lt;/pre&gt;
  &lt;p id=&quot;2yrf&quot;&gt;Такой подход позволяет передавать данные внутри ICMP Echo Request, обходя блокировки на уровне L3.&lt;/p&gt;
  &lt;h2 id=&quot;dns&quot;&gt;DNS-туннель&lt;/h2&gt;
  &lt;p id=&quot;psV2&quot;&gt;DNS-запросы обычно не блокируются. Можно кодировать данные в поддоменах:&lt;/p&gt;
  &lt;pre id=&quot;HrvM&quot;&gt;# Пример отправки данных через DNS
dig data12345.tunnel.example.com&lt;/pre&gt;
  &lt;p id=&quot;4kOr&quot;&gt;На стороне сервера — парсить запросы и извлекать данные.&lt;/p&gt;
  &lt;h2 id=&quot;httphttps&quot;&gt;HTTP/HTTPS-туннель&lt;/h2&gt;
  &lt;p id=&quot;j8pd&quot;&gt;Если доступен HTTP/HTTPS (даже без полноценного data bearer), можно использовать:&lt;/p&gt;
  &lt;pre id=&quot;JN3F&quot;&gt;# Через curl
curl -X POST -d @data.bin https://tunnel.example.com/upload

# Через socat
socat TCP-LISTEN:8080,reuseaddr,fork EXEC:&amp;#x27;curl -X POST -d @- https://tunnel.example.com&amp;#x27;&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;diag&quot;&gt;Практический пример: передача данных через DIAG&lt;/h2&gt;
  &lt;p id=&quot;AXJI&quot;&gt;Допустим, нужно передать файл с устройства на сервер, но PPP не поднимается.&lt;/p&gt;
  &lt;h2 id=&quot;1&quot;&gt;Шаг 1: Подготовка&lt;/h2&gt;
  &lt;ul id=&quot;kFg9&quot;&gt;
    &lt;li id=&quot;Yc0a&quot;&gt;Включить DIAG на модеме (AT$QCDMG);&lt;/li&gt;
    &lt;li id=&quot;354w&quot;&gt;Убедиться, что QCSuper видит фреймы;&lt;/li&gt;
    &lt;li id=&quot;7UCP&quot;&gt;На сервере — запустить socat для приёма данных.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;2&quot;&gt;Шаг 2: Кодирование данных&lt;/h2&gt;
  &lt;p id=&quot;lqwt&quot;&gt;Пользовательские данные можно внедрять в:&lt;/p&gt;
  &lt;ul id=&quot;RhZh&quot;&gt;
    &lt;li id=&quot;L2kd&quot;&gt;&lt;strong&gt;NAS-сообщения&lt;/strong&gt; (например, в поля, которые не проверяются сетью);&lt;/li&gt;
    &lt;li id=&quot;IChF&quot;&gt;&lt;strong&gt;RRC-сообщения&lt;/strong&gt; (если есть возможность модифицировать их на уровне модема);&lt;/li&gt;
    &lt;li id=&quot;PBMd&quot;&gt;&lt;strong&gt;DTCH&lt;/strong&gt; (если он активен, но не поднимает PPP).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;a7wJ&quot;&gt;&lt;strong&gt;Ссылки:&lt;/strong&gt;&lt;/h2&gt;
  &lt;ul id=&quot;KC4p&quot;&gt;
    &lt;li id=&quot;pWFH&quot;&gt;QCSuper: &lt;a href=&quot;https://github.com/P1sec/QCSuper&quot; target=&quot;_blank&quot;&gt;https://github.com/P1sec/QCSuper&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Rf3N&quot;&gt;Включение DIAG на модемах: &lt;a href=&quot;https://forum.digikey.com/t/cellular-layer3-tracing-possibility-for-qualcomm-based-modules-2g-3g-4g-lte-m-nb-iot/27228&quot; target=&quot;_blank&quot;&gt;https://forum.digikey.com/t/cellular-layer3-tracing-possibility-for-qualcomm-based-modules-2g-3g-4g-lte-m-nb-iot/27228&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;jiwi&quot;&gt;ICMP-туннели: &lt;a href=&quot;https://habr.com/ru/companies/ruvds/articles/763600/&quot; target=&quot;_blank&quot;&gt;https://habr.com/ru/companies/ruvds/articles/763600/&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;o0Nj&quot;&gt;Приём служебного GSM-трафика: &lt;a href=&quot;https://habr.com/ru/companies/timeweb/articles/947684/&quot; target=&quot;_blank&quot;&gt;https://habr.com/ru/companies/timeweb/articles/947684/&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>pole_sam:6P1lAhU6ATQ</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/6P1lAhU6ATQ?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Малоизвестные разработчики чипсетов LTE и GSM</title><published>2026-09-06T21:09:59.326Z</published><updated>2026-09-06T21:09:59.326Z</updated><summary type="html">Когда речь заходит о модемах LTE и GSM, на ум сразу приходят Qualcomm, MediaTek, Huawei и Samsung. Но за пределами этого «большого клуба» существовал и продолжает существовать целый пласт компаний, чьи чипы работали в миллионах устройств, но остались в тени. Многие из них были поглощены, закрыты или перепрофилированы, оставив после себя лишь упоминания в спецификациях и старых пресс-релизах.</summary><content type="html">
  &lt;p id=&quot;nojF&quot;&gt;Когда речь заходит о модемах LTE и GSM, на ум сразу приходят Qualcomm, MediaTek, Huawei и Samsung. Но за пределами этого «большого клуба» существовал и продолжает существовать целый пласт компаний, чьи чипы работали в миллионах устройств, но остались в тени. Многие из них были поглощены, закрыты или перепрофилированы, оставив после себя лишь упоминания в спецификациях и старых пресс-релизах.&lt;/p&gt;
  &lt;h2 id=&quot;single-mode-lte-altair--sequans&quot;&gt;Пионеры single-mode LTE: Altair и Sequans&lt;/h2&gt;
  &lt;p id=&quot;1oxz&quot;&gt;&lt;strong&gt;Altair Semiconductor&lt;/strong&gt; (Израиль) — одна из первых компаний, выпустивших коммерческий LTE-чипсет. Их FourGee-3100 (Cat. 3, 100 Мбит/с) появился на рынке ещё в 2009 году и стал первым сертифицированным Verizon решением для LTE-сетей. Позже вышли FourGee-3800 (Cat. 4, 150 Мбит/с) и FourGee-3802 (Cat. 6, 300 Мбит/с) с поддержкой LTE-Advanced. В 2014 году Altair была приобретена Sony и переименована в Sony Semiconductor Israel, но бренд Altair сохранился для IoT-линейки (ALT1160, ALT1250 — Cat-M1/NB-IoT).&lt;/p&gt;
  &lt;p id=&quot;40jn&quot;&gt;&lt;strong&gt;Sequans Communications&lt;/strong&gt; (Франция) — начинала с WiMAX, но к 2011 году полностью переключилась на LTE. Их первый LTE-чип Colibri вышел в 2010 году, а позже компания стала известна благодаря Calliope (Cat. 1 для IoT) и Monarch (первый в мире single-chip Cat-M1/NB-IoT). Sequans поставляла чипы для China Mobile, SK Telecom, Verizon и других операторов, но осталась в нише IoT-модулей, не попав в массовый смартфонный рынок.&lt;/p&gt;
  &lt;h2 id=&quot;2010--gct-leadcore-innofidei&quot;&gt;«Второй эшелон» 2010-х: GCT, Leadcore, Innofidei&lt;/h2&gt;
  &lt;p id=&quot;kCOZ&quot;&gt;&lt;strong&gt;GCT Semiconductor&lt;/strong&gt; (США/Корея) — разработчик single-mode LTE-чипов серии GDM724x, которые использовались в USB-донглах, CPE, M2M-устройствах и даже некоторых смартфонах. Их решения коммерчески доступны с 2010 года и до сих пор встречаются в IoT-модулях.&lt;/p&gt;
  &lt;p id=&quot;TP8K&quot;&gt;&lt;strong&gt;Leadcore Technology&lt;/strong&gt; (Китай) — дочерняя компания Datang Telecom, известная чипами LC1761, LC1860 и другими LTE-решениями для китайского рынка. Поддерживали TD-LTE и FDD, но остались в основном внутри экосистемы китайских OEM.&lt;/p&gt;
  &lt;p id=&quot;iE2r&quot;&gt;&lt;strong&gt;Innofidei&lt;/strong&gt; (Япония) — ещё один игрок, предлагавший single-mode LTE-чипсеты в начале 2010-х, но так и не вышедший на массовый рынок. Компания упоминается в отчётах ABI Research как один из пяти вендоров single-mode LTE, но широкой известности не получила.&lt;/p&gt;
  &lt;h2 id=&quot;icera-st-ericsson-renesas-mobile&quot;&gt;Поглощённые и исчезнувшие: Icera, ST-Ericsson, Renesas Mobile&lt;/h2&gt;
  &lt;p id=&quot;W8Nt&quot;&gt;&lt;strong&gt;Icera&lt;/strong&gt; (Великобритания) — основана в 2002 году, специализировалась на software-defined модемах с архитектурой на базе custom DSP. Их чипы ICE8040/ICE8060 поддерживали 2G/3G/4G и использовались в смартфонах и планшетах. В 2011 году NVIDIA приобрела Icera за $367 млн, но к 2015 году свернула baseband-бизнес, так и не сумев конкурировать с Qualcomm.&lt;/p&gt;
  &lt;p id=&quot;OPBs&quot;&gt;&lt;strong&gt;ST-Ericsson&lt;/strong&gt; (совместное предприятие STMicroelectronics и Ericsson) — выпускала multimode-модемы Thor M7400/M7450 и платформы NovaThor (L8540, L8580) с интеграцией LTE Cat. 4, HSPA+, GSM, TD-SCDMA. Несмотря на технологическую продвинутость (28 нм, FDSOI, carrier aggregation), компания не выдержала конкуренции и была ликвидирована в 2013 году.&lt;/p&gt;
  &lt;p id=&quot;HIoE&quot;&gt;&lt;strong&gt;Renesas Mobile&lt;/strong&gt; (Япония) — наследник wireless-бизнеса Nokia, приобретённого Renesas в 2010 году. Разрабатывала multimode LTE-чипы, но в 2013 году продала LTE-активы Broadcom за $164 млн, фактически выйдя из рынка.&lt;/p&gt;
  &lt;h2 id=&quot;beceem-wavesat-comsys&quot;&gt;Забытые имена: Beceem, Wavesat, Comsys&lt;/h2&gt;
  &lt;p id=&quot;NTfk&quot;&gt;&lt;strong&gt;Beceem Communications&lt;/strong&gt; (Израиль) — лидер рынка WiMAX-чипов, который к 2010 году выпустил первый multimode-чип BCS500 с поддержкой LTE и WiMAX. В том же году была приобретена Broadcom за $316 млн, но после сворачивания WiMAX-направления технологии Beceem так и не стали массовыми в LTE-сегменте.&lt;/p&gt;
  &lt;p id=&quot;EVbm&quot;&gt;&lt;strong&gt;Wavesat&lt;/strong&gt; (Израиль) — разработчик WiMAX-чипов Odyssey 9000, позднее поглощённый Cavium Networks в 2011 году.&lt;/p&gt;
  &lt;p id=&quot;Ylpf&quot;&gt;&lt;strong&gt;Comsys&lt;/strong&gt; (Израиль) — поставляла baseband-решения CM1125 для GSM/EDGE/WiMAX/LTE, но осталась в нише IP-лицензирования и не вышла на массовый рынок чипов.&lt;/p&gt;
  &lt;h2 id=&quot;spreadtrumunisoc-hisilicon-sanechips&quot;&gt;Китайские игроки: Spreadtrum/UNISOC, HiSilicon, Sanechips&lt;/h2&gt;
  &lt;p id=&quot;jmNU&quot;&gt;&lt;strong&gt;Spreadtrum&lt;/strong&gt; (позже UNISOC) — начинала с GSM/GPRS-чипов для ультрабюджетных телефонов, позже добавила LTE. Сегодня UNISOC — один из крупнейших вендоров LTE-платформ для IoT и бюджетных смартфонов.&lt;/p&gt;
  &lt;p id=&quot;ToPc&quot;&gt;&lt;strong&gt;HiSilicon&lt;/strong&gt; (дочерняя Huawei) — разрабатывала LTE-чипы Balong для устройств Huawei и Honor, а также для внешних OEM.&lt;/p&gt;
  &lt;p id=&quot;sGnK&quot;&gt;&lt;strong&gt;Sanechips&lt;/strong&gt; (бывшая ZTE Microelectronics) — поставляла LTE-решения для оборудования ZTE и партнёров.&lt;/p&gt;
  &lt;h2 id=&quot;oFWJ&quot;&gt;&lt;strong&gt;Почему они исчезли?&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;Pb5T&quot;&gt;Рынок baseband-модемов — один из самых безжалостных в полупроводниковой индустрии. За период с 2010 по 2015 год из него ушли десятки компаний: Texas Instruments, Freescale, NXP, Infineon, Renesas Mobile, ST-Ericsson, Broadcom, NVIDIA/Icera, и это только верхушка айсберга. Причины их ухода не случайны — они системны и повторяются из кейса в кейс. Разберем их:&lt;/p&gt;
  &lt;h2 id=&quot;1----rd&quot;&gt;1. Экстремальные затраты на R&amp;amp;D при низкой маржинальности&lt;/h2&gt;
  &lt;p id=&quot;OcmL&quot;&gt;Разработка multimode LTE-модема (GSM/UMTS/LTE, все мировые диапазоны, carrier aggregation, VoLTE) требует команды в 2000–3000 инженеров и ежегодных инвестиций в сотни миллионов долларов. При этом рынок быстро консолидировался: к 2014 году(время внедрения LTE) Qualcomm контролировала более 50% выручки, MediaTek и Intel делили ещё 30%, а всем остальным оставались крохи.&lt;/p&gt;
  &lt;p id=&quot;e4AS&quot;&gt;&lt;strong&gt;Broadcom&lt;/strong&gt; — хрестоматийный пример. Компания инвестировала около $3 млрд в baseband-бизнес (включая покупку Beceem за $316 млн и активов Renesas Mobile за $164 млн), но так и не смогла выйти на долю рынка выше 5%. В 2014 году Broadcom закрыла подразделение, уволив 2500 сотрудников.&lt;/p&gt;
  &lt;blockquote id=&quot;6S7L&quot;&gt;«Мы увидели ухудшающуюся экономику этого бизнеса: цены и маржи падали, а ряд игроков не заботились о прибыли и были готовы работать в убыток ради присутствия на рынке. Чтобы выжить, нужна была доля рынка в топ-2 или топ-3. Мы были номер четыре или пять — это нежизнеспособно».&lt;br /&gt;— Скотт Макгрегор, CEO Broadcom (2015)&lt;/blockquote&gt;
  &lt;p id=&quot;9eA3&quot;&gt;&lt;strong&gt;NVIDIA/Icera&lt;/strong&gt; — похожая история. После покупки Icera за $367 млн в 2011 году NVIDIA выпустила Tegra 4i с интегрированным модемом i500, но не смогла привлечь ни одного крупного OEM. К 2015 году компания свернула baseband-разработку, сославшись на доминирование Qualcomm и агрессивное ценообразование MediaTek.&lt;/p&gt;
  &lt;blockquote id=&quot;q1y0&quot;&gt;«Я пытался найти способы продолжить разработку модемов. После тщательного анализа стало ясно: это просто неосуществимо. Другие компании сталкиваются с теми же ограничениями».&lt;br /&gt;— Дженсен Хуанг, CEO NVIDIA (2015)&lt;/blockquote&gt;
  &lt;h2 id=&quot;2---12&quot;&gt;2. Зависимость от 1–2 крупных клиентов&lt;/h2&gt;
  &lt;p id=&quot;WtUC&quot;&gt;&lt;strong&gt;ST-Ericsson&lt;/strong&gt; — классический кейс «смерти от зависимости». Совместное предприятие STMicroelectronics и Ericsson, созданное в 2009 году, к 2012 году потеряло двух ключевых клиентов: Nokia и Sony Ericsson. Nokia, переходя на Windows Phone и затем на Android, сократила заказы, а Sony Ericsson и вовсе исчезла как бренд.&lt;/p&gt;
  &lt;p id=&quot;EKRR&quot;&gt;В 2012 году ST-Ericsson потеряла почти $1 млрд, а в 2013 году совместное предприятие было ликвидировано. Общие убытки с 2009 по 2013 год составили $2,7 млрд при выручке $7,82 млрд.&lt;/p&gt;
  &lt;blockquote id=&quot;wApF&quot;&gt;«Главная причина провала — чрезмерная зависимость от Nokia и Sony Ericsson. Оба производителя пострадали от перехода рынка на Apple и Samsung, и это ударило по ST-Ericsson».&lt;br /&gt;— аналитик Carnegie Bank (2013)&lt;/blockquote&gt;
  &lt;p id=&quot;3xbv&quot;&gt;Ericsson попыталась продолжить бизнес самостоятельно, но к 2014 году закрыла и это направление, сославшись на «снижение цен, рост затрат на R&amp;amp;D и сужение рынка».&lt;/p&gt;
  &lt;h2 id=&quot;3---qualcomm&quot;&gt;3. Патентная монополия Qualcomm&lt;/h2&gt;
  &lt;p id=&quot;Dy0S&quot;&gt;Qualcomm владела (и владеет) ключевыми патентами на CDMA, UMTS и LTE, что давало ей двойное преимущество:&lt;/p&gt;
  &lt;ul id=&quot;Wmgy&quot;&gt;
    &lt;li id=&quot;Pnq4&quot;&gt;&lt;strong&gt;Лицензионные отчисления&lt;/strong&gt; с каждого проданного устройства (3–5% от цены смартфона).&lt;/li&gt;
    &lt;li id=&quot;5XdU&quot;&gt;&lt;strong&gt;Перекрёстное лицензирование&lt;/strong&gt;: конкуренты вынуждены были покупать патенты у Qualcomm, чтобы легально выпускать свои чипы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Ep8t&quot;&gt;Это создавало «налоговый барьер»: даже если конкурент делал технически сопоставимый модем, его себестоимость оказывалась выше из-за патентных выплат.&lt;/p&gt;
  &lt;p id=&quot;FSWL&quot;&gt;&lt;strong&gt;NVIDIA&lt;/strong&gt; в 2016 году даже подала иск против Qualcomm, утверждая, что та «незаконно раздавила» её baseband-бизнес (включая Icera) через злоупотребление доминирующим положением. Иск так и не привёл к восстановлению бизнеса, но показал, насколько патентная сила Qualcomm влияла на рынок.&lt;/p&gt;
  &lt;h2 id=&quot;4---oem&quot;&gt;4. Вертикальная интеграция OEM-производителей&lt;/h2&gt;
  &lt;p id=&quot;eV0W&quot;&gt;К 2013–2015 годам крупнейшие OEM-производители начали разрабатывать собственные модемы:&lt;/p&gt;
  &lt;ul id=&quot;RiQn&quot;&gt;
    &lt;li id=&quot;Hiqq&quot;&gt;&lt;strong&gt;Samsung&lt;/strong&gt; — Exynos с интегрированными LTE-модемами.&lt;/li&gt;
    &lt;li id=&quot;rigH&quot;&gt;&lt;strong&gt;Apple&lt;/strong&gt; — переход на Qualcomm, а затем на собственные модемы (с 2023 года).&lt;/li&gt;
    &lt;li id=&quot;zM2A&quot;&gt;&lt;strong&gt;Huawei&lt;/strong&gt; — HiSilicon Balong.&lt;/li&gt;
    &lt;li id=&quot;gSCy&quot;&gt;&lt;strong&gt;Xiaomi, OPPO, vivo&lt;/strong&gt; — инвестиции в UNISOC и собственные R&amp;amp;D-центры.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;9dJV&quot;&gt;Это сократило «открытый» рынок для независимых вендоров modem-чипов. Оставшиеся игроки (Qualcomm, MediaTek, UNISOC) боролись за оставшихся OEM, а мелкие компании просто не находили покупателей.&lt;/p&gt;
  &lt;h2 id=&quot;5&quot;&gt;5. Ценовая война и «игроки, которым не важна прибыль»&lt;/h2&gt;
  &lt;p id=&quot;yWIA&quot;&gt;Рынок LTE-модемов превратился в «красный океан» с агрессивным демпингом. MediaTek, Spreadtrum (UNISOC) и китайские вендоры готовы были работать с минимальной маржой ради доли рынка.&lt;/p&gt;
  &lt;p id=&quot;YFpk&quot;&gt;&lt;strong&gt;Broadcom&lt;/strong&gt; прямо указывала на это в 2014 году:&lt;/p&gt;
  &lt;blockquote id=&quot;0gpd&quot;&gt;«На рынке было несколько игроков, которым было всё равно, зарабатывают они или нет. У них были стратегические императивы присутствовать в этом бизнесе любой ценой. Broadcom — коммерческая компания, мы так не работаем».&lt;/blockquote&gt;
  &lt;p id=&quot;XVbn&quot;&gt;Это создавало ситуацию, когда даже технологически продвинутые решения (например, NovaThor L8580 от ST-Ericsson с 28 нм FDSOI и LTE Cat. 4) не могли конкурировать по цене с более простыми чипами MediaTek и Qualcomm.&lt;/p&gt;
  &lt;h2 id=&quot;6&quot;&gt;6. Неспособность выйти на «критическую массу»&lt;/h2&gt;
  &lt;p id=&quot;55od&quot;&gt;Аналитики сходились во мнении: чтобы выжить на рынке baseband-модемов, нужна доля рынка не менее 10–15%, а лучше - 20%. Ниже этого порога R&amp;amp;D-затраты на новую генерацию (LTE-Advanced, Cat. 6/9/12, 5G) становились неподъёмными.&lt;strong&gt;GCT, Sequans, Altair&lt;/strong&gt; выжили именно потому, что ушли в ниши (IoT, M2M, CPE), где требования ниже, а конкуренция слабее. Но в массовом сегменте смартфонов они не смогли набрать критическую массу и остались «вторым эшелоном».&lt;/p&gt;
  &lt;h2 id=&quot;7&quot;&gt;7. Технологическая гонка: отставание на поколение = смерть&lt;/h2&gt;
  &lt;p id=&quot;Q8yO&quot;&gt;Рынок модемов развивался быстрее, чем рынок connectivity-чипов (Wi-Fi, Bluetooth). Если за одно поколение baseband (2–3 года) проходило два поколения connectivity, то интеграция их в один чип становилась проблемой: baseband отставал, а connectivity — нет.&lt;/p&gt;
  &lt;p id=&quot;Higw&quot;&gt;&lt;strong&gt;Broadcom&lt;/strong&gt; пыталась решить это через покупку Beceem и Renesas Mobile, но так и не смогла синхронизировать циклы разработки. В итоге компания продала/закрыла baseband-бизнес, сосредоточившись на Wi-Fi, Ethernet и других направлениях.&lt;/p&gt;
  &lt;h2 id=&quot;8&quot;&gt;8. «Эффект домино»: закрытия порождали новые закрытия&lt;/h2&gt;
  &lt;p id=&quot;9moz&quot;&gt;Когда одна крупная компания уходила с рынка, это создавало цепную реакцию:&lt;/p&gt;
  &lt;ul id=&quot;sYAZ&quot;&gt;
    &lt;li id=&quot;ZFtA&quot;&gt;Поставщики IP и инструментов теряли клиентов.&lt;/li&gt;
    &lt;li id=&quot;elog&quot;&gt;Инженеры увольнялись и уходили в Qualcomm/MediaTek.&lt;/li&gt;
    &lt;li id=&quot;hMWl&quot;&gt;OEM-производители переставали сертифицировать «рискованные» чипы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;F3Mk&quot;&gt;&lt;strong&gt;ST-Ericsson&lt;/strong&gt; после закрытия в 2013 году оставила после себя «пустоту»: Ericsson попыталась продолжить, но к 2014 году закрыла и этот бизнес. Аналогично, после ухода Broadcom в 2014 году на рынке остались только Qualcomm, Intel, MediaTek и горстка нишевых игроков.&lt;/p&gt;
  &lt;h2 id=&quot;MFwL&quot;&gt;Intel: самый дорогой провал на рынке модемов&lt;/h2&gt;
  &lt;p id=&quot;s6uc&quot;&gt;&lt;strong&gt;Intel&lt;/strong&gt; — отдельная и, пожалуй, самая болезненная глава в истории baseband-рынка. Компания потратила на развитие модемного бизнеса более &lt;strong&gt;$10 млрд&lt;/strong&gt; (включая покупку Infineon Wireless за $1,4 млрд в 2011 году), но в апреле 2019 года полностью вышла из сегмента смартфонных модемов, продав остатки Apple за $1 млрд — то есть с &lt;strong&gt;мульти-миллиардным убытком&lt;/strong&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;intel&quot;&gt;Почему Intel проиграл&lt;/h2&gt;
  &lt;p id=&quot;GhZA&quot;&gt;&lt;strong&gt;1. Зависимость от одного клиента.&lt;/strong&gt; К 2018 году Apple была фактически единственным крупным заказчиком смартфонных модемов Intel. Когда Apple заключила сделку с Qualcomm, Intel потеряла последний якорь.macrumors&lt;/p&gt;
  &lt;blockquote id=&quot;dZRy&quot;&gt;«После объявления Apple и Qualcomm мы оценили перспективы заработка на поставках этой технологии для смартфонов и пришли к выводу, что просто не видим пути к прибыли».&lt;br /&gt;— Боб Свон, CEO Intel (апрель 2019)&lt;/blockquote&gt;
  &lt;p id=&quot;MSoZ&quot;&gt;&lt;strong&gt;2. Технологическое отставание.&lt;/strong&gt; По данным инсайдеров, Intel столкнулась с серьёзными проблемами при разработке 5G-модемов:&lt;/p&gt;
  &lt;ul id=&quot;hoM4&quot;&gt;
    &lt;li id=&quot;JRmb&quot;&gt;&lt;strong&gt;Тепловыделение&lt;/strong&gt;: XMM 8160 перегревался и требовал сложной системы охлаждения.&lt;/li&gt;
    &lt;li id=&quot;mbci&quot;&gt;&lt;strong&gt;Энергопотребление&lt;/strong&gt;: 5G-модем Intel потреблял значительно больше, чем решения Qualcomm, что критично для смартфонов.&lt;/li&gt;
    &lt;li id=&quot;iq7O&quot;&gt;&lt;strong&gt;Сроки&lt;/strong&gt;: Intel не успевала к релизу iPhone 2020 с готовым 5G-чипом.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;UWeV&quot;&gt;&lt;strong&gt;3. Патентная война Qualcomm.&lt;/strong&gt; Intel поддерживала Apple в судебном процессе против Qualcomm, надеясь, что победа Apple откроет рынок. Но когда Apple сдалась и подписала 6-летний договор с Qualcomm, Intel оказалась в изоляции.&lt;/p&gt;
  &lt;blockquote id=&quot;n0Bh&quot;&gt;«Intel не смогла преодолеть искусственные и непреодолимые барьеры для честной конкуренции, созданные схемой Qualcomm, и была вынуждена выйти с рынка в этом году».&lt;br /&gt;— Роджерс, юрист Intel (декабрь 2019)&lt;/blockquote&gt;
  &lt;p id=&quot;9FuT&quot;&gt;&lt;strong&gt;4. Экономика не складывалась.&lt;/strong&gt; Даже с Apple в качестве единственного крупного клиента бизнес не был прибыльным. Intel оценивала общие затраты на разработку и acquisitions (Infineon, Beceem-конкуренты и т.д.) в &lt;strong&gt;$10+ млрд&lt;/strong&gt;, а выручка так и не покрыла эти инвестиции.&lt;/p&gt;
  &lt;h2 id=&quot;intel&quot;&gt;Что осталось после Intel&lt;/h2&gt;
  &lt;ul id=&quot;XtKT&quot;&gt;
    &lt;li id=&quot;HIin&quot;&gt;&lt;strong&gt;Apple&lt;/strong&gt; получила ~2200 инженеров, IP и оборудование для разработки собственных 5G-модемов (которые, появились в iPhone).&lt;/li&gt;
    &lt;li id=&quot;VgqD&quot;&gt;&lt;strong&gt;Intel&lt;/strong&gt; сохранила R&amp;amp;D по 5G для &lt;strong&gt;PC, IoT, автомобилей и сетевой инфраструктуры&lt;/strong&gt;, но полностью вышла из смартфонного сегмента.&lt;/li&gt;
    &lt;li id=&quot;dObZ&quot;&gt;&lt;strong&gt;Qualcomm&lt;/strong&gt; укрепила монополию: после ухода Intel и Apple–Qualcomm settlement на рынке смартфонных модемов остались Qualcomm, MediaTek, Samsung и UNISOC.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;w9cC&quot;&gt;Итог&lt;/h2&gt;
  &lt;p id=&quot;HEfG&quot;&gt;Intel стала последним крупным игроком, который попытался бросить вызов Qualcomm на рынке smartphone modems — и проиграл. История Intel подтверждает общее правило: без доли рынка ≥15–20%, без 3–5 крупных OEM-клиентов и без способности выдерживать патентное давление Qualcomm baseband-бизнес обречён на убытки.&lt;/p&gt;
  &lt;blockquote id=&quot;U02i&quot;&gt;«В бизнесе смартфонных модемов стало очевидно: нет ясного пути к прибыльности и положительной отдаче».&lt;br /&gt;— Боб Свон, CEO &lt;/blockquote&gt;

</content></entry><entry><id>pole_sam:uLxXaREJc5k</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/uLxXaREJc5k?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Как превратить бинарный CP-лог модема SIMCom A7665E в читаемый</title><published>2026-08-29T19:53:33.456Z</published><updated>2026-08-29T19:53:33.456Z</updated><summary type="html">Отладочные логи мобильных модемов часто выглядят как поток непонятных бинарных данных. Внутри могут находиться сообщения о регистрации в сети, выборе PLMN, параметрах serving cell, APN, IP-адресах и состоянии протоколов LTE. Однако без знания транспортного формата и таблицы сообщений прошивки этот поток практически бесполезен.</summary><content type="html">
  &lt;h2 id=&quot;V5dc&quot;&gt;Введение&lt;/h2&gt;
  &lt;p id=&quot;hip4&quot;&gt;Отладочные логи мобильных модемов часто выглядят как поток непонятных бинарных данных. Внутри могут находиться сообщения о регистрации в сети, выборе PLMN, параметрах serving cell, APN, IP-адресах и состоянии протоколов LTE. Однако без знания транспортного формата и таблицы сообщений прошивки этот поток практически бесполезен.&lt;/p&gt;
  &lt;p id=&quot;8DSu&quot;&gt;В этой статье разберём, как устроено распознавание debug-лога модема SIMCom A7665E на базе ASR «Crane» ASR1603. Цель — пройти весь путь от байтов, поступающих через USB, до человекочитаемой строки:&lt;/p&gt;
  &lt;pre id=&quot;EHs6&quot;&gt;байтовый поток → бинарная запись → форматное сообщение → декодированные аргументы&lt;/pre&gt;
  &lt;p id=&quot;OK8k&quot;&gt;Практически задача состоит из двух независимых частей:&lt;/p&gt;
  &lt;ul id=&quot;OVAH&quot;&gt;
    &lt;li id=&quot;lzEQ&quot;&gt;определить границы бинарных записей;&lt;/li&gt;
    &lt;li id=&quot;iawi&quot;&gt;понять смысл каждой записи по её идентификаторам и payload.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;xfbd&quot;&gt;Первую проблему можно решить детерминированно. Вторая требует базы форматных строк, соответствующей конкретной сборке прошивки.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;1&quot;&gt;1. Исходные условия&lt;/h2&gt;
  &lt;p id=&quot;AabM&quot;&gt;В качестве устройства используется модем SIMCom A7665E&lt;/p&gt;
  &lt;p id=&quot;DqWX&quot;&gt;Важно не перепутать этот поток с Qualcomm DIAG. CP-log ASR имеет другой бинарный формат, поэтому инструменты, рассчитанные на Qualcomm DIAG, например &lt;code&gt;qc_debug_monitor&lt;/code&gt;, его не распознают.&lt;/p&gt;
  &lt;p id=&quot;Wzic&quot;&gt;Итоговая архитектура декодера выглядит так:&lt;/p&gt;
  &lt;pre id=&quot;6HGy&quot;&gt;/dev/ttyUSBx
     │
     │ AT+ECPLOG=1
     ▼
поток бинарных данных
     │
     ▼
asr_proto.py
байты → Record
     │
     ▼
asr_mdb.py
(msg_type, fmt_id) + payload → строка
     │
     ▼
asr_debug_monitor.py
захват, фильтрация, цветной вывод, replay&lt;/pre&gt;
  &lt;p id=&quot;6CmS&quot;&gt;Такое разделение ответственности удобно по нескольким причинам:&lt;/p&gt;
  &lt;ul id=&quot;zNWc&quot;&gt;
    &lt;li id=&quot;kPUJ&quot;&gt;транспортный парсер не зависит от базы форматов;&lt;/li&gt;
    &lt;li id=&quot;uxvp&quot;&gt;декодер семантики не зависит от последовательного порта;&lt;/li&gt;
    &lt;li id=&quot;xZzW&quot;&gt;один и тот же протокол можно использовать в CLI, web-мониторе или тестовой системе;&lt;/li&gt;
    &lt;li id=&quot;vhVC&quot;&gt;каждый слой можно тестировать отдельно.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;2--cp-log&quot;&gt;2. Поиск CP-log-порта&lt;/h2&gt;
  &lt;h2 id=&quot;ttyusb0&quot;&gt;Почему нельзя полагаться на &lt;code&gt;ttyUSB0&lt;/code&gt;&lt;/h2&gt;
  &lt;p id=&quot;CrGd&quot;&gt;После перезагрузки модема Linux может назначить интерфейсам другие имена:&lt;/p&gt;
  &lt;pre id=&quot;96W4&quot;&gt;до перезагрузки:     ttyUSB0, ttyUSB1, ttyUSB2
после перезагрузки:  ttyUSB3, ttyUSB4, ttyUSB5&lt;/pre&gt;
  &lt;p id=&quot;UqhE&quot;&gt;Поэтому поиск порта по имени ненадёжен. Лучше использовать USB VID и номер интерфейса в USB-топологии.&lt;/p&gt;
  &lt;p id=&quot;RQey&quot;&gt;В рассматриваемом устройстве CP-log находится на интерфейсе &lt;code&gt;#2&lt;/code&gt;. В &lt;code&gt;pyserial&lt;/code&gt; его можно найти по полю &lt;code&gt;location&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;JMin&quot;&gt;from serial.tools import list_ports

MODEM_VID = 0x1e0e
DEBUG_IFACE = 2

def find_debug_port(iface=DEBUG_IFACE, vid=MODEM_VID):
    fallback = None

    for port in list_ports.comports():
        if port.vid != vid:
            continue

        location = port.location or &amp;quot;&amp;quot;

        if location.endswith(f&amp;quot;:1.{iface}&amp;quot;):
            return port.device

        fallback = fallback or port.device

    return fallback&lt;/pre&gt;
  &lt;p id=&quot;NG7a&quot;&gt;Ключевая проверка:&lt;/p&gt;
  &lt;pre id=&quot;rKri&quot;&gt;location.endswith(&amp;quot;:1.2&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;MAVU&quot;&gt;Номер &lt;code&gt;ttyUSBx&lt;/code&gt; может измениться, а номер USB-интерфейса в конкретной композиции обычно остаётся постоянным.&lt;/p&gt;
  &lt;h2 id=&quot;8Voq&quot;&gt;Включение потока&lt;/h2&gt;
  &lt;p id=&quot;MSSK&quot;&gt;CP-log не начинает передаваться автоматически. Сначала на тот же порт необходимо отправить AT-команду:&lt;/p&gt;
  &lt;pre id=&quot;AIQx&quot;&gt;ENABLE_CMD = b&amp;quot;AT+ECPLOG=1\r\n&amp;quot;
DISABLE_CMD = b&amp;quot;AT+ECPLOG=0\r\n&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;iM0M&quot;&gt;Пример открытия устройства:&lt;/p&gt;
  &lt;pre id=&quot;JJrL&quot;&gt;import serial
import time

def open_device(device, baudrate=115200):
    ser = serial.Serial(device, baudrate, timeout=0.2)

    ser.reset_input_buffer()
    ser.write(ENABLE_CMD)
    ser.flush()

    time.sleep(0.4)

    # Удаляем эхо команды и текстовый ответ OK
    ser.reset_input_buffer()

    return ser&lt;/pre&gt;
  &lt;p id=&quot;1IyD&quot;&gt;Здесь есть важная особенность: после &lt;code&gt;AT+ECPLOG=1&lt;/code&gt; модем сначала может вернуть обычный текстовый ответ:&lt;/p&gt;
  &lt;pre id=&quot;8Ysu&quot;&gt;AT+ECPLOG=1
OK&lt;/pre&gt;
  &lt;p id=&quot;vPCD&quot;&gt;Затем начинается бинарный поток. Если не очистить входной буфер, парсер может попытаться интерпретировать ASCII-ответ как начало бинарной записи.&lt;/p&gt;
  &lt;p id=&quot;H6GH&quot;&gt;При завершении работы полезно отключить лог:&lt;/p&gt;
  &lt;pre id=&quot;VVAC&quot;&gt;ser.write(DISABLE_CMD)
ser.flush()
time.sleep(0.1)
ser.reset_input_buffer()
ser.close()&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;3&quot;&gt;3. Формат бинарной записи&lt;/h2&gt;
  &lt;h2 id=&quot;ubjE&quot;&gt;Как была найдена граница сообщений&lt;/h2&gt;
  &lt;p id=&quot;fsPk&quot;&gt;В дампе регулярно повторяется последовательность:&lt;/p&gt;
  &lt;pre id=&quot;bBVb&quot;&gt;маленькое число → несколько нулей → полезная нагрузка&lt;/pre&gt;
  &lt;p id=&quot;PrUW&quot;&gt;Это позволяет предположить, что первые два байта являются длиной записи в формате little-endian.&lt;/p&gt;
  &lt;p id=&quot;iVXc&quot;&gt;Алгоритм проверки простой:&lt;/p&gt;
  &lt;ol id=&quot;ltNT&quot;&gt;
    &lt;li id=&quot;GBQz&quot;&gt;прочитать первые два байта;&lt;/li&gt;
    &lt;li id=&quot;gqSf&quot;&gt;интерпретировать их как &lt;code&gt;u16&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;uoWO&quot;&gt;перейти вперёд на указанное количество байт;&lt;/li&gt;
    &lt;li id=&quot;MD6Q&quot;&gt;проверить, похожи ли следующие два байта на очередную длину;&lt;/li&gt;
    &lt;li id=&quot;l7Ub&quot;&gt;повторить процедуру до конца буфера.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;ZIYu&quot;&gt;Если цепочка проходит через весь дамп без рассинхронизации, гипотеза подтверждается.&lt;/p&gt;
  &lt;p id=&quot;6Alv&quot;&gt;Такой формат обладает свойством самосинхронизации: если в поток попал мусор, длина обычно выходит за разумные пределы, и парсер может начать поиск следующей потенциальной записи.&lt;/p&gt;
  &lt;h2 id=&quot;7rQZ&quot;&gt;Заголовок&lt;/h2&gt;
  &lt;p id=&quot;Nurd&quot;&gt;Аргументы сообщения&lt;/p&gt;
  &lt;p id=&quot;VSwH&quot;&gt;В Python структура описывается так:&lt;/p&gt;
  &lt;pre id=&quot;Ub4l&quot;&gt;import struct

HDR = struct.Struct(&amp;quot;&amp;lt;HHHHHHI&amp;quot;)
HDR_LEN = HDR.size  # 16 байт&lt;/pre&gt;
  &lt;p id=&quot;aj7y&quot;&gt;Порядок полей:&lt;/p&gt;
  &lt;pre id=&quot;CwfQ&quot;&gt;length, flags, channel, seq, msg_type, fmt_id, timestamp&lt;/pre&gt;
  &lt;h2 id=&quot;ygey&quot;&gt;Таймстамп&lt;/h2&gt;
  &lt;p id=&quot;hfGU&quot;&gt;Поле &lt;code&gt;timestamp&lt;/code&gt; не является временем в микросекундах или миллисекундах. Экспериментальное сопоставление с известными интервалами показало, что устройство использует частоту 32768 Гц:&lt;/p&gt;
  &lt;pre id=&quot;InD3&quot;&gt;TS_HZ = 32768

def timestamp_seconds(timestamp):
    return timestamp / TS_HZ&lt;/pre&gt;
  &lt;p id=&quot;aoWG&quot;&gt;Например:&lt;/p&gt;
  &lt;pre id=&quot;01r3&quot;&gt;timestamp = 2 572 383
time      = 2 572 383 / 32 768 ≈ 78.503 с&lt;/pre&gt;
  &lt;p id=&quot;2Nmr&quot;&gt;Это абсолютное время работы устройства до момента включения ECPLOG. В пользовательском интерфейсе удобнее вычесть timestamp первой записи и показывать относительное время:&lt;/p&gt;
  &lt;pre id=&quot;ut3n&quot;&gt;[+0.000000] ...
[+0.003174] ...
[+0.006287] ...&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;4&quot;&gt;4. Потоковый парсер&lt;/h2&gt;
  &lt;p id=&quot;gX1F&quot;&gt;Парсер должен корректно работать в двух режимах:&lt;/p&gt;
  &lt;ul id=&quot;zva4&quot;&gt;
    &lt;li id=&quot;45NA&quot;&gt;с готовым бинарным файлом;&lt;/li&gt;
    &lt;li id=&quot;X9Zh&quot;&gt;с живым потоком, где одна запись может прийти несколькими частями.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;3y14&quot;&gt;Разбор одной записи&lt;/h2&gt;
  &lt;pre id=&quot;Eg2b&quot;&gt;MIN_REC = 16
MAX_REC = 16384

def take_record(buf, offset, flush=False):
    end = len(buf)

    if offset + 2 &amp;gt; end:
        return None, offset, True

    length = buf[offset] | (buf[offset + 1] &amp;lt;&amp;lt; 8)

    if length &amp;lt; MIN_REC or length &amp;gt; MAX_REC:
        # Некорректная длина: пробуем синхронизацию со следующего байта
        return None, offset + 1, False

    if offset + length &amp;gt; end:
        if flush:
            # Финальный обрезанный хвост
            return None, offset + 1, False

        # Для живого потока ждём следующую порцию данных
        return None, offset, True

    fields = HDR.unpack_from(buf, offset)

    record = {
        &amp;quot;length&amp;quot;: fields[0],
        &amp;quot;flags&amp;quot;: fields[1],
        &amp;quot;channel&amp;quot;: fields[2],
        &amp;quot;seq&amp;quot;: fields[3],
        &amp;quot;msg_type&amp;quot;: fields[4],
        &amp;quot;fmt_id&amp;quot;: fields[5],
        &amp;quot;timestamp&amp;quot;: fields[6],
        &amp;quot;payload&amp;quot;: bytes(
            buf[offset + HDR_LEN:offset + length]
        ),
        &amp;quot;offset&amp;quot;: offset,
    }

    return record, offset + length, False&lt;/pre&gt;
  &lt;h2 id=&quot;HLZH&quot;&gt;Инкрементальный режим&lt;/h2&gt;
  &lt;pre id=&quot;pfxt&quot;&gt;class StreamParser:
    def __init__(self):
        self.buffer = bytearray()

    def feed(self, chunk):
        self.buffer.extend(chunk)

        offset = 0
        end = len(self.buffer)

        while offset &amp;lt; end:
            record, next_offset, need_more = take_record(
                self.buffer,
                offset,
                flush=False
            )

            if need_more:
                break

            offset = next_offset

            if record is not None:
                yield record

        if offset:
            del self.buffer[:offset]

        # Защита от бесконечного роста при потере синхронизации
        if len(self.buffer) &amp;gt; 1 &amp;lt;&amp;lt; 20:
            del self.buffer[:len(self.buffer) - (1 &amp;lt;&amp;lt; 16)]&lt;/pre&gt;
  &lt;p id=&quot;udSn&quot;&gt;Если в середине записи пришёл только заголовок и часть payload, она остаётся во внутреннем буфере. Следующий вызов &lt;code&gt;feed()&lt;/code&gt; продолжает разбор.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;5&quot;&gt;5. Разбор первой записи&lt;/h2&gt;
  &lt;p id=&quot;bfmo&quot;&gt;Рассмотрим пример записи размером 34 байта:&lt;/p&gt;
  &lt;pre id=&quot;eTHt&quot;&gt;22 00 | 00 00 | 00 00 | 01 00 | 2b 00 | 96 14 |
5f 40 27 00 |
02 00 63 00 78 08 12 00 01 00 00 00 02 00 00 00 00 00&lt;/pre&gt;
  &lt;p id=&quot;YQni&quot;&gt;Разметка:&lt;/p&gt;
  &lt;pre id=&quot;7mcY&quot;&gt;length     flags      channel    seq
22 00      00 00      00 00      01 00

msg_type   fmt_id     timestamp
2b 00      96 14      5f 40 27 00

payload
02 00 63 00 78 08 12 00 01 00 00 00 02 00 00 00 00 00&lt;/pre&gt;
  &lt;p id=&quot;QS7G&quot;&gt;В данном случае &lt;code&gt;msg_type = 0x2b&lt;/code&gt; соответствует текстовой записи. Однако payload содержит бинарный префикс, поэтому его нельзя безусловно интерпретировать как обычную C-строку.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;6&quot;&gt;6. Типы сообщений&lt;/h2&gt;
  &lt;p id=&quot;v9sT&quot;&gt;Поле &lt;code&gt;msg_type&lt;/code&gt; определяет, как нужно обрабатывать запись:&lt;/p&gt;
  &lt;pre id=&quot;dnnO&quot;&gt;TYPE_TEXT = 0x2B

TYPE_NAMES = {
    0x2B: &amp;quot;TEXT&amp;quot;,
    0x1D: &amp;quot;TRACE&amp;quot;,
    0x17: &amp;quot;SIGNAL&amp;quot;,
    0x1A: &amp;quot;T1A&amp;quot;,
    0x16: &amp;quot;T16&amp;quot;,
    0x0E: &amp;quot;T0E&amp;quot;,
    0x03: &amp;quot;T03&amp;quot;,
}&lt;/pre&gt;
  &lt;h2 id=&quot;text&quot;&gt;TEXT-записи&lt;/h2&gt;
  &lt;p id=&quot;nzXJ&quot;&gt;TEXT-записи уже содержат готовые фрагменты текста. Их можно декодировать без базы форматных строк, извлекая печатные ASCII-последовательности.&lt;/p&gt;
  &lt;pre id=&quot;tIqc&quot;&gt;def printable_runs(data, min_run=3):
    runs = []
    current = bytearray()

    for byte in data:
        if 32 &amp;lt;= byte &amp;lt; 127:
            current.append(byte)
        else:
            if len(current) &amp;gt;= min_run:
                runs.append(current.decode(&amp;quot;latin-1&amp;quot;))
            current.clear()

    if len(current) &amp;gt;= min_run:
        runs.append(current.decode(&amp;quot;latin-1&amp;quot;))

    return runs&lt;/pre&gt;
  &lt;p id=&quot;689M&quot;&gt;Для текстовых записей достаточно использовать короткий порог:&lt;/p&gt;
  &lt;pre id=&quot;lsqx&quot;&gt;runs = printable_runs(payload, min_run=3)
text = &amp;quot; &amp;quot;.join(runs)&lt;/pre&gt;
  &lt;h2 id=&quot;terse&quot;&gt;Terse-записи&lt;/h2&gt;
  &lt;p id=&quot;upv9&quot;&gt;Terse-записи содержат не сам текст, а:&lt;/p&gt;
  &lt;ul id=&quot;cu0T&quot;&gt;
    &lt;li id=&quot;uY5y&quot;&gt;идентификатор форматной строки;&lt;/li&gt;
    &lt;li id=&quot;Y65C&quot;&gt;бинарные аргументы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Dc7q&quot;&gt;Их можно представить как удалённый вызов:&lt;/p&gt;
  &lt;pre id=&quot;TC9k&quot;&gt;diagPrintf(&amp;quot;Serving Cell: rsrp = %d&amp;quot;, rsrp);&lt;/pre&gt;
  &lt;p id=&quot;UXSP&quot;&gt;На провод передаются только:&lt;/p&gt;
  &lt;pre id=&quot;95Ot&quot;&gt;fmt_id + бинарное значение rsrp&lt;/pre&gt;
  &lt;p id=&quot;qqtj&quot;&gt;Сама строка формата находится в базе данных прошивки.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;7--fileline&quot;&gt;7. Записи &lt;code&gt;file:line&lt;/code&gt; без базы&lt;/h2&gt;
  &lt;p id=&quot;ObEZ&quot;&gt;Часть assert-сообщений содержит имя исходного файла и номер строки:&lt;/p&gt;
  &lt;pre id=&quot;TfgR&quot;&gt;rrcdsutils.c\0\xa2\x0a\x00\x00&lt;/pre&gt;
  &lt;p id=&quot;dSCI&quot;&gt;То есть payload имеет вид:&lt;/p&gt;
  &lt;pre id=&quot;lgBf&quot;&gt;имя файла + NUL + номер строки u32&lt;/pre&gt;
  &lt;p id=&quot;95nX&quot;&gt;Такой формат можно распознать независимо от версии базы:&lt;/p&gt;
  &lt;pre id=&quot;ahNy&quot;&gt;import re

SOURCE_RE = re.compile(
    r&amp;quot;\.(c|h|cpp|cc|cxx)$&amp;quot;,
    re.IGNORECASE
)

def decode_file_line(payload):
    nul = payload.find(b&amp;quot;\x00&amp;quot;)

    if nul &amp;lt; 4:
        return None

    raw_name = payload[:nul]

    if not all(32 &amp;lt;= byte &amp;lt; 127 for byte in raw_name):
        return None

    name = raw_name.decode(&amp;quot;latin-1&amp;quot;)

    if not SOURCE_RE.search(name):
        return None

    name = name.replace(&amp;quot;\\&amp;quot;, &amp;quot;/&amp;quot;).rsplit(&amp;quot;/&amp;quot;, 1)[-1]

    if len(payload) &amp;lt; nul + 5:
        return None

    line = int.from_bytes(
        payload[nul + 1:nul + 5],
        &amp;quot;little&amp;quot;
    )

    return name, line&lt;/pre&gt;
  &lt;p id=&quot;ZL5B&quot;&gt;Пример результата:&lt;/p&gt;
  &lt;pre id=&quot;nsPi&quot;&gt;rrcdsutils.c:2722&lt;/pre&gt;
  &lt;p id=&quot;ViNf&quot;&gt;Строгая проверка необходима: случайный бинарный payload тоже может содержать печатные байты. Условие с расширением исходного файла снижает вероятность ложного распознавания.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;8&quot;&gt;8. База форматных строк&lt;/h2&gt;
  &lt;h2 id=&quot;m7nZ&quot;&gt;Зачем нужна база&lt;/h2&gt;
  &lt;p id=&quot;RaAb&quot;&gt;Terse-сообщение само по себе неполно. Например, запись может содержать:&lt;/p&gt;
  &lt;pre id=&quot;abea&quot;&gt;msg_type = 0x1d
fmt_id   = 0x0b3d
payload  = бинарные аргументы&lt;/pre&gt;
  &lt;p id=&quot;pBj1&quot;&gt;Чтобы понять, что означают эти байты, нужна запись из базы:&lt;/p&gt;
  &lt;pre id=&quot;Q0pV&quot;&gt;&amp;quot;updates ( %ld , %d ) measUpdateTime: ( 0x%lx ) , ( rsrp = %d )&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;84n3&quot;&gt;В случае ASR используется база &lt;code&gt;cp_MDB.txt&lt;/code&gt; формата CATStudio &lt;code&gt;TxtDbHeader&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;mUgJ&quot;&gt;Секции базы&lt;/h2&gt;
  &lt;p id=&quot;uQjt&quot;&gt;Наиболее важны три секции:&lt;/p&gt;
  &lt;ul id=&quot;aBYu&quot;&gt;
    &lt;li id=&quot;WO2u&quot;&gt;&lt;code&gt;EnumValsRes&lt;/code&gt; — таблица форматных строк;&lt;/li&gt;
    &lt;li id=&quot;h2CU&quot;&gt;&lt;code&gt;Enums&lt;/code&gt; — преобразование числовых значений в имена;&lt;/li&gt;
    &lt;li id=&quot;QZXW&quot;&gt;&lt;code&gt;Signals&lt;/code&gt; — описания структур для &lt;code&gt;%S{...}&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;1Mvd&quot;&gt;Извлечение секций&lt;/h2&gt;
  &lt;p id=&quot;wnB3&quot;&gt;В начале файла находится индекс с байтовыми смещениями:&lt;/p&gt;
  &lt;pre id=&quot;0pPl&quot;&gt;EnumValsRes,1234,987654
Enums,987654,1048576
Signals,1048576,4567890&lt;/pre&gt;
  &lt;p id=&quot;Ehs3&quot;&gt;Пример загрузки:&lt;/p&gt;
  &lt;pre id=&quot;KyHY&quot;&gt;def parse_sections(raw):
    marker = raw.find(b&amp;quot;&amp;lt;end&amp;gt;&amp;quot;)

    if marker &amp;lt; 0:
        return {}

    header = raw[:marker].decode(
        &amp;quot;latin-1&amp;quot;,
        &amp;quot;replace&amp;quot;
    )

    sections = {}

    for line in header.splitlines():
        parts = line.split(&amp;quot;,&amp;quot;)

        if len(parts) != 3:
            continue

        name, start, end = parts

        if start.isdigit() and end.isdigit():
            sections[name] = (
                int(start),
                int(end)
            )

    return sections&lt;/pre&gt;
  &lt;h2 id=&quot;Rmba&quot;&gt;Таблица форматных строк&lt;/h2&gt;
  &lt;p id=&quot;ylkW&quot;&gt;Строка в &lt;code&gt;EnumValsRes&lt;/code&gt; выглядит примерно так:&lt;/p&gt;
  &lt;pre id=&quot;FhHA&quot;&gt;table,id,flag,flag,GROUP,MODULE,NAME,diagPrintf(&amp;quot;формат&amp;quot;, args);&lt;/pre&gt;
  &lt;p id=&quot;bb2Y&quot;&gt;Запятые могут встречаться внутри самой форматной строки, поэтому разделять строку нужно только по первым семи запятым:&lt;/p&gt;
  &lt;pre id=&quot;NoFM&quot;&gt;parts = line.split(&amp;quot;,&amp;quot;, 7)&lt;/pre&gt;
  &lt;p id=&quot;bFob&quot;&gt;Для поддержки всех вариантов вызова используется регулярное выражение:&lt;/p&gt;
  &lt;pre id=&quot;HPWv&quot;&gt;import re

FORMAT_RE = re.compile(
    r&amp;#x27;diag(?:Text|Struct)?Printf\s*\(&amp;#x27;
    r&amp;#x27;\s*&amp;quot;((?:[^&amp;quot;\\]|\\.)*)&amp;quot;&amp;#x27;
)&lt;/pre&gt;
  &lt;p id=&quot;p2Pr&quot;&gt;Оно распознаёт:&lt;/p&gt;
  &lt;pre id=&quot;VUpv&quot;&gt;diagPrintf(...)
TextPrintf(...)
StructPrintf(...)&lt;/pre&gt;
  &lt;p id=&quot;QmvP&quot;&gt;Это исправляет важную ошибку: если искать только &lt;code&gt;diagPrintf&lt;/code&gt;, записи &lt;code&gt;diagTextPrintf&lt;/code&gt; и &lt;code&gt;diagStructPrintf&lt;/code&gt; останутся без форматной строки и будут ошибочно показаны как hex.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;9&quot;&gt;9. Подбор подходящей базы&lt;/h2&gt;
  &lt;p id=&quot;ssBR&quot;&gt;База форматных строк должна соответствовать сборке прошивки. Даже если две версии используют один и тот же чипсет, идентификаторы сообщений могут отличаться.&lt;/p&gt;
  &lt;p id=&quot;AF9D&quot;&gt;Для выбора наиболее подходящей базы удобно использовать измеримые метрики.&lt;/p&gt;
  &lt;h2 id=&quot;key-match&quot;&gt;Key-match&lt;/h2&gt;
  &lt;p id=&quot;jypT&quot;&gt;Первая метрика — доля пар &lt;code&gt;(msg_type, fmt_id)&lt;/code&gt;, найденных в базе:&lt;/p&gt;
  &lt;pre id=&quot;VIVM&quot;&gt;distinct_keys = {
    (record[&amp;quot;msg_type&amp;quot;], record[&amp;quot;fmt_id&amp;quot;])
    for record in terse_records
}

matched = {
    key for key in distinct_keys
    if key in mdb_entries
}

key_match = len(matched) / len(distinct_keys)&lt;/pre&gt;
  &lt;p id=&quot;lUoq&quot;&gt;Эта метрика показывает, совпадает ли схема идентификаторов.&lt;/p&gt;
  &lt;h2 id=&quot;scalar-clean&quot;&gt;Scalar-clean&lt;/h2&gt;
  &lt;p id=&quot;mXzA&quot;&gt;Вторая метрика проверяет, удалось ли полностью разобрать аргументы скалярных сообщений без маркера &lt;code&gt;&amp;lt;?&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;N5kE&quot;&gt;scalar-clean =
число сообщений без underflow /
общее число проверяемых сообщений&lt;/pre&gt;
  &lt;p id=&quot;p0Vu&quot;&gt;Она проверяет уже не только идентификаторы, но и ширины аргументов.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;10---int--16&quot;&gt;10. Главная особенность: &lt;code&gt;int&lt;/code&gt; занимает 16 бит&lt;/h2&gt;
  &lt;p id=&quot;Zdfj&quot;&gt;Это наиболее нетривиальная часть реверса.&lt;/p&gt;
  &lt;h2 id=&quot;i6fj&quot;&gt;Симптом&lt;/h2&gt;
  &lt;p id=&quot;f3EN&quot;&gt;При стандартной интерпретации printf-аргументов каждый &lt;code&gt;%d&lt;/code&gt; ожидает 4 байта. Но результаты выглядели неправильно:&lt;/p&gt;
  &lt;pre id=&quot;26rT&quot;&gt;rsrp = 104922215&lt;/pre&gt;
  &lt;p id=&quot;T0Lm&quot;&gt;или:&lt;/p&gt;
  &lt;pre id=&quot;9Y9L&quot;&gt;rsrp = &amp;lt;?&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;1z6P&quot;&gt;Причина — payload заканчивался раньше, чем ожидал декодер.&lt;/p&gt;
  &lt;h2 id=&quot;YdnK&quot;&gt;Проверка гипотезы&lt;/h2&gt;
  &lt;p id=&quot;CTkG&quot;&gt;Для каждого сообщения можно вычислить ожидаемый размер аргументов и сравнить его с фактической длиной payload:&lt;/p&gt;
  &lt;pre id=&quot;spNI&quot;&gt;def fit_score(records, short_width):
    exact = 0
    underflow = 0
    leftover = 0

    for record in records:
        fmt = get_format(record)

        if not fmt:
            continue

        required = calculate_argument_size(
            fmt,
            short_width=short_width,
            long_width=4
        )

        actual = len(record[&amp;quot;payload&amp;quot;])

        if required == actual:
            exact += 1
        elif required &amp;gt; actual:
            underflow += 1
        else:
            leftover += 1

    return exact, underflow, leftover&lt;/pre&gt;
  &lt;p id=&quot;rjXk&quot;&gt;При ширине 2 байта количество underflow уменьшается примерно в пять раз.&lt;/p&gt;
  &lt;h2 id=&quot;gRsK&quot;&gt;Практическое правило&lt;/h2&gt;
  &lt;p id=&quot;1W9r&quot;&gt;Для ASR-терс-сообщений используется следующее соответствие:&lt;/p&gt;
  &lt;pre id=&quot;zjgb&quot;&gt;if conversion in &amp;quot;eEfFgG&amp;quot;:
    width = 8 if length in (&amp;quot;l&amp;quot;, &amp;quot;ll&amp;quot;, &amp;quot;L&amp;quot;) else 4
elif conversion == &amp;quot;p&amp;quot;:
    width = 4
elif length == &amp;quot;ll&amp;quot;:
    width = 8
elif length == &amp;quot;hh&amp;quot;:
    width = 1
elif length == &amp;quot;l&amp;quot;:
    width = 4
elif length in (&amp;quot;L&amp;quot;, &amp;quot;z&amp;quot;, &amp;quot;j&amp;quot;, &amp;quot;t&amp;quot;):
    width = 4
elif length == &amp;quot;h&amp;quot;:
    width = 2
else:
    width = 2&lt;/pre&gt;
  &lt;p id=&quot;bOlS&quot;&gt;Значения &lt;code&gt;%d&lt;/code&gt; и &lt;code&gt;%i&lt;/code&gt; необходимо интерпретировать как знаковые:&lt;/p&gt;
  &lt;pre id=&quot;1QeR&quot;&gt;value = int.from_bytes(
    payload[pos:pos + width],
    &amp;quot;little&amp;quot;,
    signed=conversion in &amp;quot;di&amp;quot;
)&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;11&quot;&gt;11. Сквозной пример декодирования&lt;/h2&gt;
  &lt;p id=&quot;5cVd&quot;&gt;Рассмотрим запись:&lt;/p&gt;
  &lt;pre id=&quot;iLf0&quot;&gt;msg_type = 0x1d
fmt_id   = 0x0b3d
payload  = e40c0000 d100 021c0f00 61e4&lt;/pre&gt;
  &lt;p id=&quot;8Y5t&quot;&gt;Форматная строка:&lt;/p&gt;
  &lt;pre id=&quot;NtiQ&quot;&gt;&amp;quot;updates ( %ld , %d ) &amp;#x27;s measUpdateTime: &amp;quot;
&amp;quot;( 0x%lx ) , ( rsrp = %d ) &amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;m4OD&quot;&gt;Результат:&lt;/p&gt;
  &lt;pre id=&quot;KW0g&quot;&gt;updates ( 3300, 209 ) measUpdateTime:
( 0xf1c02 ), ( rsrp = -7071 )&lt;/pre&gt;
  &lt;p id=&quot;Qibr&quot;&gt;При ошибочной ширине &lt;code&gt;%d = 4 байта&lt;/code&gt; декодер начал бы читать следующие аргументы с неправильных смещений и в итоге получил бы &lt;code&gt;&amp;lt;?&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;12--s&quot;&gt;12. Поддержка &lt;code&gt;%S{...}&lt;/code&gt; и структур&lt;/h2&gt;
  &lt;p id=&quot;QBRT&quot;&gt;Некоторые диагностические сообщения передают не скаляры, а структуры:&lt;/p&gt;
  &lt;pre id=&quot;4EsE&quot;&gt;%S{EmmPrintDebugInfoInd_MobileId}&lt;/pre&gt;
  &lt;p id=&quot;bCST&quot;&gt;Описание полей находится в секции &lt;code&gt;Signals&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;tL4X&quot;&gt;Минимальная модель структуры:&lt;/p&gt;
  &lt;pre id=&quot;9ngN&quot;&gt;structs = {
    &amp;quot;Example&amp;quot;: [
        (&amp;quot;field_a&amp;quot;, &amp;quot;int&amp;quot;, 1, &amp;quot;&amp;quot;),
        (&amp;quot;field_b&amp;quot;, &amp;quot;enum&amp;quot;, 1, &amp;quot;StateType&amp;quot;),
        (&amp;quot;field_c&amp;quot;, &amp;quot;pointer&amp;quot;, 1, &amp;quot;&amp;quot;),
    ]
}&lt;/pre&gt;
  &lt;p id=&quot;dcrL&quot;&gt;Декодер обрабатывает:&lt;/p&gt;
  &lt;ul id=&quot;JXXS&quot;&gt;
    &lt;li id=&quot;gWlK&quot;&gt;скалярные поля;&lt;/li&gt;
    &lt;li id=&quot;tGyp&quot;&gt;enum;&lt;/li&gt;
    &lt;li id=&quot;4bsU&quot;&gt;указатели;&lt;/li&gt;
    &lt;li id=&quot;k97N&quot;&gt;вложенные структуры;&lt;/li&gt;
    &lt;li id=&quot;cBXV&quot;&gt;массивы;&lt;/li&gt;
    &lt;li id=&quot;1mQp&quot;&gt;рекурсию.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;0KcX&quot;&gt;Упрощённая схема:&lt;/p&gt;
  &lt;pre id=&quot;ec6w&quot;&gt;def decode_struct(name, payload, pos=0, depth=0):
    if depth &amp;gt; 6:
        return f&amp;quot;{{{name}?}}&amp;quot;, pos

    fields = structs.get(name)

    if fields is None:
        return f&amp;quot;{{{name}?}}&amp;quot;, pos

    result = []

    for field_name, field_type, count, detail in fields:
        values = []

        for _ in range(count):
            if field_type == &amp;quot;enum&amp;quot;:
                value = read_u32(payload, pos)
                pos += 4
                value = enums.get(detail, {}).get(
                    value,
                    str(value)
                )

            elif field_type == &amp;quot;pointer&amp;quot;:
                value = read_u32(payload, pos)
                pos += 4
                value = hex(value)

            elif field_type == &amp;quot;int&amp;quot;:
                value = read_u32(payload, pos, signed=True)
                pos += 4

            elif detail in structs:
                value, pos = decode_struct(
                    detail,
                    payload,
                    pos,
                    depth + 1
                )

            else:
                value = &amp;quot;&amp;lt;?&amp;gt;&amp;quot;

            values.append(value)

        rendered = (
            values[0]
            if count == 1
            else &amp;quot;[&amp;quot; + &amp;quot;,&amp;quot;.join(map(str, values)) + &amp;quot;]&amp;quot;
        )

        result.append(f&amp;quot;{field_name}={rendered}&amp;quot;)

    return &amp;quot;{&amp;quot; + &amp;quot;, &amp;quot;.join(result) + &amp;quot;}&amp;quot;, pos&lt;/pre&gt;
  &lt;h2 id=&quot;vwkz&quot;&gt;Почему структуры могут декодироваться неверно&lt;/h2&gt;
  &lt;p id=&quot;yUmc&quot;&gt;Секция &lt;code&gt;Signals&lt;/code&gt; из близкой базы может не полностью соответствовать конкретной сборке модема. Например, поля большой EMM-структуры могут иметь другую раскладку или тип.&lt;/p&gt;
  &lt;p id=&quot;b6JO&quot;&gt;В результате появляются значения вроде:&lt;/p&gt;
  &lt;pre id=&quot;fOaO&quot;&gt;mcc = -1727901696&lt;/pre&gt;
  &lt;p id=&quot;ZHLK&quot;&gt;В таких случаях проблема находится не в транспортном парсере, а в несовпадении описания структуры. Исправить её можно только точной базой &lt;code&gt;cp_MDB.txt&lt;/code&gt; для конкретной версии прошивки.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;13&quot;&gt;13. Приоритет способов декодирования&lt;/h2&gt;
  &lt;p id=&quot;DAx5&quot;&gt;Одна запись может быть распознана несколькими способами. Поэтому форматтеру нужен строгий порядок выбора:&lt;/p&gt;
  &lt;pre id=&quot;jWY2&quot;&gt;1. TEXT-запись
   └─ готовая строка, база не нужна

2. file:line
   └─ имя исходного файла и номер строки

3. terse-декодирование через MDB
   └─ форматная строка + бинарные аргументы

4. встроенная ASCII-строка
   └─ длинный печатный фрагмент внутри payload

5. raw hex
   └─ неизвестный или неподдерживаемый payload&lt;/pre&gt;
  &lt;p id=&quot;lRIn&quot;&gt;Формат вывода может выглядеть так:&lt;/p&gt;
  &lt;pre id=&quot;HjYG&quot;&gt;[+0.000000] [TEXT] +ZDON
[+0.003174] [NAS] New Selected PLMN (250,1)
[+0.006287] [RRC] Serving Cell rsrp=-110.5 dBm
[+0.009460] [ASSERT] rrcdsutils.c:2722&lt;/pre&gt;
  &lt;p id=&quot;FcLg&quot;&gt;Большие необработанные записи лучше скрывать по умолчанию и включать отдельным флагом:&lt;/p&gt;
  &lt;pre id=&quot;sjDl&quot;&gt;./asr_debug_monitor.py --replay capture.bin -t&lt;/pre&gt;
  &lt;p id=&quot;wJnW&quot;&gt;где &lt;code&gt;-t&lt;/code&gt; показывает terse-записи, а:&lt;/p&gt;
  &lt;pre id=&quot;hF41&quot;&gt;./asr_debug_monitor.py --replay capture.bin -a&lt;/pre&gt;
  &lt;p id=&quot;MmN8&quot;&gt;показывает все записи, включая объёмные signal-сообщения.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;14----seq&quot;&gt;14. Контроль потерь по &lt;code&gt;seq&lt;/code&gt;&lt;/h2&gt;
  &lt;p id=&quot;ES8X&quot;&gt;Поле &lt;code&gt;seq&lt;/code&gt; — 16-битный счётчик записей. Оно позволяет заметить потерю данных на USB или переполнение буфера.&lt;/p&gt;
  &lt;p id=&quot;8XKj&quot;&gt;Поскольку счётчик циклический, сравнение выполняется по модулю 2162^{16}216:&lt;/p&gt;
  &lt;pre id=&quot;0PEP&quot;&gt;def sequence_gap(previous, current):
    return (current - previous - 1) &amp;amp; 0xFFFF&lt;/pre&gt;
  &lt;p id=&quot;JeNR&quot;&gt;Практическая проверка:&lt;/p&gt;
  &lt;pre id=&quot;GclP&quot;&gt;gap = (record.seq - last_seq - 1) &amp;amp; 0xFFFF

if 0 &amp;lt; gap &amp;lt; 0x8000:
    dropped += gap&lt;/pre&gt;
  &lt;p id=&quot;wWXc&quot;&gt;Ограничение &lt;code&gt;gap &amp;lt; 0x8000&lt;/code&gt; нужно, чтобы отличать нормальное переполнение счётчика от большого обратного скачка.&lt;/p&gt;
  &lt;p id=&quot;jGpF&quot;&gt;В интерфейсе можно показывать:&lt;/p&gt;
  &lt;pre id=&quot;Sd1i&quot;&gt;[warning] потеряно записей: 12&lt;/pre&gt;
  &lt;p id=&quot;6So1&quot;&gt;Это особенно полезно при высокоскоростном логе, когда USB-порт, пользовательский процесс или внутренний буфер не успевают обработать весь поток.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;15&quot;&gt;15. Верификация&lt;/h2&gt;
  &lt;p id=&quot;EM1m&quot;&gt;Декодер необходимо проверять на двух уровнях.&lt;/p&gt;
  &lt;h2 id=&quot;oR4J&quot;&gt;Автономные тесты&lt;/h2&gt;
  &lt;p id=&quot;Unbt&quot;&gt;Полезно протестировать отдельно:&lt;/p&gt;
  &lt;ul id=&quot;ezl6&quot;&gt;
    &lt;li id=&quot;8Gqq&quot;&gt;разбор заголовка;&lt;/li&gt;
    &lt;li id=&quot;IifS&quot;&gt;length-framing;&lt;/li&gt;
    &lt;li id=&quot;AMFg&quot;&gt;повторную синхронизацию после мусора;&lt;/li&gt;
    &lt;li id=&quot;qezt&quot;&gt;инкрементальный &lt;code&gt;StreamParser&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;6Eqo&quot;&gt;TEXT-записи;&lt;/li&gt;
    &lt;li id=&quot;47sS&quot;&gt;&lt;code&gt;file:line&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;4BJP&quot;&gt;разбор MDB;&lt;/li&gt;
    &lt;li id=&quot;9Ihr&quot;&gt;&lt;code&gt;%S{...}&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;uOGj&quot;&gt;&lt;code&gt;%e{...}&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;rAzS&quot;&gt;16-битные аргументы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;cKzK&quot;&gt;В исходном проекте такой набор из девяти тестов проходит на синтетической базе и искусственно сформированных записях.&lt;/p&gt;
  &lt;h2 id=&quot;3dgQ&quot;&gt;Сквозная проверка&lt;/h2&gt;
  &lt;p id=&quot;izYy&quot;&gt;Затем необходимо проверить полный путь:&lt;/p&gt;
  &lt;pre id=&quot;5Aog&quot;&gt;A7665E
  → USB CP-log
  → StreamParser
  → MDB decoder
  → человекочитаемый вывод&lt;/pre&gt;
  &lt;p id=&quot;5uis&quot;&gt;В корректно декодированных сообщениях должны распознаваться, например:&lt;/p&gt;
  &lt;ul id=&quot;tSvn&quot;&gt;
    &lt;li id=&quot;P5e1&quot;&gt;&lt;code&gt;+ZDON&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;PGLL&quot;&gt;выбранная PLMN;&lt;/li&gt;
    &lt;li id=&quot;ZYBz&quot;&gt;serving cell;&lt;/li&gt;
    &lt;li id=&quot;JbUY&quot;&gt;RSRP и RSRQ;&lt;/li&gt;
    &lt;li id=&quot;j28R&quot;&gt;APN;&lt;/li&gt;
    &lt;li id=&quot;2awn&quot;&gt;IP-адрес;&lt;/li&gt;
    &lt;li id=&quot;gYrv&quot;&gt;события NAS и RRC;&lt;/li&gt;
    &lt;li id=&quot;xncU&quot;&gt;сообщения IPC между L1 и protocol stack.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;16&quot;&gt;16. Ограничения метода&lt;/h2&gt;
  &lt;p id=&quot;wdN1&quot;&gt;Даже при правильно найденном транспортном формате часть сообщений может оставаться неполностью декодированной.&lt;/p&gt;
  &lt;p id=&quot;WKFB&quot;&gt;Особенно важно различать ошибки разных уровней:&lt;/p&gt;
  &lt;pre id=&quot;JnVN&quot;&gt;неправильная длина записи
    → проблема транспортного парсера

правильная запись, но &amp;lt;?&amp;gt;
    → проблема формата или ширины аргумента

правильный текст, но неверные поля структуры
    → несовпадение Signals с конкретной прошивкой&lt;/pre&gt;
  &lt;p id=&quot;6NXp&quot;&gt;Транспортный формат при этом может быть полностью понятен, даже если семантическая расшифровка остаётся неполной.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;17&quot;&gt;17. Запуск декодера&lt;/h2&gt;
  &lt;p id=&quot;T3fE&quot;&gt;Примерный набор команд:&lt;/p&gt;
  &lt;pre id=&quot;Kj1K&quot;&gt;cd /home/sam/work/modems_debug/asr_debug&lt;/pre&gt;
  &lt;p id=&quot;ThEK&quot;&gt;Живой захват с автоматическим поиском порта:&lt;/p&gt;
  &lt;pre id=&quot;XL0x&quot;&gt;./asr_debug_monitor.py&lt;/pre&gt;
  &lt;p id=&quot;cRFI&quot;&gt;Разбор сохранённого файла:&lt;/p&gt;
  &lt;pre id=&quot;h8Cm&quot;&gt;./asr_debug_monitor.py \
    --replay boot_registration.bin&lt;/pre&gt;
  &lt;p id=&quot;qRL0&quot;&gt;Разбор terse-записей:&lt;/p&gt;
  &lt;pre id=&quot;YfcI&quot;&gt;./asr_debug_monitor.py \
    --replay boot_registration.bin \
    -t&lt;/pre&gt;
  &lt;p id=&quot;oHIg&quot;&gt;Вывод всех записей:&lt;/p&gt;
  &lt;pre id=&quot;QuAd&quot;&gt;./asr_debug_monitor.py \
    --replay boot_registration.bin \
    -a&lt;/pre&gt;
  &lt;p id=&quot;jhVH&quot;&gt;Использование точной базы:&lt;/p&gt;
  &lt;pre id=&quot;yD3T&quot;&gt;./asr_debug_monitor.py \
    -m /path/to/exact/cp_MDB.txt&lt;/pre&gt;
  &lt;p id=&quot;gXAP&quot;&gt;Для захвата, переживающего ребут модема, нужен внешний wrapper:&lt;/p&gt;
  &lt;ol id=&quot;r2E9&quot;&gt;
    &lt;li id=&quot;luXb&quot;&gt;дождаться появления нужного USB-интерфейса;&lt;/li&gt;
    &lt;li id=&quot;HBc7&quot;&gt;открыть порт;&lt;/li&gt;
    &lt;li id=&quot;oNsb&quot;&gt;отправить &lt;code&gt;AT+ECPLOG=1&lt;/code&gt;;&lt;/li&gt;
    &lt;li id=&quot;RCOp&quot;&gt;записывать необработанный поток;&lt;/li&gt;
    &lt;li id=&quot;Fk5F&quot;&gt;обнаружить исчезновение порта;&lt;/li&gt;
    &lt;li id=&quot;DaXC&quot;&gt;дождаться повторной USB-энумерации;&lt;/li&gt;
    &lt;li id=&quot;w0La&quot;&gt;открыть новую сессию в отдельном файле.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;DuEe&quot;&gt;Так можно захватывать загрузку модема с самого начала, даже если во время ребута меняются имена &lt;code&gt;ttyUSBx&lt;/code&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;x0s0&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;FRgz&quot;&gt;Распознавание бинарного CP-лога ASR состоит из нескольких независимых уровней:&lt;/p&gt;
  &lt;pre id=&quot;k5L8&quot;&gt;USB-порт
  → AT+ECPLOG=1
  → length-framing
  → 16-байтный заголовок
  → msg_type + fmt_id
  → база форматных строк
  → декодирование printf-аргументов
  → структуры, enum и timestamp
  → читаемый трейс&lt;/pre&gt;
  &lt;p id=&quot;hX32&quot;&gt;Самая важная практическая находка — нестандартная упаковка аргументов: обычные &lt;code&gt;%d&lt;/code&gt;, &lt;code&gt;%u&lt;/code&gt; и &lt;code&gt;%x&lt;/code&gt; в terse-сообщениях ASR занимают 2 байта, а &lt;code&gt;%l...&lt;/code&gt; — 4 байта. Без этого правила идентификаторы сообщений могут находиться правильно, но значения будут «плыть», а декодер будет регулярно выдавать &lt;code&gt;&amp;lt;?&amp;gt;&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;0WEU&quot;&gt;Второй важный вывод — транспорт и семантику нужно разрабатывать отдельно. Формат записи можно восстановить и протестировать независимо от базы. А база, в свою очередь, может заменяться без изменений в протоколе и потоковом парсере.&lt;/p&gt;
  &lt;p id=&quot;xDt1&quot;&gt;Для полного покрытия остаётся получить точную &lt;code&gt;cp_MDB.txt&lt;/code&gt; под прошивку &lt;code&gt;A7665M5_B01V01&lt;/code&gt;. После этого должны исчезнуть ошибки в больших структурах, неизвестные enum и большая часть необработанных бинарных хвостов.&lt;/p&gt;

</content></entry><entry><id>pole_sam:CAcPKudWlw4</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/CAcPKudWlw4?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Как используются данные SIM‑карты в GSM (2G): аутентификация, ключи, IMSI, A3/A8</title><published>2026-08-15T18:36:57.708Z</published><updated>2026-08-15T18:36:57.708Z</updated><summary type="html">Всем привет! В GSM (2G) SIM‑карта хранит постоянный секретный ключ абонента Ki и идентификатор IMSI; при регистрации в сети используется механизм «вызов‑ответ»: сеть посылает случайное число RAND, SIM вычисляет подписанный ответ SRES = A3(Ki, RAND) и сеансовый ключ шифрования Kc = A8(Ki, RAND), после чего сеть проверяет SRES и при успехе включает шифрование A5.</summary><content type="html">
  &lt;p id=&quot;VDme&quot;&gt;Всем привет! В GSM (2G) SIM‑карта хранит постоянный секретный ключ абонента Ki и идентификатор IMSI; при регистрации в сети используется механизм «вызов‑ответ»: сеть посылает случайное число RAND, SIM вычисляет подписанный ответ SRES = A3(Ki, RAND) и сеансовый ключ шифрования Kc = A8(Ki, RAND), после чего сеть проверяет SRES и при успехе включает шифрование A5.&lt;/p&gt;
  &lt;p id=&quot;uy4r&quot;&gt;&lt;strong&gt;Важно: Ki никогда не передаётся по радиоинтерфейсу и не выводится из SIM; вся криптография «вызов‑ответ» выполняется внутри SIM.jucs+2&lt;/strong&gt;&lt;/p&gt;
  &lt;h2 id=&quot;2&quot;&gt;2. Роли сетевых элементов (кратко)&lt;/h2&gt;
  &lt;ul id=&quot;Qrmv&quot;&gt;
    &lt;li id=&quot;dzx6&quot;&gt;MS (Mobile Station) = ME (телефон) + SIM.&lt;/li&gt;
    &lt;li id=&quot;HqES&quot;&gt;BTS/BSC — радиодоступ.&lt;/li&gt;
    &lt;li id=&quot;eIA2&quot;&gt;MSC/VLR — коммутация и локальное управление сессиями; VLR хранит «триплеты» аутентификации для абонента.&lt;/li&gt;
    &lt;li id=&quot;hRa0&quot;&gt;HLR — домашний реестр абонентов.&lt;/li&gt;
    &lt;li id=&quot;ANBL&quot;&gt;AuC (Authentication Center) — генерирует RAND, SRES, Kc (триплеты) на основе IMSI и Ki.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;3---gsm-2g&quot;&gt;3. Протокол аутентификации GSM (2G): пошагово&lt;/h2&gt;
  &lt;p id=&quot;VB6Q&quot;&gt;Ниже — упрощённая последовательность при регистрации/доступе к услугам.&lt;/p&gt;
  &lt;pre id=&quot;qj9P&quot;&gt;text[MS/SIM]                         [MSC/VLR]                         [HLR/AuC]
    |                                |                                |
    | 1. Location Update / CM Service Request (IMSI или TMSI)         |
    |---------------------------------------------------------------&amp;gt;|
    |                                | 2. Запрос триплетов для IMSI   |
    |                                |------------------------------&amp;gt;|
    |                                | 3. Возврат N триплетов         |
    |                                | (RAND_i, SRES_i, Kc_i)         |
    |                                |&amp;lt;------------------------------|
    |                                |                                |
    | 4. AUTHENTICATION REQUEST      |                                |
    |    (RAND)                      |                                |
    |&amp;lt;-------------------------------|                                |
    | 5. SIM: SRES&amp;#x27; = A3(Ki, RAND)   |                                |
    |     Kc&amp;#x27;   = A8(Ki, RAND)       |                                |
    | 6. AUTHENTICATION RESPONSE     |                                |
    |    (SRES&amp;#x27;)                     |                                |
    |------------------------------&amp;gt;|                                |
    |                                | 7. Проверка: SRES&amp;#x27; == SRES?    |
    |                                |    Если да → аутентификация OK |
    | 8. Cipher Mode Command (A5/x)  |                                |
    |&amp;lt;-------------------------------|                                |
    | 9. Включение шифрования A5/x с Kc&amp;#x27;                               |
    |&amp;lt;================================================================&amp;gt;|&lt;/pre&gt;
  &lt;p id=&quot;r1XJ&quot;&gt;Ключевые моменты:&lt;/p&gt;
  &lt;ul id=&quot;JYUI&quot;&gt;
    &lt;li id=&quot;w02J&quot;&gt;Сеть заранее получает от AuC «триплеты» (RAND, SRES, Kc) для данного IMSI; при аутентификации она посылает только RAND.&lt;/li&gt;
    &lt;li id=&quot;3MKM&quot;&gt;SIM вычисляет SRES&amp;#x27; и Kc&amp;#x27; по тем же формулам; VLR сравнивает SRES&amp;#x27; с ожидаемым SRES.&lt;/li&gt;
    &lt;li id=&quot;loVT&quot;&gt;После успеха сеть инициирует Cipher Mode Command и далее трафик шифруется A5/x с ключом Kc.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;4--a3--a8&quot;&gt;4. Алгоритмы A3 и A8: что именно считается&lt;/h2&gt;
  &lt;p id=&quot;SMqY&quot;&gt;Формально стандарт GSM не фиксирует одну конкретную реализацию A3/A8; операторы выбирают алгоритм (часто COMP128‑1/2/3, milenage‑подобные варианты в 2G‑совместимых реализациях и др.).&lt;/p&gt;
  &lt;ul id=&quot;w5zA&quot;&gt;
    &lt;li id=&quot;kg76&quot;&gt;A3: SRES = A3(Ki, RAND) → 32‑битный ответ.&lt;/li&gt;
    &lt;li id=&quot;fNwD&quot;&gt;A8: Kc = A8(Ki, RAND) → 64‑битный сеансовый ключ для A5/x.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;niDa&quot;&gt;На практике A3 и A8 часто реализованы как единая функция, выдающая (SRES, Kc) из (Ki, RAND).&lt;/p&gt;
  &lt;h2 id=&quot;5--imsi&quot;&gt;5. Роль IMSI и почему он важен&lt;/h2&gt;
  &lt;ul id=&quot;MVE8&quot;&gt;
    &lt;li id=&quot;AHqq&quot;&gt;IMSI используется для идентификации абонента в HLR/AuC и получения правильного Ki (и триплетов).&lt;/li&gt;
    &lt;li id=&quot;LHax&quot;&gt;При первой регистрации в новой зоне MS обычно передаёт IMSI (если нет валидного TMSI), что делает IMSI видимым для любой базовой станции в радиусе.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ul id=&quot;v2Yb&quot;&gt;
    &lt;li id=&quot;5NY1&quot;&gt;В дальнейшем сеть старается использовать TMSI вместо IMSI для конфиденциальности, но IMSI всё равно может быть запрошен (например, при сбоях или специальных процедурах).&lt;/li&gt;
    &lt;li id=&quot;qoc1&quot;&gt;TMSI (Temporary Mobile Subscriber Identity) — это временный идентификатор абонента, который сеть выдаёт мобильному устройству после успешной регистрации, чтобы вместо постоянного IMSI использовать его в радиоканале для повышения конфиденциальности.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;6---gsm-2g---sim&quot;&gt;6. Риски безопасности GSM (2G), связанные с SIM и аутентификацией&lt;/h2&gt;
  &lt;p id=&quot;rEuK&quot;&gt;GSM (2G) имеет ряд фундаментальных ограничений, которые напрямую касаются использования данных SIM:&lt;/p&gt;
  &lt;ol id=&quot;Pgy3&quot;&gt;
    &lt;li id=&quot;uoRn&quot;&gt;&lt;strong&gt;Односторонняя аутентификация&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;Df8A&quot;&gt;
      &lt;li id=&quot;4473&quot;&gt;Сеть аутентифицирует телефон (MS), но телефон не аутентифицирует сеть.&lt;/li&gt;
      &lt;li id=&quot;Aoyn&quot;&gt;Это позволяет IMSI‑catcher&amp;#x27;у (фейковой базовой станции) притворяться «легальной» сетью: телефон отправляет IMSI/TMSI, проходит «аутентификацию» у злоумышленника, а трафик может не шифроваться или шифроваться слабым алгоритмом.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;xPOc&quot;&gt;&lt;strong&gt;Слабость шифрования A5/1 (и A5/2)&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;YwyZ&quot;&gt;
      &lt;li id=&quot;WKaj&quot;&gt;A5/1 (64‑битный ключ Kc) уязвим к атакам по заранее вычисленным таблицам (rainbow tables); практическая расшифровка возможна за секунды–минуты на обычном железе.&lt;/li&gt;
      &lt;li id=&quot;LNgs&quot;&gt;A5/2 ещё слабее и практически не защищает.&lt;/li&gt;
      &lt;li id=&quot;TBQc&quot;&gt;Злоумышленник может принудительно переключить сессию на A5/0 (без шифрования) или слабый A5/x.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;ANCp&quot;&gt;&lt;strong&gt;Зависимость от реализации A3/A8&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;9YIl&quot;&gt;
      &lt;li id=&quot;n2TF&quot;&gt;Ранние популярные реализации (например, COMP128‑1) имели криптографические слабости, позволяющие при достаточном числе запросов извлекать Ki.&lt;/li&gt;
      &lt;li id=&quot;XaXw&quot;&gt;Даже при более стойких A3/A8, 32‑битный SRES и 64‑битный Kc ограничивают криптостойкость по современным меркам.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;v3LU&quot;&gt;&lt;strong&gt;Перехват IMSI&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;k8J8&quot;&gt;
      &lt;li id=&quot;XMVy&quot;&gt;Поскольку IMSI передаётся в открытом виде при первой регистрации, IMSI‑catcher может собирать IMSI всех устройств в зоне покрытия.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;VwaX&quot;&gt;Эти ограничения — причина, по которой в 3G/4G/5G введена взаимная аутентификация (сеть тоже доказывается абоненту), более длинные ответы (RES вместо SRES), ключи CK/IK и более стойкие алгоритмы (Milenage, AES‑based и др.).&lt;/p&gt;
  &lt;h2 id=&quot;7----sim&quot;&gt;7. Сводная схема «данные SIM → параметры сессии»&lt;/h2&gt;
  &lt;pre id=&quot;6q7I&quot;&gt;textSIM (Ki, IMSI, A3/A8)
       │
       │ IMSI → HLR/AuC → выбор Ki
       │
       └─► AuC: для каждого RAND_i
               SRES_i = A3(Ki, RAND_i)
               Kc_i   = A8(Ki, RAND_i)
               триплет (RAND_i, SRES_i, Kc_i) → VLR

При аутентификации:
  VLR → MS: RAND
  SIM: SRES&amp;#x27; = A3(Ki, RAND)
       Kc&amp;#x27;   = A8(Ki, RAND)
  MS → VLR: SRES&amp;#x27;
  VLR: если SRES&amp;#x27; == SRES → OK, шифрование A5/x с Kc&amp;#x27;&lt;/pre&gt;
  &lt;hr /&gt;

</content></entry><entry><id>pole_sam:MUgk4kD28C5</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/MUgk4kD28C5?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>Данные вещательных каналов сотовой вышки (2G/GSM и LTE): что можно получить и как декодировать</title><published>2026-08-03T07:11:42.451Z</published><updated>2026-08-03T07:11:42.451Z</updated><summary type="html">Сотовая вышка (BTS в 2G, eNodeB в LTE) непрерывно передаёт в эфир «системную информацию» — набор параметров, которые нужны телефону (UE), чтобы обнаружить сеть, синхронизироваться и подготовиться к подключению. Это не «перехват трафика» — это открытые широковещательные (broadcast) данные, которые предназначены для приёма всеми устройствами в зоне покрытия. Их декодирование полностью пассивно, законно в большинстве юрисдикций и не затрагивает трафик абонентов.</summary><content type="html">
  &lt;p id=&quot;aRmQ&quot;&gt;Сотовая вышка (BTS в 2G, eNodeB в LTE) непрерывно передаёт в эфир «системную информацию» — набор параметров, которые нужны телефону (UE), чтобы обнаружить сеть, синхронизироваться и подготовиться к подключению. Это не «перехват трафика» — это открытые широковещательные (broadcast) данные, которые предназначены для приёма всеми устройствами в зоне покрытия. Их декодирование полностью пассивно, законно в большинстве юрисдикций и не затрагивает трафик абонентов.&lt;/p&gt;
  &lt;p id=&quot;ytlS&quot;&gt;Ниже — какие каналы есть, что они несут и что из этого можно понять о вышке и сети.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;1&quot;&gt;1. Что вообще вещает вышка&lt;/h2&gt;
  &lt;p id=&quot;MJ6S&quot;&gt;Любая вышка передаёт на нисходящей частоте (downlink) набор логических каналов. Для пассивного наблюдателя важны два класса:&lt;/p&gt;
  &lt;ul id=&quot;35bH&quot;&gt;
    &lt;li id=&quot;jnhI&quot;&gt;&lt;strong&gt;Каналы синхронизации&lt;/strong&gt; — позволяют обнаружить сигнал, получить тайминг и идентификатор соты.&lt;/li&gt;
    &lt;li id=&quot;WETF&quot;&gt;&lt;strong&gt;Вещательные каналы&lt;/strong&gt; (BCCH в 2G, BCH/DL-SCH в LTE) — несут системную информацию (System Information) с параметрами сети.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;o79B&quot;&gt;Телефон при включении делает ровно то же самое: ищет сигнал синхронизации, читает системную информацию и решает, можно ли подключиться. С помощью SDR (Software Defined Radio) и открытых инструментов этот процесс можно повторить без телефона.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;2-gsm-2g&quot;&gt;2. GSM (2G)&lt;/h2&gt;
  &lt;h2 id=&quot;4okX&quot;&gt;Каналы и сообщения&lt;/h2&gt;
  &lt;p id=&quot;J1Kn&quot;&gt;Вещательные данные GSM передаются на &lt;strong&gt;BCCH&lt;/strong&gt; (Broadcast Control Channel), который передаётся непрерывно и служит стабильным опорным «маяком» соты. Основное содержимое BCCH — это сообщения &lt;strong&gt;System Information (SI)&lt;/strong&gt;, описанные в &lt;a href=&quot;https://www.etsi.org/deliver/etsi_ts/144000_144099/144018/17.00.00_60/ts_144018v170000p.pdf&quot; target=&quot;_blank&quot;&gt;ETSI TS 144 018&lt;/a&gt; (3GPP TS 44.018). &lt;/p&gt;
  &lt;h2 id=&quot;bcch&quot;&gt;Что можно извлечь из BCCH&lt;/h2&gt;
  &lt;ul id=&quot;4uKZ&quot;&gt;
    &lt;li id=&quot;Llja&quot;&gt;&lt;strong&gt;MCC&lt;/strong&gt; (Mobile Country Code) — страна оператора&lt;/li&gt;
    &lt;li id=&quot;R8mq&quot;&gt;&lt;strong&gt;MNC&lt;/strong&gt; (Mobile Network Code) — сам оператор&lt;/li&gt;
    &lt;li id=&quot;qBqZ&quot;&gt;&lt;strong&gt;LAC&lt;/strong&gt; (Location Area Code) — код зоны местоположения&lt;/li&gt;
    &lt;li id=&quot;gMDE&quot;&gt;&lt;strong&gt;Cell ID (CI)&lt;/strong&gt; — идентификатор соты → вместе с MCC+MNC+LAC+CI образует &lt;strong&gt;CGI&lt;/strong&gt; (Cell Global Identity)&lt;/li&gt;
    &lt;li id=&quot;qGAb&quot;&gt;&lt;strong&gt;ARFCN&lt;/strong&gt; — номер радиоканала → пересчитывается в частоту&lt;/li&gt;
    &lt;li id=&quot;ZhGq&quot;&gt;&lt;strong&gt;BSIC&lt;/strong&gt; (Base Station Identity Code) — цветовой код вышки&lt;/li&gt;
    &lt;li id=&quot;CDVM&quot;&gt;&lt;strong&gt;CCCH конфигурация&lt;/strong&gt; — сколько каналов paging, AGCH и т.д.&lt;/li&gt;
    &lt;li id=&quot;Kqfb&quot;&gt;&lt;strong&gt;Параметры RACH&lt;/strong&gt; — как телефону запрашивать доступ&lt;/li&gt;
    &lt;li id=&quot;SF4w&quot;&gt;&lt;strong&gt;Параметры выбора соты&lt;/strong&gt; — минимальный уровень приёма (C1/C2), приоритеты&lt;/li&gt;
    &lt;li id=&quot;yuDJ&quot;&gt;&lt;strong&gt;Список соседей&lt;/strong&gt; — частоты соседних сот (для handover/reselection)&lt;/li&gt;
    &lt;li id=&quot;qVYn&quot;&gt;&lt;strong&gt;Признак GPRS/EDGE&lt;/strong&gt; — поддерживает ли сота пакетную передачу&lt;/li&gt;
    &lt;li id=&quot;dznm&quot;&gt;&lt;strong&gt;Cell Barring&lt;/strong&gt; — заблокирована ли сота для доступа&lt;/li&gt;
    &lt;li id=&quot;KGy2&quot;&gt;&lt;strong&gt;Информация о 3G-соседях&lt;/strong&gt; — частоты UMTS&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;pvZR&quot;&gt;Синхронизация&lt;/h2&gt;
  &lt;p id=&quot;0KwF&quot;&gt;До чтения BCCH нужно сначала найти сигнал. В GSM для этого служат:&lt;/p&gt;
  &lt;ul id=&quot;GAA5&quot;&gt;
    &lt;li id=&quot;sECW&quot;&gt;&lt;strong&gt;FCCH&lt;/strong&gt; (Frequency Correction Channel) — чистый синус на фиксированном смещении, позволяет подстроить частоту приёмника.&lt;/li&gt;
    &lt;li id=&quot;faTb&quot;&gt;&lt;strong&gt;SCH&lt;/strong&gt; (Synchronisation Channel) — несёт &lt;strong&gt;BSIC&lt;/strong&gt; и номер кадра, позволяет выровнять тайминг.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;3-lte-4g&quot;&gt;3. LTE (4G)&lt;/h2&gt;
  &lt;h2 id=&quot;YrkS&quot;&gt;Каналы и сообщения&lt;/h2&gt;
  &lt;p id=&quot;bWmS&quot;&gt;В LTE системная информация разделена на &lt;strong&gt;MIB&lt;/strong&gt; (Master Information Block) и набор &lt;strong&gt;SIB&lt;/strong&gt; (System Information Blocks), описанные в &lt;a href=&quot;https://www.3glteinfo.com/messages/lte/lte-rrc/&quot; target=&quot;_blank&quot;&gt;3GPP TS 36.331&lt;/a&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;mib&quot;&gt;MIB&lt;/h2&gt;
  &lt;p id=&quot;9cBk&quot;&gt;Передаётся на &lt;strong&gt;PBCH&lt;/strong&gt; (Physical Broadcast Channel) с периодичностью 40 мс (с повторениями каждые 10 мс). Содержит самый минимум:&lt;/p&gt;
  &lt;ul id=&quot;mRpc&quot;&gt;
    &lt;li id=&quot;XPzT&quot;&gt;&lt;strong&gt;DL Bandwidth&lt;/strong&gt; соты (в числе Resource Blocks: 1.4 / 3 / 5 / 10 / 15 / 20 МГц)&lt;/li&gt;
    &lt;li id=&quot;qkIW&quot;&gt;&lt;strong&gt;PHICH&lt;/strong&gt; конфигурация&lt;/li&gt;
    &lt;li id=&quot;TSb4&quot;&gt;&lt;strong&gt;SFN&lt;/strong&gt; (System Frame Number)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;sib1&quot;&gt;SIB1&lt;/h2&gt;
  &lt;p id=&quot;zNrI&quot;&gt;Передаётся на DL-SCH с периодичностью 80 мс (с повторениями). Несёт:&lt;/p&gt;
  &lt;ul id=&quot;S5JF&quot;&gt;
    &lt;li id=&quot;zkK3&quot;&gt;&lt;strong&gt;PLMN identity list&lt;/strong&gt; (MCC+MNC, может быть несколько)&lt;/li&gt;
    &lt;li id=&quot;DWYU&quot;&gt;&lt;strong&gt;Tracking Area Code (TAC)&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;sYoX&quot;&gt;&lt;strong&gt;Cell Identity&lt;/strong&gt; — 28-битный E-UTRAN Cell Identifier (ECI). В макросетях часто раскладывается на eNodeB ID (старшие 20 бит) и локальный/секторный Cell ID (младшие 8 бит), но это не универсальное правило&lt;/li&gt;
    &lt;li id=&quot;HegO&quot;&gt;&lt;strong&gt;Cell bar status&lt;/strong&gt; (доступна ли сота)&lt;/li&gt;
    &lt;li id=&quot;1Pxm&quot;&gt;&lt;strong&gt;Cell selection info&lt;/strong&gt; (минимальный требуемый уровень приёма, Q-RxLevMin)&lt;/li&gt;
    &lt;li id=&quot;mnBe&quot;&gt;&lt;strong&gt;p-Max&lt;/strong&gt; — максимальная разрешённая мощность UE&lt;/li&gt;
    &lt;li id=&quot;e262&quot;&gt;&lt;strong&gt;Frequency band indicator&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;iTlj&quot;&gt;&lt;strong&gt;TDD конфигурация&lt;/strong&gt; (если TDD)&lt;/li&gt;
    &lt;li id=&quot;Schg&quot;&gt;&lt;strong&gt;SI-window length&lt;/strong&gt; и &lt;strong&gt;schedulingInfoList&lt;/strong&gt; — расписание остальных SIB&lt;/li&gt;
    &lt;li id=&quot;14cD&quot;&gt;&lt;strong&gt;System info value tag&lt;/strong&gt; — версия информации&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;sib&quot;&gt;Остальные SIB&lt;/h2&gt;
  &lt;p id=&quot;6Nh1&quot;&gt;Передаются в сообщениях SystemInformation (SI) по расписанию из SIB1:&lt;/p&gt;
  &lt;p id=&quot;V15w&quot;&gt;&lt;strong&gt;SIB2&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;kzvV&quot;&gt;Общая конфигурация радио: параметры RACH, PRACH, UL-частота, ширина UL-канала&lt;/p&gt;
  &lt;p id=&quot;HXGN&quot;&gt;&lt;strong&gt;SIB3&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;smxn&quot;&gt;Параметры reselection внутри той же частоты&lt;/p&gt;
  &lt;p id=&quot;m5Uu&quot;&gt;&lt;strong&gt;SIB4&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Nc2Q&quot;&gt;Информация о соседях intra-frequency&lt;/p&gt;
  &lt;p id=&quot;VVSn&quot;&gt;&lt;strong&gt;SIB5&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;AlF6&quot;&gt;Информация о соседях inter-frequency (другие частоты LTE)&lt;/p&gt;
  &lt;p id=&quot;2s0k&quot;&gt;&lt;strong&gt;SIB6&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;pT1W&quot;&gt;Информация о соседях 3G (UTRA)&lt;/p&gt;
  &lt;p id=&quot;32EY&quot;&gt;&lt;strong&gt;SIB7&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;MbiJ&quot;&gt;Информация о соседях 2G (GERAN)&lt;/p&gt;
  &lt;p id=&quot;CEze&quot;&gt;&lt;strong&gt;SIB8&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;CaL0&quot;&gt;Информация о соседях CDMA2000&lt;/p&gt;
  &lt;p id=&quot;XVyR&quot;&gt;&lt;strong&gt;SIB9&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;9De5&quot;&gt;Home eNodeB identifier (femtocell)&lt;/p&gt;
  &lt;p id=&quot;CqlW&quot;&gt;&lt;strong&gt;SIB10&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;IPfu&quot;&gt;ETWS — первичное уведомление (Earthquake &amp;amp; Tsunami Warning)&lt;/p&gt;
  &lt;p id=&quot;MJCC&quot;&gt;&lt;strong&gt;SIB11&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;7udv&quot;&gt;ETWS — вторичное уведомление&lt;/p&gt;
  &lt;p id=&quot;gsFi&quot;&gt;&lt;strong&gt;SIB12&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;WhPS&quot;&gt;CMAS — коммерческие предупреждения (Cell Broadcast)&lt;/p&gt;
  &lt;p id=&quot;JZCV&quot;&gt;&lt;strong&gt;SIB13&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;a3oO&quot;&gt;MBMS/MBSFN-конфигурация&lt;/p&gt;
  &lt;p id=&quot;iGBQ&quot;&gt;&lt;strong&gt;SIB14&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;AX3y&quot;&gt;Extended Access Barring (EAB)&lt;/p&gt;
  &lt;p id=&quot;bJB2&quot;&gt;&lt;strong&gt;SIB15&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;V0tN&quot;&gt;MBMS Service Area Info&lt;/p&gt;
  &lt;p id=&quot;DuMz&quot;&gt;&lt;strong&gt;SIB16&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;uNqO&quot;&gt;Информация о времени (GPS/UTC)&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;4&quot;&gt;4. Как это декодируется на практике (концептуальный пайплайн)&lt;/h2&gt;
  &lt;pre id=&quot;A4JK&quot;&gt;textSDR-приёмник (I/Q) → настройка на частоту → синхронизация → демодуляция → L2/L3 декодирование → Wireshark / ASN.1&lt;/pre&gt;
  &lt;h2 id=&quot;gsm-2g&quot;&gt;Инструменты для GSM (2G)&lt;/h2&gt;
  &lt;ul id=&quot;R95X&quot;&gt;
    &lt;li id=&quot;5MoA&quot;&gt;&lt;strong&gt;gr-gsm&lt;/strong&gt; (GNU Radio GSM decoder) — основной инструмент. Компоненты:&lt;/li&gt;
    &lt;ul id=&quot;ZXLZ&quot;&gt;
      &lt;li id=&quot;01gM&quot;&gt;&lt;code&gt;grgsm_scanner&lt;/code&gt; — сканирование эфира, поиск вышек, вывод ARFCN, BSIC, Cell ID&lt;/li&gt;
      &lt;li id=&quot;xGyf&quot;&gt;&lt;code&gt;grgsm_capture&lt;/code&gt; — запись сигнала в .cfile&lt;/li&gt;
      &lt;li id=&quot;NTUX&quot;&gt;&lt;code&gt;grgsm_decode&lt;/code&gt; — декодирование BCCH, SDCCH и др. → GSMTAP в Wireshark&lt;/li&gt;
      &lt;li id=&quot;aj9f&quot;&gt;&lt;code&gt;grgsm_livemon&lt;/code&gt; — интерактивный мониторинг одного канала в реальном времени&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;GIBQ&quot;&gt;&lt;strong&gt;Wireshark&lt;/strong&gt; — анализ декодированных пакетов с фильтром &lt;code&gt;gsmtap&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;jqwn&quot;&gt;&lt;strong&gt;DragonOS&lt;/strong&gt; — готовый Linux-дистрибутив со всем предустановленным&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;BNT1&quot;&gt;(&lt;a href=&quot;https://github.com/ptrkrysik/gr-gsm/wiki/Usage:-Decoding-How-To&quot; target=&quot;_blank&quot;&gt;gr-gsm Wiki: Usage&lt;/a&gt;, &lt;a href=&quot;https://www.rtl-sdr.com/rtl-sdr-tutorial-analyzing-gsm-with-airprobe-and-wireshark/comment-page-1/&quot; target=&quot;_blank&quot;&gt;RTL-SDR Tutorial&lt;/a&gt;)&lt;/p&gt;
  &lt;h2 id=&quot;lte-4g&quot;&gt;Инструменты для LTE (4G)&lt;/h2&gt;
  &lt;ul id=&quot;hgFk&quot;&gt;
    &lt;li id=&quot;gIB0&quot;&gt;&lt;strong&gt;srsRAN&lt;/strong&gt; (бывший srsLTE) — открытый стек 4G/5G. Утилита &lt;code&gt;cell_search&lt;/code&gt; находит соты и получает параметры из MIB; для декодирования SIB нужны специальные receive-only конфигурации/примеры srsRAN, LTE-Cell-Scanner или обёртки вроде lte-sib-parser. &lt;code&gt;srsue&lt;/code&gt; в режиме только приёма может парсить SIB2–SIB6.&lt;/li&gt;
    &lt;li id=&quot;bgOg&quot;&gt;&lt;strong&gt;LTE-Cell-Scanner&lt;/strong&gt; — OpenCL-ускоренный сканер от JiaoXianjun: от I/Q-сэмплов до SIB-сообщений в ASN.1. Поддерживает FDD и TDD, RTL-SDR/HackRF/BladeRF.&lt;/li&gt;
    &lt;li id=&quot;jAFF&quot;&gt;&lt;strong&gt;lte-sib-parser&lt;/strong&gt; — обёртка над cell_search и srsue для рекурсивного сканирования по SIB5.&lt;/li&gt;
    &lt;li id=&quot;T7cP&quot;&gt;&lt;strong&gt;free5GRAN&lt;/strong&gt; — для 5G NR (MIB + SIB1).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;PiUa&quot;&gt;(&lt;a href=&quot;https://github.com/JiaoXianjun/LTE-Cell-Scanner&quot; target=&quot;_blank&quot;&gt;LTE-Cell-Scanner на GitHub&lt;/a&gt;, &lt;a href=&quot;https://docs.srsran.com/projects/4g/en/latest/app_notes/source/nbiot/source/index.html&quot; target=&quot;_blank&quot;&gt;srsRAN docs&lt;/a&gt;, &lt;a href=&quot;https://github.com/godfuzz3r/lte-sib-parser&quot; target=&quot;_blank&quot;&gt;lte-sib-parser&lt;/a&gt;)&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;5&quot;&gt;&lt;strong&gt;Что это даёт на практике&lt;/strong&gt;&lt;/h2&gt;
  &lt;ul id=&quot;vOM0&quot;&gt;
    &lt;li id=&quot;sOp2&quot;&gt;&lt;strong&gt;Идентификация оператора и страны&lt;/strong&gt; по MCC+MNC.&lt;/li&gt;
    &lt;li id=&quot;NUfU&quot;&gt;&lt;strong&gt;Картирование покрытия&lt;/strong&gt; — зная Cell ID + частоту + уровень сигнала, можно составить карту расположения и охвата базовых станций (без доступа к базам операторов). Сторонние проекты вроде &lt;a href=&quot;https://opencellid.org&quot; target=&quot;_blank&quot;&gt;OpenCelliD&lt;/a&gt; и &lt;a href=&quot;https://cellmapper.net&quot; target=&quot;_blank&quot;&gt;CellMapper&lt;/a&gt; агрегируют именно такие данные.&lt;/li&gt;
    &lt;li id=&quot;PAqV&quot;&gt;&lt;strong&gt;Понимание топологии сети&lt;/strong&gt; — какие соты являются соседями, какие частоты используются в зоне, какие поколения (2G/3G/LTE) присутствуют.&lt;/li&gt;
    &lt;li id=&quot;3Cwh&quot;&gt;&lt;strong&gt;Оценка нагрузки&lt;/strong&gt; — косвенно, по количеству paging-сообщений (но это уже не чисто broadcast, аpaging-канал, требующий чуть более активного прослушивания CCCH).&lt;/li&gt;
    &lt;li id=&quot;lcAw&quot;&gt;&lt;strong&gt;Проверка конфигурации&lt;/strong&gt; — для исследовательских и образовательных целей: какая ширина канала, какие параметры RACH, закрыта ли сота и т.д.&lt;/li&gt;
    &lt;li id=&quot;tQJB&quot;&gt;&lt;strong&gt;Косвенная оценка активности&lt;/strong&gt; — по объёму paging-трафика можно грубо судить о нагрузке, но это не системная информация и не позволяет отслеживать конкретных абонентов.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;6---broadcast&quot;&gt;6. Чего из broadcast-данных получить нельзя&lt;/h2&gt;
  &lt;p id=&quot;HGWU&quot;&gt;Важно зафиксировать границы:&lt;/p&gt;
  &lt;ul id=&quot;feIE&quot;&gt;
    &lt;li id=&quot;GVDG&quot;&gt;&lt;strong&gt;GPS-координаты вышки&lt;/strong&gt; не передаются в эфир. Координаты можно определить только косвенно — по триангуляции сигнала или по внешним базам данных (OpenCelliD).&lt;/li&gt;
    &lt;li id=&quot;RBrj&quot;&gt;&lt;strong&gt;Содержимое звонков, SMS и интернет-трафика&lt;/strong&gt; — не относится к broadcast и может быть зашифровано. В GSM может использоваться A5/0 (без шифрования), A5/1 или A5/3; в LTE — SNOW 3G или AES. Перехват и расшифровка трафика выходят за рамки данной заметки.&lt;/li&gt;
    &lt;li id=&quot;NgN6&quot;&gt;&lt;strong&gt;IMSI абонентов&lt;/strong&gt; не передаётся в broadcast/System Information. В 2G/3G/LTE постоянный идентификатор может появляться в отдельных процедурах идентификации до установления защиты, но это не вещательные данные. В 5G для этого используется SUCI.&lt;/li&gt;
    &lt;li id=&quot;DYr9&quot;&gt;&lt;strong&gt;Точная нагрузка/количество абонентов&lt;/strong&gt; — broadcast не несёт такой информации. Paging-канал может дать лишь грубую оценку совокупной активности сети и не является средством отслеживания конкретных абонентов.&lt;/li&gt;
    &lt;li id=&quot;VE1L&quot;&gt;&lt;strong&gt;Точное местоположение абонента&lt;/strong&gt; — требует данных из ядра сети (core network) или активного слежения за конкретным устройством, что выходит далеко за рамки пассивного декодирования вещательных каналов.&lt;/li&gt;
  &lt;/ul&gt;

</content></entry><entry><id>pole_sam:t8AbMPpD8pM</id><link rel="alternate" type="text/html" href="https://teletype.in/@pole_sam/t8AbMPpD8pM?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=pole_sam"></link><title>POLQA и с чем его едят</title><published>2026-07-18T18:53:47.479Z</published><updated>2026-07-18T18:55:25.883Z</updated><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/89/f5/89f55740-20d0-46f0-846c-51831fb28972.png&quot;&gt;Привет всем! Сегодня постараюсь рассказать о POLQA.
POLQA расшифровывается как Perceptual Objective Listening Quality Analysis. Это full-reference метод: он сравнивает эталонный речевой сигнал с ухудшенной версией после прохождения через сеть, кодек или устройство, а затем вычисляет оценку, близкую к MOS — Mean Opinion Score. Проще говоря, POLQA пытается математически смоделировать то, как человеческое ухо и восприятие оценивают качество речи.</summary><content type="html">
  &lt;p id=&quot;gnUR&quot;&gt;Привет всем! Сегодня постараюсь рассказать о POLQA.&lt;br /&gt;POLQA расшифровывается как &lt;em&gt;Perceptual Objective Listening Quality Analysis&lt;/em&gt;. Это full-reference метод: он сравнивает эталонный речевой сигнал с ухудшенной версией после прохождения через сеть, кодек или устройство, а затем вычисляет оценку, близкую к MOS — Mean Opinion Score. Проще говоря, POLQA пытается математически смоделировать то, как человеческое ухо и восприятие оценивают качество речи.&lt;/p&gt;
  &lt;h3 id=&quot;kHVZ&quot;&gt;&lt;br /&gt;&lt;strong&gt;Зачем он нужен&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;dx8b&quot;&gt;Главная ценность POLQA в том, что он помогает измерять качество голоса &lt;strong&gt;воспроизводимо и сравнимо&lt;/strong&gt; между лабораториями, устройствами и сценариями тестирования. Его используют для бенчмаркинга сетей, проверки кодеков, оптимизации VoIP/VoLTE и диагностики проблем с голосом в канале связи. Это особенно важно, когда качество портят не только потери пакетов, но и джиттер, компенсация задержек, time-scaling, шумоподавление и другие современные механизмы обработки.&lt;/p&gt;
  &lt;h3 id=&quot;X2PH&quot;&gt;&lt;br /&gt;Что было раньше&lt;/h3&gt;
  &lt;p id=&quot;42Kf&quot;&gt;До POLQA в инженерной практике использовали разные методы объективной оценки качества речи, включая простые энергетические и шумовые метрики, а также более продвинутые психоакустические модели; однако они либо слабо коррелировали с субъективным восприятием, либо были ограничены узким классом искажений. Затем появился PESQ, который стал важным шагом вперед благодаря моделированию слухового восприятия.&lt;/p&gt;
  &lt;h3 id=&quot;lk6M&quot;&gt;Как возник POLQA&lt;/h3&gt;
  &lt;p id=&quot;OlFK&quot;&gt;&lt;br /&gt;POLQA создавался как ответ на эти ограничения, то есть преемник PESQ, с акцентом на более точное моделирование восприятия речи в условиях современных телекоммуникаций. PESQ был спроектирован в первую очередь для &lt;strong&gt;узкополосной телефонной речи&lt;/strong&gt; и сравнительно стабильных соединений, а не для современных сетей с переменной задержкой, джиттером и более широким частотным диапазоном. PESQ хорошо решал задачу оценки качества для классических телефонных и кодековых сценариев, но в VoIP и IP-сетях сигнал часто сталкивается с &lt;strong&gt;непостоянной задержкой&lt;/strong&gt; и адаптацией jitter buffer, из-за чего точное выравнивание эталонного и тестового сигнала становится сложнее. Кроме того, в новых сетях ухудшения связаны не только с кодированием, но и с пакетными потерями, перепаковкой, временными сдвигами и другими эффектами передачи по IP, которые выходят за рамки более ранней модели применения PESQ&lt;/p&gt;
  &lt;h2 id=&quot;5it9&quot;&gt;История создания&lt;/h2&gt;
  &lt;p id=&quot;ipev&quot;&gt;Работы над POLQA начались в ITU-T Study Group 12 в 2006 году под рабочим названием P.OLQA. В 2009–2010 годах прошёл конкурс кандидатов. Лучшие модели от трёх компаний — &lt;strong&gt;OPTICOM&lt;/strong&gt; (Германия), &lt;strong&gt;SwissQual&lt;/strong&gt; (Rohde &amp;amp; Schwarz, Швейцария) и &lt;strong&gt;TNO&lt;/strong&gt; (Нидерланды) — были объединены в единый алгоритм.&lt;/p&gt;
  &lt;ul id=&quot;U6QE&quot;&gt;
    &lt;li id=&quot;l8up&quot;&gt;Первая редакция — 2011 год.&lt;/li&gt;
    &lt;li id=&quot;Owkn&quot;&gt;Вторая (исправления и улучшения) — 2014 год.&lt;/li&gt;
    &lt;li id=&quot;USzp&quot;&gt;Третья (POLQA v3 / Edition 3) — 2018 год (актуальная), с поддержкой Full Band и оптимизацией под современные сети.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;GmJM&quot;&gt;POLQA разработан специально для новых реалий: VoIP, HD Voice, 3G/4G/VoLTE, 5G, современных кодеков (EVS, Opus и др.).&lt;/p&gt;
  &lt;h3 id=&quot;xBAw&quot;&gt;Основные характеристики&lt;/h3&gt;
  &lt;ul id=&quot;WiMx&quot;&gt;
    &lt;li id=&quot;qXU0&quot;&gt;&lt;strong&gt;Тип алгоритма&lt;/strong&gt;: Full Reference (FR) — требует и reference-сигнал (чистый), и degraded-сигнал (после прохождения через систему).&lt;/li&gt;
    &lt;li id=&quot;z7JH&quot;&gt;&lt;strong&gt;Диапазоны&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;4JQ2&quot;&gt;
      &lt;li id=&quot;pWdB&quot;&gt;Narrowband (NB): 300–3400 Гц (классическая телефония).&lt;/li&gt;
      &lt;li id=&quot;sbBY&quot;&gt;Super-Wideband (SWB): до 14 кГц (HD Voice).&lt;/li&gt;
      &lt;li id=&quot;ckrD&quot;&gt;Full Band (FB, с v3): до 20–24 кГц (48 кГц сэмплирование).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;N7UG&quot;&gt;&lt;strong&gt;Выход&lt;/strong&gt;: MOS-LQO (Listening Quality Objective) от 1 (плохо) до 5 (отлично). Также дополнительные индикаторы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;JvLU&quot;&gt;Как работает POLQA (высокоуровнево)&lt;/h3&gt;
  &lt;p id=&quot;Am7n&quot;&gt;Алгоритм состоит из двух основных частей:&lt;/p&gt;
  &lt;ol id=&quot;ONsb&quot;&gt;
    &lt;li id=&quot;pe4n&quot;&gt;&lt;strong&gt;Temporal Alignment (временное выравнивание)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;Rucq&quot;&gt;
      &lt;li id=&quot;0FKJ&quot;&gt;Решает сложные проблемы VoIP: внезапные скачки задержки (shift-jitter), постепенное time-scaling (растяжение/сжатие речи), packet loss и т.д.&lt;/li&gt;
      &lt;li id=&quot;nkpI&quot;&gt;Использует macro frame, корреляцию, backtracking (аналог Viterbi алгоритма), обработку pitch-preserving техник (типа PSOLA).&lt;/li&gt;
      &lt;li id=&quot;OU2F&quot;&gt;Оценивает sample rate differences и компенсирует их.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;bNnX&quot;&gt;&lt;strong&gt;Perceptual Model (психоакустическая модель)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;clVW&quot;&gt;
      &lt;li id=&quot;T2VU&quot;&gt;Моделирует человеческое слуховое восприятие: преобразование в Bark-scale (критические полосы), loudness (Sone), masking effects (частотное и временное).&lt;/li&gt;
      &lt;li id=&quot;s8my&quot;&gt;&lt;strong&gt;Idealization&lt;/strong&gt;: &amp;quot;идеализирует&amp;quot; reference-сигнал (убирает мелкие шумы, корректирует timbre/level), чтобы имитировать Absolute Category Rating (ACR) тесты, где слушатели оценивают без прямого сравнения.&lt;/li&gt;
      &lt;li id=&quot;v0Uq&quot;&gt;Вычисляет disturbance density (плотность искажений) отдельно для additive и subtractive distortion, с учётом сильных и слабых эффектов.&lt;/li&gt;
      &lt;li id=&quot;SrRI&quot;&gt;Cognitive model преобразует perceptibility в annoyance (раздражаемость), учитывая level variations, reverberation, noise и т.д.&lt;/li&gt;
      &lt;li id=&quot;leSV&quot;&gt;Финальный mapping в MOS-LQO с полиномиальной коррекцией.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;

</content></entry></feed>