/// <summary> /// method called when the parse results are needed. That is, when any of the /// parse result properties are read. The idea is to not parse everytime the /// parseText textbox is changed. Just save the "text has been changed" flag /// and parse when the parse results are read. /// </summary> private void ParseTheParseText() { if ((this.ParseTextChanged == true) || (tbErrmsg.Text.Length != 0)) { tbErrmsg.Text = String.Empty; if (this.ParseText.Length == 0) { tbErrmsg.Text = "Enter hex text to parse"; } else { var lines = this.ParseText.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var ba = lines.HexTextLinesToBytes(); var rv = ServerDataStream.ParseByteArray(ba, -1, this.DataStreamName); this.WrkstnCmdList = rv.Item1; this.ResponseList = rv.Item2; this.dsh = rv.Item3; this.TelList = rv.Item4; this.ParseTextChanged = false; } } }
private void StartReadingServerHeartbeat() { Observable.TimeInterval <DateTime>(ServerDataStream.Select(s => DateTime.Now)) .SubscribeOn(new EventLoopScheduler()) .Subscribe(ts => { if (ts.Interval.Seconds > SERVER_HEARTBEAT_SEC) { _shutdownRequested = true; } }); }
/// <summary> /// parse the bytestream. Then write objects to the Child collection which /// are displayed when this tree node is expanded. /// In this case, write the byte stream as chunks of hex bytes. Then, /// depending on the complexity of the byte stream, parse the bytes and write /// a report of the parse results. /// </summary> protected override void FillChildren() { // the byte stream as a report of hex bytes. { var report = this.ByteStream.ToHexReport(32); var headerModel = new ReportHeaderModel("Byte data stream", report); this.Children.Add(headerModel); } // parse the bytes. var rv = ServerDataStream.ParseByteArray(this.ByteStream); var wrkstnCmdList = rv.Item1; var responseList = rv.Item2; var dsh = rv.Item3; var telList = rv.Item4; var funcList = rv.Item5; if (telList != null) { var report = telList.ToColumnReport(""); var headerModel = new ReportHeaderModel("telnet data stream", report); this.Children.Add(headerModel); } if (dsh != null) { var report = dsh.ToColumnReport(""); var headerModel = new ReportHeaderModel("Datastream header", report); this.Children.Add(headerModel); } if ((wrkstnCmdList != null) && (wrkstnCmdList.Count > 0)) { var report = wrkstnCmdList.ToColumnReport("workstation command list"); var headerModel = new ReportHeaderModel("workstation command list", report); this.Children.Add(headerModel); } if (funcList?.Count > 0) { var report = funcList.ToColumnReport(); var headerModel = new ReportHeaderModel("SCS control function list", report); this.Children.Add(headerModel); } if (responseList.Count > 0) { var report = responseList.ReportResponseItems(); var headerModel = new ReportHeaderModel("Response data stream", report); this.Children.Add(headerModel); } }
void NewParse() { var logList = new TelnetLogList(); var text = TextBox1.Text; var lines = text.Split( new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var ba = ParseHexLines(lines); var inputArray = new NetworkStreamBackedInputByteArray(ba, ba.Length); var sessionSettings = new SessionSettings(); Process5250.ParseResponseStream(logList, ba); foreach (var item in logList) { if (item.NewGroup == true) { this.Model.RunLog.Add(""); } this.Model.RunLog.Add(item.Text); } // peek at the input stream from server. Classify the data that is next // to receive. var typeData = ServerDataStream.PeekServerCommand(inputArray); // input data not recogizied. Not a 5250 data strem header. if (typeData == null) { logList.AddItem(Direction.Read, "Unknown data stream data"); logList.AddItems( Direction.Read, inputArray.PeekBytes().ToHexReport(16)); } else if (typeData.Value == TypeServerData.workstationHeader) { { var rv = Process5250.GetAndParseWorkstationCommandList( inputArray, sessionSettings); var workstationCmdList = rv.Item1; logList.AddItems(rv.Item2); } } }
ProcessWorkstationDataStream( this ConnectedSocketPack SocketPack, ScreenVisualItems VisualItems, CanvasPositionCursor Caret) { WorkstationCommandList workstationCmdList = null; List <WriteToDisplayCommand> wtdCmdList = null; DataStreamHeader dsh = null; var returnCmdList = new WorkstationCommandList(); HowReadScreen?howRead = null; var logList = new TelnetLogList(); bool gotEOR = false; while (gotEOR == false) { // input array is eof. Exit loop if have read a READ workstn command. // Otherwise, read from server. if (SocketPack.InputArray.IsEof() == true) { if (howRead != null) { break; } { var log = SocketPack.InputArray.ReadFromNetworkStream(10, 60); logList.AddItems(log); if (SocketPack.InputArray.IsEof() == true) { break; } } } // peek at the input stream from server. Classify the data that is next // to receive. var typeData = ServerDataStream.PeekServerCommand(SocketPack.InputArray); // input data not recogizied. Not a 5250 data strem header. if (typeData == null) { logList.AddItem(Direction.Read, "Unknown data stream data"); logList.AddItems( Direction.Read, SocketPack.InputArray.PeekBytes().ToHexReport(16)); break; } if (typeData.Value == TypeServerData.workstationHeader) { { var rv = Process5250.GetAndParseWorkstationCommandList( SocketPack.InputArray, SocketPack.Settings); dsh = rv.Item1; workstationCmdList = rv.Item2; logList.AddItems(rv.Item3); gotEOR = rv.Item4; } foreach (var workstationCmd in workstationCmdList) { if (workstationCmd is ClearUnitCommand) { returnCmdList.Add(workstationCmd); } // WTD command. Add to list of WTD commands. This list is returned to the // caller of this method. else if (workstationCmd is WriteToDisplayCommand) { returnCmdList.Add(workstationCmd); var wtdCommand = workstationCmd as WriteToDisplayCommand; if (wtdCmdList == null) { wtdCmdList = new List <WriteToDisplayCommand>(); } wtdCmdList.Add(wtdCommand); } else if (workstationCmd is ReadMdtFieldsCommand) { howRead = HowReadScreen.ReadMdt; } // save screen command. Build response, send back to server. else if (workstationCmd is SaveScreenCommand) { var ra = SaveScreenCommandExt.BuildSaveScreenResponse(VisualItems, Caret); // send response stream back to server. { TelnetConnection.WriteToHost(logList, ra, SocketPack.TcpStream); gotEOR = false; } } else if (workstationCmd is WriteStructuredFieldCommand) { var wsfCmd = workstationCmd as WriteStructuredFieldCommand; if (wsfCmd.RequestCode == WSF_RequestCode.Query5250) { var ra = Query5250Response.BuildQuery5250Response(); // send response stream back to server. { TelnetConnection.WriteToHost(logList, ra, SocketPack.TcpStream); gotEOR = false; } } } else if (workstationCmd is WriteSingleStructuredFieldCommand) { } } } } return(new Tuple <HowReadScreen?, List <WriteToDisplayCommand>, TelnetLogList, WorkstationCommandList, DataStreamHeader, bool>( howRead, wtdCmdList, logList, returnCmdList, dsh, gotEOR)); }
public void EntryPoint() { this.ThreadEndedEvent.Reset(); try { // loop receiving from the server until: // - the foreground thread wants to shutdown the connection. It has set // the ShutdownFlag event. while ((ShutdownFlag.State == false) && (this.ConnectionFailedEvent.State == false)) { var message = InputQueue.WaitAndDequeue( this.ShutdownFlag.EventObject, this.ConnectionFailedEvent.EventObject); if (message != null) { if (message is DataStreamHeaderMessage) { var dshMessage = message as DataStreamHeaderMessage; var dataBytes = new byte[] { 0x00, 0x0A, 0x12, 0xA0, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0xFF, 0xEF }; var dataMessage = new SendDataMessage(dataBytes); this.ToThread.PostInputMessage(dataMessage); } else if (message is DataStreamHeader) { var dsh = message as DataStreamHeader; var dataBytes = new byte[] { 0x00, 0x0A, 0x12, 0xA0, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0xFF, 0xEF }; var dataMessage = new SendDataMessage(dataBytes); this.ToThread.PostInputMessage(dataMessage); } else if (message is PrinterDataBytesMessage) { var dataMessage = message as PrinterDataBytesMessage; var dataBytes = dataMessage.DataBytes; var dataBytesLength = dataBytes.Length; // remove the IAC EOR from the end of the stream. // ( the data stream may end with a partial control function which // is continued in the next data stream. Do not want to // confuse the FF EF EOR bytes as data bytes of the possible // incomplete control function. ) { var endBytes = dataBytes.Tail(2); var cmdCode = endBytes.ParseTelnetCommandCode(); if ((cmdCode != null) && (cmdCode.Value == CommandCode.EOR)) { dataBytesLength -= 2; // dataBytes = dataBytes.SubArray(0, dataBytesLength); } } // there are remaining bytes from the previous dataBytes message. // insert these remaining bytes after the dataStreamHeader. if (this.RemainingBytes != null) { dataBytes = dataBytes.SubArray(0, dataBytesLength); var headerLength = dataBytes.GetDataStreamHeaderLength(); if (headerLength != null) { dataBytes = dataBytes.Insert(headerLength.Value, this.RemainingBytes); dataBytesLength += this.RemainingBytes.Length; } } // parse the bytes. var rv = ServerDataStream.ParseByteArray(dataBytes, dataBytesLength); var wrkstnCmdList = rv.Item1; var responseList = rv.Item2; var dsh = rv.Item3; var telList = rv.Item4; var funcList = rv.Item5; // bytes at the end of the data stream that were not recognized as // complete SCS function codes. Save now and add to the front of the // next data stream that arrives. ( add to front after the data // stream header. ) this.RemainingBytes = rv.Item6; if (1 == 1) { this.OpenDoc = PrintToPdf(dsh, funcList, this.OpenDoc); } var respBytes = new byte[] { 0x00, 0x0A, 0x12, 0xA0, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0xFF, 0xEF }; var respMessage = new SendDataMessage(respBytes); this.ToThread.PostInputMessage(respMessage); } else if (message is GeneralThreadMessage) { var generalMessage = message as GeneralThreadMessage; switch (generalMessage.MessageCode) { case ThreadMessageCode.ClearLog: { break; } } } else if (message is ExchangeMessage) { var exchangeMessage = message as ExchangeMessage; if (exchangeMessage.MessageCode == ThreadMessageCode.GetScreenContent) { } } } } } finally { // in case anyone waiting for this thread to end. Signal the ended event. ThreadEndedEvent.Set(); } }
/// <summary> /// parse from current byte forward in the InputArray. Will either parse a /// telnet command or a workstation command. /// Route what was parsed to either the FromQueue or the MasterThread. Send to /// the FromQueue if still receiving telnet commands. Otherwise, send to the /// MasterThread. /// </summary> /// <param name="InputArray"></param> /// <param name="WipCmdList"></param> /// <returns></returns> private Tuple <WorkstationCommandList, bool> ParseAndPostInputArray( InputByteArray InputArray, WorkstationCommandList WipCmdList) { WorkstationCommandList wipCmdList = null; bool gotSomething = false; if (WipCmdList == null) { var telCmd = InputArray.NextTelnetCommand(); if (telCmd != null) { this.TelnetQueue.Enqueue(telCmd); gotSomething = true; } } if (gotSomething == false) { // peek at the input stream from server. Classify the data that is next // to receive. var typeData = ServerDataStream.PeekServerCommand(InputArray); if (typeData != null) { var rv = Process5250.ParseWorkstationCommandList( InputArray, this.SessionSettings); var dsh = rv.Item1; var workstationCmdList = rv.Item2; var gotEOR = rv.Item3; var needMoreBytes = rv.Item4; // update connectionComplete flag and typeDevice depending on the stream // code of the datastream header. if ((this.ConnectionComplete == false) && (dsh != null) && (dsh.StreamCode != null)) { this.ConnectionComplete = true; if (dsh.StreamCode.Value == DataStreamCode.Terminal) { this.TypeDevice = TypeTelnetDevice.Terminal; } else { this.TypeDevice = TypeTelnetDevice.Printer; } // post message to telnet queue so that the ConnectionThread on the // other end will know to shutdown. var message = new TelnetDeviceAttrMessage(this.TypeDevice.Value); this.TelnetQueue.Enqueue(message); } // got data stream header. if (dsh != null) { if (this.ConnectionComplete == false) { this.TelnetQueue.Enqueue(dsh); } else { var message = new DataStreamHeaderMessage(dsh); PostToProcessQueue(message); } gotSomething = true; } if (workstationCmdList != null) { gotSomething = true; } // accum the workstationCmdList if (WipCmdList == null) { wipCmdList = workstationCmdList; } else { wipCmdList = WipCmdList; wipCmdList.AddRange(workstationCmdList); } // got EOR. store the now completed workstationCmdList. if ((gotEOR == true) && (wipCmdList != null)) { var msg = new WorkstationCommandListMessage(wipCmdList); PostToProcessQueue(msg); gotSomething = true; wipCmdList = null; } } } return(new Tuple <WorkstationCommandList, bool>(wipCmdList, gotSomething)); }