Программирование ARM ESP32 GAP API Tue, April 23 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

ESP32 GAP API Печать
Добавил(а) microsin   

Просмотрите содержимое папки bluetooth/bluedroid/ble каталога установки ESP-IDF [2], которая содержит следующие демонстрационные примеры и соответствующую документацию:

SMP security client (находится в каталоге bluetooth/bluedroid/ble/gatt_security_client). Этот демонстрационный проект инициализирует свои параметры безопасности и работает как клиент GATT, который может посылать security request устройству пира, и затем завершает процедуру шифрования.

Примечание: незнакомые термины и сокращения см. в Словариках статей [5, 6].

Здесь представлен обзор примера кода GATT Security Client для ESP32. GATT Client может сканировать ближайшие устройства, и после того, как интересующее устройство было найдено, может запросить безопасное соединение с ним. GATT client ведет себя как главное устройство (master), которое инициирует соединение с подчиненным устройством (slave, которое работает как сервер, см. ниже описание SMP security server) путем отправки Pairing Request, как это указано в стандарте Bluetooth Core Specification Version 4.2. Удаленное slave-устройство это обычно GATT Server, который показывает свои службы (Services) и характеристики (Characteristics). Устройство slave отвечает пакетом Pairing Response, за котороым идет аутентификация и обмен ключами. Если при этом также выполняется процесс привязки (bonding), то ключи (Long Term Keys) сохраняются в энергонезависимой памяти, чтобы их можно было повторно использовать в будущем при последующих соединениях. В завершение устанавливается зашифрованный канал связи, который может поддерживать защиту от атак типа "промежуточное звено" (Man-In-The-Middle, MITM) в зависимости от конфигурации безопасности (security configuration). Код реализован с использованием Application Profile, который после регистрации позволяет установить локальную конфигурацию приватности, поскольку события запускаются в течение времени работы программы.

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

[Конфигурирование Local Privacy для Security Client]

В примере регистрируется Application Profile следующим образом:

#define PROFILE_NUM 1
#define PROFILE_A_APP_ID 0

Эта регистрация происходит из функции app_main() путем вызова API-функции esp_ble_gattc_app_register():

...
ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID);
if (ret)
{
   ESP_LOGE(GATTC_TAG, "%s gattc app register error, error code = %x\n",
            __func__, ret);
}
...

Регистрация Application Profile вызывает срабатывание события ESP_GATTC_REG_EVT, которое обрабатывается callback-функцией esp_gattc_cb(), и перенаправляется в обработчик события профиля приложения, функцию gattc_profile_event_handler(). Здесь событие используется для конфигурирования local privacy подчиненного устройства путем вызова функции esp_ble_gap_config_local_privacy().

case ESP_GATTC_REG_EVT:
   ESP_LOGI(GATTC_TAG, "REG_EVT");
   esp_ble_gap_config_local_privacy(true);
   break;

Эта функция принадлежит к библиотеке Bluedroid API, она предназначена для конфигурирования настроек приватности по умолчанию на локальном устройстве. Как только privacy установлена, сработает событие ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, которая используется для установки параметров сканирования, и запускает сканирование ближайших периферийных устройств:

case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
   if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS)
   {
      ESP_LOGE(GATTC_TAG, "config local privacy failed, error code =%x",
               param->local_privacy_cmpl.status);
      break;
   }
   esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params);
   if (scan_ret)
   {
      ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret);
   }
   break;
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
   // Единицы длительности для duration указываются в секундах:
   uint32_t duration = 30;
   esp_ble_gap_start_scanning(duration);
   break;
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
   // Событие завершения запуска сканирования показывает, был ли
   // запуск сканирования удачным, или нет.
   if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
   {
      ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x",
               param->scan_start_cmpl.status);
      break;
   }
   ESP_LOGI(GATTC_TAG, "Scan start success");
   break;

[Конфигурирование и Bonding для подчиненного устройства]

Остальная конфигурация для GATT Client обычно выполняется таким же способом, как и в примере GATT Client. Т. е. клиент находит интересующее его устройство (GATT Server) и открывает с ним соединение. В этот момент GATT client, который обычно работает как master, инициирует pairing-процесс отправкой Pairing Request к slave-устройству. Этот запрос должен быть подтвержден ответом Pairing Response. Процесс Pairing реализован в стеке автоматически, и не требует от пользователя дополнительной конфигурации. Однако в зависимости от возможностей I/O для обоих устройств, может быть сгенерирован passkey (ключ пароля) на ESP32, что представляется пользователю с событием ESP_GAP_BLE_PASSKEY_NOTIF_EVT:

case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:  
   // Приложение получит это событие, когда у него имеется возможность
   // IO Output, и устройство пира имеет возможность IO Input. Для
   // пользователю показывается число passkey, чтобы его можно было
   // ввести для подтверждения на устройстве пира.
   ESP_LOGE(GATTS_TABLE_TAG, "The passkey Notify number:%d",
            param->ble_security.key_notif.passkey);
   break;

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

  Display Only Display Yes/No Keyboard Only No Input No Output Keyboard Display
Display Only Just Works Passkey Entry Just Works Passkey Entry
Display Yes/No
Keyboard Only Passkey Entry
No Input No Output Just Works
Keyboard Display Passkey Entry Just Works Passkey Entry

В методе Just Works временный ключ (Temporary Key) устанавливается в 0. Это практический способ для аутентификации устройств, у которых нет экрана или клавиатуры, поэтому нет способа показать или ввести passkey. Однако если у ESP32 GATT Client есть LCD, он может показать passkey, сгенерированный локально, чтобы пользователь мог ввести его на другом устройстве пира, или если у GATT Client есть клавиатура, то он может ввести passkey, сгенерированный на другом устройстве пира. Дополнительно числовое сравнение может быть выполнено, если оба устройства имеют экран и кнопки подтверждения yes/no, и используется LE Secure Connections, таким способом независимо сгенерированный passkey отображается на обоих устройствах, и пользователь вручную проверяют, что оба значения из 6 цифр совпали.

[Обмен ключами]

Когда клиент подключается к удаленному устройству, и pairing произошел успешно, происходит обмен ключами initiator и responder. Для каждого сообщения обмена ключами срабатывает событие ESP_GAP_BLE_KEY_EVT, которое может использоваться для вывода типа полученного ключа:

case ESP_GAP_BLE_KEY_EVT:
   // Покажет пользователю информацию ключа, которым произошел
   // обмен с устройством пира.
   ESP_LOGI(GATTS_TABLE_TAG, "key type = %s",
            esp_key_type_to_str(param->ble_security.ble_key.key_type));
   break;

Когда обмен ключами прошел успешно, процесс pairing завершен, и может начаться шифрование данных полезной нагрузки, выполняемое подсистемой AES-128. Это вызовет срабатывание событие ESP_GAP_BLE_AUTH_CMPL_EVT, которое используется для вывода информации:

case ESP_GAP_BLE_AUTH_CMPL_EVT:
   esp_bd_addr_t bd_addr;
   memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
   ESP_LOGI(GATTS_TABLE_TAG, "remote BD_ADDR: %08x%04x",
           (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
           (bd_addr[4] << 8)  + bd_addr[5]);
   ESP_LOGI(GATTS_TABLE_TAG, "address type = %d",
            param->ble_security.auth_cmpl.addr_type);
   ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",
            param->ble_security.auth_cmpl.success ? "success" : "fail");
   break;

В этом описании дан обзор реализованных аспектов безопасности GATT Client. BLE security охватывает Pairing, Bonding и Encryption. Чтобы установить защищенный линк между устройствами master и slave, устанавливается local privacy для GATT client, что позволяет стеку BLE автоматически установить необходимые параметры безопасности без необходимости в дополнительной конфигурации пользователя. Комбинация существующих возможностей взаимодействующих устройств определяет выпор подходящего метода для pairing, который затем выполнит стек BLE. Сразу после этого происходит генерация ключей и обмен ими, и начинается шифрование последующих сообщений с помощью подсистемы AES-128. Эти выполняемые шаги вызывают генерацию событий, которые обрабатываются соответствующими хендлерами GATT и GAP, которые могут печатать полезную информацию, такую как типы ключей, которыми произведен обмен, и pairing статус. Остальной функционал безопасности GATT client, такой как регистрация оповещений характеристик, реализуется примерно так, как сделано в этом примере проекта.

См. также GitHub репозиторий [3].

SMP security server (находится в каталоге bluetooth/bluedroid/ble/gatt_security_server). Это демо инициирует свои параметры безопасности и работает как сервер GATT, который посылает pair request устройству пира, и затем завершает процедуру шифрования.

Здесь приведен обзор примера GATT Server BLE для ESP32. Конфигурация безопасности позволяет серверу GATT работать в качестве подчиненного (slave) устройства, чтобы осуществить привязку (bond) с master-устройством (клиентом GATT), и установить с ним зашифрованный канал связи. Этот функционал определен в стандарте Bluetooth Specification version 4.2, и реализован стеком ESP-IDF BLE в API-функциях Security Manager Protocol (SMP).

BLE security охватывает 3 внутренне связанные друг с другом концепции: Pairing, Bonding и Encryption. Pairing заключается в обмене поддерживаемыми функциями и типами безопасности и необходимыми ключами. Дополнительно процедура pairing заботится о генерации и обмене общими ключами. Основной стандарт определяет Legacy Pairing и Secure Connections Pairing (введенный в Bluetooth 4.2), оба этих варианта поддерживаются ESP32. Как только обмен ключами завершился, устанавливается временный шифрованный линк, чтобы произошел обмен ключами short term и long term. Bonding заключается в сохранении в энергонезависимой памяти ключей, которыми прошел обмен, чтобы они при будущих соединениях не передавались повторно. И наконец, Encryption относится к шифрованию передаваемых данных с использованием подсистемы AES-128 и обмененных ключей. Также могут быть определены атрибуты сервера, чтобы можно было шифровать только сообщения записи или только сообщения чтения. В любой точке обмена данными slave-устройство может запросить начать шифрование выдачей security request другому устройству пира, которое вернет security response вызовом соответствующего API.

Здесь описывается только конфигурация безопасности. Остальной функционал сервера GATT, такой как определена в таблице служб, объясняется в документации примера GATT Server. Для лучшего понимания процессов в этом примере, рекомендуется ознакомиться с описанием pairing и генерацией ключей, описанных в секции 3.5 стандарта Bluetooth Specification Version 4.2 [Vol 3, Part H].

[Установка параметров безопасности]

ESP32 требует серию параметров безопасности, чтобы определить, как должны строиться pairing request и pairing response. Пакет Pairing Response, который строит GATT Server, включает такие поля, как возможности input/output, Secure Connections pairing, аутентифицированную защиту от атак Man-In-The-Middle (MITM), либо отсутствие требований по безопасности (см. Section 2.3.1 стандарта Bluetooth Specification Version 4.2 [Vol 3, Part H]). В этом примере соответствующая процедура выполняется в функции app_main(). Запрос pairing посылается инициатором (initiator), которым в нашем случае выступает удаленный GATT client (см. его описание выше). Сервер ESP32, реализованный в этом примере, принимает запрос и отвечает пакетом pairing response, который содержит те же параметры безопасности, чтобы оба устройства пришли к соглашению по доступным для них ресурсам и применимому pairing-алгоритму (Just Works или Passkey Entry). И команды запроса pairing, и команды response, обе имеют следующие параметры:

IO Capability: описывает, есть ли у устройства возможности ввода/вывода, такие как экран и/или клавиатура.
OOB Flag: описывает, есть ли у устройства поддержка обмена ключом пароля по побочному каналу (Out of Band passkey), например с помощью NFC или Wi-Fi, чтобы можно было по ним осуществить передачу ключей в качестве TK.
Authorization Request: показывает запрашиваемые свойства безопасности, такие как Bonding, Secure Connections (SC), защита MITM или ничего из этого (none), что должно присутствовать в пакетах Pairing Request и Pairing Response.
Maximum Encryption Key Size: максимальный размер ключа шифрования в байтах.
Initiator Key Distribution/Generation: показывает, какие ключи initiator запрашивает для распространения/генерации, или использования во время фазы Transport Specific Key Distribution. В запросе pairing эти ключи запрашиваются, в то время как в pairing response эти ключи подтверждаются для распространения.
Responder Key Distribution/Generation: показывает, какие ключи initiator у responder-а для распространения/генерации, или использования во время фазы Transport Specific Key Distribution. В запросе pairing эти ключи запрашиваются, в то время как в pairing response эти ключи подтверждаются для распространения.

В коде эти параметры определены следующим образом.

IO Capability:

// IO capability устанавливается в No Input No Output:
esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;

Возможны следующие значения для IO Capabilities:

ESP_IO_CAP_OUT         0   /*!< только отображение */
ESP_IO_CAP_IO          1   /*!< отображение Yes/No */
ESP_IO_CAP_IN          2   /*!< только клавиатура */
ESP_IO_CAP_NONE        3   /*!< NoInput, NoOutput: ни ввода, ни вывода */
ESP_IO_CAP_KBDISP      4   /*!< клавиатура и экран */ 

Authorization Request:

// Привязка (bonding) с устройством пира после аутентификации:
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND;

Возможные значения для Authorization Request это комбинация запросов Bonding, защиты MITM и Secure Connections:

ESP_LE_AUTH_NO_BOND: без bonding.
ESP_LE_AUTH_BOND: выполняется bonding.
ESP_LE_AUTH_REQ_MITM: защита MITM разрешена.
ESP_LE_AUTH_REQ_SC_ONLY: разрешены Secure Connections без bonding.
ESP_LE_AUTH_REQ_SC_BOND: разрешены Secure Connections с bonding.
ESP_LE_AUTH_REQ_SC_MITM: разрешены Secure Connections с защитой MITM Protection и без bonding.
ESP_LE_AUTH_REQ_SC_MITM_BOND: разрешены Secure Connections с защитой MITM и с bonding.

Maximum Encryption Key Size:

uint8_t key_size = 16;     // размер ключа должен быть 7 .. 16 байт

Initiator Key Distribution/Generation:

uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;

Инициатор распространяет ключи LTK и IRK установкой масок EncKey и IdKey.

Responder Key Distribution/Generation:

uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;

Устройство responder распространяет ключи LTK и IRK установкой масок EncKey и IdKey.

Будучи определенными, параметры устанавливаются функцией esp_ble_gap_set_security_param(), которая установит тип параметра, его значение и длину:

esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t)); 

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

[Соединение и Bonding с устройством пира]

Параметры безопасности, установленные ранее, сохраняются локально, чтобы использоваться позже, когда master-устройство подключится к slave-устройству. Каждый раз, когда удаленное устройство подключается к локальному серверу GATT, генерируется событие ESP_GATTS_CONNECT_EVT. Это событие реализовано для выполнения процесса pairing и bonding путем запуска функции esp_ble_set_encryption(), которая в качестве параметра получает адрес удаленного устройства и тип шифрования, которое будет выполняться. Затем стек BLE будет выполнять реальный процесс pairing-а в фоновом режиме. В этом примере шифрование включает защиту от атаки MITM.

case ESP_GATTS_CONNECT_EVT:
   // Запускает безопасное соединение с устройством пира, когда примет
   // запрос соединения, посланное устройством master.  
   esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);  
   break;

Доступны следующие типы шифрования:

ESP_BLE_SEC_NONE
ESP_BLE_SEC_ENCRYPT
ESP_BLE_SEC_ENCRYPT_NO_MITM
ESP_BLE_SEC_ENCRYPT_MITM

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

В этом примере I/O capabilities установлены в No Input No Output, так что будет применен pairing-метод Just Works, который не требует генерации случайного passkey из 6 цифр (подробности см. в таблице ниже). Пользователь может изменить этот пример, чтобы установить I/O capabilities в другие возможные варианты. Таким образом, в зависимости от I/O capabilities удаленного устройства, может быть сгенерирован passkey в устройстве ESP32, который представлен для пользователя событием ESP_GAP_BLE_PASSKEY_NOTIF_EVT:

case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
   // Приложение получит это событие, когда IO capability имеет возможность
   // вывода (Output), и устройство пира обладает возможностью ввода (Input).
   // Отобразить число passkey для пользователя, чтобы он ввел его на
   // устройстве пира.
   ESP_LOGE(GATTS_TABLE_TAG, "The passkey Notify number:%d",
            param->ble_security.key_notif.passkey);
   break;

Комбинация возможностей ввода и вывода (IO capabilities), которая определяет используемый алгоритм авторизации:

  Display Only Display Yes/No Keyboard Only No Input No Output Keyboard Display
Display Only Just Works Passkey Entry Just Works Passkey Entry
Display Yes/No
Keyboard Only Passkey Entry
No Input No Output Just Works
Keyboard Display Passkey Entry Just Works Passkey Entry

[Обмен ключами]

Когда клиент подключился к серверу и произошел pairing, происходит обмен ключами, показываемыми параметрами init_key и rsp_key. В этом примере генерируются и распространяются следующие ключи:

• LTK локального устройства (LTK означает Long Term Key)
• IRK локального устройства (IRK означает Identity Resolving Key)
• CSRK локального устройства (CSRK означает Connection Signature Resolving Key)
• LTK устройства пира
• IRK устройства пира

Обратите внимание, что только для примера здесь ключом CSRK устройства пира обмен не происходит. Для каждого сообщения обмена ключами, генерируется событие ESP_GAP_BLE_KEY_EVT, которое может использоваться для печать типа полученного ключа:

case ESP_GAP_BLE_KEY_EVT:
   // Покажет для пользователю информацию ключа BLE, общего с устройством пира.
   ESP_LOGI(GATTS_TABLE_TAG, "key type = %s",
            esp_key_type_to_str(param->ble_security.ble_key.key_type));
   break;

Когда обмен ключами прошел успешно, процесс pairing-а завершен. Это вызывает генерацию события ESP_GAP_BLE_AUTH_CMPL_EVT, которое используется для печати такой информации, как адрес удаленного устройства, типа адреса и pairing-статуса:

case ESP_GAP_BLE_AUTH_CMPL_EVT:
   esp_bd_addr_t bd_addr;
   memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr,  
          sizeof(esp_bd_addr_t));
   ESP_LOGI(GATTS_TABLE_TAG, "remote BD_ADDR: %08x%04x",\
            (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) +
            bd_addr[3],  
            (bd_addr[4] << 8) + bd_addr[5]);
   ESP_LOGI(GATTS_TABLE_TAG, "address type = %d",   
            param->ble_security.auth_cmpl.addr_type);  
            ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",  
            param->ble_security.auth_cmpl.success ? "success" : "fail");
   break;
}

[Разрешения безопасности для атрибутов]

Когда определяются атрибуты сервера, могут быть установлены различные разрешения для событий записи и чтения. Разрешениями для атрибутов могут быть:

ESP_GATT_PERM_READ: разрешение на чтение.
ESP_GATT_PERM_READ_ENCRYPTED: разрешение на чтение с шифрованием.
ESP_GATT_PERM_READ_ENC_MITM: разрешение на чтение с шифрованием и защитой MITM.
ESP_GATT_PERM_WRITE: разрешение на запись.
ESP_GATT_PERM_WRITE_ENCRYPTED: разрешение на запись с шифрованием.
ESP_GATT_PERM_WRITE_ENC_MITM: разрешение на запись с шифрованием и защитой MITM.
ESP_GATT_PERM_WRITE_SIGNED: разрешение на запись с подписью.
ESP_GATT_PERM_WRITE_SIGNED_MITM: разрешение на запись с подписью и защитой MITM.

Когда создается таблица служб, у каждого атрибута может быть разрешение на чтение или запись, с шифрованием или без. Когда у атрибута установлены разрешения на шифрование, и устройство пира не имеет требуемого разрешения по безопасности и пробует читать или записывать этот атрибут, локальный хост посылает ошибку недостаточной авторизации (Insufficient Authorization Error). В примере с разрешениями на шифрование определены следующие атрибуты:

...
// Значение характеристики Body Sensor Location:
   [HRS_IDX_BOBY_SENSOR_LOC_VAL] =
   {
      {ESP_GATT_AUTO_RSP},
      {ESP_UUID_LEN_16,
      (uint8_t *)&body_sensor_location_uuid,
      ESP_GATT_PERM_READ_ENCRYPTED,
      sizeof(uint8_t),
      sizeof(body_sensor_loc_val),
      (uint8_t *)body_sensor_loc_val}
   },
...
// Значение характеристики Heart Rate Control Point:
   [HRS_IDX_HR_CTNL_PT_VAL] =
   {
      {ESP_GATT_AUTO_RSP},
      {ESP_UUID_LEN_16,
      (uint8_t *)&heart_rate_ctrl_point,
      ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,
      sizeof(uint8_t),
      sizeof(heart_ctrl_point),
      (uint8_t *)heart_ctrl_point}
   },
...

[Запросы безопасности]

Во время обмена между устройствами master и slave устройство slave может в любой момент запросить начать шифрование путем выдачи команды запроса безопасности (security request command). Эта команда приведет к генерации события ESP_GAP_BLE_SEC_REQ_EVT на master-устройстве, который ответит положительным (true) security response устройству пира, чтобы принять запрос, или отрицательным (false) security response, чтобы отклонить запрос. В этом примере такое событие используется для ответа запуском шифрования с использованием API-функции esp_ble_gap_security_rsp().

case ESP_GAP_BLE_SEC_REQ_EVT:
   // Отправка положительного (true) security response устройству пира,
   // чтобы принять security request. Если бы security request нельзя
   // принять, то второй параметр должен быть false.
   esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
   break;

В этом описании дан обзор реализованных аспектов безопасности сервера GATT. BLE security охватывает Pairing, Bonding и Encryption. Чтобы установить защищенный линк между устройствами master и slave, устанавливаются параметры безопасности, определяющие возможности и функции каждого устройства. Комбинация существующих возможностей взаимодействующих устройств определяет выбор подходящего метода для pairing, который затем выполнит стек BLE. Сразу после этого происходит генерация ключей и обмен ими, и начинается шифрование последующих сообщений с помощью подсистемы AES-128 и этих ключей. Эти выполняемые шаги вызывают генерацию различных событий, которые обрабатываются соответствующими хендлерами GATT и GAP. Обработчики событий могут печатать полезную информацию, такую как типы ключей, которыми произведен обмен, и pairing статус. Кроме того, назначаются разрешения для атрибутов, которые определяют необходимость шифрования для чтения и/или записи. Остальной функционал безопасности сервера GATT, такой как определение служб и характеристик, реализуется примерно так, как сделано в этом примере проекта.

См. также GitHub репозиторий [4].

[Справочник по API-функциям GAP API]

Заголовочный файл: components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h.

Функция Описание
esp_ble_gap_register_callback Эта функция вызывается, чтобы произошло событие GAP, такое как результат сканирования.
esp_ble_gap_config_adv_data Эта функция вызывается, чтобы перезадать параметры оповещения по умолчанию (BTA default ADV parameters).
esp_ble_gap_set_scan_params Эта функция вызывается для установки параметров сканирования.
esp_ble_gap_start_scanning Эта функция позволяет устройству сканировать устройство пира, которое выдает в эфир сообщения оповещения (advertising).
esp_ble_gap_stop_scanning Эта функция function вызывается для остановки сканирования устройства пира, которое выдает в эфир сообщения оповещения.
esp_ble_gap_start_advertising Эта функция вызывается для запуска оповещения.
esp_ble_gap_stop_advertising Эта функция вызывается для остановки  оповещения.
esp_ble_gap_update_conn_params Обновляет параметры соединения, может использоваться только когда соединение установлено.
esp_ble_gap_set_pkt_data_len Эта функция устанавливает максимальный размер пакета данных.
esp_ble_gap_set_rand_addr Эта функция установит для приложения Static Random Address и Non-Resolvable Private Address.
esp_ble_gap_clear_rand_addr Эта функция очистит random address для приложения.
esp_ble_gap_config_local_privacy Разрешает/запрещает приватность локального устройства.
esp_ble_gap_config_local_icon Установит иконку видимости GAP.
esp_ble_gap_update_whitelist Добавляет устройство в белый список или удаляет устройство из белого списка.
esp_ble_gap_clear_whitelist Очищает белый список.
esp_ble_gap_get_whitelist_size Считывает размер белого списка в Controller-е.
esp_ble_gap_set_prefer_conn_params Эта функция вызывается для установки перед началом соединения предпочтительных параметров соединения, когда параметры соединения по умолчанию применять нежелательно. Этот API-вызов может использоваться только в роли master.
esp_ble_gap_set_device_name Устанавливает имя для локального устройства.
esp_ble_gap_get_local_used_addr Эта функция вызывается для получения локального используемого адреса и типа адреса. Функция esp_bt_dev_get_address получает публичный адрес.
esp_ble_resolve_adv_data Эта функция вызывается для получения ADV-данных для определенного типа.
esp_ble_gap_config_adv_data_raw Эта функция вызывается для установки сырых данных адвертайзинга. Пользователю нужно самостоятельно заполнить ADV-данные.
esp_ble_gap_config_scan_rsp_data_raw Эта функция вызывается для установки сырых данных ответа на сканирование (scan response data). Пользователю нужно самостоятельно заполнить данные ответа.
esp_ble_gap_read_rssi Эта функция вызывается для чтения RSSI удаленного устройства. Адрес результата политики линка возвратится в callback-функции GAP в ответ на событие ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT.
esp_ble_gap_add_duplicate_scan_exceptional_device Эта функция вызывается для добавления информации устройства в дубликата списка исключений сканирования.
esp_ble_gap_remove_duplicate_scan_exceptional_device Эта функция вызывается для удаления устройства из дубликата списка исключений сканирования.
esp_ble_gap_clean_duplicate_scan_exceptional_list Эта функция вызывается для очистки дубликата списка исключений сканирования. Эта API-функция удалит всю информацию об устройстве в дубликате списка исключений сканирования.
esp_ble_gap_set_security_param Установит значение параметра безопасности GAP, что изменит значение по умолчанию.
esp_ble_gap_security_rsp Предоставляет доступ к запросу безопасности.
esp_ble_set_encryption Установит шифрование с устройством пира.
esp_ble_passkey_reply Ответит значением ключа устройству пира на стадии legacy-соединения.
esp_ble_confirm_reply Ответит значением подтверждения устройству пира на стадии защищенного соединения.
esp_ble_remove_bond_device Удалит устройство из списка базы данных безопасности устройства пира. Это обслуживает unpairing-событие в соединенном состоянии.
esp_ble_get_bond_device_num Получит номер устройства из базы данных безопасности устройства пира. Оно немедленно вернет bonded-номер устройства.
esp_ble_get_bond_device_list Получит устройство из списка базы данных безопасности устройства пира. Оно немедленно вернет bonded-информацию устройства.
esp_ble_oob_req_reply Эта функция вызывается для предоставления OOB данных для SMP в ответ на ESP_GAP_BLE_OOB_REQ_EVT.
esp_ble_gap_disconnect Эта функция используется для разрыва физического соединения устройства пира. Клиент GATT может поддерживать несколько виртуальных соединений с сервером GATT, когда зарегистрировано несколько app_id. Функция esp_ble_gattc_close закроет только одно соединение сервера GATT. Если при этом существуют другие виртуальные соединения сервера GATT, то это не разорвет физическое соединение. Функция esp_ble_gap_disconnect сразу разорвет физическое соединение.
esp_ble_get_current_conn_params Эта функция вызывается для чтения информации параметров соединения устройства.
esp_gap_ble_set_channels Установит каналы BLE.
esp_gap_ble_set_authorization Эта функция вызывается для авторизации линка после Authentication (защита от атаки MITM).
esp_ble_gap_read_phy Эта функция используется для чтения текущего PHY передатчика и PHY приемника, идентифицированных по удаленному удресу.
esp_ble_gap_set_preferred_default_phy Эта функция используется, чтобы позволить хосту указать свои предпочтительные значения для PHY передатчика и PHY приемника, чтобы использовать их для всех последующих соединений через транспорт BLE.
esp_ble_gap_set_preferred_phy Эта функция используется для установки свойств PHY для соединения, идентифицированного по удаленному адресу. Controller может быть не в состоянии сделать изменение (например если пир не поддерживает запрошенный PHY), или может решить, что предпочтительнее использовать текущий PHY.
esp_ble_gap_ext_adv_set_rand_addr Эта функция используется хостом для установки случайного адреса устройства, указанного параметром Random_Address.
esp_ble_gap_ext_adv_set_params Эта функция используется хостом для установки параметров оповещения (advertising).
esp_ble_gap_config_ext_adv_data_raw Эта функция используется для установки данных в advertising PDU, у которого есть поле данных.
esp_ble_gap_config_ext_scan_rsp_data_raw Эта функция используется для предоставления данных ответа на сканирование (scan response data), используемых в scanning response PDU.
esp_ble_gap_ext_adv_start Эта функция используется для запроса к Controller, чтобы разрешить использовать один или большее количество наборов оповещения (advertising sets).
esp_ble_gap_ext_adv_stop Эта функция используется для запроса к Controller, чтобы запретить использовать один или большее количество наборов оповещения (advertising sets).
esp_ble_gap_ext_adv_set_remove Эта функция используется для удаления advertising set из Controller-а.
esp_ble_gap_ext_adv_set_clear Эта функция используется для удаления всех advertising set из Controller-а.
esp_ble_gap_periodic_adv_set_params Эта функция используется хостом для установки параметров периодического  оповещения (advertising).
esp_ble_gap_config_periodic_adv_data_raw Эта функция используется данных, используемых в периодических advertising PDU.
esp_ble_gap_periodic_adv_start Эта функция используется для запроса Controller-у, чтобы разрешить периодического оповещения для указанного advertising set.
esp_ble_gap_periodic_adv_stop Эта функция используется для запроса Controller-у, чтобы запретить периодическое оповещения для указанного advertising set.
esp_ble_gap_set_ext_scan_params Эта функция используется для установки расширенных параметров сканирования, используемых на каналах advertising-а.
esp_ble_gap_start_ext_scan Эта функция используется разрешения сканирования.
esp_ble_gap_stop_ext_scan Эта функция используется запрета сканирования.
esp_ble_gap_periodic_adv_create_sync Эта функция используется синхронизации с приемом периодических оповещений от advertiser-а, и начала приема периодических advertising-пакетов.
esp_ble_gap_periodic_adv_sync_cancel Эта функция используется отмены команды LE_Periodic_Advertising_Create_Sync, когда она ожидает выполнения.
esp_ble_gap_periodic_adv_sync_terminate Эта функция используется остановки приема периодических оповещений, идентифицируемых параметром Sync Handle.
esp_ble_gap_periodic_adv_add_dev_to_list Эта функция используется для добавления одного устройства в список периодических оповещателей, сохраненных в Controller.
esp_ble_gap_periodic_adv_remove_dev_from_list Эта функция используется удаления одного устройства из списка периодических оповещателей, сохраненных в Controller. Удаление дает немедленный эффект.
esp_ble_gap_periodic_adv_clear_dev Эта функция используется для удаления всех устройств из списка периодических оповещателей, сохраненных в Controller.
esp_ble_gap_prefer_ext_connect_params_set Эта функция используется для установки дополнительных параметров соединения.

Примечание: подробное описание функций, их параметров, используемых определений и типов данных см. в [1].

[Ссылки]

1. ESP32 GAP API site:docs.espressif.com.
2. Установка среды разработки ESP-IDF для ESP32.
3. espressif / esp-idf gatt_security_client site:github.com.
4. espressif / esp-idf gatt_security_server site:github.com.
5. ESP32: архитектура Bluetooth.
6Bluetooth: аббревиатуры и термины.

 

Комментарии  

 
+1 #1 Vadim 22.01.2023 00:05
Спасибо тебе мил человек, единственная нормальная статья...
Цитировать
 

Добавить комментарий


Защитный код
Обновить

Top of Page