bool ReceiveTerminalResponse(byte[] data) { // Clear the receive buffer if 5 seconds has lapsed since the last message var tc = System.Environment.TickCount; if (tc - recvTickCount > 5000) { //Log(LogLevel.Debug, tr => tr.Set($"Data is being cleared from the buffer due to a timeout. Content {recvBuf.ToString()}")); recvBuf = ""; } recvTickCount = System.Environment.TickCount; // Append receive data to our buffer recvBuf += System.Text.Encoding.ASCII.GetString(data, 0, data.Length); // Keep parsing until no more characters try { int index = 0; while (index < recvBuf.Length) { // Look for start character if (recvBuf[index] == (byte)'#') { // Check that we have enough bytes to validate length, if not wait for more if (recvBuf.Length < index + 5) { recvBuf = recvBuf.Substring(index); break; } // We have enough bytes to check for length index++; // Try to get the length of the new message. If it's not a valid length // we might have some corrupt data, keep checking for a valid message if (!int.TryParse(recvBuf.Substring(index, 4), out int length) || length <= 5) { continue; } // We have a valid length index += 4; // If our buffer doesn't contain enough data, wait for more if (recvBuf.Length < index + length - 5) { recvBuf = recvBuf.Substring(index - 5); continue; } // We have a valid response var response = recvBuf.Substring(index, length - 5); FireOnTcpReceive(response); // Process the response TerminalBaseResponse eftResponse = null; try { eftResponse = _parser.StringToEFTResponse(response); ProcessEFTResponse(eftResponse); if (eftResponse.GetType() == _currentStartTxnRequest?.GetPairedResponseType()) { dialogUIHandler.HandleCloseDisplay(); } } catch (ArgumentException argumentException) { logger.Error("Error parsing response string", argumentException); } index += length - 5; } // Clear our buffer if we are all done if (index == recvBuf.Length) { recvBuf = ""; } } } catch (Exception ex) { // Fail gracefully. FireOnSocketFailEvent(ClientIPErrorType.Client_ParseError, ex.Message); //Log(LogLevel.Error, tr => tr.Set($"Exception (ReceiveTerminalResponse): {ex.Message}", ex)); return(false); } return(true); }
void ProcessEFTResponse(TerminalBaseResponse response) { try { switch (response) { case null: //Log(LogLevel.Error, tr => tr.Set($"Unable to handle null param {nameof(response)}")); break; case SetDialogResponse r: if (currentRequest is SetDialogRequest) { gotResponse = true; hideDialogEvent.Set(); } break; case EFTReceiptResponse r: SendReceiptAcknowledgement(); //Log(LogLevel.Info, tr => tr.Set($"IsPrePrint={((EFTReceiptResponse)response).IsPrePrint}")); if (r.IsPrePrint == false) { FireClientResponseEvent(nameof(OnReceipt), OnReceipt, new EFTEventArgs <EFTReceiptResponse>(r)); } break; case EFTDisplayResponse r: //DialogUIHandler.HandleDisplayResponse(r); FireClientResponseEvent(nameof(OnDisplay), OnDisplay, new EFTEventArgs <EFTDisplayResponse>(r)); break; case EFTLogonResponse r: FireClientResponseEvent(nameof(OnLogon), OnLogon, new EFTEventArgs <EFTLogonResponse>(r)); break; case EFTCloudLogonResponse r: FireClientResponseEvent(nameof(OnCloudLogon), OnCloudLogon, new EFTEventArgs <EFTCloudLogonResponse>(r)); break; case EFTTransactionResponse r: FireClientResponseEvent(nameof(OnTransaction), OnTransaction, new EFTEventArgs <EFTTransactionResponse>(r)); break; case EFTGetLastTransactionResponse r: FireClientResponseEvent(nameof(OnGetLastTransaction), OnGetLastTransaction, new EFTEventArgs <EFTGetLastTransactionResponse>(r)); break; case EFTReprintReceiptResponse r: FireClientResponseEvent(nameof(OnDuplicateReceipt), OnDuplicateReceipt, new EFTEventArgs <EFTReprintReceiptResponse>(r)); break; case EFTControlPanelResponse r: FireClientResponseEvent(nameof(OnDisplayControlPanel), OnDisplayControlPanel, new EFTEventArgs <EFTControlPanelResponse>(r)); break; case EFTSettlementResponse r: FireClientResponseEvent(nameof(OnSettlement), OnSettlement, new EFTEventArgs <EFTSettlementResponse>(r)); break; case EFTStatusResponse r: FireClientResponseEvent(nameof(OnStatus), OnStatus, new EFTEventArgs <EFTStatusResponse>(r)); break; case EFTQueryCardResponse r: FireClientResponseEvent(nameof(OnQueryCard), OnQueryCard, new EFTEventArgs <EFTQueryCardResponse>(r)); break; case EFTChequeAuthResponse r: FireClientResponseEvent(nameof(OnChequeAuth), OnChequeAuth, new EFTEventArgs <EFTChequeAuthResponse>(r)); break; case EFTGetPasswordResponse r: FireClientResponseEvent(nameof(OnGetPassword), OnGetPassword, new EFTEventArgs <EFTGetPasswordResponse>(r)); break; case EFTSlaveResponse r: FireClientResponseEvent(nameof(OnSlave), OnSlave, new EFTEventArgs <EFTSlaveResponse>(r)); break; case EFTConfigureMerchantResponse r: FireClientResponseEvent(nameof(OnConfigMerchant), OnConfigMerchant, new EFTEventArgs <EFTConfigureMerchantResponse>(r)); break; case EFTClientListResponse r: FireClientResponseEvent(nameof(OnClientList), OnClientList, new EFTEventArgs <EFTClientListResponse>(r)); break; default: //Log(LogLevel.Error, tr => tr.Set($"Unknown response type", response)); break; } } catch (Exception Ex) { //Log(LogLevel.Error, tr => tr.Set($"Unhandled error in {nameof(ProcessEFTResponse)}", Ex)); } }