diff --git a/adapter_sd.go b/adapter_sd.go index ddb614d..5053e78 100644 --- a/adapter_sd.go +++ b/adapter_sd.go @@ -57,8 +57,9 @@ func init() { // Adapter is a dummy adapter: it represents the connection to the (only) // SoftDevice on the chip. type Adapter struct { - isDefault bool - handler func(Event) + isDefault bool + handler func(Event) + charWriteHandlers []charWriteHandler } // DefaultAdapter is an adapter to the default Bluetooth stack on a given @@ -123,6 +124,18 @@ func handleEvent() { case C.BLE_GAP_EVT_DISCONNECTED: handler(&DisconnectEvent{GAPEvent: gapEvent}) } + case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST: + gattsEvent := eventBuf.evt.unionfield_gatts_evt() + switch id { + case C.BLE_GATTS_EVT_WRITE: + writeEvent := gattsEvent.params.unionfield_write() + len := writeEvent.len - writeEvent.offset + data := (*[255]byte)(unsafe.Pointer(&writeEvent.data[0]))[:len:len] + handler := DefaultAdapter.getCharWriteHandler(writeEvent.handle) + if handler != nil { + handler.callback(Connection(gattsEvent.conn_handle), int(writeEvent.offset), data) + } + } } } diff --git a/gatts.go b/gatts.go index e30a3f1..d920a2c 100644 --- a/gatts.go +++ b/gatts.go @@ -22,8 +22,9 @@ type Characteristic struct { type CharacteristicConfig struct { Handle *Characteristic UUID - Value []byte - Flags CharacteristicPermissions + Value []byte + Flags CharacteristicPermissions + WriteEvent func(client Connection, offset int, value []byte) } // Handle returns the numeric handle for this characteristic. This is used diff --git a/gatts_sd.go b/gatts_sd.go index 71cd386..34e505c 100644 --- a/gatts_sd.go +++ b/gatts_sd.go @@ -55,6 +55,36 @@ func (a *Adapter) AddService(service *Service) error { char.Handle.handle = handles.value_handle char.Handle.permissions = char.Flags } + if char.Flags.Write() && char.WriteEvent != nil { + a.charWriteHandlers = append(a.charWriteHandlers, charWriteHandler{ + handle: handles.value_handle, + callback: char.WriteEvent, + }) + } } return makeError(errCode) } + +// 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 { + // Look through all handlers for a match. + // There is probably a way to do this more efficiently (with a hashmap for + // example) but the number of event handlers is likely low and improving + // this does not need an API change. + for i := range a.charWriteHandlers { + h := &a.charWriteHandlers[i] + if h.handle == handle { + // Handler found. + return h + } + } + return nil // not found +}