Bidirectional msgpack wire protocol with unpack support
This commit is contained in:
@@ -33,11 +33,20 @@ func RegisterExt(extID int8, value interface{}) {
|
||||
return v.Interface().(Marshaler).MarshalMsgpack()
|
||||
})
|
||||
} else {
|
||||
encTyp := typ
|
||||
if encTyp.Kind() == reflect.Ptr {
|
||||
encTyp = encTyp.Elem()
|
||||
}
|
||||
structEncoder := _getEncoder(encTyp)
|
||||
RegisterExtEncoder(extID, value, func(e *Encoder, v reflect.Value) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
enc := NewEncoder(&buf)
|
||||
enc.UseArrayEncodedStructs(true)
|
||||
if err := enc.Encode(v.Interface()); err != nil {
|
||||
val := v
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
if err := structEncoder(enc, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
|
||||
@@ -25,22 +25,8 @@ func Open(portName string) (serial.Port, error) {
|
||||
return serial.Open(portName, &serial.Mode{BaudRate: 115200})
|
||||
}
|
||||
|
||||
func SendByte(portName string, b byte) error {
|
||||
port, err := Open(portName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening %s: %w", portName, err)
|
||||
}
|
||||
defer port.Close()
|
||||
|
||||
_, err = port.Write([]byte{b})
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing to %s: %w", portName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendByteAndRead sends a byte and reads the response with a timeout.
|
||||
func SendByteAndRead(portName string, b byte, timeout time.Duration) ([]byte, error) {
|
||||
// SendAndReceive sends data and reads the response with a timeout.
|
||||
func SendAndReceive(portName string, data []byte, timeout time.Duration) ([]byte, error) {
|
||||
port, err := Open(portName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening %s: %w", portName, err)
|
||||
@@ -49,7 +35,7 @@ func SendByteAndRead(portName string, b byte, timeout time.Duration) ([]byte, er
|
||||
|
||||
port.SetReadTimeout(timeout)
|
||||
|
||||
_, err = port.Write([]byte{b})
|
||||
_, err = port.Write(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("writing to %s: %w", portName, err)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
|
||||
var HashKey = [8]byte{}
|
||||
|
||||
type RebootingBootsel struct{}
|
||||
type ResponseBOOTSEL struct{}
|
||||
type RequestBOOTSEL struct{}
|
||||
|
||||
type Envelope struct {
|
||||
Checksum uint32
|
||||
@@ -18,7 +19,23 @@ type Envelope struct {
|
||||
|
||||
func init() {
|
||||
msgpack.RegisterExt(0, (*Envelope)(nil))
|
||||
msgpack.RegisterExt(1, (*RebootingBootsel)(nil))
|
||||
msgpack.RegisterExt(1, (*ResponseBOOTSEL)(nil))
|
||||
msgpack.RegisterExt(2, (*RequestBOOTSEL)(nil))
|
||||
}
|
||||
|
||||
func EncodeMessage(msg any) ([]byte, error) {
|
||||
payload, err := msgpack.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode inner: %w", err)
|
||||
}
|
||||
|
||||
checksum := halfsiphash.Sum32(payload, HashKey)
|
||||
env := Envelope{Checksum: checksum, Payload: payload}
|
||||
data, err := msgpack.Marshal(&env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode envelope: %w", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func DecodeMessage(data []byte) (any, error) {
|
||||
|
||||
Reference in New Issue
Block a user