DeviceInformation::FindAllAsync не может найти устройства с идентификатором службы RFCOMM
Мне нужна простая настройка клиент / сервер с двумя телефонами Windows, и я использую следующий код для настройки сервера:
auto providerTask = create_task(RfcommServiceProvider::CreateAsync(RfcommServiceId::FromUuid(GetServiceGUID())));
providerTask.then([this](RfcommServiceProvider^ p) -> task < void >
{
this->provider = p;
this->listener = ref new StreamSocketListener();
listener->ConnectionReceived += ref new Windows::Foundation::TypedEventHandler < Windows::Networking::Sockets::StreamSocketListener ^,
Windows::Networking::Sockets::StreamSocketListenerConnectionReceivedEventArgs ^ >
(this, &ConnectionManager::OnConnectionReceived);
return create_task(listener->BindServiceNameAsync(provider->ServiceId->AsString())).then([this]()
{
this->provider->StartAdvertising(listener);
});
}).then([](task<void> t)
{
//handle exceptions at the end of the chain
try
{
t.get();
}
catch (Platform::Exception^ ex)
{
if (ex->HResult == 0x9000000F)
{
OutputDebugString(L"Bluetooth is disabled.\n");
}
else throw ex;
}
});
GetServiceGUID () просто возвращает идентификатор, который я создал для своего приложения с помощью встроенного в VS инструмента GUID; тот же самый также объявлен в манифесте приложения.
На втором устройстве я ищу такие серверы:
auto query = RfcommDeviceService::GetDeviceSelector(RfcommServiceId::FromUuid(GetServiceGUID()));
create_task(DeviceInformation::FindAllAsync(query))
.then([this](DeviceInformationCollection^ services)
{
if (services->Size > 0)
{
OutputDebugString(L"We've found a server!\n");
OutputDebugString(services->First()->Current->Name->Data());
}
});
Вызов FindAllAsync всегда возвращает пустую коллекцию, даже если в настройках оба устройства показаны как спаренные. Однако, если я использую RfcommServiceId::ObexObjectPush вместо FromUuid при настройке сервера и позже при перечислении устройств, он работает нормально. Кто-нибудь знает, почему это происходит?
1 ответ
Как выглядят строки селектора AQS в обоих случаях?
Проблема либо в:
- Селектор неожиданно не соответствует интерфейсу в системе
В основном фильтр используется для сопоставления свойств на интерфейсах устройств, которые в данный момент находятся в состоянии KM PnP. Если свойства интерфейса соответствуют тому, что логически запрашивается в селекторе, он добавляется в сбор информации об устройстве.
Может быть, попробуйте FindAllAsync без селектора, а затем посмотрите, какие интерфейсы в настоящее время перечисляются KM PnP. Запросите свойства, которые есть в селекторе. Как только вы увидите интерфейс, который, по вашему мнению, вы должны видеть, логически выясните, почему он не соответствует селектору.
- Устройство не сопряжено.
Если устройство не сопряжено, тогда не будет никаких узлов или интерфейсов для его представления. Следовательно, он не может быть обнаружен с помощью FindAllAsync
- Устройство сопряжено, но не имеет того профиля, который, по вашему мнению, имеет.
Драйвер шины Bluetooth будет создавать состояние PnP только для профилей, которые он понимает. Состояние PnP требуется для FindAllAsync, чтобы найти его. RFCOMM является базовым, поэтому он должен работать.
В любом случае, начните с написания некоторого тестового кода, как описано в 1. Это даст вам некоторую информацию для дальнейшего расследования.
Также ознакомьтесь с новыми изменениями API Windows 10 для Windows.Devices.Enumeration. Существуют новые способы обнаружения устройств Bluetooth.
-Сэм