public SipParserContext(SipMessageFactory messageFactory, SipHeaderFactory headerFactory) { _logger.Trace("Constructor called."); _messageFactory = messageFactory; _headerFactory = headerFactory; _sipParser = new SipParser(this); }
public SipParserTest() { _parser = new SipParser(); _parser.HeaderParsed += OnHeader; _parser.BodyBytesReceived += OnBody; _parser.MessageComplete += OnComplete; }
public void UnderstandCompactHeadersTest() { var mock = new Mock <ISipParserHandler>(); SipParser parser = new SipParser(mock.Object); byte[] messageBytes = Encoding.ASCII.GetBytes(ExampleSipRequests.SimpleInvite); parser.ParseRequest(messageBytes); Assert.Equal(@"""Test 15"" <sip:[email protected]>tag=as58f4201b", parser.Headers["f"].First()); //NOTE: "f" is "from" Assert.Equal(@"<sip:[email protected]>", parser.Headers["t"].First()); //NOTE: "t" is "from" Assert.Equal(@"SIP/2.0/UDP 10.10.1.99:5060;branch=z9hG4bK343bf628;rport", parser.Headers["v"].First()); //NOTE: "v" is "Via" Assert.Equal(@"<sip:[email protected]>", parser.Headers["m"].First()); //NOTE: "m" is "Contact" Assert.Equal(@"[email protected]", parser.Headers["i"].First()); //NOTE: "i" is "call-id" Assert.Equal(@"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY", parser.Headers["u"].First()); //NOTE: "u" is "Allow-Events" Assert.Equal(@"replaces", parser.Headers["k"].First()); //NOTE: "k" is "supported" Assert.Equal(@"application/sdp", parser.Headers["c"].First()); //NOTE: "c" is "Content-Type" Assert.Equal(@"258", parser.Headers["l"].First()); //NOTE: "l" is "Content-Length" Assert.Single(parser.ViaHeaders); //Assert.Equal(@"xxxxxxxx", parser.Headers["o"].First()); //NOTE: "o" is "Event" //Assert.Equal(@"xxxxxxxx", parser.Headers["e"].First()); //NOTE: "e" is "Content-Encoding" //CSeq: 102 INVITE //User-Agent: Asterisk PBX //Max-Forwards: 70 //Date: Wed, 06 Dec 2009 14:12:45 GMT }
public void ParseRequest_ValidFirstLine_ResultIsTrue(string firstLine) { var message = $"{firstLine}{EndOfHeaders}"; var messageBytes = Encoding.UTF8.GetBytes(message); var result = SipParser.TryParseRequest(messageBytes, out var request); Assert.True(result); }
public void ParseResponse_InvalidFirstLine_ResultIsFalse(string firstLine) { var message = $"{firstLine}{EndOfHeaders}"; var messageBytes = Encoding.UTF8.GetBytes(message); var result = SipParser.TryParseResponse(messageBytes, out var response); Assert.False(result); }
public void MissingHeaderThrowsSomethingTest() { var mock = new Mock <ISipParserHandler>(); SipParser parser = new SipParser(mock.Object); byte[] messageBytes = Encoding.ASCII.GetBytes(ExampleSipRequests.SimpleInvite); parser.ParseRequest(messageBytes); Assert.Throws <KeyNotFoundException>(() => parser.Headers["Header Which Is Not There"]); //TODO: maybe some other kind of exception? or a NULL return value? }
public void TortuousInviteRawSipHeaderTextTest() { string expectedBody = @"v=0 o=mhandley 29739 7272939 IN IP4 192.0.2.3 s=- c=IN IP4 192.0.2.4 t=0 0 m=audio 49217 RTP/AVP 0 12 m=video 3227 RTP/AVP 31 a=rtpmap:31 LPC "; var mock = new Mock <ISipParserHandler>(); SipParser parser = new SipParser(mock.Object); byte[] messageBytes = Encoding.ASCII.GetBytes(Rfc4475TestMessages.AShortTortuousINVITE); parser.ParseRequest(messageBytes); //NOTE: these asserts look ugly because we are testing the RAW text from the message Assert.Equal("INVITE sip:[email protected];unknownparam SIP/2.0", parser.RequestLine); //TODO: drill in for just the parts: verb, sip address (without that "unknownparam" bit), etc. Assert.Equal(13, parser.Headers.Count); Assert.Equal("sip:[email protected] ; tag = 1918181833n", parser.Headers["to"].First()); //TODO: drill in to strip that "tag" bit Assert.Equal(@"""J Rosenberg \\\"""" <sip:[email protected]> ; tag = 98asjd8", parser.Headers["from"].First()); //TODO: drill in to separate the torture cruft Assert.Equal("0068", parser.Headers["max-forwards"].First()); Assert.Equal("[email protected]", parser.Headers["call-id"].First()); Assert.Equal("150", parser.Headers["Content-Length"].First()); Assert.Equal(@"0009 INVITE", parser.Headers["cseq"].First()); //TODO - its ugly, probably not right Assert.Equal(@"SIP / 2.0 /UDP 192.0.2.2;branch=390skdjuw", parser.Headers["via"].First()); //TODO - its ugly, probably not right Assert.Equal("", parser.Headers["s"].First()); Assert.Equal(@"newfangled value continued newfangled value", parser.Headers["NewFangledHeader"].First()); Assert.Equal(";;,,;;,;", parser.Headers["UnknownHeaderWithUnusualValue"].First()); Assert.Equal("application/sdp", parser.Headers["Content-Type"].First()); Assert.Equal("<sip:services.example.com;lr;unknownwith=value;unknown-no-value>", parser.Headers["Route"].First()); Assert.Equal(@"SIP / 2.0 / TCP spindle.example.com ; branch = z9hG4bK9ikj8 , SIP / 2.0 / UDP 192.168.255.111 ; branch= z9hG4bK30239", parser.Headers["v"].Last()); //NOTE: there were 2 "Via" in the torture header, one was a "v", ahem... Assert.Equal(@"""Quoted string \""\"""" <sip:[email protected]> ; newparam = newvalue ; secondparam ; q = 0.33", parser.Headers["m"].First()); Assert.Equal(2, parser.ViaHeaders.Count()); Assert.Equal(expectedBody, parser.Body); //TODO: drill in }
public void ParseHeaders_HeaderIsInvalid(string header) { var message = $@"REGISTER sip:ss2.wcom.com SIP/2.0 {header} {EndOfHeaders}"; var messageBytes = Encoding.UTF8.GetBytes(message); SipParser.TryParseRequest(messageBytes, out var request); var headerEnumerator = request.Headers.GetEnumerator(); Assert.False(headerEnumerator.MoveNext()); }
protected async override Task ProcessAsync(Datagram value) { await NextAsync(value); if (SipParser.TryParseResponse(value.Buffer, out var response)) { await responseBuffer.SendAsync(response); } else if (SipParser.TryParseRequest(value.Buffer, out var request)) { await requestBuffer.SendAsync(request); } }
public void ParseHeaders_HeaderIsValid(string header, string name, string value) { var message = $@"REGISTER sip:ss2.wcom.com SIP/2.0 {header} {EndOfHeaders}"; var messageBytes = Encoding.UTF8.GetBytes(message); SipParser.TryParseRequest(messageBytes, out var request); var headerEnumerator = request.Headers.GetEnumerator(); Assert.True(headerEnumerator.MoveNext()); Assert.Equal(name, headerEnumerator.Current.Name); Assert.Equal(value, headerEnumerator.Current.Value); }
public void ParseFullResponse() { var message = @"SIP/2.0 200 IT'S OK, BRO! Via:SIP/2.0/UDP there.com:5060;branch=wsodil7987kjh From: LittleGuy <sip:[email protected]> To: sip:[email protected];branch=sduf9897s; Call-ID: [email protected] CSeq : 1 REGISTER Contact: <sip:[email protected];user=phone>;expires=3600 Contact: <mailto:[email protected]>;expires=4294967295 Content-Length: 8 asdf"; var messageBytes = Encoding.UTF8.GetBytes(message); var result = SipParser.TryParseResponse(messageBytes, out var response); var headers = new List <SipHeader>(); foreach (var header in response.Headers) { headers.Add(header); } var body = Encoding.UTF8.GetString(response.Body.ToArray()); Assert.True(result); Assert.Equal("SIP/2.0", response.Version); Assert.Equal("200", response.StatusCode); Assert.Equal("IT'S OK, BRO! ", response.ReasonPhrase); Assert.Equal(8, headers.Count); Assert.Equal("Via", headers[0].Name); Assert.Equal("SIP/2.0/UDP there.com:5060;branch=wsodil7987kjh", headers[0].Value); Assert.Equal("From", headers[1].Name); Assert.Equal("LittleGuy <sip:[email protected]>", headers[1].Value); Assert.Equal("To", headers[2].Name); Assert.Equal("sip:[email protected];branch=sduf9897s;", headers[2].Value); Assert.Equal("Call-ID", headers[3].Name); Assert.Equal("*****@*****.**", headers[3].Value); Assert.Equal("CSeq", headers[4].Name); Assert.Equal("1 REGISTER", headers[4].Value); Assert.Equal("Contact", headers[5].Name); Assert.Equal("<sip:[email protected];user=phone>;expires=3600", headers[5].Value); Assert.Equal("Contact", headers[6].Name); Assert.Equal("<mailto:[email protected]>;expires=4294967295", headers[6].Value); Assert.Equal("Content-Length", headers[7].Name); Assert.Equal("8", headers[7].Value); Assert.Equal("asdf", body); }
public void ParseFullRequest() { var message = @"REGISTER sip:ss2.wcom.com SIP/2.0 Via: SIP/2.0/UDP there.com:5060;branch=wsodil7987kjh From: LittleGuy <sip:[email protected]> To: sip:[email protected];branch=sduf9897s; Call-ID : [email protected] CSeq:1 REGISTER Content-Length: 8 asdf"; var messageBytes = Encoding.UTF8.GetBytes(message); var result = SipParser.TryParseRequest(messageBytes, out var request); var headers = new List <SipHeader>(); foreach (var header in request.Headers) { headers.Add(header); } var body = Encoding.UTF8.GetString(request.Body.ToArray()); Assert.True(result); Assert.Equal("REGISTER", request.Method); Assert.Equal("sip:ss2.wcom.com", request.Uri); Assert.Equal("SIP/2.0", request.Version); Assert.Equal(6, headers.Count); Assert.Equal("Via", headers[0].Name); Assert.Equal("SIP/2.0/UDP there.com:5060;branch=wsodil7987kjh", headers[0].Value); Assert.Equal("From", headers[1].Name); Assert.Equal("LittleGuy <sip:[email protected]>", headers[1].Value); Assert.Equal("To", headers[2].Name); Assert.Equal("sip:[email protected];branch=sduf9897s;", headers[2].Value); Assert.Equal("Call-ID", headers[3].Name); Assert.Equal("*****@*****.**", headers[3].Value); Assert.Equal("CSeq", headers[4].Name); Assert.Equal("1 REGISTER", headers[4].Value); Assert.Equal("Content-Length", headers[5].Name); Assert.Equal("8", headers[5].Value); Assert.Equal("asdf", body); }
private void OnSipArrived(object sender, SipParser parser) { SipConnectionState state; string localNumber; // this is the number to use in the 'client' side try { if ((phoneNumber != null) && (phoneNumber != string.Empty) && (sipState != null)) { // since the 5555 was added, need to skip over it; it may not always be present. // TODO: need to make this a configurable number from the application in some manner. // (both in length and content) if (phoneNumber.Substring(0, 4).Equals("5555")) { localNumber = phoneNumber.Substring(4); } else { localNumber = phoneNumber; } if (parser.ToField.Contains(localNumber)) { state = sipState.Process(parser); if (state == SipConnectionState.RTP_DETECTED) { RTPPort = sipState.RTPPort; } } } } catch (Exception ex) { ex.Data.Add("My Key", "VMukti--:--VmuktiModules--:--VmuktiModules--:--Call Center--:--AutoProgressiveSoftPhone--:--AutoProgressivePhone.Business--:--RTCAudioWithToneDetect.cs--:--OnSIPArrived()--"); ClsException.WriteToErrorLogFile(ex); } }