Class SIPUserAgent
A "full" SIP user agent that encompasses both client and server user agents. It is also able to manage in dialog operations after the call is established (the client and server user agents don't handle in dialog operations).
Unlike other user agents this one also manages its own RTP session object which means it can handle things like call on and off hold, RTP end point changes and sending DTMF events.
Inheritance
Implements
Inherited Members
Namespace: SIPSorcery.SIP.App
Assembly: SIPSorcery.dll
Syntax
public class SIPUserAgent : IDisposable
Constructors
| Improve this Doc View SourceSIPUserAgent()
Creates a new instance where the user agent has exclusive control of the SIP transport. This is significant for incoming requests. WIth exclusive control the agent knows that any request are for it and can handle accordingly. If the transport needs to be shared amongst multiple user agents use the alternative constructor.
Declaration
public SIPUserAgent()
SIPUserAgent(SIPTransport, SIPEndPoint, Boolean, ISIPAccount)
Creates a new SIP client and server combination user agent with a shared SIP transport instance. With a shared transport outgoing calls and registrations work the same but for incoming calls and requests the destination needs to be coordinated externally.
Declaration
public SIPUserAgent(SIPTransport transport, SIPEndPoint outboundProxy, bool isTransportExclusive = false, ISIPAccount answerSipAccount = null)
Parameters
Type | Name | Description |
---|---|---|
SIPTransport | transport | The transport layer to use for requests and responses. |
SIPEndPoint | outboundProxy | Optional. If set all requests and responses will be forwarded to this end point irrespective of their headers. |
System.Boolean | isTransportExclusive | True is the SIP transport instance is for the exclusive use of this user agent or false if it's being shared amongst multiple agents. |
ISIPAccount | answerSipAccount | Optional, will ensure that any request that require auth will be able to complete |
Properties
| Improve this Doc View SourceCallDescriptor
For a call initiated by us this is the call descriptor that was used.
Declaration
public SIPCallDescriptor CallDescriptor { get; }
Property Value
Type | Description |
---|---|
SIPCallDescriptor |
ContactURI
The default SIP URI that this URI can be contacted on. Depending on the SIP transport being used by the agent there may be multiple ways of contacting it. In that case the first URI found is used.
Declaration
public SIPURI ContactURI { get; }
Property Value
Type | Description |
---|---|
SIPURI |
Dialogue
Once either the client or server call is answered this will hold the SIP dialogue that was created by the call.
Declaration
public SIPDialogue Dialogue { get; }
Property Value
Type | Description |
---|---|
SIPDialogue |
IsCallActive
Indicates whether there is an active call or not.
Declaration
public bool IsCallActive { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
IsCalling
Indicates whether a call initiated by this user agent is in progress but is yet to get a ring or progress response.
Declaration
public bool IsCalling { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
IsHangingUp
Indicates whether the user agent is in the process of hanging up or cancelling a call.
Declaration
public bool IsHangingUp { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
IsOnLocalHold
True if we've put the remote party on hold.
Declaration
public bool IsOnLocalHold { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
IsOnRemoteHold
True if the remote party has put us on hold.
Declaration
public bool IsOnRemoteHold { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
IsRinging
Indicates whether a call initiated by this user agent has received a ringing or progress response.
Declaration
public bool IsRinging { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
MediaSession
The media (RTP) session in use for the current call.
Declaration
public IMediaSession MediaSession { get; }
Property Value
Type | Description |
---|---|
IMediaSession |
PrackSupported
Determines whether the agent will operate with support for reliable provisional responses as per RFC3262. If support is not desired it should be set to false before the initial INVITE request is sent.
Declaration
public bool PrackSupported { get; set; }
Property Value
Type | Description |
---|---|
System.Boolean |
Methods
| Improve this Doc View SourceAcceptCall(SIPRequest)
This method can be used to start the processing of a new incoming call request. The user agent will is acting as a server for this operation and it can be considered the opposite of the Call method. This is only the first step in answering an incoming call. It can still be rejected or answered after this point.
Declaration
public SIPServerUserAgent AcceptCall(SIPRequest inviteRequest)
Parameters
Type | Name | Description |
---|---|---|
SIPRequest | inviteRequest | The invite request representing the incoming call. |
Returns
Type | Description |
---|---|
SIPServerUserAgent | An ID string that needs to be supplied when the call is answered or rejected (used to manage multiple pending incoming calls). |
Answer(SIPServerUserAgent, IMediaSession, IPAddress)
Answers the call request contained in the user agent server parameter. Note the AcceptCall(SIPRequest) method should be used to create the user agent server. Any existing call will be hungup.
Declaration
public Task<bool> Answer(SIPServerUserAgent uas, IMediaSession mediaSession, IPAddress publicIpAddress = null)
Parameters
Type | Name | Description |
---|---|---|
SIPServerUserAgent | uas | The user agent server holding the pending call to answer. |
IMediaSession | mediaSession | The media session used for this call |
System.Net.IPAddress | publicIpAddress | The public IP address to use in SDP |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> |
Answer(SIPServerUserAgent, IMediaSession, String[], IPAddress)
Answers the call request contained in the user agent server parameter. Note the AcceptCall(SIPRequest) method should be used to create the user agent server. Any existing call will be hungup.
Declaration
public async Task<bool> Answer(SIPServerUserAgent uas, IMediaSession mediaSession, string[] customHeaders, IPAddress publicIpAddress = null)
Parameters
Type | Name | Description |
---|---|---|
SIPServerUserAgent | uas | The user agent server holding the pending call to answer. |
IMediaSession | mediaSession | The media session used for this call |
System.String[] | customHeaders | Custom SIP-Headers to use in Answer. |
System.Net.IPAddress | publicIpAddress | The public IP address to use in SDP |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> | True if the call was successfully answered or false if there was a problem such as incompatible codecs. |
AttendedTransfer(SIPDialogue, TimeSpan, CancellationToken, String[], String, String)
Initiates an attended transfer by asking the remote call party to call the specified destination. If the transfer is accepted the current call will be hungup.
Declaration
public Task<bool> AttendedTransfer(SIPDialogue transferee, TimeSpan timeout, CancellationToken ct, string[] customHeaders = null, string username = null, string password = null)
Parameters
Type | Name | Description |
---|---|---|
SIPDialogue | transferee | The dialog that will be replaced on the transfer target call party. |
System.TimeSpan | timeout | Timeout for the transfer request to get accepted. |
System.Threading.CancellationToken | ct | Cancellation token. Can be set to cancel the transfer prior to it being accepted or timing out. |
System.String[] | customHeaders | Optional. Custom SIP-Headers that will be set in the REFER request sent to the remote party. |
System.String | username | Optional. Used if proxy authentication required. |
System.String | password | Optional. Used if proxy authentication required. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> | True if the transfer was accepted by the Transferee or false if not. |
BlindTransfer(SIPURI, TimeSpan, CancellationToken, String[], String, String)
Initiates a blind transfer by asking the remote call party to call the specified destination. If the transfer is accepted the current call will be hungup.
Declaration
public Task<bool> BlindTransfer(SIPURI destination, TimeSpan timeout, CancellationToken ct, string[] customHeaders = null, string username = null, string password = null)
Parameters
Type | Name | Description |
---|---|---|
SIPURI | destination | The URI to transfer the call to. |
System.TimeSpan | timeout | Timeout for the transfer request to get accepted. |
System.Threading.CancellationToken | ct | Cancellation token. Can be set to cancel the transfer prior to it being accepted or timing out. |
System.String[] | customHeaders | Optional. Custom SIP-Headers that will be set in the REFER request sent to the remote party. |
System.String | username | Optional. Used if proxy authentication required. |
System.String | password | Optional. Used if proxy authentication required. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> | True if the transfer was accepted by the Transferee or false if not. |
Call(SIPCallDescriptor, IMediaSession, Int32)
Attempts to place a new outgoing call AND waits for the call to be answered or fail. Use InitiateCallAsync(SIPCallDescriptor, IMediaSession, Int32) to start a call without waiting for it to complete and monitor SIPSorcery.SIP.App.SIPUserAgent.ClientCallAnsweredHandler(SIPSorcery.SIP.App.ISIPClientUserAgent,SIPSorcery.SIP.SIPResponse) and SIPSorcery.SIP.App.SIPUserAgent.ClientCallFailedHandler(SIPSorcery.SIP.App.ISIPClientUserAgent,System.String,SIPSorcery.SIP.SIPResponse) to detect an answer or failure.
Declaration
public async Task<bool> Call(SIPCallDescriptor callDescriptor, IMediaSession mediaSession, int ringTimeout = 0)
Parameters
Type | Name | Description |
---|---|---|
SIPCallDescriptor | callDescriptor | The full descriptor for the call destination. Allows customising of additional options above the standard username, password and destination URI. |
IMediaSession | mediaSession | The RTP session for the call. |
System.Int32 | ringTimeout | Optional. If non-zero will be treated as the number of seconds to let the call ring for before giving up and cancelling. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> |
Call(String, String, String, IMediaSession, Int32)
Attempts to place a new outgoing call AND waits for the call to be answered or fail. Use InitiateCallAsync(SIPCallDescriptor, IMediaSession, Int32) to start a call without waiting for it to complete and monitor SIPSorcery.SIP.App.SIPUserAgent.ClientCallAnsweredHandler(SIPSorcery.SIP.App.ISIPClientUserAgent,SIPSorcery.SIP.SIPResponse) and SIPSorcery.SIP.App.SIPUserAgent.ClientCallFailedHandler(SIPSorcery.SIP.App.ISIPClientUserAgent,System.String,SIPSorcery.SIP.SIPResponse) to detect an answer or failure.
Declaration
public Task<bool> Call(string dst, string username, string password, IMediaSession mediaSession, int ringTimeout = 0)
Parameters
Type | Name | Description |
---|---|---|
System.String | dst | The destination SIP URI to call. |
System.String | username | Optional Username if authentication is required. |
System.String | password | Optional. Password if authentication is required. |
IMediaSession | mediaSession | The RTP session for the call. |
System.Int32 | ringTimeout | Optional. If non-zero will be treated as the number of seconds to let the call ring for before giving up and cancelling. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<System.Boolean> |
Cancel()
Cancel our call attempt prior to it being answered.
Declaration
public void Cancel()
Close()
Calling close indicates the SIP user agent is no longer required and it should not respond to any NEW requests. It will still respond to BYE in-dialog requests in order to correctly deal with re-transmits.
Declaration
public void Close()
Dispose()
Final cleanup if instance is being discarded.
Declaration
public void Dispose()
Hangup()
Hangup established call
Declaration
public void Hangup()
InitiateCallAsync(SIPCallDescriptor, IMediaSession, Int32)
Attempts to place a new outgoing call.
Declaration
public async Task InitiateCallAsync(SIPCallDescriptor sipCallDescriptor, IMediaSession mediaSession, int ringTimeout = 0)
Parameters
Type | Name | Description |
---|---|---|
SIPCallDescriptor | sipCallDescriptor | A call descriptor containing the information about how and where to place the call. |
IMediaSession | mediaSession | The media session used for this call |
System.Int32 | ringTimeout | Optional. If non-zero will be treated as the number of seconds to let the call ring for before giving up and cancelling. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task |
PutOnHold()
Send a re-INVITE request to put the remote call party on hold.
Declaration
public void PutOnHold()
SendDtmf(Byte)
Requests the RTP session to transmit a DTMF tone using an RTP event.
Declaration
public Task SendDtmf(byte tone)
Parameters
Type | Name | Description |
---|---|---|
System.Byte | tone | The DTMF tone to transmit. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task |
TakeOffHold()
Send a re-INVITE request to take the remote call party on hold.
Declaration
public void TakeOffHold()
Events
| Improve this Doc View SourceClientCallAnswered
The in progress call attempt was answered.
Declaration
public event SIPCallResponseDelegate ClientCallAnswered
Event Type
Type | Description |
---|---|
SIPCallResponseDelegate |
ClientCallFailed
The in progress call attempt failed.
Declaration
public event SIPCallFailedDelegate ClientCallFailed
Event Type
Type | Description |
---|---|
SIPCallFailedDelegate |
ClientCallRinging
The remote party has progressed our call request to ringing/in progress.
Declaration
public event SIPCallResponseDelegate ClientCallRinging
Event Type
Type | Description |
---|---|
SIPCallResponseDelegate |
ClientCallTrying
The remote party has received our call request and is working on it.
Declaration
public event SIPCallResponseDelegate ClientCallTrying
Event Type
Type | Description |
---|---|
SIPCallResponseDelegate |
OnCallHungup
Call was hungup by the remote party. Applies to calls initiated by us and calls received by us. An example of when this user agent will initiate a hang up is when a transfer is accepted by the remote calling party.
Declaration
public event Action<SIPDialogue> OnCallHungup
Event Type
Type | Description |
---|---|
System.Action<SIPDialogue> |
OnDtmfTone
Gets fired when an RTP DTMF event is detected as completed on the remote party's RTP stream.
Declaration
public event Action<byte, int> OnDtmfTone
Event Type
Type | Description |
---|---|
System.Action<System.Byte, System.Int32> |
OnIncomingCall
Gets fired when a new INVITE request is detected on the SIP transport being used by this user agent.
Declaration
public event Action<SIPUserAgent, SIPRequest> OnIncomingCall
Event Type
Type | Description |
---|---|
System.Action<SIPUserAgent, SIPRequest> |
OnReinviteRequest
The remote call party has sent us a new re-INVITE request that this class didn't know how to or couldn't handle. Things we can handle are on and off hold. Common examples of what we can't handle are changing RTP end points, changing codecs etc.
Declaration
public event Action<UASInviteTransaction> OnReinviteRequest
Event Type
Type | Description |
---|---|
System.Action<UASInviteTransaction> |
OnRtpEvent
Gets fired for every RTP event packet received from the remote party. This event allows the application to decipher the vents as it wishes.
Declaration
public event Action<RTPEvent, RTPHeader> OnRtpEvent
Event Type
Type | Description |
---|---|
System.Action<RTPEvent, RTPHeader> |
OnTransactionStateChange
Diagnostic event to allow monitoring of the INVITE transaction state.
Declaration
public event SIPTransactionStateChangeDelegate OnTransactionStateChange
Event Type
Type | Description |
---|---|
SIPTransactionStateChangeDelegate |
OnTransactionTraceMessage
Diagnostic event to receive trace messages related to the INVITE transaction state machine processing.
Declaration
public event SIPTransactionTraceMessageDelegate OnTransactionTraceMessage
Event Type
Type | Description |
---|---|
SIPTransactionTraceMessageDelegate |
OnTransferCallDescriptorCreated
Allows the call descriptor for the new call to be customised before a transfer.
Declaration
public event Action<SIPCallDescriptor, SIPRequest> OnTransferCallDescriptorCreated
Event Type
Type | Description |
---|---|
System.Action<SIPCallDescriptor, SIPRequest> |
Remarks
SIPCallDescriptor: The call descriptor to be customised SIPRequest: The refer request that initialised the transfer
OnTransferNotify
Fires when a NOTIFY request is received that contains an update about the status of a transfer. These events will be received by a user agent acting as the Transferor but only if the Transferee support the transfer subscription.
Declaration
public event Action<string> OnTransferNotify
Event Type
Type | Description |
---|---|
System.Action<System.String> |
OnTransferRequested
Fires when a REFER request is received that requests us to place a call to a new destination. The REFER request can be a blind transfer or an attended transfer. The difference is whether the REFER request includes a Replaces parameter. If it does it's used to inform the transfer target (the transfer destination requested) that if they accept our call it should replace an existing one.
Declaration
public event Func<SIPUserField, string, bool> OnTransferRequested
Event Type
Type | Description |
---|---|
System.Func<SIPUserField, System.String, System.Boolean> |
Remarks
Parameters for event delegate: bool OnTransferRequested(SIPUserField referTo, string referredBy) SIPUserField: Is the destination that we are being asked to place a call to. string referredBy: The Referred-By header from the REFER request that requested we do the transfer. bool: The boolean result can be returned as false to prevent the transfer. By default if no event handler is hooked up the transfer will be accepted.
OnTransferToTargetFailed
Fires when the call placed as a result of a transfer request is rejected or fails. The SIPUserField contains the destination that was called for the transfer.
Declaration
public event Action<SIPUserField> OnTransferToTargetFailed
Event Type
Type | Description |
---|---|
System.Action<SIPUserField> |
OnTransferToTargetSuccessful
Fires when the call placed as a result of a transfer request is successfully answered. The SIPUserField contains the destination that was called for the transfer.
Declaration
public event Action<SIPUserField> OnTransferToTargetSuccessful
Event Type
Type | Description |
---|---|
System.Action<SIPUserField> |
RemotePutOnHold
The remote call party has put us on hold.
Declaration
public event Action RemotePutOnHold
Event Type
Type | Description |
---|---|
System.Action |
RemoteTookOffHold
The remote call party has taken us off hold.
Declaration
public event Action RemoteTookOffHold
Event Type
Type | Description |
---|---|
System.Action |
ServerCallCancelled
For calls accepted by this user agent this event will be fired if the call is cancelled before it gets answered.
Declaration
public event SIPUASCancelDelegate ServerCallCancelled
Event Type
Type | Description |
---|---|
SIPUASCancelDelegate |
ServerCallRingTimeout
For calls accepted by this user agent this event will be fired if the call is answered but the answer response is never confirmed. This can occur if the client does not send the ACK or the ACK does not get through.
Declaration
public event SIPUASDelegate ServerCallRingTimeout
Event Type
Type | Description |
---|---|
SIPUASDelegate |