public void Run(params string[] args)
        {
            var ps = PhoneSystem.Root;

            //var calls = PhoneSystem.Root.GetActiveConnectionsByCallID();
            switch (args[1])
            {
            case "dnregs":
            {
                foreach (var dn in PhoneSystem.Root.GetDN().GetDisposer(x => x.Number.StartsWith(args[2] == "all"?"": args[2])))
                {
                    foreach (var r in dn.GetRegistrarContactsEx())
                    {
                        Console.WriteLine($"{r.ID}-{r.Contact}-{r.UserAgent}-{string.Join("", args.Skip(3).Select(x => $"\n\t{x}={r[x]}"))}");
                    }
                }
            }
            break;

            case "ondn":
            {
                using (var dn = PhoneSystem.Root.GetDNByNumber(args[2]))
                {
                    using (var connections = dn.GetActiveConnections().GetDisposer())
                    {
                        var alltakenconnections = connections.ToDictionary(x => x, y => y.OtherCallParties);
                        PrintDNCall(alltakenconnections);
                        foreach (var a in alltakenconnections.Values)
                        {
                            a.GetDisposer().Dispose();
                        }
                    }
                }
            }
            break;

            case "all":
            {
                PrintAllCalls();
            }
            break;

            case "drop":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Drop();
                break;

            case "answer":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Answer();
                break;

            case "pickup":
                PhoneSystem.Root.PickupCall(args[3], PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])));
                break;

            case "divertvm":
            {
                var ac = PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2]));
                ac.Divert(ac.DN.Number, true);
            }
            break;

            case "divert":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Divert(args[3], false);
                break;

            case "bargein":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Bargein(PhoneSystem.Root.GetByID <RegistrarRecord>(int.Parse(args[3])), TCX.PBXAPI.PBXConnection.BargeInMode.BargeIn);
                break;

            case "listen":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Bargein(PhoneSystem.Root.GetByID <RegistrarRecord>(int.Parse(args[3])), TCX.PBXAPI.PBXConnection.BargeInMode.Listen);
                break;

            case "whisper":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).Bargein(PhoneSystem.Root.GetByID <RegistrarRecord>(int.Parse(args[3])), TCX.PBXAPI.PBXConnection.BargeInMode.Whisper);
                break;

            case "record":
            {
                if (Enum.TryParse(args[3], out RecordingAction ra))
                {
                    PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).ChangeRecordingState(ra);
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Invalid record action");
                }
            }
            break;

            case "transfer":
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).ReplaceWith(args[3]);
                break;

            case "join":
            {
                PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).ReplaceWithPartyOf(
                    PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[3])));
            }
            break;

            case "makecall":
            {
                using (var ev = new AutoResetEvent(false))
                    using (var listener = new PsTypeEventListener <ActiveConnection>())
                        using (var registrarRecord = PhoneSystem.Root.GetByID <RegistrarRecord>(int.Parse(args[2])))
                        {
                            listener.SetTypeHandler(null, (x) => ev.Set(), null, (x) => x["devcontact"].Equals(registrarRecord.Contact), (x) => ev.WaitOne(x));
                            PhoneSystem.Root.MakeCall(registrarRecord, args[3]);
                            try
                            {
                                if (listener.Wait(5000))
                                {
                                    Console.ForegroundColor = ConsoleColor.Green;
                                    Console.WriteLine("Call initiated");
                                }
                                else
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("Call is not initiated in 5 seconds");
                                }
                            }
                            finally
                            {
                                Console.ResetColor();
                            }
                        }
            }
            break;

            case "attacheddata":
            {
                var ac = PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2]));
                Console.WriteLine("AttachedData:");
                Console.WriteLine(string.Join("\n    ", PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).AttachedData.Select(x => x.Key + "=" + x.Value).ToArray()));
                var data = args.Skip(3).Select(x => x.Split('=')).Where(x => x[0].StartsWith("public_")).ToDictionary(x => x[0], x => string.Join("=", x.Skip(1)));
                if (data.Any())
                {
                    Console.WriteLine("----------");
                    Console.WriteLine("Attaching:");
                    Console.WriteLine(string.Join("\n    ", data.Select(x => x.Key + "=" + x.Value).ToArray()));
                    using (var ev = new AutoResetEvent(false))
                        using (var listener = new PsTypeEventListener <ActiveConnection>())
                        {
                            Console.Write("Wait for update...");
                            listener.SetTypeHandler((x) => { ac = x; ev.Set(); }, null, null, (x) => x.Equals(ac), (x) => ev.WaitOne(x));
                            ac.AttachConnectionData(data);
                            try
                            {
                                if (listener.Wait(5000))
                                {
                                    Console.ForegroundColor = ConsoleColor.Green;
                                    Console.WriteLine("Updated:");
                                    Console.WriteLine(string.Join("\n    ", PhoneSystem.Root.GetByID <ActiveConnection>(int.Parse(args[2])).AttachedData.Select(x => x.Key + "=" + x.Value).ToArray()));
                                }
                                else
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.WriteLine("No update notifications received.");
                                }
                            }
                            finally
                            {
                                Console.ResetColor();
                            }
                        }
                }
            }
            break;

            case "callservice":
            {
                PhoneSystem.Root.ServiceCall(args[2], args.Skip(3).Select(x => x.Split('=')).ToDictionary(x => x[0], x => string.Join("=", x.Skip(1))));
            }
            break;

            default:
                throw new NotImplementedException("action is not implemented");
            }
        }
Пример #2
0
        public void Run(params string[] args)
        {
            PhoneSystem ps = PhoneSystem.Root;

            switch (args[1])
            {
            case "create":
            case "update":
            {
                bool isNew     = args[1] == "create";
                var  ivr       = isNew ? ps.GetTenant().CreateIVR(args[2]) : (ps.GetDNByNumber(args[2]) as IVR);
                var  param_set = args.Skip(3).Select(x => x.Split('=')).ToDictionary(x => x.First(), x => string.Join("=", x.Skip(1).ToArray()));

                bool assignForward = isNew;         //flag which trigger assignmnet of IVRForward collection
                IEnumerable <IVRForward> ivrForwards = ivr.Forwards;
                foreach (var paramdata in param_set)
                {
                    var paramname  = paramdata.Key;
                    var paramvalue = paramdata.Value;
                    switch (paramname)
                    {
                    case "PROMPT":
                        if (paramvalue.StartsWith("EXT"))
                        {
                            //record the prompt from the requested extension
                            ivr.PromptFilename = "OMSamplesTestRecodrdedPromptForIVR" + ivr.Number + ".wav";
                            var filename = Path.Combine(ps.GetParameterValue("IVRPROMPTPATH"), ivr.PromptFilename);
                            ivr.PromptFilename = filename;
                            if (File.Exists(filename))
                            {
                                File.Move(filename, filename + ".back");
                            }
                            using (var ext = PhoneSystem.Root.GetDNByNumber(paramvalue.Substring(3)) as Extension)
                                using (var ev = new AutoResetEvent(false))
                                    using (var listener = new PsTypeEventListener <ActiveConnection>())
                                    {
                                        ActiveConnection activeConnection = null;
                                        listener.SetTypeHandler(
                                            (x) => activeConnection = x,
                                            (x) => activeConnection = x,
                                            (x) => ev.Set(),
                                            (x) => x == activeConnection || (activeConnection == null && x.DN == ext && x.Status == ConnectionStatus.Connected && x.ExternalParty == "RecordFile"),
                                            (x) => ev.WaitOne(x));
                                        PhoneSystem.Root.ServiceCall("RecordFile",
                                                                     new Dictionary <string, string>()
                                            {
                                                { "filename", filename },
                                                { "extension", ext.Number }
                                            });
                                        listener.Wait(60000);    //wait a minute until recording call is finished.
                                    }
                            File.Delete(filename + ".back");
                            if (!File.Exists(filename))
                            {
                                throw new FileNotFoundException($"{filename} is not recorded");
                            }
                        }
                        else
                        {
                            ivr.PromptFilename = paramvalue;
                        }
                        break;

                    case "TO":
                        ivr.Timeout = ushort.Parse(paramvalue);
                        break;

                    case "NAME":
                        ivr.Name = paramvalue;
                        break;

                    default:             //options and TODEST
                    {
                        if (paramname.StartsWith("prop."))
                        {
                            ivr.SetProperty(paramname.Substring(5), paramvalue);
                            break;
                        }
                        var            data   = paramvalue.Split('.');
                        var            number = data[1];      //must be with . at the end
                        IVRForwardType fwdtype;
                        var            todelete = !Enum.TryParse(data[0], out fwdtype);
                        if ("TODEST" == paramname || (paramname.Length == 2 && paramname[0] == 'O' && paramname.Length == 2 && char.IsDigit(paramname, 1)))
                        {
                            var dn = ps.GetDNByNumber(number);
                            if ("TODEST" == paramname)
                            {
                                ivr.TimeoutForwardDN   = todelete ? null : dn;
                                ivr.TimeoutForwardType = todelete ? IVRForwardType.EndCall : fwdtype;
                            }
                            else
                            {
                                var option = (byte)(paramname[1] - '0');
                                var fwd    = ivrForwards.FirstOrDefault(x => x.Number == option);
                                if (fwd == null)
                                {
                                    if (todelete)
                                    {
                                        break;
                                    }
                                    fwd         = ivr.CreateIVRForward();
                                    ivrForwards = ivrForwards.Union(new IVRForward[] { fwd });
                                }
                                if (!todelete)
                                {
                                    fwd.Number      = option;
                                    fwd.ForwardDN   = dn;
                                    fwd.ForwardType = fwdtype;
                                }
                                else
                                {
                                    ivrForwards = ivrForwards.Where(x => x != fwd);
                                }
                                assignForward = true;
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException($"Unknown patameter{paramname}={paramvalue}");
                        }
                    }
                    break;
                    }
                }
                if (assignForward)
                {
                    ivr.Forwards = ivrForwards.ToArray();
                }
                ivr.Save();
            }
            break;

            case "delete":
            {
                (ps.GetDNByNumber(args[2]) as IVR).Delete();
                Console.WriteLine($"Deleted IVR {args[2]}");
                return;
            }

            case "show":
                //simply display results
                break;

            default:
                throw new ArgumentException("Invalid action name");
            }
            //show result
            {
                using (var ivrs = (args.Length > 2 ? new IVR[] { ps.GetDNByNumber(args[2]) as IVR } : ps.GetAll <IVR>().ToArray()).GetDisposer())
                {
                    var first = ivrs.First(); //exeption is there are no such extension
                    foreach (var ivr in ivrs)
                    {
                        Console.WriteLine($"IVR - {ivr.Number}:");
                        Console.WriteLine($"    NAME={ivr.Name}");
                        Console.WriteLine($"    PROMPT={ivr.PromptFilename}");
                        Console.WriteLine($"    TO={ivr.Timeout}");
                        Console.WriteLine($"    TODEST={ivr.TimeoutForwardType}.{ivr.TimeoutForwardDN?.Number}");
                        foreach (var f in ivr.Forwards.OrderBy(x => x.Number))
                        {
                            Console.WriteLine($"        O{f.Number}={f.ForwardType}.{f.ForwardDN?.Number}");
                        }
                        Console.WriteLine("    DNProperties:");
                        foreach (var p in ivr.GetProperties())
                        {
                            var name  = p.Name;
                            var value = p.Value.Length > 50 ? new string(p.Value.Take(50).ToArray()) + "..." : p.Value;
                            Console.WriteLine($"        prop.{name}={value}");
                        }
                    }
                }
            }
        }