Add wireless accesspoint mode for backwards compatibility

pull/2/head
Simon Stürz 2019-10-08 16:40:49 +02:00
parent 2b823b2a41
commit 5f0cd6aefa
4 changed files with 102 additions and 23 deletions

View File

@ -136,7 +136,7 @@ QLowEnergyServiceData BluetoothServer::deviceInformationServiceData()
serialNumberCharData.setUuid(QBluetoothUuid::SerialNumberString);
if (m_serialNumber.isNull()) {
// Note: if no serialnumber specified use the system uuid from /etc/machine-id
qCWarning(dcNetworkManagerBluetoothServer()) << "Serial number not specified. Using system uuid from /etc/machine-id as serialnumber.";
qCDebug(dcNetworkManagerBluetoothServer()) << "Serial number not specified. Using system uuid from /etc/machine-id as serialnumber.";
m_serialNumber = readMachineId().toString();
}
serialNumberCharData.setValue(m_serialNumber.toUtf8());
@ -260,7 +260,7 @@ QUuid BluetoothServer::readMachineId()
tmpId.insert(23, "-");
systemUuid = QUuid(tmpId);
} else {
qWarning(dcNetworkManagerBluetoothServer()) << "Failed to open /etc/machine-id for reading the system uuid as device information serialnumber.";
qCWarning(dcNetworkManagerBluetoothServer()) << "Failed to open /etc/machine-id for reading the system uuid as device information serialnumber.";
}
systemUuidFile.close();
@ -401,13 +401,13 @@ void BluetoothServer::serviceError(QLowEnergyService::ServiceError error)
void BluetoothServer::start()
{
if (connected()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is running and a client is connected. Doing nothing.";
if (running()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is already running. Doing nothing.";
return;
}
if (running()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is already running. Doing nothing.";
if (connected()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is running and a client is connected. Doing nothing.";
return;
}
@ -432,7 +432,6 @@ void BluetoothServer::start()
m_localDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
m_localDevice->powerOn();
// Bluetooth low energy periperal controller
m_controller = QLowEnergyController::createPeripheral(this);
connect(m_controller, &QLowEnergyController::stateChanged, this, &BluetoothServer::onControllerStateChanged);
@ -455,37 +454,23 @@ void BluetoothServer::start()
advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
advertisingData.setIncludePowerLevel(true);
advertisingData.setLocalName(m_advertiseName);
// FIXME: set guh manufacturer SIG data once available
// Note: start advertising in 100 ms interval, this makes the device better discoverable on certain phones
QLowEnergyAdvertisingParameters advertisingParameters;
advertisingParameters.setInterval(100,100);
advertisingParameters.setInterval(100, 100);
qCDebug(dcNetworkManagerBluetoothServer()) << "Start advertising" << m_advertiseName << m_localDevice->address().toString();
m_controller->startAdvertising(advertisingParameters, advertisingData, advertisingData);
// Note: setRunning(true) will be called when the service is really advertising, see onControllerStateChanged()
}
void BluetoothServer::stop()
{
if (connected() && m_controller) {
m_controller->disconnectFromDevice();
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
qCDebug(dcNetworkManagerBluetoothServer()) << "Stopping bluetooth server.";
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
if (m_controller) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Stop advertising.";
m_controller->stopAdvertising();
delete m_controller;
m_controller = nullptr;
}
if (m_localDevice) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Set host mode to connectable.";
m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
@ -493,6 +478,13 @@ void BluetoothServer::stop()
m_localDevice = nullptr;
}
if (m_controller) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Stop advertising.";
m_controller->stopAdvertising();
delete m_controller;
m_controller = nullptr;
}
setConnected(false);
setRunning(false);
}

View File

@ -36,5 +36,6 @@ static QBluetoothUuid wirelessServiceUuid = QBluetoothUuid(QUuid
static QBluetoothUuid wirelessCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fec1-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fec2-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessStateCharacteristicUuid = QBluetoothUuid(QUuid("e081fec3-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessModeCharacteristicUuid = QBluetoothUuid(QUuid("e081fec4-f757-4449-b9c9-bfa83133f7fc"));
#endif // BLUETOOTHUUIDS_H

View File

@ -60,6 +60,7 @@ WirelessService::WirelessService(QLowEnergyService *service, NetworkManager *net
m_device = m_networkManager->wirelessNetworkDevices().first();
connect(m_device, &WirelessNetworkDevice::bitRateChanged, this, &WirelessService::onWirelessDeviceBitRateChanged);
connect(m_device, &WirelessNetworkDevice::stateChanged, this, &WirelessService::onWirelessDeviceStateChanged);
connect(m_device, &WirelessNetworkDevice::modeChanged, this, &WirelessService::onWirelessModeChanged);
}
QLowEnergyService *WirelessService::service()
@ -103,6 +104,19 @@ QLowEnergyServiceData WirelessService::serviceData(NetworkManager *networkManage
}
serviceData.addCharacteristic(wirelessStatusCharacteristicData);
// Wireless mode characterisitc e081fec4-f757-4449-b9c9-bfa83133f7fc
QLowEnergyCharacteristicData wirelessModeCharacteristicData;
wirelessModeCharacteristicData.setUuid(wirelessModeCharacteristicUuid);
wirelessModeCharacteristicData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
wirelessModeCharacteristicData.addDescriptor(clientConfigDescriptorData);
wirelessModeCharacteristicData.setValueLength(1, 1);
if (networkManager->wirelessNetworkDevices().isEmpty()) {
wirelessModeCharacteristicData.setValue(WirelessService::getWirelessMode(WirelessNetworkDevice::ModeUnknown));
} else {
wirelessModeCharacteristicData.setValue(WirelessService::getWirelessMode(networkManager->wirelessNetworkDevices().first()->mode()));
}
serviceData.addCharacteristic(wirelessModeCharacteristicData);
return serviceData;
}
@ -168,6 +182,23 @@ QByteArray WirelessService::getWirelessNetworkDeviceState(const NetworkDevice::N
return QByteArray::fromHex("00");
}
QByteArray WirelessService::getWirelessMode(WirelessNetworkDevice::Mode mode)
{
switch (mode) {
case WirelessNetworkDevice::ModeUnknown:
return QByteArray::fromHex("00");
case WirelessNetworkDevice::ModeAdhoc:
return QByteArray::fromHex("01");
case WirelessNetworkDevice::ModeInfrastructure:
return QByteArray::fromHex("02");
case WirelessNetworkDevice::ModeAccessPoint:
return QByteArray::fromHex("03");
}
// Unknown
return QByteArray::fromHex("00");
}
void WirelessService::streamData(const QVariantMap &responseMap)
{
@ -359,6 +390,36 @@ void WirelessService::commandGetCurrentConnection(const QVariantMap &request)
streamData(response);
}
void WirelessService::commandStartAccessPoint(const QVariantMap &request)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not start access point. Service is not valid.";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
if (!request.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Start access point command: Missing parameters.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
QVariantMap parameters = request.value("p").toMap();
if (!parameters.contains("e") || !parameters.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Start access point command: Invalid parameters.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
m_networkManager->startAccessPoint(m_device->interface(), parameters.value("e").toString(), parameters.value("p").toString());
streamData(createResponse(WirelessServiceCommandStartAccessPoint));
}
void WirelessService::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
// Command
@ -493,6 +554,9 @@ void WirelessService::processCommand(const QVariantMap &request)
case WirelessServiceCommandGetCurrentConnection:
commandGetCurrentConnection(request);
break;
case WirelessServiceCommandStartAccessPoint:
commandStartAccessPoint(request);
break;
default:
qCWarning(dcNetworkManagerBluetoothServer()) << "Invalid request. Unknown command" << command;
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand));
@ -522,3 +586,20 @@ void WirelessService::onWirelessDeviceStateChanged(const NetworkDevice::NetworkD
m_service->writeCharacteristic(characteristic, WirelessService::getWirelessNetworkDeviceState(state));
}
void WirelessService::onWirelessModeChanged(WirelessNetworkDevice::Mode mode)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless device mode. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessModeCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless device mode. Characteristic not valid";
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Notify wireless mode changed" << WirelessService::getWirelessMode(mode);
m_service->writeCharacteristic(characteristic, WirelessService::getWirelessMode(mode));
}

View File

@ -44,7 +44,8 @@ public:
WirelessServiceCommandConnectHidden = 0x02,
WirelessServiceCommandDisconnect = 0x03,
WirelessServiceCommandScan = 0x04,
WirelessServiceCommandGetCurrentConnection = 0x05
WirelessServiceCommandGetCurrentConnection = 0x05,
WirelessServiceCommandStartAccessPoint = 0x06
};
Q_ENUM(WirelessServiceCommand)
@ -77,6 +78,7 @@ private:
// Note: static to be available in serviceData
static QByteArray getWirelessNetworkDeviceState(const NetworkDevice::NetworkDeviceState &state);
static QByteArray getWirelessMode(WirelessNetworkDevice::Mode mode);
void streamData(const QVariantMap &responseMap);
@ -89,6 +91,7 @@ private:
void commandDisconnect(const QVariantMap &request);
void commandScan(const QVariantMap &request);
void commandGetCurrentConnection(const QVariantMap &request);
void commandStartAccessPoint(const QVariantMap &request);
private slots:
// Service
@ -105,6 +108,8 @@ private slots:
// Wireless network device
void onWirelessDeviceBitRateChanged(const int &bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState &state);
void onWirelessModeChanged(WirelessNetworkDevice::Mode mode);
};
#endif // WIRELESSSERVICE_H