mirror of
https://github.com/status-im/status-keycard-go.git
synced 2025-01-18 18:31:56 +00:00
add signals
This commit is contained in:
parent
22a20d3b45
commit
c8d0142a16
@ -9,6 +9,7 @@ import (
|
||||
"github.com/status-im/keycard-go/globalplatform"
|
||||
"github.com/status-im/keycard-go/io"
|
||||
"github.com/status-im/keycard-go/types"
|
||||
"github.com/status-im/nim-keycard-go/go/keycard/signal"
|
||||
)
|
||||
|
||||
type keycardContext struct {
|
||||
@ -91,6 +92,7 @@ func (kc *keycardContext) run() {
|
||||
return
|
||||
}
|
||||
|
||||
signal.SendKeycardConnected("")
|
||||
l("card found at index %d", index)
|
||||
reader := kc.readers[index]
|
||||
|
||||
|
12
main.go
12
main.go
@ -6,6 +6,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/status-im/nim-keycard-go/go/keycard/signal"
|
||||
)
|
||||
|
||||
var kctx *keycardContext
|
||||
@ -15,6 +18,10 @@ func main() {
|
||||
}
|
||||
|
||||
func example() {
|
||||
signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||
fmt.Printf("SIGNAL %+v\n", jsonEvent)
|
||||
})
|
||||
|
||||
fmt.Printf("RUNNING EXAMPLE \n")
|
||||
res := Start()
|
||||
fmt.Printf("*** start %+v\n", C.GoString(res))
|
||||
@ -399,3 +406,8 @@ func ChangePairingPassword(jsonParams *C.char) *C.char {
|
||||
|
||||
return retValue("ok", true)
|
||||
}
|
||||
|
||||
//export SetSignalEventCallback
|
||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
||||
signal.SetSignalEventCallback(cb)
|
||||
}
|
||||
|
10
signal/events_keycard.go
Normal file
10
signal/events_keycard.go
Normal file
@ -0,0 +1,10 @@
|
||||
package signal
|
||||
|
||||
const (
|
||||
// EventSignRequestAdded is triggered when send transaction request is queued
|
||||
EventKeycardConnected = "keycard.connected"
|
||||
)
|
||||
|
||||
func SendKeycardConnected(event interface{}) {
|
||||
send(EventKeycardConnected, event)
|
||||
}
|
25
signal/signals.c
Normal file
25
signal/signals.c
Normal file
@ -0,0 +1,25 @@
|
||||
// ======================================================================================
|
||||
// cgo compilation (for desktop platforms and local tests)
|
||||
// ======================================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
typedef void (*callback)(const char *jsonEvent);
|
||||
callback gCallback = 0;
|
||||
|
||||
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||
if (gCallback) {
|
||||
gCallback(jsonEvent);
|
||||
} else {
|
||||
NotifyNode((char *)jsonEvent); // re-send notification back to status node
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetEventCallback(void *cb) {
|
||||
gCallback = (callback)cb;
|
||||
}
|
116
signal/signals.go
Normal file
116
signal/signals.go
Normal file
@ -0,0 +1,116 @@
|
||||
package signal
|
||||
|
||||
/*
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
extern bool StatusServiceSignalEvent(const char *jsonEvent);
|
||||
extern void SetEventCallback(void *cb);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"unsafe"
|
||||
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// MobileSignalHandler is a simple callback function that gets called when any signal is received
|
||||
type MobileSignalHandler func([]byte)
|
||||
|
||||
// storing the current signal handler here
|
||||
var mobileSignalHandler MobileSignalHandler
|
||||
|
||||
// All general log messages in this package should be routed through this logger.
|
||||
var logger = log.New("package", "status-go/signal")
|
||||
|
||||
// Envelope is a general signal sent upward from node to RN app
|
||||
type Envelope struct {
|
||||
Type string `json:"type"`
|
||||
Event interface{} `json:"event"`
|
||||
}
|
||||
|
||||
// NewEnvelope creates new envlope of given type and event payload.
|
||||
func NewEnvelope(typ string, event interface{}) *Envelope {
|
||||
return &Envelope{
|
||||
Type: typ,
|
||||
Event: event,
|
||||
}
|
||||
}
|
||||
|
||||
// send sends application signal (in JSON) upwards to application (via default notification handler)
|
||||
func send(typ string, event interface{}) {
|
||||
signal := NewEnvelope(typ, event)
|
||||
data, err := json.Marshal(&signal)
|
||||
if err != nil {
|
||||
logger.Error("Marshalling signal envelope", "error", err)
|
||||
return
|
||||
}
|
||||
// If a Go implementation of signal handler is set, let's use it.
|
||||
if mobileSignalHandler != nil {
|
||||
mobileSignalHandler(data)
|
||||
} else {
|
||||
// ...and fallback to C implementation otherwise.
|
||||
str := C.CString(string(data))
|
||||
C.StatusServiceSignalEvent(str)
|
||||
C.free(unsafe.Pointer(str))
|
||||
}
|
||||
}
|
||||
|
||||
// NodeNotificationHandler defines a handler able to process incoming node events.
|
||||
// Events are encoded as JSON strings.
|
||||
type NodeNotificationHandler func(jsonEvent string)
|
||||
|
||||
var notificationHandler NodeNotificationHandler = TriggerDefaultNodeNotificationHandler
|
||||
|
||||
// notificationHandlerMutex guards notificationHandler for concurrent calls
|
||||
var notificationHandlerMutex sync.RWMutex
|
||||
|
||||
// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
|
||||
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
||||
notificationHandlerMutex.Lock()
|
||||
notificationHandler = fn
|
||||
notificationHandlerMutex.Unlock()
|
||||
}
|
||||
|
||||
// ResetDefaultNodeNotificationHandler sets notification handler to default one
|
||||
func ResetDefaultNodeNotificationHandler() {
|
||||
notificationHandlerMutex.Lock()
|
||||
notificationHandler = TriggerDefaultNodeNotificationHandler
|
||||
notificationHandlerMutex.Unlock()
|
||||
}
|
||||
|
||||
// TriggerDefaultNodeNotificationHandler triggers default notification handler (helpful in tests)
|
||||
func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
|
||||
logger.Trace("Notification received", "event", jsonEvent)
|
||||
}
|
||||
|
||||
//export NotifyNode
|
||||
//nolint: golint
|
||||
func NotifyNode(jsonEvent *C.char) {
|
||||
notificationHandlerMutex.RLock()
|
||||
defer notificationHandlerMutex.RUnlock()
|
||||
notificationHandler(C.GoString(jsonEvent))
|
||||
}
|
||||
|
||||
//export TriggerTestSignal
|
||||
//nolint: golint
|
||||
func TriggerTestSignal() {
|
||||
str := C.CString(`{"answer": 42}`)
|
||||
C.StatusServiceSignalEvent(str)
|
||||
C.free(unsafe.Pointer(str))
|
||||
}
|
||||
|
||||
// SetMobileSignalHandler sets new handler for geth events
|
||||
// this function uses pure go implementation
|
||||
func SetMobileSignalHandler(handler MobileSignalHandler) {
|
||||
mobileSignalHandler = handler
|
||||
}
|
||||
|
||||
// SetSignalEventCallback set callback
|
||||
// this function uses C implementation (see `signals.c` file)
|
||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
||||
C.SetEventCallback(cb)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user