protected SipAbstractDialog(SipHeaderFactory headerFactory, SipMessageFactory messageFactory, SipAddressFactory addressFactory, ISipMessageSender messageSender, ISipListener listener, IPEndPoint listeningPoint, ISipTransaction transaction) { Check.Require(headerFactory, "headerFactory"); Check.Require(messageFactory, "messageFactory"); Check.Require(addressFactory, "addressFactory"); Check.Require(messageSender, "messageSender"); Check.Require(listener, "listener"); Check.Require(listeningPoint, "listeningPoint"); Check.Require(transaction, "transaction"); Check.Require(transaction.Request, "transaction.Request"); ValidateRequest(transaction.Request); _routeSet = new List<SipRecordRouteHeader>(); _createDate = DateTime.Now; _localSequenceNr = -1; _remoteSequenceNr = -1; _listener = listener; _listeningPoint = listeningPoint; _headerFactory = headerFactory; _messageFactory = messageFactory; _addressFactory = addressFactory; _messageSender = messageSender; _firstTransaction = transaction; _firstRequest = transaction.Request; }
public NonInviteClientTransaction(SipRequest request) { _request = request; //Check.Require() //Check.Require(request.Method != SipMethods.Invite) _state = new ProceedingState(this); }
protected override void OnTestClientUaReceive(SipContext sipContext) { if (sipContext.Request.RequestLine.Method == SipMethods.Invite) { _receivedInvite = sipContext.Request; _waitingforInviteReceived.Set(); } }
private SipRequest ApplyActions(SipRequest sipRequest) { var selected =_cmbHeaders.SelectedItem != null ? _cmbHeaders.SelectedItem.ToString() : string.Empty; if (selected != string.Empty) sipRequest.RemoveHeader(selected); return sipRequest; }
public void SendAck(SipRequest ackRequest) { Check.Require(ackRequest, "ackRequest"); Check.IsTrue(ackRequest.RequestLine.Method == SipMethods.Ack, "Can not send a request other then 'ACK'"); _messageSender.SendRequest(ackRequest); _isAckSent = true; }
internal SipNonInviteServerTransaction( SipServerTransactionTable table, SipRequest request, ISipListener listener, ISipMessageSender messageSender, ITimerFactory timerFactory) : base(table, request, listener, messageSender, timerFactory) { Check.IsTrue(request.RequestLine.Method != SipMethods.Invite, "Request method can not be 'INVITE'."); Check.IsTrue(request.RequestLine.Method != SipMethods.Ack, "Request method can not be 'ACK'."); EndCompletedTimer = _timerFactory.CreateNonInviteStxEndCompletedTimer(OnCompletedEnded); }
public ValidateRequestResult ValidateRequest(SipRequest request) { var result = new ValidateRequestResult(); if (!SipMethods.IsMethod(request.RequestLine.Method)) { result.UnSupportedSipMethod = request.RequestLine.Method; } result.MissingRequiredHeader = FindFirstMissingRequiredHeader(request); result.HasUnSupportedSipVersion = !ValidateSipVersion(request.RequestLine.Version); if (result.HasRequiredHeadersMissing) return result; result.HasInvalidSCeqMethod = !ValidateCSeqMethod(request); return result; }
protected override void GivenOverride() { /*force it to go into confirmed state*/ _okResponse = CreateOkResponse(); _rer = new SipResponseEventBuilder().WithResponse(CreateRingingResponse()).WithClientTx(InviteCtx.Object).Build(); _reo = new SipResponseEventBuilder().WithResponse(_okResponse).WithClientTx(InviteCtx.Object).Build(); ClientDialog.ProcessResponse(_rer); ClientDialog.ProcessResponse(_reo); ClientDialog.State.Should().Be(DialogState.Confirmed); /*required assertion*/ _ackRequest = ClientDialog.CreateAck(); ClientDialog.SendAck(_ackRequest); /*sent an ack*/ _beforeSentSeqNr = ClientDialog.LocalSequenceNr; }
protected SipAbstractServerTransaction(SipServerTransactionTable table, SipRequest request, ISipListener listener, ISipMessageSender messageSender, ITimerFactory timerFactory) { Check.Require(table, "table"); Check.Require(request, "request"); Check.Require(listener, "listener"); Check.Require(messageSender, "messageSender"); Check.Require(timerFactory, "timerFactory"); _table = table; _request = request; _listener = listener; _messageSender = messageSender; _timerFactory = timerFactory; }
internal SipNonInviteClientTransaction( SipClientTransactionTable table, ISipMessageSender messageSender, ISipListener listener, SipRequest request, ITimerFactory timerFactory) : base(table, request, messageSender, listener, timerFactory) { Check.IsTrue(request.RequestLine.Method != SipMethods.Invite, "Method 'INVITE' is not allowed"); Check.IsTrue(request.RequestLine.Method != SipMethods.Ack, "Method 'ACK' is not allowed"); _logger = NLog.LogManager.GetCurrentClassLogger(); ReTransmitTimer = _timerFactory.CreateNonInviteCtxRetransmitTimer(OnReTransmit); TimeOutTimer = _timerFactory.CreateNonInviteCtxTimeOutTimer(OnTimeOut); EndCompletedTimer = _timerFactory.CreateNonInviteCtxEndCompletedTimer(OnCompletedEnded); }
internal SipInviteServerTransaction( SipServerTransactionTable table, ISipMessageSender messageSender, ISipListener listener, SipRequest request, ITimerFactory timerFactory) : base(table, request, listener, messageSender, timerFactory) { Check.IsTrue(request.RequestLine.Method == SipMethods.Invite, "Method other then 'INVITE' is not allowed"); _logger = NLog.LogManager.GetCurrentClassLogger(); ReTransmitNonx200FinalResponseTimer = _timerFactory.CreateInviteStxRetransmitTimer(OnReTransmitNonx200FinalResponse); EndCompletedTimer = _timerFactory.CreateInviteStxEndCompletedTimer(OnCompletedEnded); EndConfirmedTimer = _timerFactory.CreateInviteStxEndConfirmed(OnConfirmedEnded); SendTryingTimer = _timerFactory.CreateInviteStxSendTryingTimer(OnSendTryingTimer); }
protected override void OnTestClientUaReceive(SipContext sipContext) { if (sipContext.Response != null && sipContext.Response.StatusLine.ResponseCode == SipResponseCodes.x180_Ringing) { _receivedRingingResponse = sipContext.Response; } if (sipContext.Response != null && sipContext.Response.StatusLine.ResponseCode == SipResponseCodes.x200_Ok) { _waitingforOkReceived.Set(); } if (sipContext.Request != null && sipContext.Request.RequestLine.Method == SipMethods.Bye) { _receivedBye = sipContext.Request; _waitForByeReceived.Set(); } }
public SipRequest CreateRequest(SipUri requestUri, string method, SipCallIdHeader callId, SipCSeqHeader cSeq, SipFromHeader from, SipToHeader to, SipViaHeader viaHeader, SipMaxForwardsHeader maxForwards) { Check.Require(requestUri, "requestUri"); Check.Require(method, "method"); Check.Require(callId, "callId"); Check.Require(cSeq, "cseq"); Check.Require(from, "from"); Check.Require(to , "to"); Check.Require( viaHeader,"viaHeader"); Check.Require(maxForwards, "maxforwards"); var message = new SipRequest(); message.RequestLine.Method = method; message.RequestLine.Uri = requestUri; message.RequestLine.Version = SipConstants.SipTwoZeroString; message.CallId = callId; message.To = to; message.From = from; message.CSeq = cSeq; message.Vias.SetTopMost(viaHeader); message.MaxForwards = maxForwards; return message; }
internal SipInviteClientTransaction( SipClientTransactionTable table, ISipMessageSender messageSender, ISipListener listener, SipRequest request, ITimerFactory timerFactory, SipHeaderFactory headerFactory, SipMessageFactory messageFactory) : base(table, request, messageSender, listener, timerFactory) { Check.Require(headerFactory, "headerFactory"); Check.Require(messageFactory, "messageFactory"); Check.IsTrue(request.RequestLine.Method == SipMethods.Invite, "Method other then 'INVITE' is not allowed"); _logger = NLog.LogManager.GetCurrentClassLogger(); _headerFactory = headerFactory; _messageFactory = messageFactory; ReTransmitTimer = timerFactory.CreateInviteCtxRetransmitTimer(OnReTransmit); TimeOutTimer = timerFactory.CreateInviteCtxTimeOutTimer(OnTimeOut); EndCompletedTimer = timerFactory.CreateInviteCtxEndCompletedTimer(OnCompletedEnded); }
private void ValidateRequest(SipRequest request) { Check.IsTrue(request.Contacts.Count == 1, "An invite request must always have one contact header"); Check.IsTrue(!string.IsNullOrEmpty(request.From.Tag), "An invite request from header must have a tag"); }
public ISipServerTransaction CreateServerTransaction(SipRequest request) { Check.Require(request, "request"); Check.IsTrue(SipMethods.IsMethod(request.RequestLine.Method), "Request method is not supported"); ISipServerTransaction tx; if (request.RequestLine.Method == SipMethods.Ack) { throw new ArgumentException("Can not create a transaction for the 'ACK' request"); } ISipListener txListener = _sipListener; SipAbstractDialog dialog; if (_dialogTable.TryGetValue(GetDialogId(request, true), out dialog)) { txListener = dialog; } if (request.RequestLine.Method == SipMethods.Invite) { var istx = new SipInviteServerTransaction( ServerTransactionTable, this, txListener, request, _stack.GetTimerFactory()); //istx.Start(); tx = istx; } else { var nistx = new SipNonInviteServerTransaction( ServerTransactionTable, request, txListener, this, _stack.GetTimerFactory()); //nistx.Start(); tx = nistx; } return tx; }
protected override void When() { Request = new SipRequestBuilder().Build(); _response = Request.CreateResponse(SipResponseCodes.x200_Ok); }
public void SipBasicCore_Request_SetResponse() { // Verify that we can submit a non-dialog request from // one core to another, respond to it by setting the // Response property of the RequestReceived handler arguments // and then actually receive the response. StartCores(); try { SipResponse core1Response = null; core1.ResponseReceived += delegate(object sender, SipResponseEventArgs args) { core1Response = args.Response; }; SipRequest core2Request = null; core2.RequestReceived += delegate(object sender, SipRequestEventArgs args) { core2Request = args.Request; args.Response = core2Request.CreateResponse(SipStatus.OK, "Hello World!"); args.Response.Contents = new byte[] { 5, 6, 7, 8 }; }; // Submit a request and verify the response. SipRequest request; SipResult result; SipResponse response; request = new SipRequest(SipMethod.Info, (string)core2Uri, null); request.Contents = new byte[] { 1, 2, 3, 4 }; result = core1.Request(request); response = result.Response; Assert.AreEqual(SipStatus.OK, result.Status); Assert.AreEqual(SipStatus.OK, response.Status); Assert.AreEqual("Hello World!", response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, response.Contents); // Verify that the core1 ResponseReceived event handler was called Assert.IsNotNull(core1Response); Assert.AreEqual(SipStatus.OK, core1Response.Status); Assert.AreEqual("Hello World!", core1Response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, core1Response.Contents); // Verify that the core2 RequestReceived event handler was called Assert.IsNotNull(core2Request); Assert.AreEqual(SipMethod.Info, core2Request.Method); CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, core2Request.Contents); } finally { StopCores(); } }
public void SipBasicCore_Request_Blast() { // Verify that we can submit multiple requests to a core. StartCores(); try { SipResponse core1Response = null; core1.ResponseReceived += delegate(object sender, SipResponseEventArgs args) { core1Response = args.Response; }; SipRequest core2Request = null; core2.RequestReceived += delegate(object sender, SipRequestEventArgs args) { core2Request = args.Request; args.Response = core2Request.CreateResponse(SipStatus.OK, "Hello World!"); args.Response.Contents = args.Request.Contents; }; // Submit a bunch of request and verify the responses. for (int i = 0; i < 1000; i++) { SipRequest request; SipResult result; SipResponse response; byte[] data; data = new byte[4]; Helper.Fill32(data, i); request = new SipRequest(SipMethod.Info, (string)core2Uri, null); request.Contents = data; result = core1.Request(request); response = result.Response; Assert.AreEqual(SipStatus.OK, result.Status); Assert.AreEqual(SipStatus.OK, response.Status); Assert.AreEqual("Hello World!", response.ReasonPhrase); CollectionAssert.AreEqual(data, response.Contents); // Verify that the core1 ResponseReceived event handler was called Assert.IsNotNull(core1Response); Assert.AreEqual(SipStatus.OK, core1Response.Status); Assert.AreEqual("Hello World!", core1Response.ReasonPhrase); CollectionAssert.AreEqual(data, core1Response.Contents); // Verify that the core2 RequestReceived event handler was called Assert.IsNotNull(core2Request); Assert.AreEqual(SipMethod.Info, core2Request.Method); CollectionAssert.AreEqual(data, core2Request.Contents); } } finally { StopCores(); } }
public void Go_Send(int currentPort) { try { SipUri from = new SipUri(this.AppServerSipUri); string AlarmEndPointSipUri = "sip:contact@" + this.LocalIpAddress + ":" + currentPort; SipUri to = new SipUri(AlarmEndPointSipUri); SipRequest request = MessageRequest.CreateRequest(SipMethod.Message, to, from); Random random = new Random(); int cSeq = random.Next(0, 10000); request.CSeq.SequenceNumber = cSeq; request.CSeq.Method = SipMethod.Message; //int FreePort = DoroCommon.GetAvailablePort(5060); //Console.WriteLine(FreePort); IPAddress localIP = NetworkInformation.IPv4Address; ViaHeaderField via = new ViaHeaderField(new IPDomainPort(new IPEndPoint(localIP, currentPort)), TransportProtocol.Udp); via.ResponsePort = currentPort; request.ViaHeaders.Clear(); request.ViaHeaders.Add(via); AlarmReq ar = new AlarmReq(); ar.Ref = random.Next(0, 16).ToString(); ar.Aty = "PI"; ar.Tty = "C9300"; ar.Tid = "7942098"; ar.Inf = "Heartbeat"; Console.WriteLine(ar.ToString()); string body = SerializationClass.SerializeObject(ar, false, true, true); byte[] content = Encoding.UTF8.GetBytes(body); Console.WriteLine(content.ToString()); request.Body = content; request.ContentType = new ContentTypeHeaderField(MediaType.Text, "text"); request.ContentLength = content.Length; //Console.WriteLine(request.Body.ToString()); IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(this.ServerIpAddress), this.ServerPort); IPEndPoint localEndpoint = new IPEndPoint(localIP, currentPort); Protocol.DestinationTuple d = new Protocol.DestinationTuple(localEndpoint, remoteEndPoint); Console.WriteLine("Open Port: " + localIP + ":" + currentPort + " => Sent Message to " + this.ServerIpAddress + ":" + this.ServerPort); Set_TextBox("Open Port: " + localIP + ":" + currentPort + " => Sent Message to " + this.ServerIpAddress + ":" + this.ServerPort); //Protocol.DestinationTuple d = new Protocol.DestinationTuple(this.ServerIpAddress.ToString(), this.ServerPort); CipConnection cipConnection = new CipConnection(this); cipConnection.StartListening(currentPort); cipConnection.Send(request, d); Interlocked.Increment(ref CountConnection); Set_Status(); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public void ProcessRequest(SipRequest sipRequest, SipContext context) { lock (_locker) Requests.Add(sipRequest); _onRecievedRequest(sipRequest, context); }
private bool TryGetDialogOnTx(SipRequest request, out SipAbstractDialog dialog) { dialog = null; if (request.To.Tag == null) return false; /* merged request: Based on the To tag, the UAS MAY either accept or reject the request. * If the request has a tag in the To header field, * but the dialog identifier does not match any existing dialogs*/ if(_logger.IsDebugEnabled)_logger.Debug("Searching the table for a matching dialog..."); SipAbstractDialog inTableDialog; if (_dialogTable.TryGetValue(GetDialogId(request, true), out inTableDialog)) { if (_logger.IsDebugEnabled) _logger.Debug("Found a matching dialog. Setting it on tx."); dialog = inTableDialog; return true; } else { if (_logger.IsDebugEnabled) _logger.Debug("Could not find a matching dialog."); /* If the UAS wishes to reject the request because it does not wish to recreate the dialog, it MUST respond to the request with a 481 (Call/Transaction Does Not Exist) status code and pass that to the server transaction. */ return false; } }
private bool ShouldHaveResponse(SipRequest request) { return request.RequestLine.Method != SipMethods.Ack; }
private SipUri GetDestinationUri(SipRequest request) { Check.Require(request, "request"); var topMostRoute = request.Routes.GetTopMost(); SipUri uri = null; if(topMostRoute != null) { if(_logger.IsDebugEnabled)_logger.Debug("Request has a route specified. Sending the request to topmost route !!"); uri = topMostRoute.SipUri; } else { if (_logger.IsDebugEnabled) _logger.Debug("Request has no route specified. Sending the request to request-uri"); uri = request.RequestLine.Uri; } return uri; }
/// <summary> /// Determines the condition under which a request matches a server transaction, according to rfc 3261 (17.2.3) /// </summary> /// <param name="request">the request that will be used to create the transactionid</param> /// <param name="methodoverride">if not null, this value will be used in the creation of the resulting id</param> /// <returns></returns> internal static string GetServerTransactionId(SipRequest request, string methodoverride = null) { string idMethod = request.RequestLine.Method; /*for an incoming ACK request we must take INVITE, bc it needs to match the INVITE server transaction it is going to acknowledge */ if (request.RequestLine.Method.Equals(SipMethods.Ack)) idMethod = SipMethods.Invite; /*the request that created the server transaction + incoming requests get applied this method*/ return request.Vias.GetTopMost().Branch + "-" + request.Vias.GetTopMost().SentBy + "-" + (methodoverride ?? idMethod); }
public void SendRequest(SipRequest request) { Check.Require(request, "request"); if (_logger.IsTraceEnabled) _logger.Trace("Sending request..."); var result = new SipValidator().ValidateRequest(request); if (!result.IsValid) ThrowSipException(result); var via = request.Vias.GetTopMost(); if (string.IsNullOrEmpty(via.Branch)) { via.Branch = SipUtil.CreateBranch(); } var bytes = SipFormatter.FormatMessage(request); SipUri sipUri = GetDestinationUri(request); IPEndPoint ipEndPoint = GetDestinationEndPoint(sipUri); SendBytes(bytes, ipEndPoint); if (_logger.IsDebugEnabled) _logger.Debug("Send request '{0}' --> {1}. # bytes:{2}.", request.RequestLine.Method, ipEndPoint, bytes.Length); if(_requestSentObserver != null) _requestSentObserver.OnNext(request); }
protected override void When() { _originalRequest = new SipRequestBuilder().Build(); var bytes = SipFormatter.FormatMessage(_originalRequest); _sipMessage = _parser.Parse(new DatagramPacketBuilder().WithDataBytes(bytes).Build()) as SipRequest; }
private void OnRequestReceived(SipRequest request, SipContext context) { _requestReceived.Set(); }
/// <summary> /// creates the ids that must be attempted to match a transaction against the table /// </summary> /// <param name="request"></param> /// <returns></returns> private List<string> CreateTxIdAttempts(SipRequest request) { var result = new List<string>(); /*up to now the only request that can be cancelled is 'INVITE'*/ var cancellableMethods = new[] {SipMethods.Invite}; foreach (var method in cancellableMethods) { result.Add(SipProvider.GetServerTransactionId(request, method)); } return result; }
public void SipBasicCore_Request_ReplyAsync() { // Verify that we can submit a non-dialog request from // one core to another, respond to it asynchronously and // then verify that we actually received the response. StartCores(); try { SipResponse core1Response = null; core1.ResponseReceived += delegate(object sender, SipResponseEventArgs args) { core1Response = args.Response; }; SipRequest core2Request = null; core2.RequestReceived += delegate(object sender, SipRequestEventArgs args) { SipResponse reply; core2Request = args.Request; reply = core2Request.CreateResponse(SipStatus.OK, "Hello World!"); reply.Contents = new byte[] { 5, 6, 7, 8 }; args.WillRespondAsynchronously = true; AsyncCallback callback = delegate(IAsyncResult ar) { AsyncTimer.EndTimer(ar); args.Transaction.SendResponse(reply); }; AsyncTimer.BeginTimer(TimeSpan.FromMilliseconds(100), callback, null); }; // Submit a request and verify the response. SipRequest request; SipResult result; SipResponse response; request = new SipRequest(SipMethod.Info, (string)core2Uri, null); request.Contents = new byte[] { 1, 2, 3, 4 }; result = core1.Request(request); response = result.Response; Assert.AreEqual(SipStatus.OK, result.Status); Assert.AreEqual(SipStatus.OK, response.Status); Assert.AreEqual("Hello World!", response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, response.Contents); // Verify that the core1 ResponseReceived event handler was called Assert.IsNotNull(core1Response); Assert.AreEqual(SipStatus.OK, core1Response.Status); Assert.AreEqual("Hello World!", core1Response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, core1Response.Contents); // Verify that the core2 RequestReceived event handler was called Assert.IsNotNull(core2Request); Assert.AreEqual(SipMethod.Info, core2Request.Method); CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, core2Request.Contents); } finally { StopCores(); } }
protected override void Given() { _contextSource = new FakeSipContextSource(); _sipStack = new SipStack(); _provider = new SipProvider(_sipStack, _contextSource); _inviteRequest = CreateInviteRequest(); BeforeCreateInviteTransaction(); _inviteTransaction = _provider.CreateClientTransaction(_inviteRequest).As<SipInviteClientTransaction>(); _dialog = _provider.CreateClientDialog(_inviteTransaction); _inviteTransaction.SendRequest(); GivenOverride(); }
public void SipBasicCore_Outbound_Proxy() { // Verify that we can we can force a request to a destination // other than that specified in the request URI by specifying // the core's OutboundProxyUri. StartCores(); try { SipResponse core1Response = null; core1.ResponseReceived += delegate(object sender, SipResponseEventArgs args) { core1Response = args.Response; }; SipRequest core2Request = null; core2.RequestReceived += delegate(object sender, SipRequestEventArgs args) { SipResponse reply; core2Request = args.Request; reply = core2Request.CreateResponse(SipStatus.OK, "Hello World!"); reply.Contents = new byte[] { 5, 6, 7, 8 }; core2.Reply(args, reply); }; // Submit a request and verify the response. SipRequest request; SipResult result; SipResponse response; core1.OutboundProxyUri = core2Uri; request = new SipRequest(SipMethod.Info, "sip:www.lilltek.com:8080;transport=tcp", null); request.Contents = new byte[] { 1, 2, 3, 4 }; result = core1.Request(request); response = result.Response; Assert.AreEqual(SipStatus.OK, result.Status); Assert.AreEqual(SipStatus.OK, response.Status); Assert.AreEqual("Hello World!", response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, response.Contents); // Verify that the core1 ResponseReceived event handler was called Assert.IsNotNull(core1Response); Assert.AreEqual(SipStatus.OK, core1Response.Status); Assert.AreEqual("Hello World!", core1Response.ReasonPhrase); CollectionAssert.AreEqual(new byte[] { 5, 6, 7, 8 }, core1Response.Contents); // Verify that the core2 RequestReceived event handler was called Assert.IsNotNull(core2Request); Assert.AreEqual(SipMethod.Info, core2Request.Method); CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, core2Request.Contents); } finally { StopCores(); } }
public SipRequestEventBuilder() { _request = new SipRequestBuilder().Build(); }
public void ProcessRequest(SipRequestEvent requestEvent) { Log("Received a request. RequestLine:'{0}'", requestEvent.Request.RequestLine.FormatToString()); if (requestEvent.Request.RequestLine.Method == SipMethods.Invite) { Log("Received an INVITE request."); if (_state == PhoneState.Idle) { _inviteRequest = requestEvent.Request; _ringingRetransmitSubscription = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(5)).ObserveOn(this).Subscribe((i) => { Log("Sending a ringing response..."); SendRinging(); Log("Ringing response send."); if (i == 0) { GoToState(PhoneState.Ringing); RefreshDialogForm(_dialog); } }); } else { Log("Currently busy..."); //send busy here } } if (_state == PhoneState.Idle) { if (requestEvent.Request.RequestLine.Method == SipMethods.Invite) { GoToState(PhoneState.Ringing); _pendingRequestEvent = requestEvent; this.OnUIThread(() => { //show the name of the caller in the from textboxes. _txtFromAlias.Text = requestEvent.Request.From.DisplayInfo; _txtFromAlias.Text = requestEvent.Request.From.DisplayInfo; //clear all other from-to textboxes _txtFromUri.Text = ""; requestEvent.Request.From.SipUri.FormatToString(); _txtToUri.Text = _txtToAlias.Text = ""; }); //block the processing thread _waitHandle.WaitOne(30 * 1000); } } else if (_state == PhoneState.Ringing) { if (requestEvent.Request.RequestLine.Method == SipMethods.Cancel) { //TODO: send 487 + stop ringing GoToState(PhoneState.Idle); } } else if (_state == PhoneState.WaitingForAck) { if (requestEvent.Request.RequestLine.Method == SipMethods.Ack) { Log("Received an ACK request. Going to 'CALLERESTABLISHED' state"); GoToState(PhoneState.CallerEstablished); } } else if (_state == PhoneState.CallerEstablished) { if (requestEvent.Request.RequestLine.Method == SipMethods.Bye) { Debugger.Break(); Log("Received an BYE request."); Log("Sending a OK response..."); /*send ok*/ var okResponse = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok); var serverTransaction = SipProvider.CreateServerTransaction(requestEvent.Request); serverTransaction.SendResponse(okResponse); Log("OK response send."); if (requestEvent.Dialog != null) { requestEvent.Dialog.Terminate(); Log("Terminating dialog."); } GoToState(PhoneState.Idle); } } }
private void SendMessageWaitingNotification(WOSI.CallButler.Data.CallButlerDataset.ExtensionsRow extension) { PBXPresenceInfo[] presenceInfos = GetPresenceInfoForExtension(extension.ExtensionNumber); if (presenceInfos != null) { foreach (PBXPresenceInfo presenceInfo in presenceInfos) { if (presenceInfo.Status == PBXPresenceStatus.Online) { // Create our notify message SipRequest request = new SipRequest(SIPMethodType.NOTIFY); SIPURI requestURI = new SIPURI(presenceInfo.AddressOfRecord); request.BranchID = "z9hG4bK" + Guid.NewGuid().ToString(); request.RequestURI = new SIPURI(presenceInfo.AddressOfRecord); request.HeaderFields["To", "t"].FieldValue = requestURI.ExtendedURIStringWithParameters; request.HeaderFields["From", "f"].FieldValue = requestURI.ExtendedURIStringWithParameters; request.HeaderFields.Add("Event", "message-summary"); request.HeaderFields.Add("Content-Type", "application/simple-message-summary"); StringBuilder sb = new StringBuilder(); int newVoicemailCount = dataProvider.GetNewVoicemailCount(extension.ExtensionID); int totalVoicemailCount = dataProvider.GetVoicemails(extension.ExtensionID).Count; string vmStatus = "no"; if (newVoicemailCount > 0) vmStatus = "yes"; sb.AppendFormat("Messages-Waiting: {0}\r\n", vmStatus); sb.AppendFormat("Voice-Message: {0}/{1}", newVoicemailCount, totalVoicemailCount); request.MessageBody = sb.ToString(); ipClient.SendSipRequest(request, presenceInfo.RemoteAddress, presenceInfo.RemotePort); } } } }
public void Shall_byteify_request() { var request = new SipRequest { Version = "SIP/2.0", Method = "INVITE", RequestUri = SipUri.Parse("sip:[email protected]"), From = NameAddressHeader.Parse("John Smith <sip:[email protected]>"), To = NameAddressHeader.Parse("Joe Shmoe <sip:[email protected]>"), CallId = CallIdHeader.Parse("*****@*****.**"), CSeq = CSeqHeader.Parse("1 INVITE"), ContentType = ContentTypeHeader.Parse("text/plain"), MimeVersion = ContentLengthHeader.Parse("1.0") }; request.Vias.Add(ViaHeader.Parse("SIP/2.0/UDP foo.bar.com")); request.RecordRoutes.Add(NameAddressHeader.Parse("Tommy Atkins <sip:[email protected]>")); request.Routes.Add(NameAddressHeader.Parse("John Doe <sip:[email protected]>")); request.Contacts.Add(NameAddressHeader.Parse("Prisoner X <sip:[email protected]>")); request.Authorizations.Add(AuthorizationHeader.Parse("Digest username=\"Alice\"")); request.WwwAuthenticates.Add(WwwAuthenticateHeader.Parse("Digest realm=\"abc.com\"")); request.ProxyAuthenticates.Add(WwwAuthenticateHeader.Parse("Digest realm=\"xyz.com\"")); request.ProxyAuthorizations.Add(AuthorizationHeader.Parse("Digest username=\"Bob\"")); request.CallInfos.Add(CallInfoHeader.Parse("<http://www.abc.com/photo.png>;purpose=icon")); request.Allows.Add(ContentLengthHeader.Parse("INVITE, ACK, BYE")); request.ContentEncodings.Add(ContentLengthHeader.Parse("deflate")); request.AlertInfos.Add(CallInfoHeader.Parse("<http://www.abc.com/sound.wav>")); request.ErrorInfos.Add(CallInfoHeader.Parse("<sip:[email protected]>")); request.Accepts.Add(ContentTypeHeader.Parse("application/sdp")); request.AcceptEncodings.Add(AcceptEncodingHeader.Parse("gzip")); request.AcceptLanguages.Add(AcceptEncodingHeader.Parse("en")); request.AuthenticationInfos.Add(AuthenticationInfoHeader.Parse("nextnonce=\"abc\"")); request.ProxyAuthenticationInfos.Add(AuthenticationInfoHeader.Parse("nextnonce=\"def\"")); request.OtherHeaders.Add(new GenericHeader("P-Asserted-Identity", "sip:[email protected]")); request.Bodies.Add(SipBody.Parse("Hello world!")); var buffer = new byte[ushort.MaxValue]; var success = request.TryCopyTo(buffer, 0, out int length); Assert.That(success, Is.True); var request2 = SipMessage.Parse(new ArraySegment <byte>(buffer, 0, length)); Assert.That(request2.ToString(), Is.EqualTo( "INVITE sip:[email protected] SIP/2.0\r\n" + "Via: SIP/2.0/UDP foo.bar.com\r\n" + "Record-Route: Tommy Atkins <sip:[email protected]>\r\n" + "Route: John Doe <sip:[email protected]>\r\n" + "From: John Smith <sip:[email protected]>\r\n" + "To: Joe Shmoe <sip:[email protected]>\r\n" + "Call-ID: [email protected]\r\n" + "CSeq: 1 INVITE\r\n" + "Contact: Prisoner X <sip:[email protected]>\r\n" + "Authorization: Digest username=\"Alice\"\r\n" + "WWW-Authenticate: Digest realm=\"abc.com\"\r\n" + "Proxy-Authenticate: Digest realm=\"xyz.com\"\r\n" + "Proxy-Authorization: Digest username=\"Bob\"\r\n" + "Call-Info: <http://www.abc.com/photo.png>;purpose=icon\r\n" + "Content-Type: text/plain\r\n" + "Mime-Version: 1.0\r\n" + "Allow: INVITE\r\n" + "Allow: ACK\r\n" + "Allow: BYE\r\n" + "Content-Encoding: deflate\r\n" + "Alert-Info: <http://www.abc.com/sound.wav>\r\n" + "Error-Info: <sip:[email protected]>\r\n" + "Accept: application/sdp\r\n" + "Accept-Encoding: gzip\r\n" + "Accept-Language: en\r\n" + "Authentication-Info: nextnonce=\"abc\"\r\n" + "Proxy-Authentication-Info: nextnonce=\"def\"\r\n" + "P-asserted-identity: sip:[email protected]\r\n" + "Content-Length: 12\r\n" + "\r\n" + "Hello world!")); }
/// <summary> /// validates the sip schema of the request. /// </summary> /// <param name="request"></param> private void ValidateSipSchema(SipRequest request) { if (request.From.SipUri.HasNamedHost()) throw new SipException(ExceptionMessage.NamedHostsAreNotSupported); if (request.RequestLine.Method == SipMethods.Invite) { /*13.3.1 Processing of the INVITE*/ /*If the request is an INVITE that contains an Expires header == TODO*/ /*according to rfc verify that an invite has 1 contact. Adddtional to rfc, verify that the contact is not a named host.*/ if (request.Contacts.Count != 1) { throw new SipException(SipResponseCodes.x400_Bad_Request, "An 'INVITE' request MUST contain 1 Contact header."); } if (request.Contacts[0].SipUri.HasNamedHost()) { throw new SipException(SipResponseCodes.x400_Bad_Request, "The Sipuri-host specified in the contact header must be a numeric ipaddress."); } //var from = request.Contacts[0].SipUri.GetHostAndPort(); /*fire incoming call*/ //var pc = new PhoneCall(this, _provider, _messageFactory, _headerFactory, _addressFactory, from, PhoneCallDirection.Incoming); //pc.Start(); /**/ //pc.State = CallState.Ringing; //IncomingCall(this, new VoipEventArgs<IPhoneCall>(pc)); //StartRinging(); ///*start the phone to ring + fire ringing*/ //pc.InternalSendRinging(); //pc.FireCallStateChanged(CallState.Ringing); } }
public ISipTransport SelectTransport(ISipAgent agent, SipRequest request, out NetworkBinding remoteEP) { remoteEP = null; // NOP return(null); }
private SipResponse CreateRingingResponse(SipRequest request) { var r = request.CreateResponse(SipResponseCodes.x180_Ringing); r.To.Tag = _toTag; return r; }
public static SipRequest GetSipRequest(string message, byte[] networkData, int readSize) { try { string[] parts = message.Split('\n'); if (parts.Length == 0) { return(null); } SipRequest request = SipRequest.CreateRequest(SipMethod.Message); RequestLine rl = ParseSipRequestLine(parts[0]); request.RequestLine = rl; foreach (string pt in parts) { if (pt.Contains(ViaHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); ViaHeaderField via = new ViaHeaderField(); via.Parse(p); request.ViaHeaders.Add(via); } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName(), "[CipSipParser][GetSipRequest]_ViaHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(ToHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); ToHeaderField thf = ParseToHeaderField(p); request.To = thf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName(), "[CipSipParser][GetSipRequest]_ToHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(FromHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); FromHeaderField fhf = ParseFromHeaderField(p); request.From = fhf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_FromHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(CallIdHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); CallIdHeaderField chf = new CallIdHeaderField(); chf.Parse(p); request.CallId = chf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_CallIdHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(CSeqHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); CSeqHeaderField cshf = new CSeqHeaderField(); cshf.Parse(p); request.CSeq = cshf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_CSeqHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(ContentTypeHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); ContentTypeHeaderField cthf = new ContentTypeHeaderField(); cthf.Parse(p); request.ContentType = cthf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_ContentTypeHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(UserAgentHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); UserAgentHeaderField uahf = new UserAgentHeaderField(); uahf.Parse(p); request.UserAgent = uahf; } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_UserAgentHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } else if (pt.StartsWith(ContentLengthHeaderField.LongName)) { try { string p = pt.Replace('\r', ' ').TrimEnd(); ContentLengthHeaderField clhf = new ContentLengthHeaderField(); clhf.Parse(p); request.ContentLength = clhf; int len = clhf.Length; if (len > 0) { request.Body = new byte[len]; Array.Copy(networkData, (readSize - len), request.Body, 0, len); } } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]_ContentLengthHeaderField: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } } } return(request); } catch (Exception exception) { string error_text = String.Concat(Assembly.GetExecutingAssembly().GetName().Name, Dns.GetHostName() , "[CipSipParser][GetSipRequest]: " + message + " | exception: " + exception.Message + " | innerException: " + (exception.InnerException != null && !string.IsNullOrEmpty(exception.InnerException.Message) ? exception.InnerException.Message : "") , exception.StackTrace); Console.WriteLine(error_text); throw exception; } }
public SipRequestEventBuilder WithRequest(SipRequest request) { _request = request; return(this); }
private SipMessage ProcessFirstLine(string firstLine) { if (firstLine.EndsWith(SipConstants.SipTwoZeroString)) { var message = new SipRequest(); SipRequestLine requestLine = new SipRequestLineParser().Parse(firstLine); message.RequestLine = requestLine; return message; } else if (firstLine.StartsWith(SipConstants.SipTwoZeroString)) { var message = new SipResponse(); var statusLine = new SipStatusLineParser().Parse(firstLine); message.StatusLine = statusLine; return message; } throw new SipParseException(ExceptionMessage.InvalidFirstLineFormat); }
public void ReceiveSipMessage(object sender, ConversationArgs e) { SipMessage packet = e.RawPacket; DebugWriter.WriteRCVPacket(packet); SipRequest req = packet as SipRequest; Conversation conv = this.convMgr.Find(packet); if (conv != null) { conv.RcvPacket(packet); } if (req != null) { string sipMethod = req.Method; int callID = int.Parse(req.CallID.Value); switch (sipMethod) { case SipMethodName.Invite: this.StartChat(req); break; case SipMethodName.Message: //haozes 11/25 手机客户端发来的ContentType为空 if (req.ContentType == null || string.Compare(req.ContentType.Value, "text/plain") == 0 || string.Compare(req.ContentType.Value, "text/html-fragment") == 0) { //短信 if (this.convMgr.Find(req) == null) { Conversation newSMSConv = this.convMgr.Create(req); if (newSMSConv != null) { newSMSConv.MsgRcv += new EventHandler <ConversationArgs>(this.convMgr.RaiseMsgRcv); newSMSConv.RcvPacket(req); } } } break; case SipMethodName.Bye: this.convMgr.Remove(callID); break; case SipMethodName.Benotify: if (string.Equals(req.Event.Value, SipEvent.PresenceV4.ToString(), StringComparison.OrdinalIgnoreCase)) { this.convMgr.RaisePresenceNotify(this, e); } else if (string.Equals(req.Event.Value, SipEvent.Registration.ToString(), StringComparison.OrdinalIgnoreCase)) { //registration if (req.Body.IndexOf("deregistered") > 0) { this.convMgr.RaiseDeregistered(this, null); } } else if (string.Equals(req.Event.Value, SipEvent.SyncUserInfoV4.ToString(), StringComparison.OrdinalIgnoreCase)) { this.convMgr.RaiseSyncUserInfo(this, e); } else if (string.Equals(req.Event.Value, SipEvent.Contact.ToString(), StringComparison.OrdinalIgnoreCase)) { //contact string eventType = this.GetEventType(e.Text); if (string.Equals(eventType, "AddBuddyApplication", StringComparison.OrdinalIgnoreCase)) { convMgr.RaiseAddBuddyApplication(this, new ConversationArgs(IMType.AddBuddyRequest, req)); } } else if (string.Equals(req.Event.Value, SipEvent.Conversation.ToString(), StringComparison.CurrentCultureIgnoreCase)) { string eventType = GetEventType(e.Text); if (string.Equals(eventType, "UserLeft", StringComparison.CurrentCultureIgnoreCase)) { Log.WriteLog(LogFile.Debug, "UserLeft raised!"); this.convMgr.UserLeftConvsersation(callID, GetMember(e.Text)); } } break; default: break; } //switch end } }
private void OnRequestReceived(SipRequest request, SipContext context) { // last thread should signal main test lock (_failedThreads) { Interlocked.Decrement(ref _currentThreadCount); Console.WriteLine(request.CSeq.Sequence + " done, left: " + _currentThreadCount); if (_currentThreadCount == 0) _threadsDoneEvent.Set(); } }
public void SipTcpTransport_MultipleBuffered() { // Render two messages into a single buffer and transmit them // to a TCP transport in a single send. This will result in // the two messages being processed out of the headerBuf which // is what we want to test here. TestTransport transport = new TestTransport(); EnhancedSocket sock = null; SipRequest msg1, msg2; SipRequest recvMsg; byte[] buf; int cb; try { transport.Start(new NetworkBinding("127.0.0.1:5311")); sock = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Connect("127.0.0.1", 5311); msg1 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg1.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg1.AddHeader("Count", "0"); msg1.Contents = GetContents(0); msg2 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg2.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg2.AddHeader("Count", "1"); msg2.Contents = GetContents(0); buf = Helper.Concat(msg1.ToArray(), msg2.ToArray()); cb = sock.Send(buf); Assert.AreEqual(buf.Length, cb); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg1[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("0", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg1.Contents, recvMsg.Contents); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg2[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("1", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg2.Contents, recvMsg.Contents); // Try it again, this time with some data. msg1 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg1.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg1.AddHeader("Count", "0"); msg1.Contents = GetContents(10); msg2 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg2.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg2.AddHeader("Count", "1"); msg2.Contents = GetContents(20); buf = Helper.Concat(msg1.ToArray(), msg2.ToArray()); cb = sock.Send(buf); Assert.AreEqual(buf.Length, cb); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg1[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("0", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg1.Contents, recvMsg.Contents); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg2[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("1", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg2.Contents, recvMsg.Contents); // Try it one more time, this time adding a leading CRLF msg1 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg1.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg1.AddHeader("Count", "0"); msg1.Contents = GetContents(10); msg2 = new SipRequest(SipMethod.Register, "sip:[email protected]", SipHelper.SIP20); msg2.AddHeader(SipHeader.Via, string.Format("SIP/2.0/TCP {0}", transport.LocalEndpoint)); msg2.AddHeader("Count", "1"); msg2.Contents = GetContents(20); buf = Helper.Concat(new byte[] { 0x0D, 0x0A }, msg1.ToArray(), new byte[] { 0x0D, 0x0A }, msg2.ToArray()); cb = sock.Send(buf); Assert.AreEqual(buf.Length, cb); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg1[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("0", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg1.Contents, recvMsg.Contents); recvMsg = (SipRequest)transport.Receive(); Assert.AreEqual(SipMethod.Register, recvMsg.Method); Assert.AreEqual("sip:[email protected]", recvMsg.Uri); Assert.AreEqual(SipHelper.SIP20, recvMsg.SipVersion); Assert.AreEqual(msg2[SipHeader.Via].FullText, recvMsg[SipHeader.Via].FullText); Assert.AreEqual("1", recvMsg["Count"].FullText); CollectionAssert.AreEqual(msg2.Contents, recvMsg.Contents); } finally { if (sock != null) { sock.Close(); } transport.Stop(); } }