Compare commits

...

1 Commits

Author SHA1 Message Date
deadprogram
9f0114a77a gattc/sd: copy data in interrupt handler for characteristic notification events to data that was already allocated before entering the handler
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-10-24 17:37:37 +02:00
2 changed files with 15 additions and 14 deletions

@ -240,11 +240,10 @@ func handleEvent() {
// Find the callback and call it (if there is any).
for _, callbackInfo := range gattcNotificationCallbacks {
if callbackInfo.valueHandle == hvxEvent.handle && callbackInfo.connectionHandle == gattcEvent.conn_handle {
// Create a Go slice from the data, to pass to the
// callback.
data := (*[255]byte)(unsafe.Pointer(&hvxEvent.data[0]))[:hvxEvent.len:hvxEvent.len]
if callbackInfo.callback != nil {
callbackInfo.callback(data)
// copy to Go slice from the data, to pass to the callback.
copy(callbackInfo.data, (*[255]byte)(unsafe.Pointer(&hvxEvent.data[0]))[:hvxEvent.len:hvxEvent.len])
callbackInfo.callback(callbackInfo.data[:hvxEvent.len])
}
break
}

@ -341,6 +341,7 @@ type gattcNotificationCallback struct {
connectionHandle uint16
valueHandle uint16 // may be 0 if the slot is empty
callback func([]byte)
data []byte
}
// List of notification callbacks for the current connection. Some slots may be
@ -348,6 +349,15 @@ type gattcNotificationCallback struct {
// notification callbacks.
var gattcNotificationCallbacks []gattcNotificationCallback
func (c DeviceCharacteristic) newgattcNotificationCallback(cb func([]byte)) gattcNotificationCallback {
return gattcNotificationCallback{
connectionHandle: c.connectionHandle,
valueHandle: c.valueHandle,
data: make([]byte, 255),
callback: cb,
}
}
// EnableNotifications enables notifications in the Client Characteristic
// Configuration Descriptor (CCCD). This means that most peripherals will send a
// notification with a new value every time the value of the characteristic
@ -376,11 +386,7 @@ func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) err
for i, callbackInfo := range gattcNotificationCallbacks {
// Check for empty slots.
if callbackInfo.valueHandle == 0 {
gattcNotificationCallbacks[i] = gattcNotificationCallback{
connectionHandle: c.connectionHandle,
valueHandle: c.valueHandle,
callback: callback,
}
gattcNotificationCallbacks[i] = c.newgattcNotificationCallback(callback)
updatedCallback = true
break
}
@ -393,11 +399,7 @@ func (c DeviceCharacteristic) EnableNotifications(callback func(buf []byte)) err
if !updatedCallback {
// The append call is done outside of a cricital section to avoid GC in
// a critical section.
callbackList := append(gattcNotificationCallbacks, gattcNotificationCallback{
connectionHandle: c.connectionHandle,
valueHandle: c.valueHandle,
callback: callback,
})
callbackList := append(gattcNotificationCallbacks, c.newgattcNotificationCallback(callback))
mask := DisableInterrupts()
gattcNotificationCallbacks = callbackList
RestoreInterrupts(mask)