in nmxact/nmble/ble_xport.go [157:242]
func (bx *BleXport) startSyncer() error {
syncCh, resetCh, err := bx.syncer.Start(bx)
if err != nil {
return err
}
initialSyncCh := make(chan struct{})
// Listen for events in the background:
// * sync loss
// * stack reset
// * GATT access
bx.wg.Add(1)
go func() {
defer bx.wg.Done()
accessl, err := bx.addAccessListener()
if err != nil {
bx.enqueueShutdown(err)
return
}
defer bx.RemoveListener(accessl)
for {
select {
case reason, ok := <-resetCh:
if ok {
// Ignore resets prior to initial sync.
if initialSyncCh == nil {
bx.enqueueShutdown(nmxutil.NewXportError(fmt.Sprintf(
"The BLE controller has been reset by the host; "+
"reason=%s (%d)",
ErrCodeToString(reason), reason)))
}
}
case synced, ok := <-syncCh:
if ok {
if !synced {
bx.enqueueShutdown(nmxutil.NewXportError(
"BLE host <-> controller sync lost"))
} else if initialSyncCh != nil {
close(initialSyncCh)
initialSyncCh = nil
}
}
case err, ok := <-accessl.ErrChan:
if ok {
bx.enqueueShutdown(err)
}
case bm, ok := <-accessl.MsgChan:
if ok {
switch msg := bm.(type) {
case *BleAccessEvt:
if err := bx.cm.Access(bx, msg); err != nil {
log.Debugf("Error sending access status: %s",
err.Error())
}
}
}
case <-bx.stopChan:
return
}
}
}()
bx.syncer.Refresh()
// Block until host and controller are synced.
select {
case <-initialSyncCh:
case <-time.After(bx.cfg.SyncTimeout):
return nmxutil.NewXportError(fmt.Sprintf(
"Error waiting for host <-> controller sync: timeout (%s)",
bx.cfg.SyncTimeout.String()))
case <-bx.stopChan:
return nmxutil.NewXportError("stopped")
}
return nil
}