00001 /* 00002 00003 Copyright (C) 2006-2007 by Peter Dimov. 00004 00005 This file is part of Calitko (http://www.calitko.org). 00006 00007 Calitko is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 Calitko is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Calitko; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 00021 */ 00022 00023 #include "Qt.h" 00024 #include "PacketProtocol.h" 00025 #include "AllowedFast.h" 00026 #include "BadPacket.h" 00027 #include "BitField.h" 00028 #include "Cancel.h" 00029 #include "Choke.h" 00030 #include "Have.h" 00031 #include "HaveAll.h" 00032 #include "HaveNone.h" 00033 #include "Interested.h" 00034 #include "Keepalive.h" 00035 #include "NotInterested.h" 00036 #include "Piece.h" 00037 #include "Port.h" 00038 #include "RejectRequest.h" 00039 #include "Request.h" 00040 #include "SuggestPiece.h" 00041 #include "Unchoke.h" 00042 #include "Imports.cpp" 00043 00045 int PacketProtocol::headerLength() const 00046 { 00047 return HeaderLength; 00048 } 00049 00051 00058 int PacketProtocol::payloadLength (const QByteArray &header) const 00059 { 00060 Q_ASSERT (header.length() == HeaderLength); 00061 // First four bytes are a big-endian integer saying how many bytes follow: 00062 qint32 length = 0; 00063 length |= header [3]; 00064 length |= header [2] << 8; 00065 length |= header [1] << 16; 00066 length |= header [0] << 24; 00067 return length; 00068 } 00069 00071 00082 GenericsPacket PacketProtocol::createPacket (const QByteArray &rawHeader, 00083 const QByteArray &rawPayload) const 00084 { 00085 Q_ASSERT (rawHeader.length() == HeaderLength); 00086 Packet packet; 00087 if (rawPayload.length() == 0) // Only Keepalive has no payload. 00088 packet = Keepalive(); 00089 else 00090 packet = getPacketFromTypeByte (rawPayload [0]); 00091 return parsedOrBadPacket (packet, rawHeader, rawPayload); 00092 } 00093 00095 Packet PacketProtocol::getPacketFromTypeByte (uchar byte) 00096 { 00097 PacketType type = static_cast <PacketType> (byte); 00098 switch (type) 00099 { 00100 case BitFieldPacket: 00101 return BitField(); 00102 case CancelPacket: 00103 return Cancel(); 00104 case ChokePacket: 00105 return Choke(); 00106 case HavePacket: 00107 return Have(); 00108 case InterestedPacket: 00109 return Interested(); 00110 case NotInterestedPacket: 00111 return NotInterested(); 00112 case PiecePacket: 00113 return Piece(); 00114 case RequestPacket: 00115 return Request(); 00116 case UnchokePacket: 00117 return Unchoke(); 00118 case PortPacket: 00119 return Port(); 00120 case SuggestPiecePacket: 00121 return SuggestPiece(); 00122 case HaveAllPacket: 00123 return HaveAll(); 00124 case HaveNonePacket: 00125 return HaveNone(); 00126 case RejectRequestPacket: 00127 return RejectRequest(); 00128 case AllowedFastPacket: 00129 return AllowedFast(); 00130 case KeepalivePacket: // 0xFF is not a valid packet type 00131 // fallback to BadPacket: 00132 default: 00133 return BadPacket (type); 00134 } 00135 } 00136 00138 00149 Packet PacketProtocol::parsedOrBadPacket (Packet &packet, 00150 const QByteArray &rawHeader, 00151 const QByteArray &rawPayload) 00152 { 00153 if (packet->parse (rawHeader, rawPayload)) 00154 return packet; 00155 else 00156 return BadPacket (packet->packetType(), rawHeader, rawPayload); 00157 }