80b3309c7c
This commit switches to serial port library to the better maintained go.bug.st/serial library.
99 lines
2.6 KiB
Go
99 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"go.bug.st/serial"
|
|
|
|
"git.cacert.org/cacert-gosigner/datastructures"
|
|
"git.cacert.org/cacert-gosigner/shared"
|
|
)
|
|
|
|
func sendHandShake(port serial.Port) error {
|
|
log.Debug("Shaking hands ...")
|
|
if length, err := port.Write([]byte{shared.HandshakeByte}); err != nil {
|
|
return fmt.Errorf("could not write handshake byte: %v", err)
|
|
} else {
|
|
log.Tracef("wrote %d handshake bytes", length)
|
|
}
|
|
handShakeResponse := make([]byte, 1)
|
|
if length, err := port.Read(handShakeResponse); err != nil {
|
|
return fmt.Errorf("failed to read handshake response: %v", err)
|
|
} else {
|
|
log.Tracef("read %d bytes", length)
|
|
}
|
|
if handShakeResponse[0] != shared.AckByte {
|
|
return fmt.Errorf("invalid handshake response expected 0x10 received %x", handShakeResponse[0])
|
|
}
|
|
log.Debug("Handshake successful")
|
|
return nil
|
|
}
|
|
|
|
func receiveResponse(port *serial.Port, responseChan *chan datastructures.SignerResponse, errorChan *chan error) {
|
|
header, err := shared.ReceiveBytes(port, 1, 20)
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
if header[0] != shared.HandshakeByte {
|
|
*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x%x", header, shared.HandshakeByte)
|
|
}
|
|
log.Tracef("received handshake byte")
|
|
|
|
if _, err := (*port).Write([]byte{shared.AckByte}); err != nil {
|
|
*errorChan <- errors.New("could not write ACK")
|
|
return
|
|
}
|
|
log.Tracef("sent ACK byte")
|
|
|
|
lengthBytes, err := shared.ReceiveBytes(port, 3, 2)
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
blockLength := datastructures.Decode24BitLength(lengthBytes)
|
|
log.Tracef("received block length %d", blockLength)
|
|
|
|
blockData, err := shared.ReceiveBytes(port, blockLength, 5)
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
log.Tracef("received bytes %v", blockData)
|
|
|
|
checkSum, err := shared.ReceiveBytes(port, 1, 2)
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
log.Tracef("received checksum 0x%x", checkSum[0])
|
|
|
|
trailer, err := shared.ReceiveBytes(port, len(shared.MagicTrailer), 2)
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
if string(trailer) != shared.MagicTrailer {
|
|
*errorChan <- errors.New("expected trailer bytes not found")
|
|
return
|
|
}
|
|
log.Tracef("received valid trailer bytes")
|
|
|
|
if _, err := (*port).Write([]byte{shared.AckByte}); err != nil {
|
|
*errorChan <- fmt.Errorf("could not write ACK byte: %v", err)
|
|
return
|
|
}
|
|
log.Tracef("sent ACK byte")
|
|
|
|
signerResponse, err := datastructures.SignerResponseFromData(lengthBytes, blockData, checkSum[0])
|
|
if err != nil {
|
|
*errorChan <- err
|
|
return
|
|
}
|
|
log.Infof("received response of type %s", signerResponse.Action)
|
|
|
|
*responseChan <- *signerResponse
|
|
}
|