Подробности о вариантах сокета фильтра HCI?

Пока я тестировал некоторые основные команды HCI с использованием библиотеки socket Python, кажется, что для получения любого трафика сокета с использованием AF_BLUETOOTH и BTPROTO_HCI в параметрах сокета необходимо установить фильтр «пропустить все»:

from socket import socket, AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI, SOL_HCI, HCI_FILTER
from struct import pack

PASS_ALL = pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0)

def open_socket_with_hci(dev_id: int):
    hci = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)
    hci.bind((dev_id,))
    hci.setsockopt(SOL_HCI, HCI_FILTER, PASS_ALL)
    return hci

Я нашел структуру hci_filter, определенную как:

struct hci_filter {
    uint32_t type_mask;
    uint32_t event_mask[2];
    uint16_t opcode;
};

Маска кода операции достаточно проста. Я предполагаю, что type_mask — это маска для значений (код из hci.h):

/* HCI data types */
#define HCI_COMMAND_PKT     0x01
#define HCI_ACLDATA_PKT     0x02
#define HCI_SCODATA_PKT     0x03
#define HCI_EVENT_PKT       0x04
#define HCI_DIAG_PKT        0xf0
#define HCI_VENDOR_PKT      0xff

Но может кто-нибудь объяснить 2x event_masks? Является ли 1-й для типа события HCI, а 2-й для типа подсобытия (т. е. метасобытия LE)?


person Sean McVeigh    schedule 19.12.2018    source источник
comment
Краткая заметка: существует два разных набора команд HCI: один для BT classic, а другой для BT LE. Вам нужно указать, используете ли вы ble, bt classic или оба. Я предполагаю, что используемый вами API поддерживает оба варианта.   -  person John    schedule 19.12.2018


Ответы (1)


Итак, я просматривал noble source и нашел это:

Hci.prototype.setSocketFilter = function() {
  var filter = new Buffer(14);
  var typeMask = (1 << HCI_COMMAND_PKT) | (1 << HCI_EVENT_PKT) | (1 << HCI_ACLDATA_PKT);
  var eventMask1 = (1 << EVT_DISCONN_COMPLETE) | (1 << EVT_ENCRYPT_CHANGE) | (1 << EVT_CMD_COMPLETE) | (1 << EVT_CMD_STATUS);
  var eventMask2 = (1 << (EVT_LE_META_EVENT - 32));
  var opcode = 0;

  filter.writeUInt32LE(typeMask, 0);
  filter.writeUInt32LE(eventMask1, 4);
  filter.writeUInt32LE(eventMask2, 8);
  filter.writeUInt16LE(opcode, 12);

  debug('setting filter to: ' + filter.toString('hex'));
  this._socket.setFilter(filter);
};

Таким образом, маска определяется как бит, сдвинутый влево на значение константы, определенное в Bluetooth Core Volume 2, Part E, Section 5 & 7.

person Sean McVeigh    schedule 21.12.2018