use of com.att.aro.core.packetanalysis.pojo.PacketInfo in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method analyzeRequestResponsesForSecureSessions.
/**
* Estimate RequestResponseObjects for Secure Sessions
* @param session
* @return
*/
private ArrayList<HttpRequestResponseInfo> analyzeRequestResponsesForSecureSessions(Session session) {
session.setDataInaccessible(true);
boolean flag = false;
TCPPacket tcpPacket = null;
HttpRequestResponseInfo rrInfo = null;
HttpRequestResponseInfo downlinkRRInfo = null;
ArrayList<HttpRequestResponseInfo> results = new ArrayList<>();
for (PacketInfo packetInfo : session.getAllPackets()) {
tcpPacket = (TCPPacket) packetInfo.getPacket();
byte[] data = tcpPacket.getData();
int packetPosition = tcpPacket.getDataOffset();
if (packetInfo.getDir() == PacketDirection.UPLINK) {
if ((packetPosition + 4) < tcpPacket.getLen() && data[packetPosition] == TLS_APPLICATION_DATA) {
rrInfo = generateRequestResponseObjectsForSSLOrUDPSessions(session.getRemoteHostName(), packetInfo.getDir(), packetInfo, true);
results.add(rrInfo);
flag = true;
}
updateRequestResponseObject(rrInfo, packetInfo);
}
if (packetInfo.getDir() == PacketDirection.DOWNLINK) {
if (flag && (packetPosition + 4) < tcpPacket.getLen() && data[packetPosition] == TLS_APPLICATION_DATA) {
downlinkRRInfo = generateRequestResponseObjectsForSSLOrUDPSessions(session.getRemoteHostName(), packetInfo.getDir(), packetInfo, true);
results.add(downlinkRRInfo);
flag = false;
}
updateRequestResponseObject(downlinkRRInfo, packetInfo);
}
}
if (results.isEmpty()) {
if (!session.getUplinkPacketsSortedBySequenceNumbers().isEmpty()) {
PacketInfo packetInfo = identifyCorrectTransmissionStream(session.getUplinkPacketsSortedBySequenceNumbers().firstEntry().getValue(), session.getAckNumbers(), session, PacketDirection.UPLINK);
rrInfo = generateRequestResponseObjectsForSSLOrUDPSessions(session.getRemoteHostName(), PacketDirection.UPLINK, packetInfo, true);
packetInfo = identifyCorrectTransmissionStream(session.getUplinkPacketsSortedBySequenceNumbers().lastEntry().getValue(), session.getAckNumbers(), session, PacketDirection.UPLINK);
rrInfo.setLastDataPacket(packetInfo);
results.add(rrInfo);
}
if (!session.getDownlinkPacketsSortedBySequenceNumbers().isEmpty()) {
PacketInfo packetInfo = identifyCorrectTransmissionStream(session.getDownlinkPacketsSortedBySequenceNumbers().firstEntry().getValue(), session.getAckNumbers(), session, PacketDirection.DOWNLINK);
downlinkRRInfo = generateRequestResponseObjectsForSSLOrUDPSessions(session.getRemoteHostName(), PacketDirection.DOWNLINK, packetInfo, true);
packetInfo = identifyCorrectTransmissionStream(session.getDownlinkPacketsSortedBySequenceNumbers().lastEntry().getValue(), session.getAckNumbers(), session, PacketDirection.DOWNLINK);
downlinkRRInfo.setLastDataPacket(packetInfo);
results.add(downlinkRRInfo);
}
}
return results;
}
use of com.att.aro.core.packetanalysis.pojo.PacketInfo in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method identifyCorrectTCPTransmissionStreamHelper.
/**
* Helper method to recursively iterate through all of the child packets by next sequence number (relative to parent packet) to identify if there is any ACK received
* @param packetInfoListForSequenceNumber Initial packet list by a sequence number
* @param ackNumbersSet Set of all the ACK numbers
* @param session Session object
* @param direction Packet direction Uplink or Downlink
* @return True if any packet in the chain has received an ACK in session, otherwise False
*/
private boolean identifyCorrectTCPTransmissionStreamHelper(List<PacketInfo> packetInfoListForSequenceNumber, Set<Long> ackNumbersSet, Session session, PacketDirection direction) {
if (packetInfoListForSequenceNumber == null || packetInfoListForSequenceNumber.size() == 0) {
return false;
}
for (PacketInfo packetInfo : packetInfoListForSequenceNumber) {
TCPPacket tcpPacket = (TCPPacket) packetInfo.getPacket();
long nextSequenceOrAckNumber = tcpPacket.getSequenceNumber() + tcpPacket.getPayloadLen();
if (ackNumbersSet.contains(nextSequenceOrAckNumber)) {
return true;
}
List<PacketInfo> packetInfoListForNextSequenceNumber = PacketDirection.DOWNLINK.equals(direction) ? session.getDownlinkPacketsSortedBySequenceNumbers().get(nextSequenceOrAckNumber) : session.getUplinkPacketsSortedBySequenceNumbers().get(nextSequenceOrAckNumber);
return identifyCorrectTCPTransmissionStreamHelper(packetInfoListForNextSequenceNumber, ackNumbersSet, session, direction);
}
return false;
}
use of com.att.aro.core.packetanalysis.pojo.PacketInfo in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method populateWaterfallContent.
private void populateWaterfallContent(Session session) {
Double sslNegotiationDuration = null;
double contentDownloadDuration = 0;
double requestDuration = 0;
double timeToFirstByte = 0;
Double dnsTime = null;
Double synTime = null;
if (session.getDnsRequestPacket() != null && session.getDnsResponsePacket() != null) {
dnsTime = session.getDnsRequestPacket().getTimeStamp();
}
Double sslNegTime = null;
PacketInfo handshake = session.getLastSslHandshakePacket();
if (handshake != null) {
sslNegTime = handshake.getTimeStamp();
}
for (HttpRequestResponseInfo rrinfo : session.getRequestResponseInfo()) {
if (rrinfo.getDirection() != HttpDirection.REQUEST || rrinfo.getAssocReqResp() == null || rrinfo.getFirstDataPacket() == null) {
// Only process non-HTTPS request/response pairs
continue;
}
double startTime = -1;
double firstReqPacket = rrinfo.getFirstDataPacket().getTimeStamp();
PacketInfo lastPkt = rrinfo.getLastDataPacket();
double lastReqPacket = lastPkt != null ? lastPkt.getTimeStamp() : -1;
HttpRequestResponseInfo resp = rrinfo.getAssocReqResp();
// check getAssocReqResp firstDataPacket and lastDataPacket packet
if (resp == null || resp.getFirstDataPacket() == null || resp.getLastDataPacket() == null) {
continue;
}
double firstRespPacket = resp.getFirstDataPacket().getTimeStamp();
double lastRespPacket = resp.getLastDataPacket().getTimeStamp();
// Add DNS and initial connect to fist req/resp pair only
Double dnsDuration = null;
if (dnsTime != null) {
startTime = dnsTime.doubleValue();
if (synTime != null) {
dnsDuration = synTime.doubleValue() - dnsTime.doubleValue();
} else {
dnsDuration = firstReqPacket - dnsTime.doubleValue();
}
// Prevent from being added again
dnsTime = null;
}
Double initConnDuration = null;
if (synTime != null) {
initConnDuration = firstReqPacket - synTime;
if (startTime < 0.0) {
startTime = synTime.doubleValue();
}
// Prevent from being added again
synTime = null;
}
// Calculate request time
if (startTime < 0.0) {
startTime = firstReqPacket;
}
// Store waterfall in request/response
if (sslNegTime != null && lastRespPacket >= sslNegTime) {
sslNegotiationDuration = sslNegTime - firstReqPacket;
contentDownloadDuration = lastRespPacket - sslNegTime;
} else {
if (firstRespPacket >= lastReqPacket && lastReqPacket != -1) {
contentDownloadDuration = lastRespPacket - firstRespPacket;
requestDuration = lastReqPacket - firstReqPacket;
timeToFirstByte = firstRespPacket - lastReqPacket;
} else {
contentDownloadDuration = lastRespPacket - firstReqPacket;
}
}
RequestResponseTimeline reqRespTimeline = new RequestResponseTimeline(startTime, dnsDuration, initConnDuration, sslNegotiationDuration, requestDuration, timeToFirstByte, contentDownloadDuration);
rrinfo.setWaterfallInfos(reqRespTimeline);
rrinfo.getWaterfallInfos().setLastRespPacketTime(lastRespPacket);
}
}
use of com.att.aro.core.packetanalysis.pojo.PacketInfo in project VideoOptimzer by attdevsupport.
the class TraceDataReaderImpl method readPcapTraceFile.
private AbstractTraceResult readPcapTraceFile(String filepath, Double startTime, Double duration, AbstractTraceResult dresult) throws IOException {
if (!filereader.fileExist(filepath)) {
if (LOGGER != null) {
LOGGER.error("No packet file found at: " + filepath);
}
return null;
}
AbstractTraceResult result = dresult;
if (this.packetreader == null) {
// this.packetreader = new PacketReaderImpl();
throw new NullPointerException("this.packetreader is null");
}
this.packetreader.readPacket(filepath, this);
double pcapTime0 = 0;
double traceDuration = 0;
// Determine application name associated with each packet
if (!allPackets.isEmpty()) {
pcapTime0 = startTime != null ? startTime.doubleValue() : allPackets.get(0).getPacket().getTimeStamp();
traceDuration = duration != null ? duration.doubleValue() : allPackets.get(allPackets.size() - 1).getPacket().getTimeStamp() - pcapTime0;
List<Integer> appIds = result.getAppIds();
if (appIds == null) {
appIds = Collections.emptyList();
result.setAppIds(appIds);
}
// Determine if timezone difference needs to be accounted for
int tzDiff = 0;
int captureOffset = result.getCaptureOffset();
if (captureOffset != -1) {
int localOffset = Calendar.getInstance().getTimeZone().getRawOffset() / 1000;
int collectorOffset = captureOffset * 60 * -1;
tzDiff = collectorOffset - localOffset;
}
result.setPcapTimeOffset(pcapTime0 - tzDiff);
int packetIdx = 0;
List<String> appInfos = result.getAppInfos();
Set<String> allAppNames = result.getAllAppNames();
Map<String, Set<InetAddress>> appIps = result.getAppIps();
for (Iterator<PacketInfo> iter = allPackets.iterator(); iter.hasNext(); ) {
PacketInfo packetInfo = iter.next();
// Filter out non-IP packets
if (!(packetInfo.getPacket() instanceof IPPacket)) {
iter.remove();
continue;
}
IPPacket ipPacket = (IPPacket) packetInfo.getPacket();
PacketDirection packetDirection = determinePacketDirection(packetInfo, ipPacket.getSourceIPAddress(), ipPacket.getDestinationIPAddress());
if (packetDirection.equals(PacketDirection.UNKNOWN) && (ipPacket instanceof TCPPacket || ipPacket instanceof UDPPacket)) {
unknownPackets.add(packetInfo);
}
packetInfo.setDir(packetDirection);
packetInfo.setTimestamp(ipPacket.getTimeStamp() - pcapTime0 - tzDiff);
// Associate application ID with the packet
String appName = getAppNameForPacket(packetIdx, appIds, appInfos);
packetInfo.setAppName(appName);
allAppNames.add(appName);
// Group IPs by app
Set<InetAddress> ips = appIps.get(appName);
if (ips == null) {
ips = new HashSet<InetAddress>();
appIps.put(appName, ips);
}
ips.add(packetInfo.getRemoteIPAddress());
// Set packet ID to match Wireshark ID
packetInfo.setPacketId(++packetIdx);
}
if (!unknownPackets.isEmpty()) {
for (Iterator<PacketInfo> iterator = unknownPackets.iterator(); iterator.hasNext(); ) {
PacketInfo packetInfo = iterator.next();
IPPacket ipPacket = (IPPacket) packetInfo.getPacket();
PacketDirection packetDirection = determinePacketDirection(packetInfo, ipPacket.getSourceIPAddress(), ipPacket.getDestinationIPAddress());
iterator.remove();
if (packetDirection.equals(PacketDirection.UNKNOWN)) {
packetDirection = PacketDirection.UPLINK;
Packet packet = packetInfo.getPacket();
if (packet instanceof TCPPacket) {
int sourcePort = ((TCPPacket) packet).getSourcePort();
int destinationPort = ((TCPPacket) packet).getDestinationPort();
this.localIPAddresses.add(ipPacket.getSourceIPAddress().getHostAddress());
this.remoteIPAddresses.add(ipPacket.getDestinationIPAddress().getHostAddress());
this.localPortNumbers.add(sourcePort);
this.remotePortNumbers.add(destinationPort);
} else if (packet instanceof UDPPacket) {
int sourcePort = ((UDPPacket) packet).getSourcePort();
int destinationPort = ((UDPPacket) packet).getDestinationPort();
this.localIPAddresses.add(ipPacket.getSourceIPAddress().getHostAddress());
this.remoteIPAddresses.add(ipPacket.getDestinationIPAddress().getHostAddress());
this.localPortNumbers.add(sourcePort);
this.remotePortNumbers.add(destinationPort);
}
}
packetInfo.setDir(packetDirection);
}
}
if (!unknownPackets.isEmpty()) {
LOGGER.error("Packets with no direction identified.");
}
Collections.sort(allPackets);
} else {
pcapTime0 = startTime != null ? startTime.doubleValue() : filereader.getLastModified(filepath) / 1000.0;
traceDuration = duration != null ? duration.doubleValue() : 0.0;
}
Date traceDateTime = new Date((long) (pcapTime0 * 1000));
result.setPcapTime0(pcapTime0);
result.setTraceDuration(traceDuration);
result.setTraceDateTime(traceDateTime);
return result;
}
use of com.att.aro.core.packetanalysis.pojo.PacketInfo in project VideoOptimzer by attdevsupport.
the class RrcStateRangeFactoryImpl method create3G.
/**
* This method contains the main algorithm for creating the List of
* RrcStateRange for a 3G profile
*
* @param analysisData
* Analysis data
* @param profile
* 3G profile
* @return list of RRC State range values.
*/
private List<RrcStateRange> create3G(List<PacketInfo> packetlist, Profile3G profile, double traceDuration) {
List<PacketInfo> packetInfos = packetlist;
List<RrcStateRange> result = new ArrayList<RrcStateRange>();
if (packetInfos != null && !packetInfos.isEmpty()) {
// Get important profile info
double idleDchPromoAvg = profile.getIdleDchPromoAvg();
double idleDchPromoMin = profile.getIdleDchPromoMin();
double idleDchPromoMax = profile.getIdleDchPromoMax();
double fachDchPromoAvg = profile.getFachDchPromoAvg();
double fachDchPromoMin = profile.getFachDchPromoMin();
double fachDchPromoMax = profile.getFachDchPromoMax();
double dchFachTimer = profile.getDchFachTimer();
double fachIdleTimer = profile.getFachIdleTimer();
double timer = 0;
DchDemotionQueue dchDemotionQueue = new DchDemotionQueue(profile);
FachQueue fachQueue = new FachQueue(profile);
// Set up initial packet
PacketInfo prevPacket = packetInfos.get(0);
double currTimeStamp = prevPacket.getTimeStamp();
prevPacket.setStateMachine(RRCState.PROMO_IDLE_DCH);
// Add initial idle state
addStateRangeEx(result, 0, Double.MAX_VALUE, RRCState.STATE_IDLE, currTimeStamp);
for (int i = 1; i <= packetInfos.size(); ++i) {
PacketInfo packet;
PacketDirection dir;
int currLen;
if (i >= packetInfos.size()) {
// The last iteration of this loop
packet = null;
dir = PacketDirection.UPLINK;
currTimeStamp = Double.MAX_VALUE;
currLen = 0;
} else {
// Iteration on a packet
packet = packetInfos.get(i);
dir = packet.getDir();
currTimeStamp = packet.getTimeStamp();
currLen = packet.getLen();
}
double prevTimeStamp = (prevPacket == null ? 0.0 : prevPacket.getTimeStamp());
double deltaTime = currTimeStamp - prevTimeStamp;
// the next state to be determined
RRCState state = null;
RRCState promoState = (prevPacket == null ? RRCState.STATE_IDLE : prevPacket.getStateMachine());
if (promoState == RRCState.PROMO_IDLE_DCH || promoState == RRCState.PROMO_FACH_DCH) {
double promoAvg, promoMin, promoMax;
if (promoState == RRCState.PROMO_IDLE_DCH) {
promoAvg = idleDchPromoAvg;
promoMin = idleDchPromoMin;
promoMax = idleDchPromoMax;
} else {
promoAvg = fachDchPromoAvg;
promoMin = fachDchPromoMin;
promoMax = fachDchPromoMax;
}
if (dir == PacketDirection.UPLINK && timer + deltaTime <= promoMin) {
// Case
// 1
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, promoState, currTimeStamp);
state = promoState;
timer += deltaTime;
} else if (dir == PacketDirection.DOWNLINK && timer + deltaTime <= promoMin) {
// TODO: handle an error situation here: a DOWNLINK DCH
// packet follows "immediately" after a packet on
// FACH/IDLE
// promotion
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, promoState, currTimeStamp);
state = promoState;
timer += deltaTime;
} else if (timer + deltaTime <= promoMax) {
// Case 2
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, promoState, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
} else if (timer + deltaTime <= promoAvg + dchFachTimer) {
// Case
// 3
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
} else if (timer + deltaTime <= promoAvg + dchFachTimer + fachIdleTimer) {
// 4
if (dir == PacketDirection.DOWNLINK) {
fachQueue.init();
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
// FACH->DCH
double tMax0 = currTimeStamp - fachDchPromoAvg;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchFachTimer, RRCState.TAIL_DCH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_FACH_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
} else {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchFachTimer, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
state = RRCState.STATE_FACH;
}
} else {
// downlink
fachQueue.init();
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchFachTimer, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
state = RRCState.PROMO_FACH_DCH;
timer = 0;
} else {
state = RRCState.STATE_FACH;
}
}
} else {
// case 5
if (dir == PacketDirection.UPLINK) {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchFachTimer, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, currTimeStamp);
state = RRCState.PROMO_IDLE_DCH;
timer = 0;
} else {
// downlink
double tMax0 = currTimeStamp - idleDchPromoAvg;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, promoAvg - timer, promoState, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchFachTimer, RRCState.TAIL_DCH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_IDLE_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
}
}
// break;
} else if (promoState == RRCState.STATE_DCH) {
// ***
double dchTail = dchDemotionQueue.getDCHTail(currTimeStamp);
if (deltaTime <= dchTail + 1e-5) {
// DCH Case 1
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.update(currTimeStamp, currLen, dir);
} else if (deltaTime <= dchTail + fachIdleTimer) {
// 2
if (dir == PacketDirection.DOWNLINK) {
// downlink
fachQueue.init();
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
double tMax0 = currTimeStamp - fachDchPromoAvg;
changeStateRangeBack(result, dchFachTimer - dchTail, RRCState.TAIL_DCH);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchTail, RRCState.TAIL_DCH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_FACH_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
} else {
changeStateRangeBack(result, dchFachTimer - dchTail, RRCState.TAIL_DCH);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchTail, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
state = RRCState.STATE_FACH;
}
} else {
// uplink
fachQueue.init();
changeStateRangeBack(result, dchFachTimer - dchTail, RRCState.TAIL_DCH);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchTail, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
state = RRCState.PROMO_FACH_DCH;
timer = 0;
} else {
state = RRCState.STATE_FACH;
}
}
} else {
// DCH Case 3
if (dir == PacketDirection.UPLINK) {
// uplink
changeStateRangeBack(result, dchFachTimer - dchTail, RRCState.TAIL_DCH);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchTail, RRCState.TAIL_DCH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, currTimeStamp);
state = RRCState.PROMO_IDLE_DCH;
timer = 0;
} else {
// downlink
double tMax0 = currTimeStamp - idleDchPromoAvg;
changeStateRangeBack(result, dchFachTimer - dchTail, RRCState.TAIL_DCH);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, dchTail, RRCState.TAIL_DCH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_IDLE_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
}
}
// break;
} else if (promoState == RRCState.STATE_FACH) {
if (deltaTime <= fachIdleTimer) {
if (dir == PacketDirection.UPLINK) {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
state = RRCState.PROMO_FACH_DCH;
timer = 0;
} else {
state = RRCState.STATE_FACH;
}
} else {
// downlink
if (fachQueue.simFACH(currTimeStamp, dir, currLen)) {
double tMax0 = currTimeStamp - fachDchPromoAvg;
/*
* TODO: ( diff ) handle the case where promo
* delay is 0 ( for what - if )
*/
if (tMax0 > prevTimeStamp || fachDchPromoAvg < 1e-6) {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_FACH_DCH, currTimeStamp);
} else {
// *** handle an error situation here: a
// DOWNLINK DCH packet follows "immediately"
// after a packet on FACH
// try
tMax0 = currTimeStamp - fachDchPromoMin;
// y?
if (tMax0 > prevTimeStamp) {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_FACH_DCH, currTimeStamp);
} else {
// still not working - try to
// insert a
// promotion after some previous
// packet
boolean bFixed = false;
for (int ii = i - 1; ii > 0; ii--) {
PacketInfo earlierPacket = packetInfos.get(ii);
if (earlierPacket.getStateMachine() == RRCState.STATE_FACH) {
// FACH-DCH promo: from
// packets[ii].ts to
// packets[ii].ts+y
// DCH: from packets[ii].ts+y to
// tMax
double piTimeStamp = packetInfos.get(ii).getTimeStamp();
if (earlierPacket.getDir() == PacketDirection.UPLINK && currTimeStamp >= piTimeStamp + fachDchPromoMin) {
int resultSize = result.size() - 1;
// boolean bDone = false;
for (int jj = resultSize; jj > 0; jj--) {
// double EPS = 1e-4;
if (result.get(jj).getBeginTime() == piTimeStamp) {
for (int k = 0; k < resultSize - jj + 1; k++) {
result.remove(result.size() - 1);
}
double avgDchPromo;
if (currTimeStamp >= piTimeStamp + fachDchPromoAvg) {
avgDchPromo = fachDchPromoAvg;
} else {
avgDchPromo = fachDchPromoMin;
}
result.add(new RrcStateRange(piTimeStamp, piTimeStamp + avgDchPromo, RRCState.PROMO_FACH_DCH));
result.add(new RrcStateRange(piTimeStamp + avgDchPromo, prevTimeStamp, RRCState.STATE_DCH));
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_DCH, currTimeStamp);
break;
}
// #undef EPS
}
bFixed = true;
break;
}
} else {
break;
}
}
if (!bFixed) {
// still not working - force it on
// FACH
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
state = RRCState.STATE_FACH;
fachQueue.init();
}
}
}
// finish handling the error case
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
} else {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_FACH, currTimeStamp);
state = RRCState.STATE_FACH;
}
}
} else {
if (dir == PacketDirection.UPLINK) {
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, currTimeStamp);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, currTimeStamp);
state = RRCState.PROMO_IDLE_DCH;
timer = 0;
} else {
// downlink
double tMax0 = currTimeStamp - idleDchPromoAvg;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, fachIdleTimer, RRCState.TAIL_FACH, tMax0);
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.STATE_IDLE, tMax0);
// promoTime = tMax - tt;
prevTimeStamp = addStateRangeEx(result, prevTimeStamp, Double.MAX_VALUE, RRCState.PROMO_IDLE_DCH, currTimeStamp);
state = RRCState.STATE_DCH;
dchDemotionQueue.init(currTimeStamp, currLen, dir);
}
}
}
if (packet != null) {
packet.setStateMachine(state);
}
prevPacket = packet;
}
}
result = compressStateRanges(result);
// Truncate state ranges at end of trace
Iterator<RrcStateRange> iter = result.iterator();
double prevTimeStamp = 0.0;
while (iter.hasNext()) {
RrcStateRange rrc = iter.next();
if (rrc.getBeginTime() >= traceDuration) {
iter.remove();
}
if (rrc.getEndTime() > traceDuration) {
rrc.setEndTime(traceDuration);
}
prevTimeStamp = rrc.getEndTime();
}
if (prevTimeStamp < traceDuration) {
// Add idle time to end of trace
result.add(new RrcStateRange(prevTimeStamp, traceDuration, RRCState.STATE_IDLE));
}
return result;
}
Aggregations