diff --git a/adapter_hci.go b/adapter_hci.go index c5c5ce3..fe5d57f 100644 --- a/adapter_hci.go +++ b/adapter_hci.go @@ -22,6 +22,7 @@ type hciAdapter struct { connectedDevices []Device notificationsStarted bool + charWriteHandlers []charWriteHandler } func (a *hciAdapter) enable() error { @@ -174,3 +175,23 @@ func (a *hciAdapter) findConnection(handle uint16) Device { return Device{} } + +// charWriteHandler contains a handler->callback mapping for characteristic +// writes. +type charWriteHandler struct { + handle uint16 + callback func(connection Connection, offset int, value []byte) +} + +// getCharWriteHandler returns a characteristic write handler if one matches the +// handle, or nil otherwise. +func (a *Adapter) getCharWriteHandler(handle uint16) *charWriteHandler { + for i := range a.charWriteHandlers { + h := &a.charWriteHandlers[i] + if h.handle == handle { + return h + } + } + + return nil +} diff --git a/gatts_hci.go b/gatts_hci.go index 6f8935a..abc7bb7 100644 --- a/gatts_hci.go +++ b/gatts_hci.go @@ -53,6 +53,16 @@ func (a *Adapter) AddService(service *Service) error { service.Characteristics[i].Handle.value = service.Characteristics[i].Value } + if (service.Characteristics[i].Flags.Write() || + service.Characteristics[i].Flags.WriteWithoutResponse()) && + service.Characteristics[i].WriteEvent != nil { + handlers := append(a.charWriteHandlers, charWriteHandler{ + handle: valueHandle, + callback: service.Characteristics[i].WriteEvent, + }) + a.charWriteHandlers = handlers + } + if debug { println("added characteristic", charHandle, valueHandle, service.Characteristics[i].UUID.String()) } @@ -71,11 +81,17 @@ func (a *Adapter) AddService(service *Service) error { // Write replaces the characteristic value with a new value. func (c *Characteristic) Write(p []byte) (n int, err error) { - if !c.permissions.Notify() { - return 0, errNoNotify + if !(c.permissions.Write() || c.permissions.WriteWithoutResponse() || + c.permissions.Notify() || c.permissions.Indicate()) { + return 0, errNoWrite } - c.value = append([]byte{}, p...) + hdl := c.adapter.getCharWriteHandler(c.handle) + if hdl != nil { + hdl.callback(Connection(c.handle), 0, p) + } + + copy(c.value, p) if c.cccd&0x01 != 0 { // send notification