in plc4go/tools/plc4xpcapanalyzer/internal/cbusanalyzer/analyzer.go [130:193]
func (a *Analyzer) getCurrentPayload(packetInformation common.PacketInformation, payload []byte, mergeCallback func(int), currentInboundPayloads map[string][]byte, lastPayload *[]byte) ([]byte, error) {
srcUip := packetInformation.SrcIp.String()
payload = filterXOnXOff(payload)
if len(payload) == 0 {
return nil, common.ErrEmptyPackage
}
currentPayload := currentInboundPayloads[srcUip]
if currentPayload != nil {
log.Debug().Func(func(e *zerolog.Event) {
e.
Bytes("currentPayload", currentPayload).
Bytes("actualPayload", payload).
Interface("allPayload", append(currentPayload, payload...)).
Msg("Prepending current payload currentPayload to actual payload actualPayload: allPayload")
})
currentPayload = append(currentPayload, payload...)
} else {
currentPayload = payload
}
if len(currentPayload) == 1 && currentPayload[0] == '!' {
// This is an errormessage from the server
return currentPayload, nil
}
containsError := false
// We ensure that there are no random ! in the string
currentPayload, containsError = filterOneServerError(currentPayload)
if containsError {
// Save the current inbound payload for the next try
currentInboundPayloads[srcUip] = currentPayload
return []byte{'!'}, nil
}
// Check if we have a termination in the middle
isMergedMessage, shouldClearInboundPayload := mergeCheck(¤tPayload, srcUip, mergeCallback, currentInboundPayloads, lastPayload)
if !isMergedMessage {
// When we have a merge message we already set the current payload to the tail
currentInboundPayloads[srcUip] = currentPayload
} else {
log.Debug().Stringer("packetInformation", packetInformation).
Interface("remainder", currentInboundPayloads[srcUip]).
Msg("Remainder %+q")
}
if lastElement := currentPayload[len(currentPayload)-1]; (lastElement != '\r') && (lastElement != '\n') {
return nil, common.ErrUnterminatedPackage
} else {
log.Debug().Stringer("packetInformation", packetInformation).
Uint8("lastElement", lastElement).
Msg("Last element")
if shouldClearInboundPayload {
if currentSavedPayload := currentInboundPayloads[srcUip]; currentSavedPayload != nil {
// We remove our current payload from the beginning of the cache
for i, b := range currentPayload {
if currentSavedPayload[i] != b {
panic("programming error... at this point they should start with the identical bytes")
}
}
}
currentInboundPayloads[srcUip] = nil
}
}
log.Debug().Stringer("packetInformation", packetInformation).
Bytes("currentPayload", currentPayload).
Msg("Returning payload")
return currentPayload, nil
}