2020-05-30 21:55:20 +03:00
|
|
|
package bluetooth
|
|
|
|
|
|
|
|
import (
|
2022-08-03 14:15:10 +03:00
|
|
|
"fmt"
|
|
|
|
|
2020-05-30 21:55:20 +03:00
|
|
|
"github.com/go-ole/go-ole"
|
2022-08-03 14:15:10 +03:00
|
|
|
"github.com/saltosystems/winrt-go"
|
2022-07-04 19:48:45 +03:00
|
|
|
"github.com/saltosystems/winrt-go/windows/devices/bluetooth/advertisement"
|
2022-08-03 14:15:10 +03:00
|
|
|
"github.com/saltosystems/winrt-go/windows/foundation"
|
2020-05-30 21:55:20 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type Adapter struct {
|
2022-07-04 19:48:45 +03:00
|
|
|
watcher *advertisement.BluetoothLEAdvertisementWatcher
|
2020-09-10 18:17:45 +03:00
|
|
|
|
|
|
|
connectHandler func(device Addresser, connected bool)
|
2020-05-30 21:55:20 +03:00
|
|
|
}
|
|
|
|
|
2020-06-01 14:26:45 +03:00
|
|
|
// DefaultAdapter is the default adapter on the system.
|
|
|
|
//
|
|
|
|
// Make sure to call Enable() before using it to initialize the adapter.
|
2020-09-10 18:17:45 +03:00
|
|
|
var DefaultAdapter = &Adapter{
|
|
|
|
connectHandler: func(device Addresser, connected bool) {
|
|
|
|
return
|
|
|
|
},
|
|
|
|
}
|
2020-05-30 21:55:20 +03:00
|
|
|
|
|
|
|
// Enable configures the BLE stack. It must be called before any
|
|
|
|
// Bluetooth-related calls (unless otherwise indicated).
|
|
|
|
func (a *Adapter) Enable() error {
|
|
|
|
return ole.RoInitialize(1) // initialize with multithreading enabled
|
|
|
|
}
|
2022-08-03 14:15:10 +03:00
|
|
|
|
|
|
|
func awaitAsyncOperation(asyncOperation *foundation.IAsyncOperation, genericParamSignature string) error {
|
|
|
|
var status foundation.AsyncStatus
|
|
|
|
|
|
|
|
// We need to obtain the GUID of the AsyncOperationCompletedHandler, but its a generic delegate
|
|
|
|
// so we also need the generic parameter type's signature:
|
|
|
|
// AsyncOperationCompletedHandler<genericParamSignature>
|
|
|
|
iid := winrt.ParameterizedInstanceGUID(foundation.GUIDAsyncOperationCompletedHandler, genericParamSignature)
|
|
|
|
|
|
|
|
// Wait until the async operation completes.
|
|
|
|
waitChan := make(chan struct{})
|
|
|
|
asyncOperation.SetCompleted(foundation.NewAsyncOperationCompletedHandler(ole.NewGUID(iid), func(instance *foundation.AsyncOperationCompletedHandler, asyncInfo *foundation.IAsyncOperation, asyncStatus foundation.AsyncStatus) {
|
|
|
|
status = asyncStatus
|
|
|
|
close(waitChan)
|
|
|
|
}))
|
|
|
|
// Wait until async operation has stopped, and finish.
|
|
|
|
<-waitChan
|
|
|
|
|
|
|
|
if status != foundation.AsyncStatusCompleted {
|
|
|
|
return fmt.Errorf("async operation failed with status %d", status)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|