Example #1
0
// Dial ...
func (d *Device) Dial(ctx context.Context, a ble.Addr) (ble.Client, error) {
	d.sendCmd(d.cm, 31, xpc.Dict{
		"kCBMsgArgDeviceUUID": xpc.MakeUUID(a.String()),
		"kCBMsgArgOptions": xpc.Dict{
			"kCBConnectOptionNotifyOnDisconnection": 1,
		},
	})
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case c := <-d.chConn:
		c.SetContext(ctx)
		return NewClient(c)
	}
}
Example #2
0
// Dial ...
func (h *HCI) Dial(ctx context.Context, a ble.Addr) (ble.Client, error) {
	b, err := net.ParseMAC(a.String())
	if err != nil {
		return nil, ErrInvalidAddr
	}
	h.params.connParams.PeerAddress = [6]byte{b[5], b[4], b[3], b[2], b[1], b[0]}
	if _, ok := a.(RandomAddress); ok {
		h.params.connParams.PeerAddressType = 1
	}
	if err = h.Send(&h.params.connParams, nil); err != nil {
		return nil, err
	}
	var tmo <-chan time.Time
	if h.dialerTmo != time.Duration(0) {
		tmo = time.After(h.dialerTmo)
	}
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-h.done:
		return nil, h.err
	case c := <-h.chMasterConn:
		return gatt.NewClient(c)
	case <-tmo:
		err := h.Send(&h.params.connCancel, nil)
		if err == nil {
			// The pending connection was canceled successfully.
			return nil, fmt.Errorf("connection timed out")
		}
		// The connection has been established, the cancel command
		// failed with ErrDisallowed.
		if err == ErrDisallowed {
			return gatt.NewClient(<-h.chMasterConn)
		}
		return nil, errors.Wrap(err, "cancel connection failed")
	}
}