Implement first client command
The client can now talk to the old Perl signer implementation. Running socat has been documented in README.md. Commonly used I/O code has been moved to the shared/io.go file.
This commit is contained in:
parent
5aa557c9aa
commit
65855152ce
6 changed files with 287 additions and 84 deletions
|
@ -7,7 +7,6 @@ import (
|
|||
"fmt"
|
||||
"git.cacert.org/cacert-gosigner/datastructures"
|
||||
"git.cacert.org/cacert-gosigner/shared"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
|
@ -70,7 +69,7 @@ readLoop:
|
|||
if err != nil {
|
||||
log.Printf("ERROR %v\n", err)
|
||||
} else {
|
||||
SendResponse(&port, response)
|
||||
_ = SendResponse(&port, response)
|
||||
}
|
||||
case <-timeout:
|
||||
log.Println("timeout in main loop")
|
||||
|
@ -90,7 +89,7 @@ func SendResponse(port *serial.Port, response *datastructures.SignerResponse) er
|
|||
return err
|
||||
}
|
||||
|
||||
if ack, err := receiveBytes(port, 1, 5); err != nil {
|
||||
if ack, err := shared.ReceiveBytes(port, 1, 5); err != nil {
|
||||
return err
|
||||
} else if ack[0] != 0x10 {
|
||||
return errors.New(fmt.Sprintf("invalid ack byte 0x%02x", ack[0]))
|
||||
|
@ -112,7 +111,7 @@ func SendResponse(port *serial.Port, response *datastructures.SignerResponse) er
|
|||
return err
|
||||
}
|
||||
|
||||
if ack, err := receiveBytes(port, 1, 5); err != nil {
|
||||
if ack, err := shared.ReceiveBytes(port, 1, 5); err != nil {
|
||||
return err
|
||||
} else if ack[0] == 0x10 {
|
||||
tryAgain = false
|
||||
|
@ -146,13 +145,13 @@ func handleNulAction(command datastructures.SignerRequest) (*datastructures.Sign
|
|||
|
||||
// Receive a request and generate a request data structure
|
||||
func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest, errorChan *chan error) {
|
||||
header, err := receiveBytes(port, 1, 20)
|
||||
header, err := shared.ReceiveBytes(port, 1, 20)
|
||||
if err != nil {
|
||||
*errorChan <- err
|
||||
return
|
||||
}
|
||||
if header[0] != 0x02 {
|
||||
*errorChan <- errors.New(fmt.Sprintf("unexpected byte 0x%x expected 0x02", header))
|
||||
*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x02", header)
|
||||
}
|
||||
|
||||
if _, err := (*port).Write([]byte{0x10}); err != nil {
|
||||
|
@ -160,19 +159,19 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
|
|||
return
|
||||
}
|
||||
|
||||
lengthBytes, err := receiveBytes(port, 3, 2)
|
||||
lengthBytes, err := shared.ReceiveBytes(port, 3, 2)
|
||||
if err != nil {
|
||||
*errorChan <- err
|
||||
return
|
||||
}
|
||||
blockLength := binary.BigEndian.Uint32([]byte{0x0, lengthBytes[0], lengthBytes[1], lengthBytes[2]})
|
||||
blockData, err := receiveBytes(port, int(blockLength), 5)
|
||||
blockData, err := shared.ReceiveBytes(port, int(blockLength), 5)
|
||||
if err != nil {
|
||||
*errorChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
checkSum, err := receiveBytes(port, 1, 2)
|
||||
checkSum, err := shared.ReceiveBytes(port, 1, 2)
|
||||
if err != nil {
|
||||
*errorChan <- err
|
||||
return
|
||||
|
@ -183,7 +182,7 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
|
|||
*errorChan <- err
|
||||
}
|
||||
|
||||
trailer, err := receiveBytes(port, len(shared.MagicTrailer), 2)
|
||||
trailer, err := shared.ReceiveBytes(port, len(shared.MagicTrailer), 2)
|
||||
if err != nil {
|
||||
*errorChan <- err
|
||||
return
|
||||
|
@ -201,25 +200,3 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
|
|||
*commandChan <- *command
|
||||
}
|
||||
|
||||
// receive the requested number of bytes from serial port and stop after the given timeout in seconds
|
||||
func receiveBytes(port *serial.Port, count int, timeout time.Duration) ([]byte, error) {
|
||||
timeoutCh := time.After(timeout * time.Second)
|
||||
readCh := make(chan []byte, 1)
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
data := make([]byte, count)
|
||||
if _, err := io.ReadAtLeast(*port, data, count); err != nil {
|
||||
errCh <- err
|
||||
} else {
|
||||
readCh <- data
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-timeoutCh:
|
||||
return nil, errors.New("timeout")
|
||||
case err := <-errCh:
|
||||
return nil, err
|
||||
case data := <-readCh:
|
||||
return data, nil
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue