protected void ProcessFromTo(SIPMsg message) { this.Frames = this.Frames.Concat(message.Frames).ToList(); //Console.WriteLine("SIPEvent: ProcessFromTo()"); if (this.From == string.Empty) { this.From = message.Headers.From; } else { if (message.Headers.From.Length > this.From.Length && message.Headers.From.Contains(this.From)) { this.From = message.Headers.From; } } //Get or update "To" value if (this.To == string.Empty) { this.To = message.Headers.To; } else { if (message.Headers.To.Length > this.To.Length && message.Headers.To.Contains(this.To)) { this.To = message.Headers.To; } } }
protected void ProcessExportSources(SIPMsg message) { foreach (var exportSource in message.ExportSources) { if (!this.ExportSources.Contains(exportSource)) { this.ExportSources.Add(exportSource); } } }
//public new abstract string ToString(); public virtual void Update(SIPMsg message) { this.SipMessages.Add(message); switch (message.Type) { case SIPMsg.SIPMsgType.Request: switch (message.RequestLine.Method.ToUpper()) { case "INVITE": this.SipMethods.Add(Models.SipMethods.INVITE); break; case "ACK": this.SipMethods.Add(Models.SipMethods.ACK); break; case "BYE": this.SipMethods.Add(Models.SipMethods.BYE); break; case "REFER": this.SipMethods.Add(Models.SipMethods.REFER); break; case "REGISTER": this.SipMethods.Add(Models.SipMethods.REGISTER); break; default: this.SipMethods.Add(Models.SipMethods.Unknown_Request); break; } break; case SIPMsg.SIPMsgType.Status: if (message.StatusLine.StatusInfo.ToLower().Contains("trying")) { this.SipMethods.Add(Models.SipMethods.trying); } else if (message.StatusLine.StatusInfo.ToLower().Contains("ringing")) { this.SipMethods.Add(Models.SipMethods.ringing); } else if (message.StatusLine.StatusInfo.ToLower().Contains("ok")) { this.SipMethods.Add(Models.SipMethods.ok); } else { this.SipMethods.Add(Models.SipMethods.Unknown_Status); } break; } }
public override void Update(SIPMsg message) { base.Update(message); //Process From and To fields this.ProcessFromTo(message); this.ProcessExportSources(message); //Process timestamp if (this.TimeStamp == DateTime.MinValue || this.TimeStamp > message.Timestamp) { this.TimeStamp = message.Timestamp; } }
private bool PossibleAuthentization(SIPMsg message) { switch (message.Type) { case SIPMsg.SIPMsgType.Request: var method = message.RequestLine.Method.ToUpper(); if (SIPEvent.AuthentizationMethods.Contains(method)) { return(true); } break; } return(false); }
public override void Update(SIPMsg message) { base.Update(message); //Process From and To fields this.ProcessFromTo(message); this.ProcessExportSources(message); //Process timestamp if (this.TimeStamp == DateTime.MinValue || this.TimeStamp > message.Timestamp) { this.TimeStamp = message.Timestamp; } //Process state switch (message.Type) { case SIPMsg.SIPMsgType.Request: switch (message.RequestLine.Method) { case "REGISTER": this.State = SipAuthenticationState.ESTABLISHING; break; default: break; } break; case SIPMsg.SIPMsgType.Status: switch (this.State) { case SipAuthenticationState.ESTABLISHING: if (message.StatusLine.StatusCode == "200") { this.State = SipAuthenticationState.SUCCESSFUL; } if (message.StatusLine.StatusCode[0] == '4') { this.State = SipAuthenticationState.REJECTED; this.RejectReason = message.StatusLine.StatusInfo; } break; default: break; } break; } }
private bool PossibleCall(SIPMsg message) { switch (message.Type) { case SIPMsg.SIPMsgType.Request: var method = message.RequestLine.Method.ToUpper(); if (SIPEvent.CallMethods.Contains(method)) { return(true); } break; case SIPMsg.SIPMsgType.Status: var status = message.StatusLine.StatusInfo.ToLower(); if (SIPEvent.CallStatuses.Contains(status)) { return(true); } break; } return(false); }
public override void Update(SIPMsg message) { base.Update(message); //Process From and To fields this.ProcessFromTo(message); this.ProcessExportSources(message); //Process timestamps if(this.TimeStamp == DateTime.MinValue || this.TimeStamp > message.Timestamp) { this.TimeStamp = message.Timestamp; } this.End = message.Timestamp; //Process state switch(message.Type) { case SIPMsg.SIPMsgType.Request: switch(message.RequestLine.Method) { case "INVITE": this.State = SipCallState.ESTABLISHING; break; case "CANCEL": if(this.State == SipCallState.ESTABLISHING || this.State == SipCallState.IN_PROGRESS) { this.State = SipCallState.CANCELLED; } break; case "BYE": if(this.State == SipCallState.IN_PROGRESS) { this.State = SipCallState.COMPLETE; } break; default: break; } break; case SIPMsg.SIPMsgType.Status: switch(this.State) { case SipCallState.ESTABLISHING: if(message.StatusLine.StatusCode == "200") { this.State = SipCallState.IN_PROGRESS; } if(message.StatusLine.StatusCode[0] == '4') { this.State = SipCallState.REJECTED; this.RejectReason = message.StatusLine.StatusInfo; } break; default: break; } break; } if(message.Headers.CallID != string.Empty && this.CallId == string.Empty) { this.CallId = message.Headers.CallID; } //Get or update "RTPAddress" values if(message.Body != null && (message.Body.RTPAddress != string.Empty && message.Body?.RTPPort != string.Empty)) { var found = false; foreach(var address in this.RTPAddresses) { var addressString = message.Body.RTPAddress + ":" + message.Body.RTPPort; //address.ToString(); if(addressString == address.ToString()) { found = true; break; } } if(!found) { try { this.RTPAddresses.Add(new IPEndPointEF(IPAddress.Parse(message.Body.RTPAddress), int.Parse(message.Body.RTPPort))); } catch { //TODO throw some kind of "improper IP:port format" exception } } } if(message.Body != null) foreach(var codec in message.Body.PossibleCodecs) { if(!this.PossibleCodecs.Contains(codec)) { var list = this.PossibleCodecs as List<string>; list.Add(codec); } } }
protected override void ProcessConversation() { { var stream = new PDUStreamBasedProvider(this.CurrentConversation, EfcPDUProviderType.SingleMessage); var reader = new PDUStreamReader(stream, Encoding.Default); do { this.OnBeforeProtocolParsing(); //Parse protocol.... SIPMsg _message; _message = new SIPMsg(reader); if (!_message.Valid) { this.SnooperExport.TimeStampFirst = _message.Timestamp; this.SnooperExport.AddExportReport( ExportReport.ReportLevel.Warn, this.Name, "parsing of SIP message failed, frame numbers: " + string.Join(",", _message.Frames) + ": " + _message.InvalidReason, _message.ExportSources); Console.WriteLine("parsing of SIP message failed, frame numbers: " + string.Join(",", _message.Frames) + ": " + _message.InvalidReason); continue; } this.OnAfterProtocolParsing(); //Console.WriteLine("successful parsing: frame " + string.Join(",", _message.FrameNumbers.ToArray())); //Do some magic... SIPEvent _event; if (this._eventsDictionary.TryGetValue(_message.Headers.CallID, out _event)) { //Event already present switch (_event.Type) { case SIPEventType.Authentization: //Console.WriteLine("authentication "+_message.Headers.CallID+" present"); _event.Update(_message); break; case SIPEventType.Call: //Console.WriteLine("call "+_message.Headers.CallID+" present"); _event.Update(_message); break; case SIPEventType.Unknown: var oldEvent = _event as SIPUnknownEvent; if (this.PossibleCall(_message)) { this._eventsDictionary.Remove(_message.Headers.CallID); this.SnooperExport.DiscardExportObject(_event); _event = new SIPCall(this.SnooperExport); this._eventsDictionary.Add(_message.Headers.CallID, _event); _event.UpdateFromUnkownEvent(oldEvent); } else if (this.PossibleAuthentization(_message)) { this._eventsDictionary.Remove(_message.Headers.CallID); this.SnooperExport.DiscardExportObject(_event); _event = new SIPAuthentization(this.SnooperExport); this._eventsDictionary.Add(_message.Headers.CallID, _event); _event.UpdateFromUnkownEvent(oldEvent); } _event.Update(_message); break; default: Console.WriteLine("unknown event " + _message.Headers.CallID + " present"); //TODO throw some exception break; } } else { //New event, create if (_message.Type == SIPMsg.SIPMsgType.Request && _message.RequestLine.Method == "REGISTER") { _event = new SIPAuthentization(this.SnooperExport); this._eventsDictionary.Add(_message.Headers.CallID, _event); //Console.WriteLine("authentication " + _message.Headers.CallID + " added"); _event.Update(_message); } else if (_message.Type == SIPMsg.SIPMsgType.Request && _message.RequestLine.Method == "INVITE") { _event = new SIPCall(this.SnooperExport); this._eventsDictionary.Add(_message.Headers.CallID, _event); //Console.WriteLine("call " + _message.Headers.CallID + " added"); _event.Update(_message); } else // type can't be easily decided { if (this.PossibleCall(_message)) { _event = new SIPCall(this.SnooperExport); } else if (this.PossibleAuthentization(_message)) { _event = new SIPAuthentization(this.SnooperExport); } else { _event = new SIPUnknownEvent(this.SnooperExport); } this._eventsDictionary.Add(_message.Headers.CallID, _event); _event.Update(_message); } } // this.eventExporter.AddExportedData(); //Export some meaningful message, object, what so ever... // this.eventExporter.AddExportReport(); //Export problem, exception some meaningful note that will be part of exported data object or export report in case that no data were exported between two escalation of BeforeProtocolParsing //Console.WriteLine(_message.ToString()); } while(reader.NewMessage()); //Export this.OnBeforeDataExporting(); var _callCounter = 0; foreach (var kvp in this._eventsDictionary) { if (kvp.Value.Type == SIPEventType.Unknown) { this.SnooperExport.DiscardExportObject(kvp.Value); } else { if (kvp.Value is SIPCall) { // Process RTP flows of every call var s = kvp.Value as SIPCall; //s.CallId = _callCounter.ToString(); // Pass it inside the call //s.SetExportedPayloads(this.ProcessRTP(s.RTPAddresses, _callCounter.ToString())); ++_callCounter; } //Console.WriteLine("event " + kvp.Key); //Console.WriteLine(kvp.Value.ToString()); kvp.Value.ExportValidity = ExportValidity.ValidWhole; //TODO there should be list of guids (frames, other objects) //kvp.Value.ExportSources.Add(this.CurrentConversation); //todo switch to used PDUs this.SnooperExport.AddExportObject(kvp.Value); } } this.OnAfterDataExporting(); //Clean event dictionary this._eventsDictionary.Clear(); } }