⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transaction.java

📁 The WLAN Traffic Visualizer is a platform independent Java program providing accurate measurement of
💻 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 + -