Exemple #1
0
        private void Handle100Trying(SipMessage last, SipMessage current)
        {
            if (current == null)
            {
                // TODO: no message received
                return;
            }

            this.WaitForMessage(current, this.Handle183, 10, 50, 100, 1000, 2000, 5000);
        }
Exemple #2
0
        private void Handle183(SipMessage last, SipMessage current)
        {
            if (current.Method == "180")
            {
                this.WaitForMessage(current, this.Handle183, 100, 500, 1000);
                return;
            }

            if (current.SdpData != null)
            {
                this.SetSdpInformation(current.SdpData);
            }

            this.stateChanged(this, DialogState.PreAck);

            var resp = current as SipResponse;

            if (resp == null)
            {
                Console.WriteLine("sip response is null. expected a 183 response");
                return;
            }

            Console.WriteLine(resp.StatusCode);

            if (resp.StatusCode == 183)
            {
                var ack = new AckMessage(current.CallId, last.From, current.To, 70, null, current.Via);
                ack.Headers["Allow"] = "INVITE,BYE,REGISTER,ACK,OPTIONS,CANCEL,INFO,SUBSCRIBE,NOTIFY,REFER,UPDATE";

                ack.Contact = last.Contact;

                ack.Headers["CSeq"] = this.callSequence + " ACK";
                ack.Headers["From"] = last.Headers["From"];

                ack.Headers["Session-ID"] = current.Headers["Session-ID"];

                ack.Headers["Content-Length"] = "0";

                this.Send(ack);

                this.stateChanged(this, DialogState.Answered);

                SipMessage response;
                if (this.TryGetNextMessage(60000, out response))
                {
                    this.Handle200Ack(ack, response);
                }
            }
        }
Exemple #3
0
        private void HandleInviteResponse(SipMessage request, SipMessage response)
        {
            if (response != null)
            {
                switch (response.Method.ToLowerInvariant())
                {
                case "100":
                    this.WaitForMessage(response, this.Handle183, 100, 500, 1000, 2000, 5000);
                    break;

                default:
                    throw new InvalidOperationException("Cant handle this message: " + response.Method);
                }
            }
        }
Exemple #4
0
        public bool TryReceive(CancellationTokenSource tks, out SipMessage msg)
        {
            msg = null;

            var resp = this.client.ReceiveAsync();
            UdpReceiveResult result;

            if (resp.IsCanceled)
            {
                Console.WriteLine("resp is cancelled");

                // generate 408 timeout
                return(false);
            }

            try
            {
                result = resp.Result;
                resp.Wait(tks.Token);
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("operation cancelled");
                return(false);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(false);
            }

            // TODO: copy custom headers as record route
            var data = result.Buffer;

            msg = SipMessage.Parse(data);
            if (msg != null)
            {
                Console.WriteLine("message received: {0}", msg.Method);
            }

            return(true);
        }
Exemple #5
0
        private void WaitForMessage(SipMessage currentMessage, MessageReceivedEventHandler handler, int timer, params int[] timers)
        {
            Task.Factory.StartNew(
                () =>
            {
                foreach (var i in new[] { timer }.Concat(timers))
                {
                    SipMessage msg;
                    if (this.TryGetNextMessage(i, out msg))
                    {
                        if (msg.CallId == this.CallId)
                        {
                            handler(currentMessage, msg);
                            return;
                        }
                    }
                }

                handler(currentMessage, null);
            });
        }
Exemple #6
0
 private bool TryGetNextMessage(int timeout, out SipMessage msg)
 {
     return(this.TryGetNextMessage(new CancellationTokenSource(timeout).Token, out msg));
 }
Exemple #7
0
        private void Send(SipMessage msg)
        {
            var dgram = msg.Serialize();

            this.connection.Send(dgram, dgram.Length, this.remoteHost);
        }
Exemple #8
0
        public void Send(SipMessage msg)
        {
            var dgram = msg.Serialize();

            this.client.Send(dgram, dgram.Length, this.remoteHost);
        }
Exemple #9
0
        private void Handle200Ack(SipMessage request, SipMessage response)
        {
            if (response.Method == "200")
            {
                this.stateChanged(this, DialogState.Answered);
                var ack = new AckMessage(request.CallId, request.From, request.To, 70, request.Supported, request.Via);
                ack.Headers["CSeq"] = request.Headers["CSeq"].ToString().Split(' ')[0] + " ACK";
                this.Send(ack);
            }

            while (!this.TryGetNextMessage(100, out response))
            {
                Console.WriteLine("waiting for bye");
                if (this.byeRequest.IsCancellationRequested)
                {
                    response = null;
                    break;
                }
            }

            if (response == null)
            {
                Console.WriteLine("but message was null");
                this.stateChanged(this, DialogState.Hanging);

                var bye = new SipMessage(request.To, "BYE")
                {
                    CallId      = request.CallId,
                    From        = request.From,
                    MaxForwards = 70,
                    Contact     = request.Contact,
                    Via         = request.Via
                };
                bye.Headers["Allow"] = "INVITE,BYE,REGISTER,ACK,OPTIONS,CANCEL,INFO,SUBSCRIBE,NOTIFY,REFER,UPDATE";

                bye.Headers["CSeq"] = Interlocked.Increment(ref this.callSequence) + " BYE";

                bye.Headers["Session-ID"] = request.Headers["Session-ID"];

                bye.Headers["Content-Length"] = "0";
                this.Send(bye);
                this.stateChanged(this, DialogState.Hungup);

                // TODO: check this response is a 200 OK
                //this.TryGetNextMessage(this.byeRequest.Token, out response);
                this.byeRequest.Cancel();
            }
            else
            {
                this.stateChanged(this, DialogState.Hanging);

                // this is a bye request
                var msg = new OkResponse(response.To)
                {
                    CallId      = response.CallId,
                    From        = response.From,
                    MaxForwards = 70,
                    Via         = response.Via
                };

                msg.Headers["Allow"] = "INVITE,BYE,REGISTER,ACK,OPTIONS,CANCEL,INFO,SUBSCRIBE,NOTIFY,REFER,UPDATE";

                msg.Contact = request.Contact;

                // TODO: maybe this sequence is not correct
                msg.Headers["CSeq"] = response.Headers["CSeq"];

                msg.Headers["Session-ID"] = response.Headers["Session-ID"];

                msg.Headers["Content-Length"] = "0";

                this.Send(msg);
                this.stateChanged(this, DialogState.Hungup);

                this.byeRequest.Cancel();
            }
        }