public int Send(ConnectionState state, byte[] data) { if (!Connected) { Log("Cannot send in state 'not connected'"); return(-1); } TPKT resPkt = new TPKT(); TPDU resPdu = new TPDU(); if (data.Length <= m_MaxTPDUSize) { // No fragmentation resPdu.MakeDataPacket(data); resPkt.SetPayload(resPdu.GetBytes()); TCPSend(state, resPkt.GetBytes()); } else { // With fragmentation int workedLength = 0; int fragLength; bool lastDataUnit; while (workedLength < data.Length) { fragLength = data.Length - workedLength; if (fragLength > m_MaxTPDUSize) { fragLength = m_MaxTPDUSize; lastDataUnit = false; } else { lastDataUnit = true; } resPdu.MakeDataPacket(data, workedLength, fragLength, lastDataUnit); resPkt.SetPayload(resPdu.GetBytes()); TCPSend(state, resPkt.GetBytes()); workedLength += fragLength; } } return(0); }
public void Process(IsoServiceProvider client, byte[] inPacket, int len) { int workedLen; TPKT PKT; TPDU PDU; byte[] packet = new byte[len]; Array.Copy(inPacket, packet, len); workedLen = 0; while (workedLen < len) { PKT = new TPKT(packet, len); PDU = new TPDU(PKT.Payload); switch (PDU.PDUType) { case (byte)TPDU.TPDU_TYPES.CR: { if (Connected) { break; } TPKT resPkt = new TPKT(); TPDU resPdu = new TPDU(); resPdu.PDUType = (byte)TPDU.TPDU_TYPES.CC; Connected = false; m_payloadFragmentData = new MemoryStream(1024); // Stream for TPDU fragments, S7 PDU has max. 960 bytes // get connect confirm, if tsaps not equal a exception is thrown try { resPdu.PduCon = PDU.PduCon.HandleConnectRequest(LocalTsaps, m_ProposedMaxTPDUSize, EnableLocalTsapCheck); // Add TPDU to TPKT resPkt.SetPayload(resPdu.GetBytes()); // send connect confirm TCPSend(client.client, resPkt.GetBytes()); Connected = true; m_MaxTPDUSize = resPdu.PduCon.GetMaxTPDUSize(); } catch (Exception) { } } break; case (byte)TPDU.TPDU_TYPES.DT: { if (!Connected) { Log("DT packet before state 'connected' received."); m_payloadFragmentData.SetLength(0); break; } // Handle DT TPDU fragments if (PDU.PduData.EOT == false) { m_payloadFragmentData.Write(PDU.PduData.Payload, 0, PDU.PduData.Payload.Length); } else { if (m_payloadFragmentData.Length == 0) { OnReceived(client, PDU.PduData.Payload); } else { m_payloadFragmentData.Write(PDU.PduData.Payload, 0, PDU.PduData.Payload.Length); byte[] payload = new byte[m_payloadFragmentData.Length]; payload = m_payloadFragmentData.ToArray(); OnReceived(client, payload); m_payloadFragmentData.SetLength(0); } } } break; case (byte)TPDU.TPDU_TYPES.DR: // Disconnect Request client.client.EndConnection(); break; default: Log("Cannot handle pdu type " + PDU.PDUType); break; } // Build next packet to work on workedLen += PKT.Length; Array.Copy(inPacket, workedLen, packet, 0, len - workedLen); } }