|
Registriert seit: 13. Dez 2007 Ort: Bruck an der Mur 69 Beiträge |
#5
Nur kurz zur Info - es scheint, dass das Enumerieren der Characteristiken in Win11 IN einem Thread sein sollt - nicht im Haupthread...
(Message loop und BTLE stehen sowieso auf "Kriegsfuß". Manche Dinge müssen im Haupthread gemacht werden, manche eben nicht). Der Fix ist im Endefekt in der Datei System.Win.BluetoothWinRT.pas in den Routinen "DoDiscoverServices" und "DoGetCharacteristics" und "DoGetIncludedServices" einzubauen (Ich habe auch noch eine Art "Timeout" hinzugefügt...): Hier mein Code:
Code:
Bitte mal mit dem Snipplets probieren und für fTimeout = 10000 einsetzen. fCharacteristicsFetched ist auch von mir und sollte im TWinRTBluetoothGattService als private variable deklariert werden.
function TWinRTBluetoothLEDevice.DoDiscoverServices: Boolean;
var I: Integer; LGattService: GenericAttributeProfile_IGattDeviceService; dev3 : IBluetoothLEDevice3; res3 : IAsyncOperation_1__GenericAttributeProfile_IGattDeviceServicesResult; serviceRes : GenericAttributeProfile_IGattDeviceServicesResult; LGattServices: IVectorView_1__GenericAttributeProfile_IGattDeviceService; begin Result := True; FServices.Clear; CheckInitialized; if FID = 0 then begin if not Supports(FBluetoothLEDevice, IBluetoothLEDevice3, dev3) then raise EBluetoothDeviceException.CreateRes(@SBluetoothLEDeviceNotPaired); if TAsyncOperation<IAsyncOperation_1__GenericAttributeProfile_IGattDeviceServicesResult>.Wait( dev3.GetGattServicesAsync(BluetoothCacheMode.Uncached), res3 ) = AsyncStatus.Completed then begin serviceRes := res3.GetResults; LGattServices := serviceRes.Services; if LGattServices.Size > 0 then begin for I := 0 to LGattServices.Size - 1 do begin LGattService := LGattServices.GetAt(I); FServices.Add(TWinRTBluetoothGattService.Create(Self, LGattService, TBluetoothServiceType.Primary)); end; end; end; end else begin if FBluetoothLEDevice.GattServices.Size > 0 then for I := 0 to FBluetoothLEDevice.GattServices.Size - 1 do begin LGattService := FBluetoothLEDevice.GattServices.GetAt(I); FServices.Add(TWinRTBluetoothGattService.Create(Self, LGattService, TBluetoothServiceType.Primary)); end; end; // ########################################### // #### enumerate the characteristics at once: note on windows 11 it seems // that the enumeration of characteristics NEED to be in a thread and // we trigger the characteristics fetch for i := 0 to fServices.Count - 1 do begin TWinRTBluetoothGattService(fServices[i]).FTimeout := fOperationTimeout; TWinRTBluetoothGattService(fServices[i]).DoGetCharacteristics; end; DoOnServicesDiscovered(Self, FServices); end; tion TWinRTBluetoothGattService.DoGetCharacteristics: TBluetoothGattCharacteristicList; var I: Integer; service3 : GenericAttributeProfile_IGattDeviceService3; LGattCharacteristics: IVectorView_1__GenericAttributeProfile_IGattCharacteristic; res3 : IAsyncOperation_1__GenericAttributeProfile_IGattCharacteristicsResult; status1 : IAsyncOperation_1__GenericAttributeProfile_GattOpenStatus; charactersRes : GenericAttributeProfile_IGattCharacteristicsResult; characteristic : GenericAttributeProfile_IGattCharacteristic; begin Result := FCharacteristics; if fCharacteristicsFetched then exit; CheckNotClosed; FCharacteristics.Clear; if Supports(FGattService, GenericAttributeProfile_IGattDeviceService3, service3) then begin if TAsyncOperation<IAsyncOperation_1__GenericAttributeProfile_GattOpenStatus>.Wait( service3.OpenAsync(GenericAttributeProfile_GattSharingMode.SharedReadAndWrite), status1 ) <> AsyncStatus.Completed then exit(nil); if (status1.GetResults = GenericAttributeProfile_GattOpenStatus.Success) or (status1.GetResults = GenericAttributeProfile_GattOpenStatus.AlreadyOpened) then begin if TAsyncOperation<IAsyncOperation_1__GenericAttributeProfile_IGattCharacteristicsResult>.Wait( service3.GetCharacteristicsAsync(BluetoothCacheMode.Uncached), res3, FTimeout ) = AsyncStatus.Completed then begin charactersRes := res3.GetResults; LGattCharacteristics := charactersRes.Characteristics; if LGattCharacteristics.Size > 0 then begin for I := LGattCharacteristics.Size - 1 downto 0 do begin characteristic := LGattCharacteristics.GetAt(I); FCharacteristics.Add(TWinRTBluetoothGattCharacteristic.Create(Self, characteristic)); end; end; end; end else OutputDebugString(PChar('RequestAccessAysync failed with code ' + Integer(status1.GetResults).tostring)); end else begin // does not work any more -> need to do sync LGattCharacteristics := (FGattService as GenericAttributeProfile_IGattDeviceService2).GetAllCharacteristics; if LGattCharacteristics.Size > 0 then for I := 0 to LGattCharacteristics.Size - 1 do FCharacteristics.Add(TWinRTBluetoothGattCharacteristic.Create(Self, LGattCharacteristics.GetAt(I))); end; for i := 0 to FCharacteristics.Count - 1 do begin TWinRTBluetoothGattCharacteristic(fCharacteristics[i]).FTimeout := FTimeout; TWinRTBluetoothGattCharacteristic(fCharacteristics[i]).DoGetDescriptors; end; fCharacteristicsFetched := True; Result := FCharacteristics; end; function TWinRTBluetoothGattService.DoGetIncludedServices: TBluetoothGattServiceList; var I: Integer; LGattServices: IVectorView_1__GenericAttributeProfile_IGattDeviceService; service3 : GenericAttributeProfile_IGattDeviceService3; res3 : IAsyncOperation_1__GenericAttributeProfile_IGattDeviceServicesResult; serviceRes : GenericAttributeProfile_IGattDeviceServicesResult; status1 : IAsyncOperation_1__GenericAttributeProfile_GattOpenStatus; begin CheckNotClosed; FIncludedServices.Clear; if Supports(FGattService, GenericAttributeProfile_IGattDeviceService3, service3) then begin if TAsyncOperation<IAsyncOperation_1__GenericAttributeProfile_GattOpenStatus>.Wait( service3.OpenAsync(GenericAttributeProfile_GattSharingMode.SharedReadAndWrite), status1 ) <> AsyncStatus.Completed then exit(nil); if (status1.GetResults = GenericAttributeProfile_GattOpenStatus.Success) or (status1.GetResults = GenericAttributeProfile_GattOpenStatus.AlreadyOpened) then begin if TAsyncOperation<IAsyncOperation_1__GenericAttributeProfile_IGattDeviceServicesResult>.Wait( service3.GetIncludedServicesAsync, res3, FTimeout ) = AsyncStatus.Completed then begin serviceRes := res3.GetResults; LGattServices := serviceRes.Services; if LGattServices.Size > 0 then begin for I := LGattServices.Size - 1 downto 0 do FIncludedServices.Add(TWinRTBluetoothGattService.Create(FDevice, LGattServices.GetAt(I), TBluetoothServiceType.Primary)); end; end; end else OutputDebugString(PChar('RequestAccessAysync failed with code ' + Integer(status1.GetResults).tostring)); end else begin LGattServices := (FGattService as GenericAttributeProfile_IGattDeviceService2).GetAllIncludedServices; if LGattServices.Size > 0 then for I := 0 to LGattServices.Size - 1 do FIncludedServices.Add(TWinRTBluetoothGattService.Create(FDevice, LGattServices.GetAt(I), TBluetoothServiceType.Primary)); end; Result := FIncludedServices; end; Falls wer noch interesse hat ich kann das File auch schicken - nur nicht ganz öffentlich machen... |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |