/* OscarPacketAnalyser.java
*
* Copyright 2011 Aleksey Konovalov
* All Rights Reserved.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*/
package ru.caffeineim.protocols.icq.core;
import java.io.DataInputStream;
import java.io.IOException;
import android.util.Log;
import ru.caffeineim.protocols.icq.Snac;
import ru.caffeineim.protocols.icq.core.exceptions.LoginException;
import ru.caffeineim.protocols.icq.exceptions.BadPacketException;
import ru.caffeineim.protocols.icq.packet.received.AuthorizationReply;
import ru.caffeineim.protocols.icq.packet.received.ReceivedPackedRegistry;
import ru.caffeineim.protocols.icq.packet.received.ReceivedPacket;
import ru.caffeineim.protocols.icq.packet.sent.generic.AuthorizationRequest;
import ru.caffeineim.protocols.icq.packet.sent.generic.SignonCommand;
/**
* <p>
* Created by
*
* @author Fabrice Michellonet
* @author Samolisov Pavel
* @author Konovalov Aleksey
*/
public class OscarPacketAnalyser {
private static final String LOG_TAG = "ICQ:OscarPacketAnalyser";
private final OscarConnection connection;
private int nbPacket = 0;
public OscarPacketAnalyser(OscarConnection connection) {
this.connection = connection;
}
public final void initialize() {
nbPacket = 0;
}
/**
* The function is where we manage the received packets. Recognize them,
* analyse and give an answer to the server.
*
* @param packet
* The byte array received from the ICQ server.
* @throws LoginException
* @throws IOException
* @throws BadPacketException
*/
protected final void handlePacket(DataInputStream packet) throws LoginException,
IOException, BadPacketException {
++nbPacket;
boolean handled = false;
try {
handled = handleInitialPackets(packet);
} catch (LoginException E) {
throw new LoginException(E.getErrorType(), E);
}
// "normal" service
if (!handled) {
try {
handleService(packet);
} catch (Exception e) {
Log.e(LOG_TAG,
"failed to service packet (continuing with other packets)",
e);
}
}
}
private final boolean handleInitialPackets(DataInputStream packet)
throws LoginException, IOException, BadPacketException {
switch(nbPacket) {
case 1:
connection.sendFlap(new AuthorizationRequest(
connection.getUserId(), connection.getPassword()));
break;
case 2:
AuthorizationReply reply = new AuthorizationReply(packet);
reply.execute(connection);
break;
case 3:
/* BOS hello */
connection.sendFlap(new SignonCommand(connection.getCookie()));
break;
default:
return false;
}
return true;
}
protected final void handleService(DataInputStream packet) throws Exception {
ReceivedPacket receivedFlap = new ReceivedPacket(packet, true);
int familyId = receivedFlap.getSnac().getFamilyId();
int subTypeId = receivedFlap.getSnac().getSubTypeId();
Log.d(LOG_TAG, "Received " + familyId + " - " + subTypeId);
// TODO
// Dumper.log(packet, true, 8, 16);
try {
packet.reset();
ReceivedPacket packetHandler = ReceivedPackedRegistry
.getPacketHandler(familyId, subTypeId, packet);
if (packetHandler == null) {
Log.w(LOG_TAG, "Unknown packet (familyId = " + familyId
+ ", subType = " + subTypeId);
return;
}
packetHandler.execute(connection);
packetHandler.notifyEvent(connection);
packetHandler.matchRequest(connection);
// if logged to the Server
if (familyId == Snac.BOS_FAMILY && subTypeId == Snac.SRV_REPLYBOS_COMMAND) {
connection.setAuthorized(true);
}
} catch (Exception ex) {
ex.printStackTrace();
Log.e(LOG_TAG, "Could not parse packet", ex);
}
}
/**
* This method gives access to the OscarConnection class.
*
* @return The filtering engine.
*/
public final OscarConnection getConnection() {
return connection;
}
}
|