📄 transaction.java
字号:
package model;
//Copyright (C) 2008 Harald Unander, Wang Wenjuan
//
// This file is part of WlanTV.
//
// WlanTV 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 3 of the License, or
// (at your option) any later version.
//
// WlanTV 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 WlanTV. If not, see <http://www.gnu.org/licenses/>.
import java.util.ArrayList;
import model.Packet;
import model.Conversation.AP;
import model.Packet.CH_MODES;
import model.Packet.FClass;
import model.Packet.FType;
public class Transaction {
public static final long GROUP_ADDR_BIT = 0x800000000000L;
public ArrayList<OneTransaction> list = new ArrayList<OneTransaction>();
public enum Type {FULL, ABORTED, RECONSTRUCTED};
public Conversation conversation;
private static final int MAX_ACK_DELAY = 150;
private float averagePacketLength;
private int unicastByteCount;
private int unicastCount;
private float averageUnicastLength;
private long byteCount;
private int reconstrucedPacketLen;
private long captureSpan;
private long captureStartTime;
private long captureEndTime;
private int captureLastTransactionNo;
private enum State {INIT, AFTER_PS_POLL, AFTER_CTS, AFTER_RTS, WAIT_FOR_ACK};
public void calculate(ArrayList<Packet> packets, String captureFile, CH_MODES mode, boolean advanced, int _reconstructedPacketLen) {
this.reconstrucedPacketLen = _reconstructedPacketLen;
list.clear();
conversation = new Conversation(advanced);
// System.out.println("Finding frame durations and transactions...");
int packetCount = 0;
byteCount = 0;
unicastByteCount = 0;
unicastCount = 0;
for (Packet r : packets) {
r.calculate(mode);
byteCount += r.frameLen + RawPacket.getWiresharkLenCompensation();
packetCount++;
if (Transaction.DataUnicast(r)) {
unicastByteCount += r.frameLen;
unicastCount++;
}
}
averagePacketLength = byteCount/(float)packetCount;
averageUnicastLength = unicastByteCount/(float)unicastCount;
if (reconstrucedPacketLen == 0)
reconstrucedPacketLen = (int)averageUnicastLength;
findTransactions(packets);
conversation.removeUnusedAPs();
try {
conversation.scanAp(captureFile);
} catch (Exception e) {
e.printStackTrace();
}
for (OneTransaction one : list) {
updateSlotAndPreambleFromBeacon(conversation.getAp(one.AP), one.packetList, mode);
}
captureStartTime = list.get(0).timeStamp;
captureLastTransactionNo = list.size() - 1;
OneTransaction last = list.get(captureLastTransactionNo);
captureEndTime = last.timeStamp + last.totalDur;
captureSpan = captureEndTime - captureStartTime;
// System.out.println("Transactions: "+transaction.list.size());
// System.out.println("byte count "+byteCount);
}
public long getCaptureSpan() {
return captureSpan;
}
public void setCaptureSpan(long captureSpan) {
this.captureSpan = captureSpan;
}
public long getCaptureStartTime() {
return captureStartTime;
}
public void setCaptureStartTime(long captureStartTime) {
this.captureStartTime = captureStartTime;
}
public long getCaptureEndTime() {
return captureEndTime;
}
public void setCaptureEndTime(long captureEndTime) {
this.captureEndTime = captureEndTime;
}
public int getCaptureLastTransactionNo() {
return captureLastTransactionNo;
}
public void setCaptureLastTransactionNo(int captureLastTransactionNo) {
this.captureLastTransactionNo = captureLastTransactionNo;
}
public void findTransactions(ArrayList<Packet> packets) {
State state = State.INIT;
ArrayList<Packet> pList = new ArrayList<Packet>();
for (Packet p : packets) {
if (state == State.INIT) {
state = handleFirstFrame(pList, p);
}
else if (state == State.AFTER_PS_POLL) {
if (p.fType==Packet.FType.ACK) {
pList.add(p);
state = transactionEnd(pList,Type.FULL,null);
}
else if (DataUnicast(p) || ManUnicast(p)) {
pList.add(p);
state = State.WAIT_FOR_ACK;
}
else {
state = transactionEnd(pList,Type.ABORTED,null);
state = handleFirstFrame(pList, p);
}
}
else if (state == State.AFTER_CTS) {
if (DataUnicast(p) || ManUnicast(p)) {
pList.add(p);
state = State.WAIT_FOR_ACK;
}
else if (DataGroupCast(p) || ManGroupCast(p)) {
pList.add(p);
state = State.WAIT_FOR_ACK;
}
else {
state = transactionEnd(pList,Type.ABORTED,null);
state = handleFirstFrame(pList, p);
}
}
else if (state == State.AFTER_RTS) {
if (p.fType==Packet.FType.CTS) {
pList.add(p);
state = State.AFTER_CTS;
}
else {
state = transactionEnd(pList,Type.ABORTED,null);
state = handleFirstFrame(pList, p);
}
}
else if (state == State.WAIT_FOR_ACK) {
Packet prev = pList.get(pList.size()-1);
if (p.fType==Packet.FType.ACK) {
long timeDiff = p.timeStamp - prev.frameTimeRel;
if (timeDiff < MAX_ACK_DELAY) { //TODO delay depends on mode&rate
pList.add(p);
state = transactionEnd(pList,Type.FULL,prev);
}
else {
state = transactionEnd(pList,Type.ABORTED,prev);
state = handleFirstFrame(pList, p);
}
}
else {
state = transactionEnd(pList,Type.ABORTED,prev);
state = handleFirstFrame(pList, p);
}
}
else {
state = transactionEnd(pList,Type.ABORTED,null);
state = handleFirstFrame(pList, p);
}
}
}
private State handleFirstFrame(ArrayList<Packet> pList, Packet p) {
State state;
pList.add(p);
if(ManGroupCast(p) || DataGroupCast(p)){
state = transactionEnd(pList,Type.FULL,null);
}
else if((p.fType==Packet.FType.ACK)) {
// TODO check if space for packet
// int len = Integer.parseInt(Main.pilotProp.getProperty("reconstruct.size","100"));
Packet r = Availability.makeDummyDataPacket(p.chMode,0,reconstrucedPacketLen,p.timeStamp-p.getSifsDur(),FType.RECONSTRUCTED);
pList.add(0,r);
state = transactionEnd(pList,Type.RECONSTRUCTED,null);
}
else if ((p.fType==Packet.FType.PS_POLL)) {
p.wlanDuration = Packet.findAckDuration(p);
state = State.AFTER_PS_POLL;
}
else if ((p.fType==Packet.FType.CTS)) {
state = State.AFTER_CTS;
}
else if ((p.fType==Packet.FType.RTS)) {
state = State.AFTER_RTS;
}
else if (DataUnicast(p) || ManUnicast(p)) {
state = State.WAIT_FOR_ACK;
}
else {
state = transactionEnd(pList,Type.ABORTED,null);
}
return state;
}
@SuppressWarnings("unchecked")
private State transactionEnd(ArrayList<Packet> pList, Type type, Packet unicastPacket) {
OneTransaction one = new OneTransaction(type);
one.unicastPacket = unicastPacket;
one.packetList = (ArrayList<Packet>) pList.clone();
pList.clear();
for (Packet p : one.packetList)
if (p.wlanBadFcs!=0) {
if (p.wlanDuration>400) p.wlanDuration=0;
one.badFcs = true;
}
one.findAddresses();
if (!one.badFcs) {
if (one.packetList.get(0).fType == FType.BEACON) {
conversation.updateBeaconApList(one.packetList.get(0));
}
else if (one.unicastPacket!=null) {
conversation.updateUnicastStaList(one);
}
}
if (one.packetList.size() == 1) {
one.findTimes(one.packetList.get(0));
}
else if (one.packetList.size() == 2) {
one.findTimes(one.packetList.get(0),one.packetList.get(1));
}
else if (one.packetList.size() == 3) {
one.findTimes(one.packetList.get(0),one.packetList.get(1),one.packetList.get(2));
}
else if (one.packetList.size() == 4) {
one.findTimes(one.packetList.get(0),one.packetList.get(1),one.packetList.get(2),one.packetList.get(3));
}
else {
// System.out.println("Transaction: Internal error: "+pList.size());
pList.clear();
return State.INIT;
}
list.add(one);
// StringBuffer sb = new StringBuffer();
// Result r = one.ArrayList<Result>.get(0);
// sb.append(list.size()+" "+r.frameNumber+" "+Result.longToMac(r.wlanRa)+" "+Result.longToMac(r.wlanSa)+" "+Result.longToMac(r.wlanDa)+" ++ ");
// sb.append("AP:"+Result.longToMac(one.AP)+" STA:"+Result.longToMac(one.STA)+" Hide:"+one.hide+" ");
// if (one.AP!=0) for (long sta : Result.getApList().get(one.AP).STA) sb.append(Result.longToMac(sta)+" ");
// System.out.println(sb);
pList.clear();
return State.INIT;
}
public void updateSlotAndPreambleFromBeacon(AP ap, ArrayList<Packet> packetList, CH_MODES mode) {
if (ap!=null)
for (Packet p : packetList) {
p.mgmtPreamble = ap.mgmtPreamble;
p.mgmtShortSlotTime = ap.mgmtShortSlotTime;
p.calculate(mode);
p.channel = ap.channel;
}
}
public static boolean DataGroupCast(Packet p){
// Broadcast or multicast data
if (p.findFrameClass()==Packet.FClass.DATA && (
( p.wlanDa&GROUP_ADDR_BIT)==GROUP_ADDR_BIT || (p.wlanDa&0xffffff000000L)==0x01005e000000L )
)
return true;
else return false;
}
public static boolean DataUnicast(Packet p){
if (p.findFrameClass()==Packet.FClass.DATA && (p.wlanDa&GROUP_ADDR_BIT)==0) return true;
else return false;
}
public static boolean ManGroupCast(Packet p){
// Broadcast or multicast data
if(p.fType==FType.BEACON && (p.wlanDa&GROUP_ADDR_BIT)==GROUP_ADDR_BIT){
return true;
}
else if(p.fType==FType.PROBE_REQ && (p.wlanDa&GROUP_ADDR_BIT)==GROUP_ADDR_BIT) {
return true;
}
else return false;
}
public static boolean ManUnicast(Packet p){
if (p.findFrameClass()==Packet.FClass.MANAGEMENT && (p.wlanDa&GROUP_ADDR_BIT)==0) return true;
else return false;
}
public class OneTransaction {
public boolean badFcs;
public boolean hide;
public int backOffTime;
public int totalDur;
public long timeStamp;
public Type type = Type.FULL;
public int difsDur;
public int sifsDur;
public ArrayList<Packet> packetList;
public long AP;
public long STA;
public Packet unicastPacket;
public OneTransaction() {
}
public OneTransaction(Type type){
this.type = type;
}
public void findAddresses() {
AP = 0;
STA = 0;
for (Packet p : packetList) {
if (p.wlanBssid!=0) AP = p.wlanBssid;
if (ManUnicast(p)) {
if (p.wlanDa == p.wlanBssid) STA = p.wlanSa;
else if (p.wlanSa == p.wlanBssid) STA = p.wlanDa;
}
else if (DataUnicast(p)) {
if (p.wlanToDs==1 && p.wlanFromDs==0 && p.wlanSa!=0) STA = p.wlanSa;
else if (p.wlanToDs==0 && p.wlanFromDs==1 && p.wlanDa!=0) STA = p.wlanDa; //TODO Not supporting IBSS
}
else if (p.findFrameClass()==FClass.CONTROL) {
if (p.fType==FType.PS_POLL && p.wlanTa!=0) STA = p.wlanTa;
else if (p.fType==FType.CTS && p.wlanRa!=0) STA = p.wlanRa;
}
else if (p.findFrameClass()==FClass.MANAGEMENT) {
if (p.fType==FType.PROBE_REQ && p.wlanSa!=0) STA = p.wlanSa;
}
if (STA!=0 && AP!=0) break;
}
// if (STA==0 && !ManGroupCast(packetList.get(0))) {
// System.out.println("No STA address for: "+packetList.get(0).frameNumber);
// for (long l : conversation.getApList().keySet()) System.out.print(l+" "); System.out.println("Ap");
// for (long l : conversation.getStaList().keySet()) System.out.print(l+" "); System.out.println("Sta");
// System.out.println(packetList.size());
// }
// if (AP==0) {
// System.out.println("No AP address for: "+packetList.get(0).frameNumber);
// for (long l : conversation.getApList().keySet()) System.out.print(l+" "); System.out.println("Ap");
// for (long l : conversation.getStaList().keySet()) System.out.print(l+" "); System.out.println("Sta");
// System.out.println(packetList.size());
// }
}
private void findTimes(Packet p0) {
if (type == Type.ABORTED && p0.wlanDuration > 0) { // imagine missing packet
findTimes(p0,null);
}
else {
difsDur = p0.getDifsDur();
sifsDur = 0;
backOffTime = p0.getBackoffDur();
totalDur = p0.frameDur;
timeStamp = p0.timeStamp;
}
}
private void findTimes(Packet p0, Packet p1) {
if (type == Type.ABORTED && p1 != null && p1.wlanDuration > 0) { // imagine missing packet
findTimes(p0,p1,null);
}
else {
difsDur = p0.getDifsDur();
sifsDur = p0.getSifsDur();
backOffTime = p0.getBackoffDur();
//last sifs included in wlan dur
totalDur = p0.frameDur + p0.wlanDuration;
timeStamp = p0.timeStamp;
}
}
private void findTimes(Packet p0, Packet p1, Packet p2) {
if (type == Type.ABORTED && p2 != null && p2.wlanDuration > 0) { // imagine missing packet
findTimes(p0,p1,p2,null);
}
else {
difsDur = p0.getDifsDur();
sifsDur = p0.getSifsDur() + p1.getSifsDur();
backOffTime = p0.getBackoffDur();
//last sifs included in wlan dur
totalDur = p0.getSifsDur() + p0.frameDur + p1.frameDur + p1.wlanDuration;
timeStamp = p0.timeStamp;
}
}
private void findTimes(Packet p0, Packet p1, Packet p2, Packet p3) {
difsDur = p0.getDifsDur();
sifsDur = p0.getSifsDur() + p1.getSifsDur() + p2.getSifsDur();
backOffTime = p0.getBackoffDur();
//last sifs included in wlan dur
totalDur = p0.getSifsDur() + p1.getSifsDur() + p0.frameDur + p1.frameDur + p2.frameDur + p2.wlanDuration;
timeStamp = p0.timeStamp;
}
public String getTransactionInfo() {
StringBuffer sb = new StringBuffer();
sb.append("Frame no\t" +packetList.get(0).frameNumber+"\n");
// sb.append("Timestamp\t" +timeStamp+"\n");
sb.append("Duration\t" +totalDur+"\n");
sb.append("BadFcs\t" + badFcs+"\n");
// sb.append("Hide\t" +hide+"\n");
sb.append("Backoff\t" +backOffTime+"\n");
sb.append("Type\t" +type+"\n");
sb.append("DIFS\t" +difsDur+"\n");
sb.append("SIFS\t" +sifsDur+"\n");
// sb.append("PktCount\t" +packetList.size()+"\n");
sb.append("AP\t" +Packet.longToMac(AP)+"\n");
sb.append("STA\t" +Packet.longToMac(STA));
// sb.append("UniAck\t" +hasUnicastAck+"\n");
return sb.toString();
}
}
public float getAveragePacketLength() {
return averagePacketLength;
}
public float getAverageUnicastLength() {
return averageUnicastLength;
}
public long getByteCount() {
return byteCount;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -