/******************************************************************************* Jimm - Mobile Messaging - J2ME ICQ clone Copyright (C) 2003-05 Jimm Project This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************** File: src/jimm/comm/DisconnectPacket.java Version: ###VERSION### Date: ###DATE### Author(s): Manuel Linsmayer, Andreas Rossbacher *******************************************************************************/ // #sijapp cond.if protocols_ICQ is "true" # package protocol.icq.packet; import jimm.*; import jimm.comm.*; public class DisconnectPacket extends Packet { // Packet types public static final int TYPE_SRV_COOKIE = 1; public static final int TYPE_SRV_GOODBYE = 2; public static final int TYPE_CLI_GOODBYE = 3; // UIN as string (== null for CLI_GOODBYE packets) protected String uin; // Server (!= null only for SRV_COOKIE packets) protected String server; // Cookie (!= null only for SRV_COOKIE packets) protected byte[] cookie; // Reason for disconnect as an error code (>= 0 only for SRV_DISCONNECT packets) protected int error; // Reason for disconnect as a string (!= null only for SRV_DISCONNECT packets) protected String description; // Constructs a SRV_COOKIE packet public DisconnectPacket(String uin, String server, byte[] cookie) { this.uin = uin; this.server = server; this.cookie = new byte[cookie.length]; System.arraycopy(cookie, 0, this.cookie, 0, cookie.length); this.error = -1; this.description = null; } // Constructs a SRV_GOODBYE packet public DisconnectPacket(int error, String description) { this.uin = null; this.server = null; this.cookie = null; this.error = error; this.description = description; } // Constructs a CLI_GOODBYE packet public DisconnectPacket() { this.uin = null; this.server = null; this.cookie = null; this.error = -1; this.description = null; } public String getUin() { return uin; } // Returns the packet type public int getType() { if (this.uin != null) { return DisconnectPacket.TYPE_SRV_COOKIE; } else if (this.error >= 0) { return DisconnectPacket.TYPE_SRV_GOODBYE; } else { return DisconnectPacket.TYPE_CLI_GOODBYE; } } public JimmException makeException() { // Unknown error int toThrow = 100; switch (getError()) { // Multiple logins case 0x0001: toThrow = 110; break; // Bad password case 0x0004: case 0x0005: toThrow = 111; break; // Non-existant UIN case 0x0007: case 0x0008: toThrow = 112; break; // Too many clients from same IP case 0x0015: case 0x0016: toThrow = 113; break; // Rate exceeded case 0x0018: case 0x001d: toThrow = 114; break; } return new JimmException(toThrow, getError()); } // Returns the server, or null if packet type is not SRV_COOKIE public String getServer() { if (this.getType() == DisconnectPacket.TYPE_SRV_COOKIE) { return this.server; } else { return null; } } // Returns the cookie, or null if packet type is not SRV_COOKIE public byte[] getCookie() { if (DisconnectPacket.TYPE_SRV_COOKIE == this.getType()) { byte[] result = new byte[this.cookie.length]; System.arraycopy(this.cookie, 0, result, 0, this.cookie.length); return result; } else { return null; } } // Returns the error as an error code, or -1 if packet type is not SRV_GOODBYE public int getError() { return (TYPE_SRV_GOODBYE == getType()) ? error : -1; } // Returns the package as byte array public byte[] toByteArray() { OutStream buf = new OutStream(); buf.writeZeroes(6); // Assemble SRV_COOKIE if (this.getType() == DisconnectPacket.TYPE_SRV_COOKIE) { // DISCONNECT.UIN buf.writeTLV(0x0001, StringUtils.stringToByteArray(this.uin)); // DISCONNECT.SERVER buf.writeTLV(0x0005, StringUtils.stringToByteArray(this.server)); // DISCONNECT.COOKIE buf.writeTLV(0x0006, this.cookie); } // Assemble SRV_GOODBYE else if (this.getType() == DisconnectPacket.TYPE_SRV_GOODBYE) { // DISCONNECT.UIN buf.writeTLV(0x0001, StringUtils.stringToByteArray(this.uin)); // DISCONNECT.DESCRIPTION buf.writeTLV(0x0004, StringUtils.stringToByteArray(description)); // DISCONNECT.ERROR buf.writeTLVWord(0x0008, error); } // Allocate memory byte[] _buf = buf.toByteArray(); assembleFlapHeader(_buf, 0x04); return _buf; } // Parses given byte array and returns a Packet object public static Packet parse(byte[] flapData) throws JimmException { // Get length of FLAP data //int flapLength = Util.getWordBE(buf, offset + 4); // Variables for all possible TLVs String uin = null; String server = null; byte[] cookie = null; int error = -1; String description = null; // Read all TLVs ArrayReader marker = new ArrayReader(flapData, 0); while (marker.isNotEnd()) { int tlvType = marker.getTlvType(); byte[] tlvValue = marker.getTlv(); if (null == tlvValue) { throw new JimmException(135, 0); } // Save value switch (tlvType) { case 0x0001: // uin uin = StringUtils.byteArrayToAsciiString(tlvValue); break; case 0x0005: // server server = StringUtils.byteArrayToAsciiString(tlvValue); break; case 0x0006: // cookie cookie = tlvValue; break; case 0x0008: // error case 0x0009: // error error = Util.getWordBE(tlvValue, 0); break; case 0x0004: // description case 0x000B: // description description = StringUtils.byteArrayToAsciiString(tlvValue); break; default: // Do nothing on default (ignore all unknown TLVs) } } // CLI_GOODBYE if ((uin == null) && (server == null) && (cookie == null) && (error == -1) && (description == null)) { return new DisconnectPacket(); // SRV_COOKIE } else if ((uin != null) && (server != null) && (cookie != null) && (error == -1) && (description == null)) { return new DisconnectPacket(uin, server, cookie); // SRV_GOODBYYE } else if ((server == null) && (cookie == null) && (error != -1) && (description != null)) { return new DisconnectPacket(error, description); } else { // Other TLV combinations are not valid throw new JimmException(135, 2); } } } // #sijapp cond.end #