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"); } }
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}"); } } } } }