public class BasicSipStream extends Object implements SipStream
BasicSipStream only does some very basic analysis of the SIP
messages in order to determine which dialog the message belongs to. It is
faster and consumes less memory than the DefaultSipStream but is not
capable of detecting so-called derived dialogs since it (falsely) assumes it
can use the call-id as a unique key for each dialog.
Also, if multiple pcaps are merged it will not always handle the case where
e.g. the initial message indicating the start of the stream shows up after we
have already seen other messages in the stream (could happen if you merge two
pcaps where the first pcap contains messages that arrived later time - hence,
you didn't merge the pcaps in cronological order). If you need this accuracy,
then you should be using the DefaultSipStream instead.SipStream.CallState| Constructor and Description |
|---|
BasicSipStream(PcapGlobalHeader globalHeader,
StreamId streamIdentifier) |
| Modifier and Type | Method and Description |
|---|---|
void |
addMessage(SipPacket message)
|
SipStream |
createEmptyClone()
Create an empty clone of this
SipStream. |
SDP |
get200OkSDP()
Convenience method for returning the
SDP found on the 200 OK to the first INVITE
request. |
SipStream.CallState |
getCallState()
Which
SipStream.CallState the call is in. |
long |
getDuration()
The duration for a
SipStream is calculated differently depending
on what the stream is capturing. |
SDP |
getInviteSDP()
Convenience method for returning the
SDP found on the first INVITE request. |
List<SipPacket> |
getPackets()
|
long |
getPostDialDelay()
Post Dial Delay (PDD) is defined as the time it takes between the INVITE
and until some sort of ringing signal is received (18x responses).
|
StreamId |
getStreamIdentifier()
Get the identifier used for grouping the
SipPackets together. |
long |
getTimeOfFirstPacket()
Get the arrival time of the very first packet in this stream.
|
long |
getTimeOfLastPacket()
Get the arrival time of the last packet in this stream.
|
boolean |
handshakeComplete()
Indicates whether the INVITE handshake was completed.
|
boolean |
isTerminated()
Check whether this
SipStream is in the terminated state, which it is if any of the following is true:
For INVITE streams:
If the initial handshake failed with an error
response (which will include CANCEL scenarios)
If the call was successfully established and a BYE
request and the corresponding final response has been processed
|
boolean |
reTranmitsDetected()
Indicates whether there were retransmissions detected.
|
void |
save(OutputStream out)
Save this
SipStream to the specified OutputStream. |
void |
save(String filename)
Save this
SipStream to the specified file. |
void |
write(OutputStream out)
Write this
Stream to the specified OutputStream. |
public BasicSipStream(PcapGlobalHeader globalHeader, StreamId streamIdentifier)
public void addMessage(SipPacket message) throws SipPacketParseException
SipStreamSipPacket to this SipStream. By doing so you will
force the SipStream to move its internal state machine along
since it just "received" a new SipPacket.addMessage in interface SipStreamSipPacketParseException - in case something goes wrong while parsing the
SipPacketpublic boolean isTerminated()
SipStreamSipStream is in the terminated state, which it is if any of the following is true:
For INVITE streams:
isTerminated in interface SipStreampublic List<SipPacket> getPackets()
getPackets in interface SipStreamgetPackets in interface Stream<SipPacket>public long getPostDialDelay()
throws SipPacketParseException
getPostDialDelay in interface SipStreamSipStream is not an
INVITE scenario.SipPacketParseException - in case anything goes wrong while trying to calculate the
PDD.public long getDuration()
SipStream is calculated differently depending
on what the stream is capturing. For dialogs (INVITE, SUBSCRIBE, REFER)
the duration is equal to the duration of the dialog. As such, any
re-transmissions of the terminating event etc will NOT be taken into
consideration when calculating the duration. However, if the underlying
sip stream is not a dialog, then the duration will simply be the time
between the first and last message that we recorded. Get the duration in microseconds of the stream. Note, see comment on
Packet.getArrivalTime() regarding the microsecond precision.
Depending on the underlying protocol this can be as simple as the time
between the first to the last packet, which is what the RtpStream
does. Or, it can be more complicated as with a SipStream that
checks the duration of the dialog (if one was established).getDuration in interface SipStreamgetDuration in interface Stream<SipPacket>Stream. If the
duration cannot be calulated for whatever reason (no packets at
all? Only one packet?), then -1 (negative one) will be returned.public StreamId getStreamIdentifier()
SipPackets together. Currently, this is the
same as the call-id.
Note, perhaps this should be a dialog id instead since ideally that is what we should be
using for grouping together SipStreams. On the other hand, using the dialog-id as an
identifier can make things messy for forked dialogs etc. This works and keeps things simple
so we will stick with it for now.getStreamIdentifier in interface SipStreamgetStreamIdentifier in interface Stream<SipPacket>public void write(OutputStream out) throws IOException
Streamwrite in interface Stream<SipPacket>out - the OutputStream, which typically is a
PcapOutputStream.IOExceptionpublic SipStream.CallState getCallState()
SipStreamSipStream.CallState the call is in.
NOTE: this only applies to INVITE dialogs.getCallState in interface SipStreamSipStream.CallState.public boolean handshakeComplete()
SipStreamhandshakeComplete in interface SipStreampublic boolean reTranmitsDetected()
SipStreamreTranmitsDetected in interface SipStreampublic void save(String filename) throws IOException
SipStreamSipStream to the specified file.save in interface SipStreamIOExceptionpublic void save(OutputStream out) throws IOException
SipStreamSipStream to the specified OutputStream. The
difference between this method and Stream.write(OutputStream) is that
the latter assumes that the pcap headers etc already have been written to
the stream. However, this method will write this SipStream as a
standalone pcap.save in interface SipStreamIOExceptionpublic long getTimeOfFirstPacket()
StreamPacket.getArrivalTime() regarding the
microsecond precision.getTimeOfFirstPacket in interface Stream<SipPacket>Stream doesn't contain any
packets.public long getTimeOfLastPacket()
StreamPacket.getArrivalTime() regarding the
microsecond precision.getTimeOfLastPacket in interface Stream<SipPacket>Stream doesn't contain any
packets.public SipStream createEmptyClone()
SipStreamSipStream. What this means is that
you get a SipStream with the same StreamId and underlying
PcapGlobalHeader (which you really do not need to know) but
otherwise it is empty. I.e., it doesn't contain any SipPackets.
Use this method when you e.g. have a SipStream that you want to
split in two. A typical scenario is if you have a SipStream that
went through a SIP Proxy but you want to split this stream in one "left"
side and one "right" side. You do so by figuring out which message
belongs to each side and then create two empty clones and then drive the
traffic from each side through the new SipStreams. This will then
give you two separate SipStream but that still will have the
stats available.createEmptyClone in interface SipStreampublic SDP getInviteSDP() throws SipPacketParseException
SipStreamSDP found on the first INVITE request. Note, if
you want to find the SDP for a re-invite, then you will have to SipStream.getPackets() and
find the particular INVITE you are looking for.getInviteSDP in interface SipStreamSipPacketParseExceptionpublic SDP get200OkSDP() throws SipPacketParseException
SipStreamSDP found on the 200 OK to the first INVITE
request.
Note, if you want to find the SDP for 200 OK to a re-invite, then you will have to
SipStream.getPackets() and find the particular response you are looking for.get200OkSDP in interface SipStreamSipPacketParseExceptionCopyright © 2021. All Rights Reserved.