)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Skip Navigation Links

Public general use code classes and xml files that we've compiled and used over the years:

Ericsson AXE support class of Optical Fiber Network (OFN) business model.

    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: