2018-10-31 11:17:51 +01:00
|
|
|
package datastructures
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SignerRequest struct {
|
|
|
|
Version uint8
|
|
|
|
Action Action
|
|
|
|
System uint8
|
|
|
|
Root uint8
|
|
|
|
Configuration uint8
|
|
|
|
Parameter1 uint8
|
|
|
|
Parameter2 uint16
|
|
|
|
Parameter3 uint8
|
|
|
|
Content1 string
|
|
|
|
Content2 string
|
|
|
|
Content3 string
|
|
|
|
}
|
|
|
|
|
2020-04-17 19:38:54 +02:00
|
|
|
const protocolVersion = 1
|
|
|
|
|
2018-10-31 11:17:51 +01:00
|
|
|
func SignerRequestFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerRequest, error) {
|
2020-04-17 19:39:01 +02:00
|
|
|
headerLength := Decode24BitLength(blockData[0:3])
|
2018-10-31 11:17:51 +01:00
|
|
|
headerBytes := blockData[3 : 3+headerLength]
|
|
|
|
|
|
|
|
contentBytes := blockData[3+headerLength:]
|
2020-04-17 19:39:01 +02:00
|
|
|
content1Length := Decode24BitLength(contentBytes[0:3])
|
2018-10-31 11:17:51 +01:00
|
|
|
content1 := string(contentBytes[3 : 3+content1Length])
|
|
|
|
|
|
|
|
content2Offset := 3 + content1Length
|
2020-04-17 19:39:01 +02:00
|
|
|
content2Length := Decode24BitLength(contentBytes[content2Offset : content2Offset+3])
|
2018-10-31 11:17:51 +01:00
|
|
|
content2 := string(contentBytes[3+content2Offset : 3+content2Offset+content2Length])
|
|
|
|
|
|
|
|
content3Offset := 3 + content2Offset + content2Length
|
2020-04-17 19:39:01 +02:00
|
|
|
content3Length := Decode24BitLength(contentBytes[content3Offset : content3Offset+3])
|
2018-10-31 11:17:51 +01:00
|
|
|
content3 := string(contentBytes[3+content3Offset : 3+content3Offset+content3Length])
|
|
|
|
|
|
|
|
calculated := CalculateXorCheckSum([][]byte{lengthBytes, blockData})
|
|
|
|
if checkSum != calculated {
|
|
|
|
return nil, errors.New(fmt.Sprintf("invalid checksum expected 0x%x got 0x%x", calculated, checkSum))
|
|
|
|
}
|
|
|
|
return &SignerRequest{
|
|
|
|
Version: headerBytes[0],
|
|
|
|
Action: Action(headerBytes[1]),
|
|
|
|
System: headerBytes[2],
|
|
|
|
Root: headerBytes[3],
|
|
|
|
Configuration: headerBytes[4],
|
|
|
|
Parameter1: headerBytes[5],
|
|
|
|
Parameter2: binary.BigEndian.Uint16([]byte{headerBytes[6], headerBytes[7]}),
|
|
|
|
Parameter3: headerBytes[8],
|
|
|
|
Content1: content1,
|
|
|
|
Content2: content2,
|
|
|
|
Content3: content3,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r SignerRequest) Serialize() []byte {
|
|
|
|
parameter2Bytes := make([]byte, 2)
|
|
|
|
binary.BigEndian.PutUint16(parameter2Bytes, r.Parameter2)
|
|
|
|
headerBytes := bytes.Join([][]byte{
|
|
|
|
{r.Version, byte(r.Action), r.System, r.Root, r.Configuration, r.Parameter1},
|
|
|
|
parameter2Bytes, {r.Parameter3}}, []byte{})
|
|
|
|
content1Bytes := []byte(r.Content1)
|
|
|
|
content2Bytes := []byte(r.Content2)
|
|
|
|
content3Bytes := []byte(r.Content3)
|
|
|
|
blockBytes := bytes.Join([][]byte{
|
|
|
|
encode24BitLength(headerBytes), headerBytes,
|
|
|
|
encode24BitLength(content1Bytes), content1Bytes,
|
|
|
|
encode24BitLength(content2Bytes), content2Bytes,
|
|
|
|
encode24BitLength(content3Bytes), content3Bytes,
|
|
|
|
}, []byte{})
|
|
|
|
return bytes.Join([][]byte{encode24BitLength(blockBytes), blockBytes}, []byte{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewNulRequest() *SignerRequest {
|
2020-04-17 19:38:54 +02:00
|
|
|
return &SignerRequest{
|
2020-04-17 19:39:01 +02:00
|
|
|
Version: protocolVersion,
|
|
|
|
Action: ActionNul,
|
2020-04-17 19:38:54 +02:00
|
|
|
Content1: time.Now().UTC().Format("010203042006.05"),
|
|
|
|
}
|
2018-10-31 11:17:51 +01:00
|
|
|
}
|