)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » Axe (Ia.Ftn.Cl.Model.Business.Ericsson)

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

Ericsson AXE support class of Fixed Telecommunications Network (FTN) business model.

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