Skip to content

Commit

Permalink
Send logs in chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCutter committed Mar 15, 2024
1 parent b150ffd commit 3e4bd53
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 51 deletions.
178 changes: 157 additions & 21 deletions api/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,21 @@ message Configuration {
string NTPServer = 6;
}

/*
Log messages
*/

message LogMessagesRequest {
bool Continue = 1;
}

message LogMessagesResponse {
bytes Payload = 1;
bool More = 2;
}

message Response {
ErrorCode Error = 1;
bytes Payload = 2;
Expand Down
41 changes: 23 additions & 18 deletions cmd/witnessctl/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"log"
"net"
"os"
"strings"
"time"

"github.com/cheggaaa/pb/v3"
Expand Down Expand Up @@ -78,29 +79,33 @@ func (d Device) hab() error {
return nil
}

func (d Device) consoleLogs() (string, error) {
buf, err := d.u2f.Command(api.U2FHID_ARMORY_CONSOLE_LOGS, nil)
if err != nil {
return "", err
func (d Device) getLogMessages(cmd byte) (string, error) {
b := strings.Builder{}
req := &api.LogMessagesRequest{}
rsp := &api.LogMessagesResponse{More: true}
for rsp.More {
rb, _ := proto.Marshal(req)
buf, err := d.u2f.Command(cmd, rb)
if err != nil {
return "", err
}
if err := proto.Unmarshal(buf, rsp); err != nil {
return "", err
}
b.Write(rsp.GetPayload())
req.Continue = true
time.Sleep(10 * time.Millisecond)
}

return string(buf), nil
return b.String(), nil
}

func (d Device) crashLogs() (string, error) {
buf, err := d.u2f.Command(api.U2FHID_ARMORY_CRASH_LOGS, nil)
if err != nil {
return "", err
}
res := &api.Response{}
if err := proto.Unmarshal(buf, res); err != nil {
return "", err
}
if res.Error != api.ErrorCode_NONE {
return "", fmt.Errorf("%v: %s", res.Error, res.Payload)
}
func (d Device) consoleLogs() (string, error) {
return d.getLogMessages(api.U2FHID_ARMORY_CONSOLE_LOGS)
}

return string(res.Payload), nil
func (d Device) crashLogs() (string, error) {
return d.getLogMessages(api.U2FHID_ARMORY_CRASH_LOGS)
}

func (d Device) sendUpdateHeader(signature []byte, total int) (err error) {
Expand Down
53 changes: 41 additions & 12 deletions trusted_os/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const (
MII_STATUS = 0x1
// Table 22–8, Status register bit definitions, 802.3-2008
STATUS_LINK = 2

// Max bytes to return via HID - we use 64 as a safe guess for protobuf wire overhead
maxChunkSize = api.MaxMessageSize - 64
)

// witnessStatus represents the latest view of the witness applet's status.
Expand All @@ -54,6 +57,8 @@ type controlInterface struct {
SRKHash string

ota *otaBuffer

logBuffer []byte
}

func getStatus() (s *api.Status) {
Expand Down Expand Up @@ -154,20 +159,44 @@ func (ctl *controlInterface) HAB(_ []byte) []byte {
return api.EmptyResponse()
}

func (ctl *controlInterface) ConsoleLogs(_ []byte) (res []byte) {
logs := getConsoleLogs()
return []byte(logs)
}

func (ctl *controlInterface) CrashLogs(_ []byte) (res []byte) {
logs, err := retrieveLastCrashLog(ctl.RPC.Storage)
if err != nil {
log.Printf("Failed to read crash log: %v", err)
func (ctl *controlInterface) handleLogsRequest(r []byte, l func() []byte) (res []byte) {
req := &api.LogMessagesRequest{}
if err := proto.Unmarshal(r, req); err != nil {
log.Printf("Failed to parse LogMessages request: %v", err)
return api.ErrorResponse(err)
}
log.Printf("got %d bytes of crash log", len(logs))
res, _ = proto.Marshal(&api.Response{Payload: logs})
return res
if !req.Continue {
log.Printf("Grabbing log messages...")
logs := l()
log.Printf("Found %d bytes of log messages to send", len(logs))
ctl.logBuffer = make([]byte, len(logs))
copy(ctl.logBuffer, logs)
}
ret := &api.LogMessagesResponse{}
if l := len(ctl.logBuffer); l > maxChunkSize {
ret.More = true
ret.Payload, ctl.logBuffer = ctl.logBuffer[:maxChunkSize], ctl.logBuffer[maxChunkSize:]
} else {
ret.More = false
ret.Payload = ctl.logBuffer
ctl.logBuffer = nil
}
b, _ := proto.Marshal(ret)
return b
}

func (ctl *controlInterface) ConsoleLogs(r []byte) (res []byte) {
return ctl.handleLogsRequest(r, func() []byte { return getConsoleLogs() })
}

func (ctl *controlInterface) CrashLogs(r []byte) (res []byte) {
return ctl.handleLogsRequest(r, func() []byte {
l, err := retrieveLastCrashLog(ctl.RPC.Storage)
if err != nil {
return []byte(fmt.Sprintf("Failed to retrieve crash logs: %v", err))
}
return l
})
}

func (ctl *controlInterface) Start() {
Expand Down

0 comments on commit 3e4bd53

Please sign in to comment.