/// <summary> /// Entry-point for submitting a query to the remote device /// </summary> /// <param name="data"></param> /// <returns></returns> public CommResponse Query(ClientCommData data) { lock (this.Port) { try { //set the proper parameters to the port this.Port.BaudRate = this.Setting.BaudRate; this.Port.Parity = this.Setting.Parity; this.Port.DataBits = this.Setting.DataBits; this.Port.StopBits = this.Setting.StopBits; this.Port.RtsEnable = this.Setting.RtsEnable; } catch (Exception ex) { return(new CommResponse( data, CommResponse.Critical, ex.Message)); } //convert the request data as an ordinary byte array byte[] outgoing = ((IByteArray)data.OutgoingData).Data; //create a writer for accumulate the incoming data var incoming = new ByteArrayWriter(); const int tempSize = 64; var temp = new byte[tempSize]; //retries loop for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++) { try { //flush any residual content this.Port .DiscardInBuffer(); this.Port .DiscardOutBuffer(); #if NET45 //System.Diagnostics.Trace.WriteLine("TX: " + ByteArrayHelpers.ToHex(outgoing)); #endif //phyiscal writing this.Port.WriteTimeout = 500; this.Port .Write(outgoing, 0, outgoing.Length); } catch (Exception ex) { return(new CommResponse( data, CommResponse.Critical, ex.Message)); } incoming.Drop(); //start the local timer bool timeoutExpired; int totalTimeout = this.Latency + data.Timeout; using (Timer timer = new Timer( _ => timeoutExpired = true, state: null, dueTime: totalTimeout, period: Timeout.Infinite)) { //reception loop, until a valid response or timeout timeoutExpired = false; while (timeoutExpired == false) { int length = this.Port.BytesToRead; if (length > 0) { if (length > tempSize) { length = tempSize; } try { //read the incoming data from the physical port this.Port .Read(temp, 0, length); } catch (Exception ex) { return(new CommResponse( data, CommResponse.Critical, ex.Message)); } //append data to the writer incoming.WriteBytes( temp, 0, length); //try to decode the stream data.IncomingData = incoming.ToReader(); #if NET45 //System.Diagnostics.Trace.WriteLine("RX: " + ByteArrayHelpers.ToHex(incoming.ToByteArray())); #endif CommResponse result = data .OwnerProtocol .Codec .ClientDecode(data); //exit whether any concrete result: either good or bad if (result.Status == CommResponse.Ack) { return(result); } else if (result.Status == CommResponse.Critical) { return(result); } else if (result.Status != CommResponse.Unknown) { break; } } Thread.Sleep(0); //stop immediately if the host asked to abort //TODO } } //using (timer) } //for //no attempt was successful return(new CommResponse( data, CommResponse.Critical)); } //lock }
/// <summary> /// Entry-point for submitting a query to the remote device /// </summary> /// <param name="data"></param> /// <returns></returns> public CommResponse Query(ClientCommData data) { lock (this.Port) { //convert the request data as an ordinary byte array byte[] outgoing = ((IByteArray)data.OutgoingData).Data; //create a writer for accumulate the incoming data var incoming = new ByteArrayWriter(); const int tempSize = 64; var temp = new byte[tempSize]; //retries loop for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++) { //phyiscal writing this.Port .Send(outgoing); incoming.Drop(); //start the local timer bool timeoutExpired; int totalTimeout = this.Latency + data.Timeout; using (Timer timer = new Timer( _ => timeoutExpired = true, state: null, dueTime: totalTimeout, period: Timeout.Infinite)) { //reception loop, until a valid response or timeout timeoutExpired = false; while (timeoutExpired == false) { var length = this.Port.Available; if (length > 0) { if (length > tempSize) { length = tempSize; } //read the incoming data from the physical port this.Port .Receive(temp, length, SocketFlags.None); //append data to the writer incoming.WriteBytes( temp, 0, length); //try to decode the stream data.IncomingData = incoming.ToReader(); CommResponse result = data .OwnerProtocol .Codec .ClientDecode(data); //exit whether any concrete result: either good or bad if (result.Status == CommResponse.Ack) { return(result); } else if (result.Status == CommResponse.Critical) { return(result); } else if (result.Status != CommResponse.Unknown) { break; } } Thread.Sleep(0); //stop immediately if the host asked to abort //TODO } } //using (timer) } //for //no attempt was successful return(new CommResponse( data, CommResponse.Critical)); } //lock }