/// <summary>
        /// GEt legacy response payload.
        /// </summary>
        /// <param name="pdu"></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        private PduPayload GetLegacyResponsePayload(LegacyPdu pdu, ulong?requestId)
        {
            PduPayload payload = pdu.Payload;

            if (payload == null && pdu.ErrorPayload == null)
            {
                throw new KsiServiceException("Invalid response payload: null.");
            }

            if (payload != null && payload.Type != GetPayloadTagType(true))
            {
                throw new KsiServiceException("Unexpected response payload tag type. Type: " + payload.Type + "; Expected type: " + GetPayloadTagType(true));
            }

            if (pdu.ErrorPayload != null)
            {
                if (payload != null)
                {
                    // If error payload exists then Payload should be null. Log it.
                    LogUnexpectedPayloads(pdu);
                }
                throw new KsiServiceException(FormatServerErrorStatus(pdu.ErrorPayload.Status, pdu.ErrorPayload.ErrorMessage));
            }

            CheckMacAlgorithm(pdu.Mac, _macAlgorithm);

            if (!LegacyPdu.ValidateMac(pdu.Encode(), pdu.Mac, _macKey))
            {
                throw new KsiServiceException("Invalid MAC in response PDU.");
            }

            if (requestId.HasValue)
            {
                RequestResponsePayload requestResponsePayload = payload as RequestResponsePayload;

                if (requestResponsePayload == null)
                {
                    throw new KsiServiceException("Cannot get request ID from payload. Payload type: " + payload?.GetType());
                }

                if (requestResponsePayload.RequestId != requestId)
                {
                    throw new KsiServiceException("Unknown request ID: " + requestResponsePayload.RequestId);
                }
            }

            ResponsePayload responsePayload = payload as ResponsePayload;

            if (responsePayload == null)
            {
                throw new KsiServiceException("Cannot get status from payload. Payload type: " + payload?.GetType());
            }

            if (responsePayload.Status != 0)
            {
                throw new KsiServiceException(FormatServerErrorStatus(responsePayload.Status, responsePayload.ErrorMessage));
            }

            return(payload);
        }
        /// <summary>
        /// Get response payload.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="pdu"></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        private PduPayload GetResponsePayload(byte[] data, Pdu pdu, ulong?requestId)
        {
            PduPayload   payload      = GetPayload(pdu, GetPayloadTagType(false), requestId);
            ErrorPayload errorPayload = pdu.ErrorPayload;

            if (payload == null && errorPayload == null)
            {
                throw new KsiServiceException("Invalid response PDU. Could not find a valid payload. PDU: " + pdu);
            }

            if (errorPayload != null)
            {
                // There should be only one payload if an error payload exists. If not then write log.
                if (pdu.Payloads.Count > 0)
                {
                    LogUnexpectedPayloads(pdu);
                }

                throw new KsiServiceException(FormatServerErrorStatus(errorPayload.Status, errorPayload.ErrorMessage));
            }

            CheckMacAlgorithm(pdu.Mac, _macAlgorithm);

            if (!Pdu.ValidateMac(data, pdu.Mac, _macKey))
            {
                throw new KsiServiceException("Invalid MAC in response PDU.");
            }

            if (requestId.HasValue)
            {
                RequestResponsePayload requestResponsePayload = payload as RequestResponsePayload;

                if (requestResponsePayload == null)
                {
                    throw new KsiServiceException("Cannot get request ID from payload.");
                }

                if (requestResponsePayload.RequestId != requestId)
                {
                    throw new KsiServiceException("Unknown request ID: " + requestResponsePayload.RequestId);
                }

                if (requestResponsePayload.Status != 0)
                {
                    throw new KsiServiceException(FormatServerErrorStatus(requestResponsePayload.Status, requestResponsePayload.ErrorMessage));
                }
            }

            if (HasUnexpectedPayload(pdu, payload, GetAdditionallyAllowedPayloadTagTypes()))
            {
                LogUnexpectedPayloads(pdu);
            }

            return(payload);
        }
        /// <summary>
        /// Get payoad from PDU by tag type and request ID.
        /// </summary>
        /// <param name="pdu"></param>
        /// <param name="tagType"></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        private static PduPayload GetPayload(Pdu pdu, uint tagType, ulong?requestId)
        {
            foreach (PduPayload payload in pdu.Payloads)
            {
                if (payload.Type == tagType)
                {
                    if (!requestId.HasValue)
                    {
                        return(payload);
                    }

                    RequestResponsePayload responsePayload = payload as RequestResponsePayload;

                    if (responsePayload != null && responsePayload.RequestId == requestId)
                    {
                        return(payload);
                    }
                }
            }

            return(null);
        }