func()

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(&currentPayload, 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
}