diff --git a/peripheral.go b/peripheral.go index 27a9130..3aa61f8 100644 --- a/peripheral.go +++ b/peripheral.go @@ -48,9 +48,12 @@ type Peripheral interface { // WriteDescriptor writes the value of a characteristic descriptor. WriteDescriptor(d *Descriptor, b []byte) error - // SetNotifyValue sets notifications or indications for the value of a specified characteristic. + // SetNotifyValue sets notifications for the value of a specified characteristic. SetNotifyValue(c *Characteristic, f func(*Characteristic, []byte, error)) error + // SetIndicateValue sets indications for the value of a specified characteristic. + SetIndicateValue(c *Characteristic, f func(*Characteristic, []byte, error)) error + // ReadRSSI retrieves the current RSSI value for the remote peripheral. ReadRSSI() int } diff --git a/peripheral_darwin.go b/peripheral_darwin.go index 9dde494..434e65e 100644 --- a/peripheral_darwin.go +++ b/peripheral_darwin.go @@ -189,6 +189,12 @@ func (p *peripheral) SetNotifyValue(c *Characteristic, f func(*Characteristic, [ return nil } +func (p *peripheral) SetIndicateValue(c *Characteristic, + f func(*Characteristic, []byte, error)) error { + // TODO: Implement set indications logic for darwin (https://github.com/paypal/gatt/issues/32) + return nil +} + func (p *peripheral) ReadRSSI() int { rsp := p.sendReq(43, xpc.Dict{"kCBMsgArgDeviceUUID": p.id}) return rsp.MustGetInt("kCBMsgArgData") diff --git a/peripheral_linux.go b/peripheral_linux.go index 58668f6..acaf3d9 100644 --- a/peripheral_linux.go +++ b/peripheral_linux.go @@ -260,14 +260,14 @@ func (p *peripheral) WriteDescriptor(d *Descriptor, value []byte) error { return nil } -func (p *peripheral) SetNotifyValue(c *Characteristic, +func (p *peripheral) setNotifyValue(c *Characteristic, flag uint16, f func(*Characteristic, []byte, error)) error { if c.cccd == nil { return errors.New("no cccd") // FIXME } ccc := uint16(0) if f != nil { - ccc = gattCCCNotifyFlag + ccc = flag p.sub.subscribe(c.vh, func(b []byte, err error) { f(c, b, err) }) } b := make([]byte, 5) @@ -285,6 +285,17 @@ func (p *peripheral) SetNotifyValue(c *Characteristic, return nil } +func (p *peripheral) SetNotifyValue(c *Characteristic, + f func(*Characteristic, []byte, error)) error { + return p.setNotifyValue(c, gattCCCNotifyFlag, f) +} + +func (p *peripheral) SetIndicateValue(c *Characteristic, + f func(*Characteristic, []byte, error)) error { + return p.setNotifyValue(c, gattCCCIndicateFlag, f) +} + + func (p *peripheral) ReadRSSI() int { // TODO: implement return -1 @@ -348,7 +359,7 @@ func (p *peripheral) loop() { // The default value is 672 bytes buf := make([]byte, 672) - // Handling response or notification + // Handling response or notification/indication for { n, err := p.l2c.Read(buf) if n == 0 || err != nil { @@ -359,10 +370,11 @@ func (p *peripheral) loop() { b := make([]byte, n) copy(b, buf) - if b[0] != attOpHandleNotify { + if (b[0] != attOpHandleNotify) && (b[0] != attOpHandleInd) { rspc <- b continue } + h := binary.LittleEndian.Uint16(b[1:3]) f := p.sub.fn(h) if f == nil { @@ -371,5 +383,11 @@ func (p *peripheral) loop() { continue } go f(b[3:], nil) + + if b[0] == attOpHandleInd { + // write aknowledgement for indication + p.l2c.Write([]byte{attOpHandleCnf}) + } + } } diff --git a/readme.md b/readme.md index 052cd83..ea3a957 100644 --- a/readme.md +++ b/readme.md @@ -94,6 +94,10 @@ characteristics, you may need to reboot the other device to pick up the changes. This is a common source of confusion and apparent bugs. For an OS X central, see http://stackoverflow.com/questions/20553957. +## Known Issues + +Currently OS X vesion does not support subscribing to indications. +Please check [#32](https://github.com/paypal/gatt/issues/32) for the status of this issue. ## REFERENCES