void HciManager::handleHciEventPacket(const quint8 *data, int size) { if (size < HCI_EVENT_HDR_SIZE) { qCWarning(QT_BT_BLUEZ) << "Unexpected HCI event packet size:" << size; return; } hci_event_hdr *header = (hci_event_hdr *) data; size -= HCI_EVENT_HDR_SIZE; data += HCI_EVENT_HDR_SIZE; if (header->plen != size) { qCWarning(QT_BT_BLUEZ) << "Invalid HCI event packet size"; return; } qCDebug(QT_BT_BLUEZ) << "HCI event triggered, type:" << hex << header->evt; switch (header->evt) { case EVT_ENCRYPT_CHANGE: { const evt_encrypt_change *event = (evt_encrypt_change *) data; qCDebug(QT_BT_BLUEZ) << "HCI Encrypt change, status:" << (event->status == 0 ? "Success" : "Failed") << "handle:" << hex << event->handle << "encrypt:" << event->encrypt; QBluetoothAddress remoteDevice = addressForConnectionHandle(event->handle); if (!remoteDevice.isNull()) emit encryptionChangedEvent(remoteDevice, event->status == 0); } break; case EVT_CMD_COMPLETE: { auto * const event = reinterpret_cast<const evt_cmd_complete *>(data); static_assert(sizeof *event == 3, "unexpected struct size"); // There is always a status byte right after the generic structure. Q_ASSERT(size > static_cast<int>(sizeof *event)); const quint8 status = data[sizeof *event]; const auto additionalData = QByteArray(reinterpret_cast<const char *>(data) + sizeof *event + 1, size - sizeof *event - 1); emit commandCompleted(event->opcode, status, additionalData); } break; case LeMetaEvent: handleLeMetaEvent(data); break; default: break; } }
/*! * Process all incoming HCI events. Function cannot process anything else but events. */ void HciManager::_q_readNotify() { unsigned char buffer[HCI_MAX_EVENT_SIZE]; int size; size = ::read(hciSocket, buffer, sizeof(buffer)); if (size < 0) { if (errno != EAGAIN && errno != EINTR) qCWarning(QT_BT_BLUEZ) << "Failed reading HCI events:" << qt_error_string(errno); return; } const unsigned char *data = buffer; // Not interested in anything but valid HCI events if ((size < HCI_EVENT_HDR_SIZE + 1) || buffer[0] != HCI_EVENT_PKT) return; hci_event_hdr *header = (hci_event_hdr *)(&buffer[1]); size = size - HCI_EVENT_HDR_SIZE - 1; data = data + HCI_EVENT_HDR_SIZE + 1; if (header->plen != size) { qCWarning(QT_BT_BLUEZ) << "Invalid HCI event packet size"; return; } qCDebug(QT_BT_BLUEZ) << "HCI event triggered, type:" << hex << header->evt; switch (header->evt) { case EVT_ENCRYPT_CHANGE: { const evt_encrypt_change *event = (evt_encrypt_change *) data; qCDebug(QT_BT_BLUEZ) << "HCI Encrypt change, status:" << (event->status == 0 ? "Success" : "Failed") << "handle:" << hex << event->handle << "encrypt:" << event->encrypt; QBluetoothAddress remoteDevice = addressForConnectionHandle(event->handle); if (!remoteDevice.isNull()) emit encryptionChangedEvent(remoteDevice, event->status == 0); } break; default: break; } }