/// <summary>
        /// Creates a SIP register request.
        /// </summary>
        /// <param name="aor">The address-of-record.</param>
        /// <returns>Message.</returns>
        public virtual Message CreateRegister(SIPURI aor)
        {
            if (aor != null)
            {
                RemoteParty = new Address(aor.ToString());
            }
            if (LocalParty == null)
            {
                LocalParty = new Address(RemoteParty.ToString());
            }
            Message m = CreateRequest("REGISTER");

            m.InsertHeader(new Header("", "Authorization"));
            return(m);
        }
        private bool UpdatePhoneLine(TextBox tb, Button holdBt, Button resumeBt, Button endBt, PhoneLine phoneLine)
        {
            bool isActive = false;

            if (phoneLine == null)
            {
                tb.Text          = "Idle";
                holdBt.Enabled   = false;
                resumeBt.Enabled = false;
                endBt.Enabled    = false;
            }
            else
            {
                String statusText = "";

                bool  isRinging = false;
                bool  isEnded   = false;
                Int16 remoteParticipantCount = (Int16)phoneLine.RemoteParties.Count;

                if (remoteParticipantCount == 1)
                {
                    RemoteParty remoteParty = phoneLine.RemoteParties[0];

                    if (remoteParty.State == BriaAPI.CallStates.Ringing)
                    {
                        statusText = "Incoming call from: ";
                        isRinging  = true;
                    }
                    else if (remoteParty.State == BriaAPI.CallStates.Connecting)
                    {
                        statusText = "Outbound call to: ";
                    }
                    else if (remoteParty.State == BriaAPI.CallStates.Connected)
                    {
                        if (phoneLine.HoldState == BriaAPI.HoldStates.LocalHold)
                        {
                            statusText = "Call put on Hold: ";
                        }
                        else if (phoneLine.HoldState == BriaAPI.HoldStates.RemoteHold)
                        {
                            statusText = "Call held by remote: ";
                        }
                        else
                        {
                            statusText = "Active call with: ";
                            isActive   = true;
                        }
                    }
                    else if (remoteParty.State == BriaAPI.CallStates.Failed)
                    {
                        statusText = "Call Failed [";
                        isEnded    = true;
                    }
                    else if (remoteParty.State == BriaAPI.CallStates.Ended)
                    {
                        statusText = "Call Ended [";
                        isEnded    = true;
                    }

                    statusText += remoteParty.DisplayName;
                    statusText += " (" + remoteParty.Number + ")";

                    if (isEnded)
                    {
                        statusText += "]";
                    }
                }
                else
                {
                    statusText  = "Conference call with ";
                    statusText += remoteParticipantCount.ToString();
                    statusText += " participants";

                    if (phoneLine.HoldState == BriaAPI.HoldStates.LocalHold)
                    {
                        statusText += " on Hold";
                    }
                    else if (phoneLine.HoldState == BriaAPI.HoldStates.RemoteHold)
                    {
                        statusText = " held by remote";
                    }
                    else
                    {
                        isActive = true;
                    }
                }

                tb.Text = statusText;

                if ((isRinging) || (phoneLine.HoldState == BriaAPI.HoldStates.LocalHold))
                {
                    holdBt.Enabled   = false;
                    resumeBt.Enabled = true;
                }
                else
                {
                    holdBt.Enabled   = true;
                    resumeBt.Enabled = false;
                }

                endBt.Enabled = true;
            }

            return(isActive);
        }
        private void MainThread_OnCallStatus(BriaAPI.CallStatusEventArgs args)
        {
            Boolean[] lineInUse = new Boolean[6];

            List <BriaAPI.Call> callList = args.CallList;

            foreach (BriaAPI.Call call in callList)
            {
                Boolean   existingCall = false;
                PhoneLine phoneLine    = null;

                // Check if the call was previously in the list
                for (int i = 0; i < 6; i++)
                {
                    phoneLine = phoneLines[i];

                    if ((phoneLine != null) && (phoneLine.Id == call.CallId))
                    {
                        phoneLine.RemoteParties.Clear();

                        lineInUse[i] = true;
                        existingCall = true;
                        break;
                    }
                }

                // If the call is not already existing, we have to add as new call
                if (!existingCall)
                {
                    PhoneLine newPhoneLine = new PhoneLine(call.CallId);
                    phoneLine = newPhoneLine;

                    // Find empty slot to put it in
                    for (int i = 0; i < 6; i++)
                    {
                        if (phoneLines[i] == null)
                        {
                            phoneLines[i] = phoneLine;
                            lineInUse[i]  = true;
                            break;
                        }
                    }
                }

                // And fill in the information
                phoneLine.HoldState = call.HoldState;

                foreach (BriaAPI.CallParticipant participant in call.ParticipantList)
                {
                    RemoteParty remoteParty = new RemoteParty();
                    remoteParty.Number        = participant.Number;
                    remoteParty.DisplayName   = participant.DisplayName;
                    remoteParty.TimeInitiated = participant.TimeInitiated;
                    remoteParty.State         = participant.CallState;

                    phoneLine.RemoteParties.Add(remoteParty);

                    if ((phoneLine.RemoteParties.Count == 1) && (remoteParty.State == BriaAPI.CallStates.Ringing))
                    {
                        phoneLine.IsRinging = true;
                    }
                    else
                    {
                        phoneLine.IsRinging = false;
                    }
                }
            }

            // Finally clear out any phoneLine that is no longer active
            for (int i = 0; i < 6; i++)
            {
                if (lineInUse[i] == false)
                {
                    phoneLines[i] = null;
                }
            }

            UpdateCallStates();
        }
        /// <summary>
        /// Creates a SIP request.
        /// </summary>
        /// <param name="method">The SIP method (invite etc.)</param>
        /// <param name="content">The SIP body contents.</param>
        /// <param name="contentType">The type of the SIP body.</param>
        /// <returns>Message.</returns>
        public virtual Message CreateRequest(string method, string content = "", string contentType = "")
        {
            Server = false;
            if (RemoteParty == null)
            {
                Debug.Assert(false, String.Format("No remoteParty for UAC\n"));
            }
            if (LocalParty == null)
            {
                LocalParty = new Address("\"Anonymous\" <sip:[email protected]>");
            }
            //TODO: Use Remote Party instead of Remote Target?
            SIPURI uri;

            if (RemoteTarget != null)
            {
                uri = new SIPURI(RemoteTarget.ToString());
            }
            else
            {
                uri = new SIPURI(RemoteParty.ToString());
            }

            if (method == "REGISTER")
            {
                //TODO: Is this right ?
                //uri.User = "";
            }
            if ((method != "ACK") && (method != "CANCEL"))
            {
                LocalSeq = ++LocalSeq;
            }
            //TODO: Use Remote Party instead of Remote Target?
            Header to;

            if (RemoteTarget != null)
            {
                to = new Header(RemoteTarget.ToString(), "To");
            }
            else
            {
                to = new Header(RemoteParty.ToString(), "To");
            }

            Header from = new Header(LocalParty.ToString(), "From");

            from.Attributes["tag"] = LocalTag;
            Header cSeq        = new Header(LocalSeq + " " + method, "CSeq");
            Header callId      = new Header(CallID, "Call-ID");
            Header maxForwards = new Header(MaxForwards.ToString(), "Max-Forwards");
            Header via         = Stack.CreateVia();
            Dictionary <string, object> branchParams = new Dictionary <string, object>
            {
                { "To", to.Value },
                { "From", @from.Value },
                { "CallId", callId.Value },
                { "CSeq", cSeq.Number }
            };

            via.Attributes["branch"] = Transaction.CreateBranch(branchParams, false);
            if (LocalTarget == null)
            {
                LocalTarget      = Stack.Uri.Dup();
                LocalTarget.User = LocalParty.Uri.User;
            }
            Header contact = new Header(LocalTarget.ToString(), "Contact");

            Header[]      headerList = { to, from, cSeq, callId, maxForwards, via, contact };
            List <Header> headers    = headerList.ToList();

            // Check this TODO
            //
            if (RouteSet.Count != 0)
            {
                headers.AddRange(RouteSet);
            }

            //app adds other headers such as Supported, Require and Proxy-Require
            if (!string.IsNullOrEmpty(contentType))
            {
                headers.Add(new Header(contentType, "Content-Type"));
            }
            Dictionary <string, List <Header> > headerDict = new Dictionary <string, List <Header> >();

            foreach (Header h in headers)
            {
                if (headerDict.ContainsKey(h.Name))
                {
                    headerDict[h.Name].Add(h);
                }
                else
                {
                    List <Header> temp = new List <Header> {
                        h
                    };
                    headerDict.Add(h.Name, temp);
                }
            }
            Request = Message.CreateRequest(method, uri, headerDict, content);
            return(Request);
        }