// 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) } }
// 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") } }