1: using Ia.Cl.Model;
2: using System;
3: using System.CodeDom;
4: using System.Collections.Generic;
5: using System.Configuration;
6: using System.IO;
7: using System.Linq;
8: using System.Text.RegularExpressions;
9: using System.Web.UI.WebControls;
10:
11: namespace Ia.Ngn.Cl.Model.Business.Ericsson
12: {
13: ////////////////////////////////////////////////////////////////////////////
14:
15: /// <summary publish="true">
16: /// Ericsson AXE support class of Optical Fiber Network (OFN) business model.
17: /// </summary>
18: ///
19: /// <remarks>
20: /// Copyright © 2018-2020 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
21: ///
22: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
23: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
24: ///
25: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
26: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27: ///
28: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
29: ///
30: /// Copyright notice: This notice may not be removed or altered from any source distribution.
31: /// </remarks>
32: public class Axe
33: {
34: private static List<string> properlySelectedAxeServiceList = new List<string>();
35: private static Queue<ProvisioningWorkflow> synchronizationProvisioningWorkflowQueue = new Queue<ProvisioningWorkflow>();
36: private static Queue<ProvisioningWorkflow> serviceSuspentionSynchronizationProvisioningWorkflowQueue = new Queue<ProvisioningWorkflow>();
37:
38: /// <summary/>
39: public enum Opcode { Suscp, Sulie, SusccXxx, SusccTboTbi, SusccIcs, ConfirmCommandSemicolon, KeepAliveCommandSemicolon }
40:
41: /// <summary/>
42: public class ProvisioningWorkflow
43: {
44: /// <summary/>
45: public Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn Pstn { get; set; }
46:
47: /// <summary/>
48: public string ReadCommand { get; set; }
49:
50: /// <summary/>
51: public string UpdateCommand { get; set; }
52:
53: /// <summary/>
54: public string DeleteCommand { get; set; }
55:
56: /// <summary/>
57: public string ServiceSuspensionCommand { get; set; }
58:
59: /// <summary/>
60: public string ExecuteSemicolon { get; set; }
61:
62: /// <summary/>
63: public ProvisioningWorkflow()
64: {
65:
66: }
67: }
68:
69: /// <summary/>
70: public static string Host(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn)
71: {
72: string host;
73:
74: switch (pstn.Name)
75: {
76: case "MSF": host = ConfigurationManager.AppSettings["axeMsfEricssonServerHost"].ToString(); break;
77: case "SLMA": host = ConfigurationManager.AppSettings["axeSlmaEricssonServerHost"].ToString(); break;
78: default: host = string.Empty; break;
79: }
80:
81: return host;
82: }
83:
84: /// <summary/>
85: public static int Port { get { return 23; } } // 23 telnet port
86:
87: /// <summary/>
88: public static string UserName(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn)
89: {
90: string userName;
91:
92: switch (pstn.Name)
93: {
94: case "MSF": userName = ConfigurationManager.AppSettings["axeMsfEricssonServerUserName"].ToString(); break;
95: case "SLMA": userName = ConfigurationManager.AppSettings["axeSlmaEricssonServerUserName"].ToString(); break;
96: default: userName = string.Empty; break;
97: }
98:
99: return userName;
100: }
101:
102: /// <summary/>
103: public static string Password(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn)
104: {
105: string password;
106:
107: switch (pstn.Name)
108: {
109: case "MSF": password = ConfigurationManager.AppSettings["axeMsfEricssonServerPassword"].ToString(); break;
110: case "SLMA": password = ConfigurationManager.AppSettings["axeSlmaEricssonServerPassword"].ToString(); break;
111: default: password = string.Empty; break;
112: }
113:
114: return password;
115: }
116:
117: /// <summary/>
118: public static string LogoutCommand { get { return ConfigurationManager.AppSettings["axeEricssonServerLogoutCommand"].ToString(); } }
119:
120: /// <summary/>
121: public static List<string> ServiceSymbolList { get; } = new List<string>();
122:
123: ////////////////////////////////////////////////////////////////////////////
124:
125: /// <summary>
126: /// Response of Ericsson AXE
127: /// </summary>
128: public class Response
129: {
130: public int Service { get; set; }
131:
132: /// <summary/>
133: public bool IsSuccess { get { return ReturnCode == Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Successful; } }
134:
135: /// <summary/>
136: public bool IsProvisioned { get; set; }
137:
138: /// <summary/>
139: public Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode ReturnCode { get; set; }
140:
141: /// <summary/>
142: //public string Ctag { get; set; } // no need because the commad string is included in response body
143:
144: /// <summary/>
145: public DateTime DateTime { get; set; }
146:
147: /// <summary/>
148: public string CommandString { get; set; }
149:
150: /// <summary/>
151: public int Snb { get; set; }
152:
153: /// <summary/>
154: public string Dev { get; set; }
155:
156: /// <summary/>
157: public string Dety { get; set; }
158:
159: /// <summary/>
160: public string Sut { get; set; }
161:
162: /// <summary/>
163: public string Scl { get; set; }
164:
165: /// <summary/>
166: public string Mis { get; set; }
167:
168: /// <summary/>
169: public string Cos { get; set; }
170:
171: /// <summary/>
172: public string Content { get; set; }
173:
174: /// <summary/>
175: //public Dictionary<string, string> QueryDictionary { get; set; }
176:
177: /// <summary/>
178: public Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService ServiceSupplementaryService { get; set; }
179:
180: ////////////////////////////////////////////////////////////////////////////
181:
182: /// <summary>
183: ///
184: /// </summary>
185: public Response(string content)
186: {
187: string service;
188: Match match;
189: Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService serviceSupplementaryService;
190: Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode returnCode;
191:
192: if (content.Contains("GENERAL AVAILABILITY FOR SUPPLEMENTARY SERVICES SUBSCRIBER CATEGORIES")) // result of SULIE
193: {
194: /*
195: SUBSCRIBER DATA
196: SNB DEV DETY SUT SCL MIS COS
197: 25381611 LIMA-18146
198: GENERAL AVAILABILITY FOR SUPPLEMENTARY SERVICES SUBSCRIBER CATEGORIES
199:
200: SCL
201: ALS-1
202:
203: SUBSCRIBER METER DATA
204: SNB UCMS CMV1 MISC
205: 25381611 1 0
206: SUB1 SUB2 SUB3 SUB4
207: 0 0 0 0
208: END
209: */
210:
211: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Successful;
212: }
213: else if (content.StartsWith("SUBSCRIBER DATA") && content.EndsWith("END")) // order important
214: {
215: /*
216: SUBSCRIBER DATA
217: SNB DEV DETY SUT SCL MIS COS
218: 25382234 LIMA-634 CCB-1
219:
220: END
221:
222:
223: SUBSCRIBER DATA
224: SNB DEV DETY SUT SCL MIS COS
225: 25387526 NC
226: END
227:
228:
229: SUBSCRIBER DATA
230: SNB DEV DETY SUT SCL MIS COS
231: 25381111 PB IPT-2
232: ANT-2
233: CBA-2
234:
235: END
236: */
237: match = Regex.Match(content, @"\r\n(\d{8})\s+");
238:
239: if (match.Success)
240: {
241: service = match.Groups[1].Value;
242:
243: this.CommandString = @"SUSCP:SNB=" + service + ";";
244:
245: this.Service = int.Parse(service);
246:
247: if (content.Contains(" NC"))
248: {
249: this.IsProvisioned = false;
250: }
251: else
252: {
253: serviceSupplementaryService = Ia.Ngn.Cl.Model.Business.Ericsson.Axe.ServiceSupplementaryServiceStateFromServiceNetManagerOutputString(content);
254:
255: this.IsProvisioned = true;
256: this.ServiceSupplementaryService = serviceSupplementaryService;
257: }
258:
259: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Successful;
260: }
261: else
262: {
263: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Failed;
264: }
265: }
266: else if (content.Contains("EXECUTED"))
267: {
268: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Successful;
269: }
270: else if (content.Contains("NOT ACCEPTED") && content.Contains("UNREASONABLE VALUE"))
271: {
272: /*
273: <SUSCP:SNB=25612222;
274: NOT ACCEPTED
275: UNREASONABLE VALUE
276: (0)SNB=25612222
277: */
278: match = Regex.Match(content, @"SNB=(\d{8})");
279:
280: if (match.Success)
281: {
282: service = match.Groups[1].Value;
283:
284: this.CommandString = @"SUSCP:SNB=" + service + ";";
285:
286: this.Service = int.Parse(service);
287: this.IsProvisioned = false;
288:
289: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.NotAcceptedUnreasonableValue;
290: }
291: else
292: {
293: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.Failed;
294: }
295: }
296: else if (content.Contains("NOT ACCEPTED") && content.Contains("SUBSCRIBER NOT CONNECTED"))
297: {
298: /*
299: <SULIE:SNB=25384651;
300: SULIE:SNB=25384651;
301: <;
302: NOT ACCEPTED
303: FAULT CODE 41
304: SUBSCRIBER NOT CONNECTED
305: (0)SNB=25384651
306: */
307:
308: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.SubscriberNotConnected;
309: }
310: else if (content.Contains("NOT ACCEPTED") && content.Contains("COMMAND UNKNOWN"))
311: {
312: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.NotAcceptedCommandUnknown;
313: }
314: else if (content.Contains("TIME OUT"))
315: {
316: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.TimeOut;
317: }
318: else
319: {
320: returnCode = Ia.Ngn.Cl.Model.Client.Ericsson.Axe.ResultCode.UnknownError;
321: }
322:
323: this.ReturnCode = returnCode;
324: this.Content = content;
325: this.ParseSuscp(content, out int snb, out string dev, out string dety, out string sut, out string scl, out string mis, out string cos);
326: this.Snb = snb;
327: this.Dev = dev;
328: this.Dety = dety;
329: this.Sut = sut;
330: this.Scl = scl;
331: this.Mis = mis;
332: this.Cos = cos;
333: }
334:
335: ////////////////////////////////////////////////////////////////////////////
336:
337: /// <summary>
338: ///
339: /// </summary>
340: private void ParseSuscp(string suscpOutputContent, out int snb, out string dev, out string dety, out string sut, out string scl, out string mis, out string cos)
341: {
342: using (StringReader stringReader = new StringReader(suscpOutputContent))
343: {
344: bool startReadingSnbInformationFlag;
345: int snbIndex, devIndex, detyIndex, sutIndex, sclIndex, misIndex, cosIndex;
346: string s, line;
347: List<string> snbList, devList, detyList, sutList, sclList, misList, cosList;
348:
349: startReadingSnbInformationFlag = false;
350: snbIndex = devIndex = detyIndex = sutIndex = sclIndex = misIndex = cosIndex = -1;
351: snb = -1;
352: dev = dety = sut = scl = mis = cos = string.Empty;
353:
354: snbList = new List<string>();
355: devList = new List<string>();
356: detyList = new List<string>();
357: sutList = new List<string>();
358: sclList = new List<string>();
359: misList = new List<string>();
360: cosList = new List<string>();
361:
362: while ((line = stringReader.ReadLine()) != null)
363: {
364: if (!string.IsNullOrWhiteSpace(line))
365: {
366: if (line.StartsWith("SUBSCRIBER DATA") || line.StartsWith("END") || line.StartsWith("GENERAL AVAILABILITY"))
367: {
368: startReadingSnbInformationFlag = false;
369: }
370: else if (line.StartsWith("SNB") && line.Contains("DEV"))
371: {
372: snbIndex = 0; // line.IndexOf("SNB");
373: devIndex = line.IndexOf("DEV");
374: detyIndex = line.IndexOf("DETY");
375: sutIndex = line.IndexOf("SUT");
376: sclIndex = line.IndexOf("SCL");
377: misIndex = line.IndexOf("MIS");
378: cosIndex = line.IndexOf("COS");
379:
380: startReadingSnbInformationFlag = true;
381: }
382: else if (startReadingSnbInformationFlag)
383: {
384: line = line.PadRight(cosIndex + 3, ' '); // 3 for the string COS
385:
386: s = line.Substring(snbIndex, devIndex - snbIndex).Trim();
387: if (!string.IsNullOrEmpty(s)) snbList.Add(s);
388:
389: s = line.Substring(devIndex, detyIndex - devIndex).Trim();
390: if (!string.IsNullOrEmpty(s)) devList.Add(s);
391:
392: s = line.Substring(detyIndex, sutIndex - detyIndex).Trim();
393: if (!string.IsNullOrEmpty(s)) detyList.Add(s);
394:
395: s = line.Substring(sutIndex, sclIndex - sutIndex).Trim();
396: if (!string.IsNullOrEmpty(s)) sutList.Add(s);
397:
398: s = line.Substring(sclIndex, misIndex - sclIndex).Trim();
399: if (!string.IsNullOrEmpty(s)) sclList.Add(s);
400:
401: s = line.Substring(misIndex, cosIndex - misIndex).Trim();
402: if (!string.IsNullOrEmpty(s)) misList.Add(s);
403:
404: s = line.Substring(cosIndex, line.Length - cosIndex).Trim();
405: if (!string.IsNullOrEmpty(s)) cosList.Add(s);
406:
407: snb = int.Parse(string.Join(",", snbList));
408: dev = string.Join(",", devList);
409: dety = string.Join(",", detyList);
410: sut = string.Join(",", sutList);
411: scl = string.Join(",", sclList);
412: mis = string.Join(",", misList);
413: cos = string.Join(",", cosList);
414: }
415: else
416: {
417:
418: }
419: }
420: else
421: {
422:
423: }
424: }
425: }
426: }
427:
428: ////////////////////////////////////////////////////////////////////////////
429: ////////////////////////////////////////////////////////////////////////////
430: }
431:
432: ////////////////////////////////////////////////////////////////////////////
433:
434: /// <summary>
435: ///
436: /// </summary>
437: public Axe() { }
438:
439: ////////////////////////////////////////////////////////////////////////////
440:
441: /// <summary>
442: ///
443: /// </summary>
444: public static string ProperlySelectedSingleServiceQueueServiceNumber(ref int referenceIndex, List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> pstnList, out int itemIndex, out int listCount)
445: {
446: string service;
447:
448: if (properlySelectedAxeServiceList.JustStartedOrRolledOver())
449: {
450: properlySelectedAxeServiceList = AllPossibleServiceNumbersPreferablyNotInAxeSubscriberWithinPstn(pstnList).ToList();
451:
452: // Sort the strings by their reversed characters
453: // https://www.codingame.com/playgrounds/213/using-c-linq---a-practical-overview/reverse-and-orderby
454:
455: properlySelectedAxeServiceList = properlySelectedAxeServiceList.OrderBy(str => new string(str.Reverse().ToArray())).ToList();
456: }
457:
458: service = properlySelectedAxeServiceList.Next(ref referenceIndex, out itemIndex, out listCount);
459:
460: return service;
461: }
462:
463: ////////////////////////////////////////////////////////////////////////////
464:
465: /// <summary>
466: ///
467: /// </summary>
468: public static List<string> AllPossibleServiceNumbersPreferablyNotInAxeSubscriberWithinPstn(List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> pstnList)
469: {
470: var allPossibleServiceNumbersWithinPstn = new List<int>();
471:
472: foreach (var pstn in pstnList)
473: {
474: allPossibleServiceNumbersWithinPstn.AddRange(Ia.Ngn.Cl.Model.Data.Service.AllPossibleServiceNumbersWithinPstn(pstn.Name));
475: }
476:
477: var snbList = Ia.Ngn.Cl.Model.Data.Ericsson.Subscriber.SnbList();
478:
479: var list = allPossibleServiceNumbersWithinPstn.Except(snbList).ToList();
480:
481: // if list is empty then will use the all list
482: if (list.Count == 0) list = allPossibleServiceNumbersWithinPstn;
483:
484: var servicelist = list.ConvertAll<string>(u => u.ToString());
485:
486: var hashSet = new HashSet<string>(servicelist);
487:
488: return hashSet.ToList();
489: }
490:
491: ////////////////////////////////////////////////////////////////////////////
492:
493: /// <summary>
494: ///
495: /// </summary>
496: public static ProvisioningWorkflow SynchronizeAxeServiceIcsxRouteToMatchImsServiceRouterVendorProvisioningWorkflowItem(Ia.Ngn.Cl.Model.Business.Default.Procedure procedure)
497: {
498: ProvisioningWorkflow provisioningWorkflow;
499: List<ProvisioningWorkflow> list;
500:
501: provisioningWorkflow = null;
502:
503: if (synchronizationProvisioningWorkflowQueue.Count == 0 && procedure == Ia.Ngn.Cl.Model.Business.Default.Procedure.InitializeOrIterate)
504: {
505: list = Ia.Ngn.Cl.Model.Business.Ericsson.Axe.DeleteAndUpdateAndReadCommandToSynchronizeAxeServiceIcsxRouteToMatchImsServiceRouterVendorProvisioningWorkflowList();
506:
507: synchronizationProvisioningWorkflowQueue = new Queue<ProvisioningWorkflow>(list); // don't shuffle because a modify command is followed by a read .Shuffle());
508: }
509:
510: if (synchronizationProvisioningWorkflowQueue.Count > 0) provisioningWorkflow = synchronizationProvisioningWorkflowQueue.Dequeue();
511:
512: return provisioningWorkflow;
513: }
514:
515: ////////////////////////////////////////////////////////////////////////////
516:
517: /// <summary>
518: ///
519: /// </summary>
520: public static List<ProvisioningWorkflow> DeleteAndUpdateAndReadCommandToSynchronizeAxeServiceIcsxRouteToMatchImsServiceRouterVendorProvisioningWorkflowList()
521: {
522: int icsxRoute;
523: string service;
524: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
525: Ia.Ngn.Cl.Model.Business.Default.SwitchRoute pstnSwitchRoute, switchRouteToMigratedRouterVendor;
526: ProvisioningWorkflow provisioningWorkflow;
527: List<ProvisioningWorkflow> provisioningWorkflowList;
528:
529: provisioningWorkflowList = new List<ProvisioningWorkflow>();
530:
531: var imsServiceToOntRouterVendorInAllowedToBeMigratedOltDictionary = Ia.Ngn.Cl.Model.Data.Service.ImsServiceToOntRouterVendorInAllowedToBeMigratedOltDictionary;
532:
533: var axeServiceToSwitchRouteDictionary = Ia.Ngn.Cl.Model.Data.Ericsson.Subscriber.PstnServiceToSwitchRouteDictionary();
534:
535: // will exclude exempt numbers
536: var serviceExemptionList = Ia.Ngn.Cl.Model.Data.Provision.ServiceOfServiceExemptFromProvisionProcessingList();
537:
538: foreach (KeyValuePair<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> kvp in imsServiceToOntRouterVendorInAllowedToBeMigratedOltDictionary)
539: {
540: service = kvp.Key;
541: vendor = kvp.Value;
542:
543: if (axeServiceToSwitchRouteDictionary.ContainsKey(service))
544: {
545: pstnSwitchRoute = axeServiceToSwitchRouteDictionary[service];
546:
547: if (vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia) switchRouteToMigratedRouterVendor = Ia.Ngn.Cl.Model.Business.Default.SwitchRoute.NokiaIms;
548: else if (vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei) switchRouteToMigratedRouterVendor = Ia.Ngn.Cl.Model.Business.Default.SwitchRoute.HuaweiIms;
549: else switchRouteToMigratedRouterVendor = Ia.Ngn.Cl.Model.Business.Default.SwitchRoute.Unknown;
550:
551: if (pstnSwitchRoute != switchRouteToMigratedRouterVendor && switchRouteToMigratedRouterVendor != Ia.Ngn.Cl.Model.Business.Default.SwitchRoute.Unknown)
552: {
553: if (!serviceExemptionList.Contains(service))
554: {
555: provisioningWorkflow = new ProvisioningWorkflow();
556:
557: icsxRoute = Ia.Ngn.Cl.Model.Business.Ericsson.Subscriber.SwitchRouteToIcsxRoute(switchRouteToMigratedRouterVendor);
558:
559: provisioningWorkflow.Pstn = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnFromService(service);
560:
561: provisioningWorkflow.ExecuteSemicolon = ConfirmCommandSemicolon();
562:
563: provisioningWorkflow.DeleteCommand = DeleteServiceCommand(service);
564: provisioningWorkflow.UpdateCommand = UpdateServiceRouteCommand(service, icsxRoute);
565: provisioningWorkflow.ReadCommand = ReadServiceCommand(service);
566:
567: provisioningWorkflowList.Add(provisioningWorkflow);
568: }
569: }
570: }
571: }
572:
573: return provisioningWorkflowList;
574: }
575:
576: ////////////////////////////////////////////////////////////////////////////
577:
578: /// <summary>
579: ///
580: /// </summary>
581: public static ProvisioningWorkflow SynchronizeBetweenServiceRequestAdministrativeIssueAndEricssonAxePstnServiceProvisioningWorkflowItem()
582: {
583: ProvisioningWorkflow provisioningWorkflow;
584: List<ProvisioningWorkflow> list;
585:
586: provisioningWorkflow = null;
587:
588: if (serviceSuspentionSynchronizationProvisioningWorkflowQueue.Count == 0)
589: {
590: list = Ia.Ngn.Cl.Model.Business.Ericsson.Axe.ServiceSuspentionAndReadCommandSynchronizeBetweenServiceRequestAdministrativeIssueAndEricssonAxePstnServiceProvisioningWorkflowList();
591:
592: serviceSuspentionSynchronizationProvisioningWorkflowQueue = new Queue<ProvisioningWorkflow>(list); // don't shuffle because a modify command is followed by a read .Shuffle());
593: }
594:
595: if (serviceSuspentionSynchronizationProvisioningWorkflowQueue.Count > 0) provisioningWorkflow = serviceSuspentionSynchronizationProvisioningWorkflowQueue.Dequeue();
596:
597: return provisioningWorkflow;
598: }
599:
600: ////////////////////////////////////////////////////////////////////////////
601:
602: /// <summary>
603: ///
604: /// </summary>
605: public static List<ProvisioningWorkflow> ServiceSuspentionAndReadCommandSynchronizeBetweenServiceRequestAdministrativeIssueAndEricssonAxePstnServiceProvisioningWorkflowList()
606: {
607: bool state;
608: ProvisioningWorkflow provisioningWorkflow;
609: List<ProvisioningWorkflow> provisioningWorkflowList;
610:
611: provisioningWorkflowList = new List<ProvisioningWorkflow>();
612:
613: Ia.Ngn.Cl.Model.Data.Provision.EricssonAxePstnServiceSuspensionMismatchBetweenServiceRequestAdministrativeIssueAndServiceServiceList(out List<string> serviceToSuspendList, out List<string> serviceToReleaseList, out _, out _);
614:
615: // will exclude exempt numbers
616: var serviceExemptionList = Ia.Ngn.Cl.Model.Data.Provision.ServiceOfServiceExemptFromProvisionProcessingList();
617:
618: state = true;
619:
620: foreach (var service in serviceToSuspendList)
621: {
622: if (!serviceExemptionList.Contains(service))
623: {
624: provisioningWorkflow = new ProvisioningWorkflow();
625:
626: provisioningWorkflow.Pstn = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnFromService(service);
627:
628: provisioningWorkflow.ExecuteSemicolon = ConfirmCommandSemicolon();
629:
630: provisioningWorkflow.ServiceSuspensionCommand = ServiceSuspensionCommand(service, state);
631:
632: provisioningWorkflow.ReadCommand = ReadServiceCommand(service);
633:
634: provisioningWorkflowList.Add(provisioningWorkflow);
635: }
636: }
637:
638:
639: state = false;
640:
641: foreach (var service in serviceToReleaseList)
642: {
643: if (!serviceExemptionList.Contains(service))
644: {
645: provisioningWorkflow = new ProvisioningWorkflow();
646:
647: provisioningWorkflow.Pstn = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnFromService(service);
648:
649: provisioningWorkflow.ExecuteSemicolon = ConfirmCommandSemicolon();
650:
651: provisioningWorkflow.ServiceSuspensionCommand = ServiceSuspensionCommand(service, state);
652:
653: provisioningWorkflow.ReadCommand = ReadServiceCommand(service);
654:
655: provisioningWorkflowList.Add(provisioningWorkflow);
656: }
657: }
658:
659: return provisioningWorkflowList;
660: }
661:
662: ////////////////////////////////////////////////////////////////////////////
663:
664: /// <summary>
665: ///
666: /// </summary>
667: public static Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService ServiceSupplementaryServiceStateFromServiceNetManagerOutputString(string content)
668: {
669: string service;
670: Match match;
671: Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService serviceSupplementaryService;
672:
673: serviceSupplementaryService = new Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService();
674:
675: /*
676: SUBSCRIBER DATA
677: SNB DEV DETY SUT SCL MIS COS
678: 25382234 LIMA-634 CCB-1
679:
680: END
681:
682: SUBSCRIBER DATA
683: SNB DEV DETY SUT SCL MIS COS
684: 25381111 PB IPT-2
685: ANT-2
686: CBA-2
687:
688: END
689: */
690:
691:
692: /*
693: 2019-12-29 07:58:44: ServiceSymbolList: Service symbol list: CBA-2, IPT-2, ANT-2, FLA-2, GUG-5, CAW-1, ENQ-2, CCB-1, CDP-1, CBA-1, CFUF-1, IPT-3, APT-2, CFUV-1,
694: CBP-1, CCB-2, FLA-1, ENQ-1, CBB-1, CBA-9, TCL-9, CBA-3, GUG-2, TBO-2, TBI-1, ICS-3, FDC-1, LNR-1, CBA-15, TBO-1, CBA-7, BIC-1, FDC-2, CBA-10, MCIDSC-1, ADI-2,
695: LIBAMA-14, OCG-1, TLI-14, BAT-1, GUG-0, GUG-3, BOC-1
696: */
697:
698: /*
699: Unknown: IPT-2, CDP-1, APT-2, ENQ-1, CBP-1, CBB-1, CBA-7, CBA-15, CBA-1, CBA-9, TCL-9, CBA-10, FDC-1, CCB-2, FLA-1, CBA-3, OCG-1, TLI-14, BAT-1, FDC-2, LIBAMA-14, MCIDSC-1, LNR-1, GUG-2, GUG-0, GUG-3
700:
701: IPT-3,ANT-2 CallerId
702: CFUF-1,CFUV-1 CallForwarding
703: CAW-1,FLA-2 CallWaiting
704: ENQ-2,FLA-2 ConferenceCall
705: GUG-5 WakeupCall
706: ADI-2 AbbriviatedCalling
707: CCB-1 InternationalCallingUserControlled
708: CBA-2 InternationalCalling
709: TBO-1,TBI-1 ServiceSuspension
710: TBO-2,TBI-1 ServiceSuspension due to ServiceAdministrativelySuspendedByBillingDepartment
711: BIC-1,BOC-1 ServiceSuspension due to ServiceAdministrativelySuspendedForOtherReasons
712: BIC-1 ServiceSuspension
713: BOC-1 ServiceSuspension
714:
715: */
716: match = Regex.Match(content, @"\r\n(\d{8})\s+");
717:
718: if (match.Success)
719: {
720: service = match.Groups[1].Value;
721:
722: if (int.TryParse(service, out int snb))
723: {
724: serviceSupplementaryService.Service = snb;
725:
726: if (content.Contains("IPT-3") && content.Contains("ANT-2") /*&& outputContent.Contains("APT-2")*/) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallerId);
727: if (/*outputContent.Contains("CDP-1") &&*/ content.Contains("CFUF-1") && content.Contains("CFUV-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallForwarding);
728: //if (outputContent.Contains("OCG-1") && outputContent.Contains("TLI-14")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.MagneticCart);
729: //if (outputContent.Contains("FLA-2") && outputContent.Contains("MCIDSC-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallMonitoring);
730: if (content.Contains("CAW-1") && content.Contains("FLA-2")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallWaiting);
731: if (content.Contains("ENQ-2") && content.Contains("FLA-2")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ConferenceCall);
732: if (content.Contains("GUG-5")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.WakeupCall);
733: if (content.Contains("ADI-2")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.AbbriviatedCalling);
734: if (content.Contains("CCB-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCallingUserControlled);
735: if (content.Contains("CBA-2")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCalling);
736:
737: //if (outputContent.Contains("FDC-1") && outputContent.Contains("LNR-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.OneWayHotoutputContent);
738: //if (outputContent.Contains("FDC-2") && outputContent.Contains("LNR-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.TwoWayHotoutputContent);
739:
740: //if (outputContent.Contains("SSI-1")) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.???);
741:
742: if (content.Contains("TBO-1") && content.Contains("TBI-1"))
743: {
744: //serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ManualBillingDisconnect);
745: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
746: }
747:
748: if (content.Contains("TBO-2") && content.Contains("TBI-1"))
749: {
750: serviceSupplementaryService.ServiceAdministrativelySuspendedByBillingDepartment = true;
751: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
752: }
753:
754: if (content.Contains("BIC-1") && content.Contains("BOC-1"))
755: {
756: serviceSupplementaryService.ServiceAdministrativelySuspendedForOtherReasons = true;
757: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
758: }
759: else if (content.Contains("BIC-1"))
760: {
761: //serviceSupplementaryService.IncomingDisconnect = true;
762: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
763: }
764: else if (content.Contains("BOC-1"))
765: {
766: //serviceSupplementaryService.OutgoingDisconnect = true;
767: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
768: }
769:
770: if (content.Contains("PB")) serviceSupplementaryService.IsPbx = true;
771:
772: Ia.Ngn.Cl.Model.Business.Ericsson.Axe.ExtractAndUpdateUniqueAxeServiceSymbolListFromOutputContent(content);
773: }
774: else
775: {
776: }
777: }
778: else
779: {
780: }
781:
782: return serviceSupplementaryService;
783: }
784:
785: ////////////////////////////////////////////////////////////////////////////
786: ////////////////////////////////////////////////////////////////////////////
787:
788: /// <summary>
789: ///
790: /// </summary>
791: public static string ReadServiceCommand(string service)
792: {
793: return AxeCommand(Opcode.Suscp, int.Parse(service));
794: }
795:
796: ////////////////////////////////////////////////////////////////////////////
797:
798: /// <summary>
799: ///
800: /// </summary>
801: public static string DeleteServiceCommand(string service)
802: {
803: return AxeCommand(Opcode.Sulie, int.Parse(service));
804: }
805:
806: ////////////////////////////////////////////////////////////////////////////
807:
808: /// <summary>
809: ///
810: /// </summary>
811: public static string UpdateSupplementaryServiceCommand(string service, Ia.Ngn.Cl.Model.Business.Service.SupplementaryService supplementaryService, bool supplementaryServiceState)
812: {
813: int snb;
814: string command;
815:
816: snb = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.Number(service);
817:
818: switch (supplementaryService)
819: {
820: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.AbbriviatedCalling):
821: {
822: command = AxeCommand(Opcode.SusccXxx, snb);
823: break;
824: }
825: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallerId):
826: {
827: command = AxeCommand(Opcode.SusccXxx, snb);
828: break;
829: }
830: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallForwarding):
831: {
832: command = AxeCommand(Opcode.SusccXxx, snb);
833: break;
834: }
835: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallWaiting):
836: {
837: command = AxeCommand(Opcode.SusccXxx, snb);
838: break;
839: }
840: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ConferenceCall):
841: {
842: command = AxeCommand(Opcode.SusccXxx, snb);
843: break;
844: }
845: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.WakeupCall):
846: {
847: command = AxeCommand(Opcode.SusccXxx, snb);
848: break;
849: }
850: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCallingUserControlled):
851: {
852: command = AxeCommand(Opcode.SusccXxx, snb);
853: break;
854: }
855: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCalling):
856: {
857: command = AxeCommand(Opcode.SusccXxx, snb);
858: break;
859: }
860: case (Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension):
861: {
862: command = AxeCommand(Opcode.SusccXxx, snb);
863: break;
864: }
865: default:
866: {
867: command = snb + ",unknown SupplementaryService: " + supplementaryServiceState.ToString().ToLower();
868: break;
869: }
870: }
871:
872: return command;
873: }
874:
875: ////////////////////////////////////////////////////////////////////////////
876:
877: /// <summary>
878: ///
879: /// </summary>
880: public static string UpdateServiceRouteCommand(string service, int ics)
881: {
882: var snb = int.Parse(service);
883:
884: return AxeCommand(Opcode.SusccIcs, snb, ics);
885: }
886:
887: ////////////////////////////////////////////////////////////////////////////
888:
889: /// <summary>
890: ///
891: /// </summary>
892: public static string ServiceSuspensionCommand(string service, bool serviceSuspensionState)
893: {
894: string command;
895:
896: var snb = int.Parse(service);
897:
898: if (serviceSuspensionState) command = AxeCommand(Opcode.SusccTboTbi, snb, 2, 1); // suspend
899: else command = AxeCommand(Opcode.SusccTboTbi, snb, 0, 0); // release
900:
901: return command;
902: }
903:
904: ////////////////////////////////////////////////////////////////////////////
905:
906: /// <summary>
907: ///
908: /// </summary>
909: public static string ConfirmCommandSemicolon()
910: {
911: return AxeCommand(Opcode.ConfirmCommandSemicolon);
912: }
913:
914: ////////////////////////////////////////////////////////////////////////////
915:
916: /// <summary>
917: ///
918: /// </summary>
919: public static string KeepAliveCommandSemicolon()
920: {
921: return AxeCommand(Opcode.KeepAliveCommandSemicolon);
922: }
923:
924: ////////////////////////////////////////////////////////////////////////////
925: ////////////////////////////////////////////////////////////////////////////
926:
927: /// <summary>
928: ///
929: /// </summary>
930: private static string AxeCommand(Opcode opcode)
931: {
932: string command;
933:
934: if (opcode == Opcode.ConfirmCommandSemicolon) command = ";";
935: else if (opcode == Opcode.KeepAliveCommandSemicolon) command = ";";
936: else throw new System.ArgumentOutOfRangeException("AxeCommand(): Opcode unrecognized. ");
937:
938: return command;
939: }
940:
941: ////////////////////////////////////////////////////////////////////////////
942:
943: /// <summary>
944: ///
945: /// </summary>
946: private static string AxeCommand(Opcode opcode, int snb)
947: {
948: string command;
949:
950: if (opcode == Opcode.Suscp) command = "SUSCP:SNB=" + snb + ";";
951: else if (opcode == Opcode.Sulie) command = "SULIE:SNB=" + snb + ";"; // SULIE must be followed with semicolon';'
952: else if (opcode == Opcode.SusccXxx) command = "SUSCC:SNB=" + snb + ",SCL=Xxx;"; // SUSCC must be followed with semicolon';'
953: else throw new System.ArgumentOutOfRangeException("AxeCommand(): Opcode unrecognized. ");
954:
955: return command;
956: }
957:
958: ////////////////////////////////////////////////////////////////////////////
959:
960: /// <summary>
961: ///
962: /// </summary>
963: private static string AxeCommand(Opcode opcode, int snb, int parameter)
964: {
965: string command;
966:
967: if (opcode == Opcode.SusccIcs) command = "SUSCC:SNB=" + snb + ",SCL=ICS-" + parameter + "&TBO-0&TBI-0&BOC-0&BIC-0;"; // SUSCC must be followed with semicolon';'
968: else if (opcode == Opcode.SusccXxx) command = "SUSCC:SNB=" + snb + ",SCL=Xxx-" + parameter + ";"; // SUSCC must be followed with semicolon';'
969: else throw new System.ArgumentOutOfRangeException("AxeCommand(): Opcode unrecognized. ");
970:
971: return command;
972: }
973:
974: ////////////////////////////////////////////////////////////////////////////
975:
976: /// <summary>
977: ///
978: /// </summary>
979: private static string AxeCommand(Opcode opcode, int snb, int parameter1, int parameter2)
980: {
981: string command;
982:
983: if (opcode == Opcode.SusccTboTbi) command = "SUSCC:SNB=" + snb + ",SCL=TBO-" + parameter1 + "&TBI-" + parameter2 + ";"; // SUSCC must be followed with semicolon';'
984: else throw new System.ArgumentOutOfRangeException("AxeCommand(): Opcode unrecognized. ");
985:
986: return command;
987: }
988:
989: ////////////////////////////////////////////////////////////////////////////
990:
991: /// <summary>
992: ///
993: /// </summary>
994: public static string AxeDisplayTimeCommand
995: {
996: get
997: {
998: return ";";
999: }
1000: }
1001:
1002: ////////////////////////////////////////////////////////////////////////////
1003:
1004: /// <summary>
1005: /// Extract unique AXE service symbols into array
1006: /// </summary>
1007: public static void ExtractAndUpdateUniqueAxeServiceSymbolListFromOutputContent(string outputContent)
1008: {
1009: MatchCollection matchCollection;
1010:
1011: matchCollection = Regex.Matches(outputContent, @"\b[A-Z]{3,8}-\d+\b");
1012:
1013: if (matchCollection.Count > 0)
1014: {
1015: foreach (Match match in matchCollection)
1016: {
1017: if (!match.Value.StartsWith("LIMA")) // LIMA-3445 is a circuit
1018: {
1019: if (!ServiceSymbolList.Contains(match.Value))
1020: {
1021: ServiceSymbolList.Add(match.Value);
1022: }
1023: }
1024: }
1025: }
1026: }
1027:
1028: ////////////////////////////////////////////////////////////////////////////
1029: ////////////////////////////////////////////////////////////////////////////
1030: }
1031:
1032: ////////////////////////////////////////////////////////////////////////////
1033: ////////////////////////////////////////////////////////////////////////////
1034: }
1035: