Общаемся с SIM-картой на низком уровне

:


f: не могу представить, как крусач может работать) Наши курсачи обычно пыляться где-то на полках
m: Вот у меня есть плата. К ней нужно подрубить сим-карту, и эта плата должна прочитать смс оттуда)
m: плата покупная, а вот программируем ее мы)
f: а нельзя смс с телефона прочитать?

— из жизни, орфография сохранена

Ну а если вам все-таки интересно узнать больше о сим-картах, протоколах передачи и их файловой структуре, прошу под кат. Ну и куда же без кода…


Начать стоит с того, что сим-карта является разновидностью смарт-карт, поэтому она полностью подчиняется стандарту ISO-7816. Я не буду говорить, какие выводы она имеет (об этом уже подробно говорили в предыдущей статье).

На процессор некоторых симок (если точнее — смарт-карт) можно подавать синхронизирующий сигнал до 20 МГц. Но ведь при включении симки терминал не знает ее параметров, поэтому общение начинается с, максимум, 4 МГц. Впоследствии, терминал узнает симку получше и может изменить параметры передачи.

К выводу I/O должен быть подключен pull-up резистор номиналом 20 КОм. В те моменты, когда терминалу и симке нечего сказать друг другу (т.е. они оба находятся в Z-состоянии) этот резистор обеспечит на выводе логическую единицу.


Активация сим-карты и последующий cold reset


Диаграмма довольно проста, cold reset начинается с момента времени Т а. Стоит лишь отметить, что I/O управляется здесь только симкой. Терминал должен игнорировать любой сигнал на нем, пока RST в нуле. После симка обязана дать ответ (Answer to reset).

Деактивация


Определенных рамок времени здесь нет, I/O также управляется симкой.


У всех смарт-карт и, соответственно, сим-карт существует два типа протоколов передачи — побайтовый T0 и блочный T1. Я рассмотрю только Т0.

Сразу скажу, что T0 как две капли воды похож на UART (он используется в передаче по COM-порту). Но с небольшими оговорками. Начнем с самого начала.

Момент времени в протоколе T0 носит название элементарной единицы времени (etu), которая равна:

где F (коэффициент преобразования тактовых импульсов) и D (коэффициент регулирования скорости передачи битов) задаются исходя из ATR, а f – частота синхроимпульса для карты. По умолчанию, F = 372, а D = 1.

Передача на выводе I/O начинается с появлением стартового бита — спада с логической единицы. Время, отведенное каждому биту равно etu. Далее идут 8 битов данных, 1 бит четности и, как минимум, 2 стоповых бита. Временной отрезок между двумя стартовыми битами всегда должен быть больше или равен 12 etu и меньше или равен 9600 etu.


Как я уже говорил, симка посылает ATR после cold reset’a. Именно в нем содержится информация с рекомендуемым значением частоты синхронизации, списком поддерживающих протоколов передачи и т.д.

Самый первый байт в ATR — TS. Он показывает, какое кодирование применяется – прямое или инверсное.

Прямое кодирование: если TS равен HHLH HHLL, то высокий уровень напряжения в цепи I/O кодирует логическую единицу, а момент времени 2 на рисунке кодирует наименьший значимый бит. При таком кодировании значение байта TS равно 0x3B.

Обратное кодирование: если TS равен HHLL LLLL, то низкий уровень напряжения в цепи I/O кодирует логическую единицу, а H – логический ноль. Момент времени 2 на рисунке кодирует наибольший значимый бит. При таком кодировании значение байта TS равно 0x3F.

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


Команды делятся на два типа: Command Transport Data Unit (C-TPDU) и Response Transport Data Unit (R-TPDU), т.е. команда и ответ на нее. Команды всегда составляют пару: на любую команду, переданную на карту, карта ответит R-TPDU. R-TPDU всегда заканчивается статусным байтом, характеризующим успешность команды.

Структура C-TPDU:

табл.1
Код Длина Описание
CLA 1 Класс инструкции Заголовок
INS 1 Код инструкции
P1 1 Параметр инструкции 1
P2 1 Параметр инструкции 2
Lc 0 или 1 Количество байтов в поле Data
Data Lc Данные команды Тело
Le 0 или 1 Максимальное количество байтов, ожидаемых в ответ

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

Стоит отметить, что если мы ошиблись в каком-либо параметре команды, симка сообщит об этом в статусном байте, но она имеет право проигнорировать команду, если та была абсолютно некорректна (например, состояла из одного байта).

Структура R-TPDU:

табл.2
Код Длина Описание
Data Lr Данные ответа
SW1 1 Статусный байт 1
SW2 1 Статусный байт 2

Типы файлов:

1. Master file (MF) — корень.
2. Dedicated files (DF) — обыкновенные папки.
3. Elementary files (EF) делятся на:
— Transparent EF — состоят из последовательности байтов,
— Linear fixed EF — состоят из последовательности записей одинакового размера,
— Cyclic EF — тоже самое, но при достижении конца файла, следующая запись начинается с нулевой записи, по кругу.


Попробуем прочитать и записать смс-сообщение, находящееся в файле EF SMS в папке DF TELECOM.

1) SELECT

До совершения операции над файлом необходимо сначала его выбрать. Вначале нужно выбрать папку DF TELECOM.

Отправка заголовка команды SELECT:

A0 A4 00 00 02

Ответ — статусный байт:

A4 (повторяет байт инструкции)

Отправка тела команды:

7F 10 (ID данной папки)

Схожим образом выбираем EF SMS.

2) READ RECORD

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

Отправка заголовка команды READ RECORD:

A0 B2 01 04 B0 (01 — порядковый номер смс)

Ответ:

B2 07 07 91 97 62 92 90 90 F0 11 FF 04 81 21 43 00 08 FF 08 04 45 04 30 04 31 04 40 FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF 90 00

Все, кроме первых и последних двух байтов (B2, 07, 90, 00) является записью сообщения. Разберем его.

табл.3
07 Длина номера смс-центра в байтах.
91 Тип номера смс-центра (в данном случае, он представлен в международном формате).
97 62 92 90 90 F0 Номер смс-центра — +7-926-290-90-90 (читать с конца байта). Символ F нужен для выравнивания.
11 Длина номера смс-центра.
04 Длина номера отправителя.
81 Тип номера отправителя.
21 43 Номер отправителя — 1234 (опять читать с конца байта).
00 Идентификатор протокола.
08 Кодировка (00 — только латиница, 08 — с кириллицей).
08 Длина сообщения в байтах.
04 45 04 30 04 31 04 40 Сообщение — «хабр». Кодируется в UTF-16.

Важно отметить, что когда в сообщении содержатся только латинские символы, используется особая 7-битная GSM кодировка.

Возьмем слово «hi».

табл.4
h i
68 69 Смотрим в UTF-8.
0110 1000 0110 1001 Преобразуем в двоичный код.
1110 1000 0011 0100 Дополняем старший байт младшими битами следующего байта.
E8 34 Именно так будет выглядеть «hi» в 7-битной кодировке.

3) UPDATE RECORD

Отправка заголовка команды UPDATE RECORD:

A0 DC 02 04 B0 (02 — порядковый номер смс)

Ответ — статусный байт:

DC (повторяет байт инструкции)

Далее отправляется тело команды в соответствии с табл.3.


В качестве аппаратной реализации была выбрана ПЛИС Altera DE1, т.к. курсач сдавать надо это замечательная плата для небольших проектов. Весь проект писали я и Breaknus, на VHDL и C. Среды разработок — Quartus II и Eclipse.

Разъем сим-карты припаян к пяти проводам IDE-шины. Плата имеет внутренние pull-up резисторы.

Краткая схема работы проекта:

Для ввода/вывода данных был собран NIOS II процессор. После ввода команды в консоли NIOS’а, она преобразуется в шестнадцатеричный код и передается побайтово в vhdl-блок. В этом блоке команда передается согласно протоколу T0 на I/O симки. После приема ответа блок передает его в NIOS, и ответ выводится в NIOS консоль. Активация/деактивация карты выбирается переключателем на плате. Нужные временные рамки для активации/деактивации, а также частота синхронизации карты обеспечиваются vhdl-блоком.

Скачать проект


Хочу выразить благодарность Сухинину Борису Михайловичу. Именно он познакомил нас с миром ПЛИС на замечательных лабораторных и находил время отвечать на наши вопросы.
1. ISO-7816 (Википедия)
2. ETSI TS 100 977 — Mobile Equipment (SIM-ME) Interface
3. ETSI TS 102 221 — UICC-Terminal interface