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 }