private int ReceivePacket(ushort NodeID, SCCIFunctions Function, SCCISubFunctions SubFunction, out int SourceOffset, bool PreserveBuffer = false) { bool error; var packetLength = ReceiveHeader(NodeID, Function, SubFunction, out error, out SourceOffset); ReceiveBody(packetLength, PreserveBuffer, SourceOffset); if (error) { var code = (SCCIErrors)m_ReadBuffer[2]; var details = m_ReadBuffer[3]; switch (code) { case SCCIErrors.InvalidSfunction: case SCCIErrors.InvalidFunction: throw new ProtocolErrorFrameInvalidHeaderException(String.Format(Resources.SCCIMasterAdapter_SCCI_protocol_error, code, details), code, details); case SCCIErrors.BadCRC: throw new ProtocolErrorFrameInvalidCRCException(String.Format(Resources.SCCIMasterAdapter_SCCI_protocol_error, code, details), code, details); default: throw new ProtocolErrorFrameException(String.Format(Resources.SCCIMasterAdapter_SCCI_protocol_error, code, details), code, details); } } return(packetLength); }
private void SendPacket(ushort NodeID, SCCIFunctions Function, SCCISubFunctions SubFunction, int UserDataLength) { // CRC and prefix UserDataLength += 3; // Fill prefix and CRC m_WriteBuffer[0] = (ushort)(NodeID | FRAME_START); m_WriteBuffer[1] = (ushort)((((ushort)Function << 3) | (ushort)SubFunction) << 8); m_WriteBuffer[UserDataLength - 1] = CRC16.ComputeCRC(m_WriteBuffer, UserDataLength - 1); Utils.SerializeUShortArrayToBytes(m_WriteBuffer, UserDataLength, m_RawWriteBuffer); try { m_Port.Write(m_RawWriteBuffer, 0, UserDataLength * 2); } catch (TimeoutException) { throw new SerialConnectionTimeoutException(Resources.SCCIMasterAdapter_Communication_exception_hardware_timeout); } catch (Exception e) { throw new SerialConnectionException(String.Format(Resources.SCCIMasterAdapter_Communication_exception, e.Message), e); } }
private void ImplementWAX(ushort NodeID, SCCIFunctions Function, SCCISubFunctions SubFunction, int UserDataLength) { var repCount = m_RetransmitsOnErrCount + 1; Exception savedEx = null; while (repCount-- > 0) { try { savedEx = null; int sourceOffset; ResetReceiveBuffer(); SendPacket(NodeID, Function, SubFunction, UserDataLength); ReceivePacket(NodeID, Function, SubFunction, out sourceOffset); break; } catch (ProtocolInvaidPacketFormatException e) { savedEx = e; } catch (ProtocolInvaidFunctionException e) { savedEx = e; } catch (ProtocolErrorFrameInvalidHeaderException e) { savedEx = e; } catch (ProtocolErrorFrameInvalidCRCException e) { savedEx = e; } catch (ProtocolBadCRCException e) { savedEx = e; } catch (ProtocolTimeoutException e) { if (m_CatchTimeouts) { savedEx = e; } else { throw; } } } if (repCount == 0 && savedEx != null) { throw savedEx; } }
private void ImplementRAX(ushort NodeID, SCCIFunctions Function, SCCISubFunctions SubFunction, SCCISubFunctions SubFunctionRep, int UserDataLength) { Action <Exception> errorHandler = delegate(Exception SavedException) { var repCount = m_RetransmitsOnErrCountForArrays; while (repCount-- > 0) { try { SavedException = null; int sourceOffset; ResetReceiveBuffer(); SendPacket(NodeID, Function, SubFunctionRep, UserDataLength); ReceivePacket(NodeID, Function, SubFunctionRep, out sourceOffset); break; } catch (ProtocolInvaidPacketFormatException e) { SavedException = e; } catch (ProtocolInvaidFunctionException e) { SavedException = e; } catch (ProtocolErrorFrameInvalidHeaderException e) { SavedException = e; } catch (ProtocolErrorFrameInvalidCRCException e) { SavedException = e; } catch (ProtocolBadCRCException e) { SavedException = e; } catch (ProtocolTimeoutException e) { SavedException = e; } } if (SavedException != null) { throw SavedException; } }; try { int sourceOffset; ResetReceiveBuffer(); SendPacket(NodeID, Function, SubFunction, UserDataLength); ReceivePacket(NodeID, Function, SubFunction, out sourceOffset); } catch (ProtocolInvaidPacketFormatException e) { errorHandler(e); } catch (ProtocolInvaidFunctionException e) { errorHandler(e); } catch (ProtocolBadCRCException e) { errorHandler(e); } catch (ProtocolTimeoutException e) { if (m_CatchTimeouts) { errorHandler(e); } else { throw; } } }
private int ReceiveHeader(ushort NodeID, SCCIFunctions Function, SCCISubFunctions SubFunction, out bool Error, out int SourceOffset) { Error = false; SourceOffset = 0; var packetLength = -1; var receivedHeader = false; var timeout = Environment.TickCount + m_TimeoutSync; while (Environment.TickCount < timeout || IGNORE_TIMEOUTS) { lock (m_ReadSync) { if (m_RawReadBufferLength > 3) { if (m_RawReadBuffer[0] != FRAME_START_BYTE) { SourceOffset++; continue; } Utils.DeserializeBytesToUShortArray(m_RawReadBuffer, 4, m_ReadBuffer, SourceOffset); receivedHeader = true; } } if (receivedHeader) { if ((m_ReadBuffer[0] & 0xFF00) != FRAME_START) { throw new ProtocolInvaidPacketFormatException(String.Format(Resources.SCCIMasterAdapter_Parser_error_wrong_START_byte, m_ReadBuffer[0] >> 8)); } var node = (ushort)(m_ReadBuffer[0] & 0x00FF); var code = (ushort)(m_ReadBuffer[1] >> 8); if (node != NodeID) { throw new ProtocolInvaidPacketFormatException(String.Format(Resources.SCCIMasterAdapter_Parser_error_wrong_node_ID, node)); } if ((code & FUNCTION_RR_MASK) == 0) { throw new ProtocolInvaidPacketFormatException(Resources.SCCIMasterAdapter_Parser_error_wrong_RR_bit); } var fnc = (code & FUNCTION_CODE_MASK) >> 3; var sfnc = (code & FUNCTION_SCODE_MASK); if (fnc >= m_Lengths.GetLength(0) || sfnc >= m_Lengths.GetLength(1)) { throw new ProtocolInvaidFunctionException( String.Format(Resources.SCCIMasterAdapter_Parser_error_invalid_value_in_field, code.ToString(@"X")), code); } if (fnc == (int)SCCIFunctions.Error) { Error = true; } else if ((fnc != (int)Function) || (sfnc != (int)SubFunction)) { throw new ProtocolInvaidFunctionException( String.Format(Resources.SCCIMasterAdapter_Response_is_not_matched_to_request, Function, SubFunction, fnc, sfnc), code); } packetLength = m_Lengths[fnc, sfnc]; Trace.Assert(packetLength != -1, String.Format(@"FNC: {0}, SFNC{1}", fnc, sfnc)); break; } var tout = timeout - Environment.TickCount; tout = (tout < 0) ? 0 : tout; m_DataReceivedEvent.WaitOne(tout); } if (!receivedHeader) { throw new ProtocolTimeoutException(Resources.SCCIMasterAdapter_General_error_timeout_while_reading_frame_header); } return(packetLength); }