func()

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
}