شركة التطبيقات المتكاملة لتصميم النظم البرمجية الخاصة ش.ش.و.

Integrated Applications Programming Company

Skip Navigation LinksHome » Code Library » Ems

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

Element Management System (EMS) support class for Huawei's Optical Fiber Network (OFN) business model.

   1:  using System;
   2:  using System.Collections;
   3:  using System.Collections.Generic;
   4:  using System.Configuration;
   5:  using System.Data;
   6:  using System.Linq;
   7:  using System.Text.RegularExpressions;
   8:   
   9:  namespace Ia.Ngn.Cl.Model.Business.Huawei
  10:  {
  11:      ////////////////////////////////////////////////////////////////////////////
  12:   
  13:      /// <summary publish="true">
  14:      /// Element Management System (EMS) support class for Huawei's Optical Fiber Network (OFN) business model.
  15:      /// </summary>
  16:   
  17:      /// <remarks> 
  18:      /// Copyright © 2016-2022 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 Ems
  31:      {
  32:          private static Queue<string> emsCommandQueue = new Queue<string>();
  33:          private static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.HuaweiOltList.PickRandom();
  34:   
  35:          /// <summary/>
  36:          public enum EmsOpcode
  37:          {
  38:              LstDevByDt, LstDevByDev, LstDevByDevIp, LstBoard, LstPort, LstOnt, LstVag, ModOntAlias, ModOntAliasAnnul, ModOntVaprofileAluSipB, LstOntSipInfo, CfgOntVainDiv, CfgOntVainDivVacant, AddVoipPstnUser, AddMsanVoipPstnUser, LstVoipPstnUser, DelVoipPstnUser, CfgVoipPstnAccount, CfgVoipPstnAccountVacant, SaveDev, ResetOnt
  39:          }
  40:   
  41:          /// <summary/>
  42:          public enum BellcoreState { Unknown = 0, IsNr = 1, OosAu, OosMa, OosAuma };
  43:   
  44:          /// <summary/>
  45:          public static string Host { get { return ConfigurationManager.AppSettings["nceServerHost"].ToString(); } }
  46:   
  47:          /// <summary/>
  48:          public static int Port { get { return int.Parse(ConfigurationManager.AppSettings["nceServerPort"].ToString()); } }
  49:   
  50:          /// <summary/>
  51:          public static string LoginUser { get { return PrepareCtaggedCommand(ConfigurationManager.AppSettings["nceServerLoginUser"].ToString()); } }
  52:   
  53:          /// <summary/>
  54:          public static string LogoutUser { get { return PrepareCtaggedCommand(ConfigurationManager.AppSettings["nceServerLogoutUser"].ToString()); } }
  55:   
  56:          ////////////////////////////////////////////////////////////////////////////
  57:   
  58:          /// <summary>
  59:          /// Response class of NCE TL1 NBI following the "10.3 Response Format Description standard" in iManager NCE Unified Network Management System Guide.
  60:          /// </summary>
  61:          public class Response
  62:          {
  63:              /// <summary/>
  64:              public enum CompletionCodeType { DENY, COMPLD };
  65:   
  66:              /// <summary/>
  67:              public enum CommandType { Operation, Query };
  68:   
  69:              /// <summary/>
  70:              public bool OperationCommand { get { return !QueryCommand; } }
  71:   
  72:              /// <summary/>
  73:              public bool QueryCommand { get; set; }
  74:   
  75:              /// <summary/>
  76:              public int BlockTag { get; set; }
  77:   
  78:              /// <summary/>
  79:              public int CurrentBlockCount { get; set; }
  80:   
  81:              /// <summary/>
  82:              public int TotalCount { get; set; }
  83:   
  84:              /// <summary/>
  85:   
  86:              public string Ctag { get; set; }
  87:   
  88:              /// <summary/>
  89:              public string CompletionCode { get; set; }
  90:   
  91:              /// <summary/>
  92:              public string Title { get; set; }
  93:   
  94:              /// <summary/>
  95:              public long En { get; set; }
  96:   
  97:              /// <summary/>
  98:              public string Endesc { get; set; }
  99:   
 100:              /// <summary/>
 101:              public Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode ResultCode { get; set; }
 102:   
 103:              /// <summary/>
 104:              public string CommandFromCorrelationTagDictionaryByCtag
 105:              {
 106:                  get
 107:                  {
 108:                      string opcode;
 109:   
 110:                      if (Ia.Ngn.Cl.Model.Data.Huawei.Ems.CorrelationTagDictionary.ContainsKey(Ctag)) opcode = Ia.Ngn.Cl.Model.Data.Huawei.Ems.CorrelationTagDictionary[Ctag];
 111:                      else opcode = string.Empty;
 112:   
 113:                      return opcode;
 114:                  }
 115:              }
 116:   
 117:              /// <summary/>
 118:              public DataTable QueryDataTable { get; set; }
 119:   
 120:              /// <summary/>
 121:              public Response() { }
 122:          }
 123:   
 124:          ////////////////////////////////////////////////////////////////////////////
 125:   
 126:          /// <summary>
 127:          ///
 128:          /// </summary>
 129:          public Ems() { }
 130:   
 131:          ////////////////////////////////////////////////////////////////////////////
 132:          ////////////////////////////////////////////////////////////////////////////
 133:   
 134:          /// <summary>
 135:          ///
 136:          /// </summary>
 137:          private static List<string> PrepareCtaggedCommand(List<string> commandList)
 138:          {
 139:              List<string> ctaggedCommandList;
 140:   
 141:              if (commandList.Count > 0)
 142:              {
 143:                  ctaggedCommandList = new List<string>(commandList.Count);
 144:   
 145:                  foreach (string command in commandList)
 146:                  {
 147:                      ctaggedCommandList.Add(PrepareCtaggedCommand(command));
 148:                  }
 149:              }
 150:              else ctaggedCommandList = new List<string>();
 151:   
 152:              return ctaggedCommandList;
 153:          }
 154:   
 155:          ////////////////////////////////////////////////////////////////////////////
 156:   
 157:          /// <summary>
 158:          ///
 159:          /// </summary>
 160:          public static string PrepareCtaggedCommand(string command)
 161:          {
 162:              string ctaggedCommand, ctag;
 163:   
 164:              if (command.Contains("{ctag}"))
 165:              {
 166:                  ctag = Ia.Cl.Model.Default.RandomNumber(12);
 167:   
 168:                  Ia.Ngn.Cl.Model.Data.Huawei.Ems.CorrelationTagDictionary[ctag] = command;
 169:   
 170:                  ctaggedCommand = command.Replace("{ctag}", ctag);
 171:              }
 172:              else
 173:              {
 174:                  ctaggedCommand = string.Empty;
 175:              }
 176:   
 177:              return ctaggedCommand;
 178:          }
 179:   
 180:          ////////////////////////////////////////////////////////////////////////////
 181:   
 182:          /// <summary>
 183:          ///
 184:          /// </summary>
 185:          public static string PrepareCtaggedCommand(string command, string ctag)
 186:          {
 187:              string ctaggedCommand;
 188:   
 189:              if (command.Contains("{ctag}"))
 190:              {
 191:                  Ia.Ngn.Cl.Model.Data.Huawei.Ems.CorrelationTagDictionary[ctag] = command;
 192:   
 193:                  ctaggedCommand = command.Replace("{ctag}", ctag);
 194:              }
 195:              else
 196:              {
 197:                  ctaggedCommand = string.Empty;
 198:              }
 199:   
 200:              return ctaggedCommand;
 201:          }
 202:   
 203:          ////////////////////////////////////////////////////////////////////////////
 204:          ////////////////////////////////////////////////////////////////////////////
 205:   
 206:          /// <summary>
 207:          ///
 208:          /// </summary>
 209:          public static string HuaweiAccessNameFormatFromInaccurateHuaweiFileAndEmsNameFormat(string line)
 210:          {
 211:              // see: ConstructMduNameFromNddOntAccessName(string accessName)
 212:   
 213:              if (!Regex.IsMatch(line, @"^(\w{3})-(\d{3})-(\d{3})$") && !Regex.IsMatch(line, @"^(\w{3})-([1-9]\d{3})-(\d{3})$"))
 214:              {
 215:                  /*
 216:                  replace:
 217:                  and DEV not like 'MDU-___-01-____-___' 
 218:                  and DEV not like 'MDU-___-B4-___-___' 
 219:                  and DEV not like 'MDU-___-B4-____-___' 
 220:                  and DEV not like '___-B4-___-___' 
 221:                  and DEV not like '___-B4-____-___' 
 222:                  and DEV not like 'ONT-___-___-___' 
 223:                  and DEV not like 'MDU--___-____-___' 
 224:                  and DEV not like 'ONT-___-____-___' 
 225:                  and DEV not like '___-___-___V8R016C10S200'
 226:                  and DEV not like '___-____-___sHERIFARD'
 227:                  and DEV not like 'QSR1319-002'
 228:                   */
 229:   
 230:                  line = line.Replace("MDU--", ""); // must be before line.Replace("MDU-", "");
 231:                  line = line.Replace("MDU-", "");
 232:                  line = line.Replace("MDI-", "");
 233:                  line = line.Replace("B4-", "");
 234:                  line = line.Replace("-01-", "-");
 235:                  line = line.Replace("-4-", "-");
 236:                  line = line.Replace("ONT-", "");
 237:                  line = line.Replace("V8R016C10S200", "");
 238:                  line = line.Replace("sHERIFARD", "");
 239:                  line = line.Replace("QSR1319-002", "QSR-1319-002");
 240:   
 241:                  /*
 242:                  regex:
 243:                  and DEV not like '___.___._'
 244:                  and DEV not like 'MDU-___-0___-___' 
 245:                  and DEV not like 'MDU-___-___-___' 
 246:                  and DEV not like 'MDU-___-____-___' 
 247:                  and DEV not like '___-____-__'
 248:                  and DEV not like '___-__-___'
 249:                  and DEV not like '___-_-___'
 250:                  and DEV not like '___[_]___-___'
 251:                  and DEV not like '___ ____-___'
 252:                  and DEV not like '___0____-___'
 253:                   */
 254:   
 255:                  // below must be after line.Replace("MDU-", "");
 256:                  line = Regex.Replace(line, @"^(\w{3})\.(\d{3})\.(\d)$", "$1-$2-00$3");
 257:                  line = Regex.Replace(line, @"^(\w{3})-0(\d{3})-(\d{3})$", "$1-$2-$3");
 258:                  line = Regex.Replace(line, @"^(\w{3})-(\d{3})-(\d{3})$", "$1-$2-$3");
 259:                  line = Regex.Replace(line, @"^(\w{3})-(\d{4})-(\d{3})$", "$1-$2-$3");
 260:                  line = Regex.Replace(line, @"^(\w{3})-(\d{4})-(\d{2})$", "$1-$2-$3");
 261:                  line = Regex.Replace(line, @"^(\w{3})-(\d{2})-(\d{3})$", "$1-$2-$3");
 262:                  line = Regex.Replace(line, @"^(\w{3})_(\d{3})-(\d{3})$", "$1-$2-$3");
 263:                  line = Regex.Replace(line, @"^(\w{3})_(\d{3})-(\d{3})$", "$1-$2-$3");
 264:                  line = Regex.Replace(line, @"^(\w{3}) (\d{4})-(\d{3})$", "$1-$2-$3");
 265:                  line = Regex.Replace(line, @"^(\w{3})0(\d{4})-(\d{3})$", "$1-$2-$3");
 266:              }
 267:   
 268:              /*
 269:              no change
 270:              and DEV not like '___-___-___'
 271:              and DEV not like '___-____-___'
 272:               */
 273:   
 274:              return line;
 275:   
 276:              /*
 277:              // below do to all dev and alias in EMS
 278:              using (var db = new Ia.Ngn.Cl.Model.Ngn())
 279:              {
 280:                  var list = (from eo in db.EmsOnts select eo.ALIAS).ToList();
 281:  
 282:                  sb = new StringBuilder(list.Count * 50);
 283:  
 284:                  foreach (string l in list)
 285:                  {
 286:                      var v = Ia.Ngn.Cl.Model.Business.Huawei.Ems.HuaweiAccessNameFormatFromInaccurateHuaweiFileAndEmsNameFormat(l);
 287:  
 288:                      if(l != v) sb.AppendLine("[" + l + "]: [" + v + "]");
 289:                  }
 290:  
 291:                  filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\HuaweiAccessNameFormatFromInaccurateHuaweiFileAndEmsNameFormat.txt";
 292:                  File.WriteAllText(filePath, sb.ToString());
 293:              }
 294:               */
 295:          }
 296:   
 297:          ////////////////////////////////////////////////////////////////////////////
 298:   
 299:          /// <summary>
 300:          ///
 301:          /// </summary>
 302:          public static List<string> ConstructPossibleMduNameListFromNddOntAccessName(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt)
 303:          {
 304:              // see RemoveMduNameInHuaweiOntActivationReportSpecificNameFormat(string line)
 305:              List<string> possibleMduNameList;
 306:   
 307:              possibleMduNameList = new List<string>();
 308:   
 309:              // SAB-1443-001
 310:              possibleMduNameList.Add(nddOnt.Access.Symbol + "-" + nddOnt.Access.Pon.ToString().PadLeft(3, '0') + "-" + nddOnt.Access.Ont.ToString().PadLeft(3, '0'));
 311:   
 312:              // MDU-SAB-1443-001
 313:              possibleMduNameList.Add("MDU-" + nddOnt.Access.Symbol + "-" + nddOnt.Access.Pon.ToString().PadLeft(3, '0') + "-" + nddOnt.Access.Ont.ToString().PadLeft(3, '0'));
 314:   
 315:              if (nddOnt.Access.Name == "MGF.1306.1")
 316:              {
 317:                  // MDU-MGF-B4-1306-001
 318:                  possibleMduNameList.Add("MDU-MGF-B4-1306-001");
 319:              }
 320:              else if (nddOnt.Access.Name == "MGF.1522.4")
 321:              {
 322:                  // MGF-B4-1522-004
 323:                  possibleMduNameList.Add("MGF-B4-1522-004");
 324:              }
 325:              else if (nddOnt.Access.Name == "SAA.547.3")
 326:              {
 327:                  // ONT-SAA-547-003
 328:                  possibleMduNameList.Add("ONT-SAA-547-003");
 329:              }
 330:   
 331:              return possibleMduNameList;
 332:          }
 333:   
 334:          ////////////////////////////////////////////////////////////////////////////
 335:   
 336:          /// <summary>
 337:          ///
 338:          /// </summary>
 339:          public static string Semicolon
 340:          {
 341:              get
 342:              {
 343:                  return ";";
 344:              }
 345:          }
 346:   
 347:          ////////////////////////////////////////////////////////////////////////////
 348:   
 349:          /// <summary>
 350:          ///
 351:          /// </summary>
 352:          public static string EmsKeepAliveCommand
 353:          {
 354:              get
 355:              {
 356:                  return PrepareCtaggedCommand("SHAKEHAND:::{ctag}::;");
 357:              }
 358:          }
 359:   
 360:          ////////////////////////////////////////////////////////////////////////////
 361:   
 362:          /// <summary>
 363:          ///
 364:          /// </summary>
 365:          public static string ProperlySelectedSingleEmsCommandToManageOntNetworkElements
 366:          {
 367:              get
 368:              {
 369:                  string command;
 370:                  List<string> list;
 371:   
 372:                  command = EmsKeepAliveCommand;
 373:   
 374:                  if (emsCommandQueue.Count == 0)
 375:                  {
 376:                      olt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.HuaweiOltList.NextOf(olt);
 377:   
 378:                      list = Ia.Ngn.Cl.Model.Business.Huawei.Ems.EmsCommandsToRetrieveOntAndOntSipInfoWithDefinedFamilyType_EmsCommandsToRetrieveOntForOntsDefinedInNddDocument_EmsCommandsToUpdateAndRetrieveOntAliasWithItsAccessNameList(olt);
 379:   
 380:                      emsCommandQueue = new Queue<string>(list);
 381:                  }
 382:   
 383:                  if (emsCommandQueue.Count > 0) command = emsCommandQueue.Dequeue();
 384:   
 385:                  return command;
 386:              }
 387:          }
 388:   
 389:          ////////////////////////////////////////////////////////////////////////////
 390:   
 391:          /// <summary>
 392:          ///
 393:          /// </summary>
 394:          public static List<string> EmsCommandsToRetriveOntNetworkElementDataByAccessName(string input)
 395:          {
 396:              Ia.Cl.Model.Result result;
 397:              List<string> list;
 398:   
 399:              result = new Ia.Cl.Model.Result();
 400:              list = new List<string>(5);
 401:   
 402:              if (!string.IsNullOrEmpty(input))
 403:              {
 404:                  if (input.Length > 0)
 405:                  {
 406:                      input = input.Trim();
 407:                      input = input.ToUpper();
 408:   
 409:                      if (Ia.Ngn.Cl.Model.Business.Access.AccessNameIsInAValidFormat(input))
 410:                      {
 411:                          if (Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.AccessNameIsWithinAllowedOntList(input, out string accessName))
 412:                          {
 413:                              list = Ia.Ngn.Cl.Model.Business.Huawei.Ems.EmsCommandsToRetrieveSfuOntAndOntSipInfoOrMduOntAndVoipPstnUserAndVagAndBoardForSingleOntsWithDefinedFamilyTypeOrDefinedMduDevAndForItIfThisSingleOntDefinedInNddDocumentList(accessName);
 414:                          }
 415:                          else
 416:                          {
 417:                              result.AddError("EmsCommandsToRetriveOntNetworkElementDataByAccessName(): Error: accessName is not within allowed ONT list. ");
 418:                          }
 419:                      }
 420:                      else
 421:                      {
 422:                          result.AddError("EmsCommandsToRetriveOntNetworkElementDataByAccessName(): Error: accessName is not valid. ");
 423:                      }
 424:                  }
 425:                  else
 426:                  {
 427:                      result.AddError("EmsCommandsToRetriveOntNetworkElementDataByAccessName(): Error: accessName is empty. ");
 428:                  }
 429:              }
 430:              else
 431:              {
 432:                  result.AddError("EmsCommandsToRetriveOntNetworkElementDataByAccessName(): Error: accessName is null or empty. ");
 433:              }
 434:   
 435:              if (list.Count == 0) list.Add(EmsKeepAliveCommand);
 436:   
 437:              return list;
 438:          }
 439:   
 440:          ////////////////////////////////////////////////////////////////////////////
 441:   
 442:          /// <summary>
 443:          ///
 444:          /// </summary>
 445:          public static List<string> EmsCommandsToRetriveOntNetworkElementDataByService(string service)
 446:          {
 447:              Ia.Cl.Model.Result result;
 448:              List<string> list;
 449:   
 450:              result = new Ia.Cl.Model.Result();
 451:              list = new List<string>(5);
 452:   
 453:              if (!string.IsNullOrEmpty(service))
 454:              {
 455:                  service = service.Trim();
 456:                  service = service.ToUpper();
 457:   
 458:                  if (Ia.Ngn.Cl.Model.Business.Service.ServiceHasEightDigitsAndIsWithinAllowedDomainList(service))
 459:                  {
 460:                      list = Ia.Ngn.Cl.Model.Business.Huawei.Ems.EmsCommandsToRetrieveVoipPstnUser(service);
 461:                  }
 462:                  else
 463:                  {
 464:                      result.AddError("EmsCommandsToRetriveOntNetworkElementDataByService(): Error: Service number \"" + service + "\" does not belong to the network.");
 465:                  }
 466:              }
 467:              else
 468:              {
 469:                  result.AddError("EmsCommandsToRetriveOntNetworkElementDataByService(): Error: service is null or empty.");
 470:              }
 471:   
 472:              if (list.Count == 0) list.Add(EmsKeepAliveCommand);
 473:   
 474:              return list;
 475:          }
 476:   
 477:          ////////////////////////////////////////////////////////////////////////////
 478:          ////////////////////////////////////////////////////////////////////////////
 479:   
 480:          /// <summary>
 481:          ///
 482:          /// </summary>
 483:          public static string ReadDevListByDtCommand(string devType)
 484:          {
 485:              string command;
 486:   
 487:              command = FormatEmsDevLstCommand(EmsOpcode.LstDevByDt, devType);
 488:   
 489:              return command;
 490:          }
 491:   
 492:          ////////////////////////////////////////////////////////////////////////////
 493:   
 494:          /// <summary>
 495:          ///
 496:          /// </summary>
 497:          public static string ReadDevListByDevCommand(string dev)
 498:          {
 499:              string command;
 500:   
 501:              command = FormatEmsDevLstCommand(EmsOpcode.LstDevByDev, dev);
 502:   
 503:              return command;
 504:          }
 505:   
 506:          ////////////////////////////////////////////////////////////////////////////
 507:   
 508:          /// <summary>
 509:          ///
 510:          /// </summary>
 511:          public static string SaveDevCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev)
 512:          {
 513:              return FormatEmsDevLstCommand(EmsOpcode.SaveDev, mduDev.Dev);
 514:          }
 515:   
 516:          ////////////////////////////////////////////////////////////////////////////
 517:   
 518:          /// <summary>
 519:          ///
 520:          /// </summary>
 521:          public static string SaveDevCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MsanDev msanDev)
 522:          {
 523:              return FormatEmsDevLstCommand(EmsOpcode.SaveDev, msanDev.Dev);
 524:          }
 525:   
 526:          ////////////////////////////////////////////////////////////////////////////
 527:   
 528:          /// <summary>
 529:          ///
 530:          /// </summary>
 531:          public static string SaveDevCommand(string dev)
 532:          {
 533:              return FormatEmsDevLstCommand(EmsOpcode.SaveDev, dev);
 534:          }
 535:   
 536:          ////////////////////////////////////////////////////////////////////////////
 537:   
 538:          /// <summary>
 539:          ///
 540:          /// </summary>
 541:          public static string ReadBoardListCommand(string dev)
 542:          {
 543:              string command;
 544:   
 545:              command = FormatEmsBoardLstCommand(EmsOpcode.LstBoard, dev);
 546:   
 547:              return command;
 548:          }
 549:   
 550:          ////////////////////////////////////////////////////////////////////////////
 551:   
 552:          /// <summary>
 553:          ///
 554:          /// </summary>
 555:          public static string ReadOntListCommand(int did)
 556:          {
 557:              string command;
 558:   
 559:              command = FormatEmsLstCommand(EmsOpcode.LstOnt, did);
 560:   
 561:              return command;
 562:          }
 563:   
 564:          ////////////////////////////////////////////////////////////////////////////
 565:   
 566:          /// <summary>
 567:          ///
 568:          /// </summary>
 569:          public static string ReadOntCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont)
 570:          {
 571:              string command;
 572:   
 573:              command = FormatEmsLstCommand(EmsOpcode.LstOnt, ont);
 574:   
 575:              return command;
 576:          }
 577:   
 578:          ////////////////////////////////////////////////////////////////////////////
 579:   
 580:          /// <summary>
 581:          ///
 582:          /// </summary>
 583:          public static string UpdateOntFromH248ToSipCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont)
 584:          {
 585:              string command;
 586:   
 587:              command = FormatEmsModCommand(EmsOpcode.ModOntVaprofileAluSipB, ont);
 588:   
 589:              return command;
 590:          }
 591:   
 592:          ////////////////////////////////////////////////////////////////////////////
 593:   
 594:          /// <summary>
 595:          ///
 596:          /// </summary>
 597:          public static string ReadPortListCommand(string dev, int fn, int sn)
 598:          {
 599:              string command;
 600:   
 601:              command = FormatEmsPortLstCommand(EmsOpcode.LstPort, dev, fn, sn);
 602:   
 603:              return command;
 604:          }
 605:   
 606:          ////////////////////////////////////////////////////////////////////////////
 607:          ////////////////////////////////////////////////////////////////////////////
 608:   
 609:          /// <summary>
 610:          ///
 611:          /// </summary>
 612:          public static string CreateOrModifyOntSipInfoCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int telPort)
 613:          {
 614:              string command;
 615:   
 616:              command = FormatEmsCfgOntVainDivCommand(EmsOpcode.CfgOntVainDiv, nddOnt, service, telPort);
 617:   
 618:              return command;
 619:          }
 620:   
 621:          ////////////////////////////////////////////////////////////////////////////
 622:   
 623:          /// <summary>
 624:          ///
 625:          /// </summary>
 626:          public static string ReadOntSipInfoCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt)
 627:          {
 628:              string command;
 629:   
 630:              command = FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, nddOnt);
 631:   
 632:              return command;
 633:          }
 634:   
 635:          ////////////////////////////////////////////////////////////////////////////
 636:   
 637:          /// <summary>
 638:          ///
 639:          /// </summary>
 640:          public static string ReadOntSipInfoCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string ctag)
 641:          {
 642:              string command;
 643:   
 644:              command = FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, nddOnt, ctag);
 645:   
 646:              return command;
 647:          }
 648:   
 649:          ////////////////////////////////////////////////////////////////////////////
 650:   
 651:          /// <summary>
 652:          ///
 653:          /// </summary>
 654:          public static string VacateOntSipInfoCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int telPort)
 655:          {
 656:              string command;
 657:   
 658:              command = FormatEmsCfgOntVainDivCommand(EmsOpcode.CfgOntVainDivVacant, nddOnt, service, telPort);
 659:   
 660:              return command;
 661:          }
 662:   
 663:          ////////////////////////////////////////////////////////////////////////////
 664:   
 665:          /// <summary>
 666:          ///
 667:          /// </summary>
 668:          public static string ResetOntCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt)
 669:          {
 670:              var command = FormatEmsResetCommand(EmsOpcode.ResetOnt, nddOnt);
 671:   
 672:              return command;
 673:          }
 674:   
 675:          ////////////////////////////////////////////////////////////////////////////
 676:   
 677:          /// <summary>
 678:          ///
 679:          /// </summary>
 680:          public static string CreateOrModifyVoipPstnUserCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int sn, int port)
 681:          {
 682:              string command;
 683:   
 684:              if (nddOnt != null)
 685:              {
 686:                  command = FormatEmsVoipPstnUserCommand(EmsOpcode.AddVoipPstnUser, mduDev.Dev, nddOnt.Rack, sn, port, service);
 687:              }
 688:              else command = string.Empty;
 689:   
 690:              return command;
 691:          }
 692:   
 693:          ////////////////////////////////////////////////////////////////////////////
 694:   
 695:          /// <summary>
 696:          ///
 697:          /// </summary>
 698:          public static string CreateOrModifyMsanVoipPstnUserCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MsanDev msanDev, int fn, int sn, int pn, string service)
 699:          {
 700:              string command;
 701:   
 702:              if (msanDev != null)
 703:              {
 704:                  command = FormatEmsVoipPstnUserCommand(EmsOpcode.AddMsanVoipPstnUser, msanDev.Dev, fn, sn, pn, service);
 705:              }
 706:              else command = string.Empty;
 707:   
 708:              return command;
 709:          }
 710:   
 711:          ////////////////////////////////////////////////////////////////////////////
 712:   
 713:          /// <summary>
 714:          ///
 715:          /// </summary>
 716:          public static string ReadVoipPstnUserCommand(string dev, int sn, int pn)
 717:          {
 718:              var command = FormatEmsLstVoipPstnUserCommand(EmsOpcode.LstVoipPstnUser, dev, sn, pn);
 719:   
 720:              return command;
 721:          }
 722:   
 723:          ////////////////////////////////////////////////////////////////////////////
 724:   
 725:          /// <summary>
 726:          ///
 727:          /// </summary>
 728:          public static string DeleteVoipPstnUserCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int sn, int telPort)
 729:          {
 730:              string command;
 731:   
 732:              if (nddOnt != null)
 733:              {
 734:                  command = FormatEmsVoipPstnUserCommand(EmsOpcode.DelVoipPstnUser, mduDev.Dev, nddOnt.Rack, sn, telPort, service);
 735:              }
 736:              else command = string.Empty;
 737:   
 738:              return command;
 739:          }
 740:   
 741:          ////////////////////////////////////////////////////////////////////////////
 742:   
 743:          /// <summary>
 744:          ///
 745:          /// </summary>
 746:          public static string DeleteVoipPstnUserCommand(string dev, int fn, int sn, int pn)
 747:          {
 748:              return FormatEmsVoipPstnUserCommand(EmsOpcode.DelVoipPstnUser, dev, fn, sn, pn, string.Empty);
 749:          }
 750:   
 751:          ////////////////////////////////////////////////////////////////////////////
 752:   
 753:          /// <summary>
 754:          ///
 755:          /// </summary>
 756:          public static string CreateOrModifyVoipPstnAccountCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int sn, int telPort)
 757:          {
 758:              var command = FormatEmsCfgVoipPstnAccountCommand(EmsOpcode.CfgVoipPstnAccount, mduDev.Dev, nddOnt.Pon.PonGroup.Olt.Odf.Router.Vendor, nddOnt.Rack, service, sn, telPort);
 759:   
 760:              return command;
 761:          }
 762:   
 763:          ////////////////////////////////////////////////////////////////////////////
 764:   
 765:          /// <summary>
 766:          ///
 767:          /// </summary>
 768:          public static string ReadVoipPstnAccountCommand(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt)
 769:          {
 770:              string command;
 771:   
 772:              command = null; // FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, nddOnt);
 773:   
 774:              return command;
 775:          }
 776:   
 777:          ////////////////////////////////////////////////////////////////////////////
 778:   
 779:          /// <summary>
 780:          ///
 781:          /// </summary>
 782:          public static string VacateVoipPstnAccountCommand(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt, string service, int sn, int telPort)
 783:          {
 784:              var command = FormatEmsCfgVoipPstnAccountCommand(EmsOpcode.CfgVoipPstnAccountVacant, mduDev.Dev, nddOnt.Pon.PonGroup.Olt.Odf.Router.Vendor, nddOnt.Rack, service, sn, telPort);
 785:   
 786:              return command;
 787:          }
 788:   
 789:          ////////////////////////////////////////////////////////////////////////////
 790:   
 791:          /// <summary>
 792:          ///
 793:          /// </summary>
 794:          public static string VacateVoipPstnAccountCommand(string dev, int fn, int sn, int pn)
 795:          {
 796:              var command = FormatEmsCfgVoipPstnAccountCommand(EmsOpcode.CfgVoipPstnAccountVacant, dev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined, fn, string.Empty, sn, pn);
 797:   
 798:              return command;
 799:          }
 800:   
 801:          ////////////////////////////////////////////////////////////////////////////
 802:          ////////////////////////////////////////////////////////////////////////////
 803:   
 804:          /// <summary>
 805:          ///
 806:          /// </summary>
 807:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, int did)
 808:          {
 809:              return FormatEmsLstCommand(amsOpcode, 0, did, null, string.Empty);
 810:          }
 811:   
 812:          /*
 813:          ////////////////////////////////////////////////////////////////////////////
 814:  
 815:          /// <summary>
 816:          ///
 817:          /// </summary>
 818:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon)
 819:          {
 820:              return FormatEmsLstCommand(amsOpcode, 0, 0, pon, null, string.Empty);
 821:          }
 822:          */
 823:   
 824:          ////////////////////////////////////////////////////////////////////////////
 825:   
 826:          /// <summary>
 827:          ///
 828:          /// </summary>
 829:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont)
 830:          {
 831:              return FormatEmsLstCommand(amsOpcode, 0, 0, ont, string.Empty);
 832:          }
 833:   
 834:          ////////////////////////////////////////////////////////////////////////////
 835:   
 836:          /// <summary>
 837:          ///
 838:          /// </summary>
 839:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont, string ctag)
 840:          {
 841:              return FormatEmsLstCommand(amsOpcode, 0, 0, ont, ctag);
 842:          }
 843:   
 844:          ////////////////////////////////////////////////////////////////////////////
 845:   
 846:          /// <summary>
 847:          ///
 848:          /// </summary>
 849:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont, int telPort)
 850:          {
 851:              return FormatEmsLstCommand(amsOpcode, telPort, 0, ont, string.Empty);
 852:          }
 853:   
 854:          ////////////////////////////////////////////////////////////////////////////
 855:   
 856:          /// <summary>
 857:          ///
 858:          /// </summary>
 859:          private static string FormatEmsLstCommand(EmsOpcode amsOpcode, int telPort, int did, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont, string ctag)
 860:          {
 861:              int sn, pn, ontId;
 862:              string command;
 863:   
 864:              if (amsOpcode == EmsOpcode.LstOnt)
 865:              {
 866:                  if (ont != null)
 867:                  {
 868:                      sn = ont.CardSlot;
 869:                      pn = ont.Port;
 870:                      ontId = ont.InternalNumber;
 871:   
 872:                      //command = "LST-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::;";
 873:                      command = "LST-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::SHOWOPTION=SERIALNUM VAPROF;";
 874:                      //command = "LST-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::SHOWOPTION=SERIALNUM PWD LOID CHECKCODE ALMPROF DEV VLAN PRI IP MASK GATE ROUTEIP ROUTEMASK NEXTHOP SNMPPROF OPTALMPROF VAPROF MACLEARN SRVLEVELPROF HARDWAREVERSION LSTUPTIME LSTDOWNTIME DEVCURRENTTIME VASPROFILESET;";
 875:                  }
 876:                  /*
 877:                  else if (pon != null)
 878:                  {
 879:                      sn = pon.CardSlot;
 880:                      pn = pon.Port;
 881:  
 882:                      command = "LST-ONT::DEV=" + pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ":{ctag}::;";
 883:                  }
 884:                  */
 885:                  else if (did > 0)
 886:                  {
 887:                      command = "LST-ONT::DID=" + did + ":{ctag}::;";
 888:                  }
 889:                  else
 890:                  {
 891:                      command = string.Empty;
 892:                  }
 893:              }
 894:              else if (amsOpcode == EmsOpcode.LstOntSipInfo)
 895:              {
 896:                  if (ont != null)
 897:                  {
 898:                      sn = ont.CardSlot;
 899:                      pn = ont.Port;
 900:                      ontId = ont.InternalNumber;
 901:   
 902:                      command = "LST-ONTSIPINFO::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::;";
 903:                  }
 904:                  /*
 905:                  else if (pon != null)
 906:                  {
 907:                      sn = pon.CardSlot;
 908:                      pn = pon.Port;
 909:  
 910:                      command = "LST-ONTSIPINFO::DEV=" + pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ":{ctag}::;";
 911:                  }
 912:                  */
 913:                  else
 914:                  {
 915:                      command = string.Empty;
 916:                  }
 917:              }
 918:              else if (amsOpcode == EmsOpcode.LstVag)
 919:              {
 920:                  if (did > 0)
 921:                  {
 922:                      command = "LST-VAG::DID=" + did + ",VAGID=0:{ctag}::;";
 923:                  }
 924:                  else
 925:                  {
 926:                      command = string.Empty;
 927:                  }
 928:              }
 929:              else
 930:              {
 931:                  command = string.Empty;
 932:              }
 933:   
 934:              var preparedCtaggedCommand = (string.IsNullOrEmpty(ctag)) ? PrepareCtaggedCommand(command) : PrepareCtaggedCommand(command, ctag);
 935:   
 936:              return preparedCtaggedCommand;
 937:          }
 938:   
 939:          ////////////////////////////////////////////////////////////////////////////
 940:   
 941:          /// <summary>
 942:          ///
 943:          /// </summary>
 944:          private static string FormatEmsLstVoipPstnUserCommand(EmsOpcode amsOpcode, string dev, int sn, int pn)
 945:          {
 946:              return FormatEmsLstVoipPstnUserCommand(amsOpcode, dev, sn, pn, string.Empty);
 947:          }
 948:   
 949:          ////////////////////////////////////////////////////////////////////////////
 950:   
 951:          /// <summary>
 952:          ///
 953:          /// </summary>
 954:          private static string FormatEmsLstVoipPstnUserCommand(EmsOpcode amsOpcode, string service)
 955:          {
 956:              return FormatEmsLstVoipPstnUserCommand(amsOpcode, string.Empty, -1, -1, service);
 957:          }
 958:   
 959:          ////////////////////////////////////////////////////////////////////////////
 960:   
 961:          /// <summary>
 962:          ///
 963:          /// </summary>
 964:          private static string FormatEmsLstVoipPstnUserCommand(EmsOpcode amsOpcode, string dev, int sn, int pn, string service)
 965:          {
 966:              string command;
 967:   
 968:              if (amsOpcode == EmsOpcode.LstVoipPstnUser)
 969:              {
 970:                  if (!string.IsNullOrEmpty(service) && string.IsNullOrEmpty(dev))
 971:                  {
 972:                      // LST-VOIPPSTNUSER::DN=+96524805054:{ctag}::;  // OK MSAN
 973:                      // LST-VOIPPSTNUSER::DN=+96525650644:{ctag}::;  // OK MDU No matching port
 974:                      // LST-VOIPPSTNUSER::DN=96525650644:{ctag}::;  // OK MDU (no + prefix)
 975:                      // LST-VOIPPSTNUSER::DN=+96525442262:{ctag}::;  // OK, NO matching port
 976:   
 977:                      command = "LST-VOIPPSTNUSER::DN=" + service + ":{ctag}::;";
 978:                  }
 979:                  else
 980:                  {
 981:                      // sn = ont.CardSlot; you can not use ont.CardSlot for SN in Huawei MDUs
 982:                      // LST-VOIPPSTNUSER::DEV=MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::;
 983:                      // LST-VOIPPSTNUSER::DEV=ARD_MSAN_Cabinet 1_Frame 0,FN=0,SN=2,PN=0:{ctag}::;
 984:   
 985:                      command = "LST-VOIPPSTNUSER::DEV=" + dev + ",FN=0,SN=" + sn + ",PN=" + pn + ":{ctag}::;";
 986:                  }
 987:              }
 988:              else
 989:              {
 990:                  command = string.Empty;
 991:              }
 992:   
 993:              return PrepareCtaggedCommand(command);
 994:          }
 995:   
 996:          ////////////////////////////////////////////////////////////////////////////
 997:   
 998:          /// <summary>
 999:          ///
        /// </summary>
        private static string FormatEmsDevLstCommand(EmsOpcode amsOpcode, string parameter)
        {
            int devTypeId;
            string command;
 
            if (amsOpcode == EmsOpcode.LstDevByDt)
            {
                devTypeId = Ia.Ngn.Cl.Model.Data.Huawei.Dev.DevTypeToDevTypeIdDictionary[parameter];
 
                if (devTypeId != 0)
                {
                    command = "LST-DEV::DT=" + devTypeId + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else if (amsOpcode == EmsOpcode.LstDevByDev)
            {
                if (!string.IsNullOrEmpty(parameter))
                {
                    command = "LST-DEV::DEV=" + parameter + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else if (amsOpcode == EmsOpcode.LstDevByDevIp)
            {
                if (!string.IsNullOrEmpty(parameter))
                {
                    command = "LST-DEV::DEVIP=" + parameter + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else if (amsOpcode == EmsOpcode.SaveDev)
            {
                // after creating, modifing, or deleted a number in MDU we should save the configuration of device
                if (!string.IsNullOrEmpty(parameter))
                {
                    command = "SAVE-DEV::DEV=" + parameter + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static bool IsASaveDevCommand(string command)
        {
            bool b;
 
            if (!string.IsNullOrEmpty(command))
            {
                b = command.StartsWith("SAVE-DEV:");
            }
            else b = false;
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsBoardLstCommand(EmsOpcode amsOpcode, string dev)
        {
            int fn;
            string command;
 
            fn = 0;
 
            if (amsOpcode == EmsOpcode.LstBoard)
            {
                if (!string.IsNullOrWhiteSpace(dev))
                {
                    command = "LST-BOARD::DEV=" + dev + ",FN=" + fn + ":{ctag}::SHOWOPTION=BNAME;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsPortLstCommand(EmsOpcode amsOpcode, string dev, int fn, int sn)
        {
            string command;
 
            if (amsOpcode == EmsOpcode.LstPort)
            {
                if (!string.IsNullOrWhiteSpace(dev))
                {
                    command = "LST-PORT::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsModCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont)
        {
            int sn, pn, ontId;
            string command;
 
            if (ont != null)
            {
                if (amsOpcode == EmsOpcode.ModOntAlias)
                {
                    // MOD-ONT::DEV=OLT-JHB-SAA-01,FN=0,SN=1,PN=1,ONTID=20:{ctag}::ALIAS=SAA.502.20;
                    sn = ont.CardSlot;
                    pn = ont.Port;
                    ontId = ont.InternalNumber;
 
                    command = "MOD-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::ALIAS=" + ont.Access.Name + ";";
                }
                else if (amsOpcode == EmsOpcode.ModOntAliasAnnul)
                {
                    // MOD-ONT::DEV=OLT-JHB-SAA-01,FN=0,SN=1,PN=1,ONTID=20:{ctag}::ALIAS=;
                    sn = ont.CardSlot;
                    pn = ont.Port;
                    ontId = ont.InternalNumber;
 
                    command = "MOD-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::ALIAS=;";
                }
                else if (amsOpcode == EmsOpcode.ModOntVaprofileAluSipB)
                {
                    // MOD-ONT::DEV=OLT-ALU,FN=0,SN=1,PN=0,ONTID=2:{ctag}::VAPROFILE=ALU-SIP-B-MS;
                    sn = ont.CardSlot;
                    pn = ont.Port;
                    ontId = ont.InternalNumber;
 
                    command = "MOD-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::VAPROFILE=ALU-SIP-B-MS;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsCfgOntVainDivCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont, string service, int telPort)
        {
            string command, aid, impiOrPrividUser, sipSubscriberRegistrationPassword, emsEmpty;
 
            /*
CFG-ONTVAINDIV::DEV=OLT_01,FN=0,SN=1,PN=0,ONTID=2,SIPUSERNAME_2=+96524674071,SIPUSERPWD_2=admin,SIPNAME_2=+96524674071@ims.moc.kw:{ctag}::;
   7340032 2017-12-20 17:26:33
M  {ctag} COMPLD
   EN=0   ENDESC=Succeeded.
;
CFG-ONTVAINDIV::DEV=OLT-QRN-FUN-01,FN=0,SN=1,PN=1,ONTID=20,SIPUSERNAME_2=+96524674071,SIPUSERPWD_2=admin,SIPNAME_2=+96524674071@ims.moc.kw:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-QRN-FUN-01,FN=0,SN=1,PN=1,ONTID=20,SIPUSERNAME_2=a2,SIPUSERPWD_2=admin,SIPNAME_2=a2@ims.moc.kw:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-QRN-FUN-01,FN=0,SN=1,PN=1,ONTID=20,SIPUSERNAME_3=a3,SIPUSERPWD_3=admin,SIPNAME_3=a2@ims.moc.kw:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-QRN-FUN-01,FN=0,SN=1,PN=1,ONTID=20,SIPUSERNAME_4=a4,SIPUSERPWD_4=admin,SIPNAME_4=a2@ims.moc.kw:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-JHB-JBA-01,FN=0,SN=1,PN=0,ONTID=2,SIPUSERNAME_1=--,SIPUSERPWD_1=--,SIPNAME_1=--:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-JHB-JBA-01,FN=0,SN=1,PN=0,ONTID=2,SIPUSERNAME_2=--,SIPUSERPWD_2=--,SIPNAME_2=--:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-JHB-JBA-01,FN=0,SN=1,PN=0,ONTID=2,SIPUSERNAME_3=--,SIPUSERPWD_3=--,SIPNAME_3=--:{ctag}::;
CFG-ONTVAINDIV::DEV=OLT-JHB-JBA-01,FN=0,SN=1,PN=0,ONTID=2,SIPUSERNAME_4=--,SIPUSERPWD_4=--,SIPNAME_4=--:{ctag}::;
*/
 
            aid = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.ImpuAid(service); //"+965" + service
 
            // send priv_96525212254 for Nokia switch and +96524602283@ims.moc.kw for Huawei switch
            if (ont.Pon.PonGroup.Olt.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei)
            {
                impiOrPrividUser = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.Impi(service);
                sipSubscriberRegistrationPassword = Ia.Ngn.Cl.Model.Business.Huawei.Ims.SipSubscriberRegistrationPassword;
            }
            else //if(ont.Pon.PonGroup.Olt.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia)
            {
                impiOrPrividUser = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.PrividUser(service);
                sipSubscriberRegistrationPassword = Ia.Ngn.Cl.Model.Business.Nokia.Ims.SipSubscriberRegistrationPassword;
            }
 
            if (ont != null)
            {
                if (amsOpcode == EmsOpcode.CfgOntVainDiv)
                {
                    command = @"CFG-ONTVAINDIV::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=" + ont.Rack + ",SN=" + ont.CardSlot + ",PN=" + ont.Port + ",ONTID=" + ont.InternalNumber + ",SIPUSERNAME_" + telPort + "=" + aid + ",SIPUSERPWD_" + telPort + "=" + sipSubscriberRegistrationPassword + ",SIPNAME_" + telPort + "=" + impiOrPrividUser + ":{ctag}::;";
                }
                else if (amsOpcode == EmsOpcode.CfgOntVainDivVacant)
                {
                    emsEmpty = "--"; // this means vacant
                    // also SIPUSERPWD_n is "--"
                    command = @"CFG-ONTVAINDIV::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=" + ont.Rack + ",SN=" + ont.CardSlot + ",PN=" + ont.Port + ",ONTID=" + ont.InternalNumber + ",SIPUSERNAME_" + telPort + "=" + emsEmpty + ",SIPUSERPWD_" + telPort + "=" + emsEmpty + ",SIPNAME_" + telPort + "=" + emsEmpty + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsCfgVoipPstnAccountCommand(EmsOpcode amsOpcode, string dev, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor, int fn, string service, int sn, int pn)
        {
            string command, aid, impiOrPrividUser, sipSubscriberRegistrationPassword, emsEmpty;
 
            /*
CFG-VOIPPSTNACCOUNT::DEV= MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::BINDINDEX=0,UserName=priv_96524602285,Password=1234;
CFG-VOIPPSTNACCOUNT::DEV= MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::BINDINDEX=0,UserName=--,Password=--;
*/
 
            if (amsOpcode == EmsOpcode.CfgVoipPstnAccount)
            {
                aid = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.ImpuAid(service); //"+965" + service for reference only
 
                // send priv_96525212254 for Nokia switch and +96524602283@ims.moc.kw for Huawei switch
                if (vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei)
                {
                    impiOrPrividUser = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.Impi(service);
                    sipSubscriberRegistrationPassword = Ia.Ngn.Cl.Model.Business.Huawei.Ims.SipSubscriberRegistrationPassword;
                }
                else if (vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia)
                {
                    impiOrPrividUser = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.PrividUser(service);
                    sipSubscriberRegistrationPassword = Ia.Ngn.Cl.Model.Business.Nokia.Ims.SipSubscriberRegistrationPassword;
                }
                else
                {
                    throw new ArgumentOutOfRangeException("amsOpcode undefined");
                }
 
                // CFG-VOIPPSTNACCOUNT::DEV= MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::BINDINDEX=0,UserName= priv_96524602285,Password=1234;
                command = @"CFG-VOIPPSTNACCOUNT::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ",PN=" + pn + ":{ctag}::BINDINDEX=0,UserName=" + impiOrPrividUser + ",Password=" + sipSubscriberRegistrationPassword + ";";
            }
            else if (amsOpcode == EmsOpcode.CfgVoipPstnAccountVacant)
            {
                emsEmpty = "--"; // this means vacant
                                 // also UserName is "--"
                command = @"CFG-VOIPPSTNACCOUNT::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ",PN=" + pn + ":{ctag}::BINDINDEX=0,UserName=" + emsEmpty + ",Password=" + emsEmpty + ";";
            }
            else command = string.Empty;
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsVoipPstnUserCommand(EmsOpcode amsOpcode, string dev, int fn, int sn, int pn, string service)
        {
            string command;
 
            /*
            Add new SIP number on MDU:
            ADD-VOIPPSTNUSER::DEV=MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::MGID=0,DN=96524602285;
            Delete SIP number from MDU:
            DEL-VOIPPSTNUSER::DEV=MDU-JBA-943-002,FN=0,SN=3,PN=10:7::;
            */
 
            if (amsOpcode == EmsOpcode.AddVoipPstnUser)
            {
                var serviceWithCountryCode = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.ServiceWithCountryCode(service);
 
                // ADD-VOIPPSTNUSER::DEV=MDU-MA5616-TEST-S,FN=0,SN=4,PN=1:{ctag}::MGID=0,DN=96524674072;
                // ADD-VOIPPSTNUSER::DEV=MDU-JBA-943-002,FN=0,SN=3,PN=10:{ctag}::MGID=0,DN=96524602285;
                command = @"ADD-VOIPPSTNUSER::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ",PN=" + pn + ":{ctag}::MGID=0,DN=" + serviceWithCountryCode + ";";
            }
            else if (amsOpcode == EmsOpcode.AddMsanVoipPstnUser)
            {
                var dn = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.Aid(service);
 
                // ADD-VOIPPSTNUSER::DEV=JHR_MSAN_Cabinet 0_Frame 0,FN=0,SN=3,PN=10:{ctag}::MGID=0,DN=+96524602285;
                command = @"ADD-VOIPPSTNUSER::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ",PN=" + pn + ":{ctag}::MGID=0,DN=" + dn + ";";
            }
            else if (amsOpcode == EmsOpcode.DelVoipPstnUser)
            {
                // DEL-VOIPPSTNUSER::DEV=MDU-MA5616-TEST-S,FN=0,SN=4,PN=1:7::;
                // PN IS TELPORT for MDU
                command = @"DEL-VOIPPSTNUSER::DEV=" + dev + ",FN=" + fn + ",SN=" + sn + ",PN=" + pn + ":{ctag}::;";
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static string FormatEmsResetCommand(EmsOpcode amsOpcode, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont)
        {
            string command;
 
            /*
             * Reset ONT
             * RESET-ONT::DEV=OLT-KHP-KHP-A3-01,FN=0,SN=4,PN=1,ONTID=14:{ctag}::;
            */
 
            if (ont != null)
            {
                if (amsOpcode == EmsOpcode.ResetOnt)
                {
                    var sn = ont.CardSlot;
                    var pn = ont.Port;
                    var ontId = ont.InternalNumber;
 
                    command = "RESET-ONT::DEV=" + ont.Pon.PonGroup.Olt.EmsName + ",FN=0,SN=" + sn + ",PN=" + pn + ",ONTID=" + ontId + ":{ctag}::;";
                }
                else
                {
                    command = string.Empty;
                }
            }
            else
            {
                command = string.Empty;
            }
 
            return PrepareCtaggedCommand(command);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return a bool indicator as to weather the command is a CFG "slow" command
        /// </summary>
        public static bool IsACfgCommand(string command)
        {
            bool b;
            string s;
 
            if (!string.IsNullOrEmpty(command))
            {
                s = command.ToLower();
                b = s.Contains("cfg-ontvaindiv") || s.Contains("cfg-voippstnaccount");
            }
            else b = false;
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static void EmsNameAndCardPortOntSquenceFromOntPosition(string ontPosition, out string amsName, out string pon)
        {
            Match match;
 
            if (!string.IsNullOrEmpty(ontPosition))
            {
                // SUR-1-1-1-1-1;
                match = Regex.Match(ontPosition, @"([a-zA-Z]{3}\-\d{1,2}\-\d{1,2})\-(\d{1,2}\-\d{1,2}\-\d{1,2})");
 
                amsName = match.Groups[1].Value;
                pon = match.Groups[2].Value;
            }
            else
            {
                amsName = string.Empty;
                pon = string.Empty;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> EmsCommandsToRetrieveSfuOntAndOntSipInfoOrMduOntAndVoipPstnUserAndVagAndBoardForSingleOntsWithDefinedFamilyTypeOrDefinedMduDevAndForItIfThisSingleOntDefinedInNddDocumentList(string accessName)
        {
            List<string> list;
 
            list = EmsCommandsToRetrieveSfuOntAndOntSipInfoOrMduOntAndVoipPstnUserAndVagAndBoardForSingleOntsWithDefinedFamilyTypeOrDefinedMduDevList(accessName);
 
            if (list.Count == 0) list = EmsCommandToRetrieveSingleOntDefinedInNddDocumentList(accessName);
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> EmsCommandsToRetrieveVoipPstnUser(string service)
        {
            var list = EmsCommandsToRetrieveVoipPstnUserForMduAndMsan(service);
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandsToRetrieveVoipPstnUserForMduAndMsan(string service)
        {
            List<string> list;
 
            list = new List<string>();
 
            if (!string.IsNullOrEmpty(service))
            {
                // for MDUs numbers will look like 96524805054
                // for MSAN numbers will look like +96524805054
 
                var serviceWithCountryCode = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.ServiceWithCountryCode(service);
                var impuAid = Ia.Ngn.Cl.Model.Business.NumberFormatConverter.ImpuAid(service);
 
                list.Add(FormatEmsLstVoipPstnUserCommand(EmsOpcode.LstVoipPstnUser, serviceWithCountryCode));
                list.Add(FormatEmsLstVoipPstnUserCommand(EmsOpcode.LstVoipPstnUser, impuAid));
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> EmsCommandsToRetrieveOntAndOntSipInfoWithDefinedFamilyType_EmsCommandsToRetrieveOntForOntsDefinedInNddDocument_EmsCommandsToUpdateAndRetrieveOntAliasWithItsAccessNameList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt)
        {
            HashSet<string> hashSet1, hashSet2, hashSet3, hashSet;
 
            //hashSet1 = new HashSet<string>(EmsCommandsToRetrieveOntForOntsDefinedInNddDocumentList(olt)); takes too long
            hashSet1 = new HashSet<string>(EmsCommandsToRetrieveOntForOntsWithAccessList(olt));
 
            hashSet2 = new HashSet<string>(EmsCommandsToRetrieveOntAndOntSipInfoWithDefinedFamilyTypeList(olt));
 
            hashSet3 = new HashSet<string>(); // EmsCommandsToUpdateAndRetrieveOntAliasWithItsAccessNameList(olt);
 
            hashSet = new HashSet<string>(hashSet1);
            hashSet.UnionWith(hashSet2);
            hashSet.UnionWith(hashSet3);
 
            return hashSet.Shuffle().ToList();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> EmsCommandsToUpdateAndRetrieveOntAliasWithItsAccessNameList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt)
        {
            string accessName, ontId, ontAlias;
            List<string> list;
            Dictionary<string, string> ontAccessIdToOntAccessNameDictionary;
            Hashtable ontIdWithNullAccessHashtable;
            //Ia.Ngn.Cl.Model.Business.Nokia.Ont.FamilyType familyType;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
            //List<Ia.Ngn.Cl.Model.Ont> ontList;
            Dictionary<string, string> ontIdToAliasForNonNullAccessDictionary;
            Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> ontIdToOntDictionary;
            list = null;
 
            ontAccessIdToOntAccessNameDictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntAccessNameDictionary;
 
            ontIdToAliasForNonNullAccessDictionary = Ia.Ngn.Cl.Model.Data.Huawei.Ont.IdToAliasForNonNullAccessDictionary;
 
            ontIdWithNullAccessHashtable = Ia.Ngn.Cl.Model.Data.Huawei.Ont.IdWithNullAccessHashtable;
 
            ontIdToOntDictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIdToOntDictionary;
 
            using (var db = new Ia.Ngn.Cl.Model.Ngn())
            {
                list = new List<string>();
 
                //ontList = (from o in db.Onts where o.Access != null select o).ToList();
 
                // insert descriptions for missing entries
                if (ontIdToAliasForNonNullAccessDictionary.Count > 0)
                {
                    foreach (KeyValuePair<string, string> kvp in ontIdToAliasForNonNullAccessDictionary) //Ia.Ngn.Cl.Model.Ont ont in ontList)
                    {
                        ontId = kvp.Key;
                        ontAlias = kvp.Value;
 
                        if (ontAccessIdToOntAccessNameDictionary.ContainsKey(ontId))
                        {
                            accessName = ontAccessIdToOntAccessNameDictionary[ontId];
 
                            if (ontAlias != accessName)
                            {
                                // below: too slow needs to be changed
                                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntById(ontId);
 
                                if (nddOnt.Pon.PonGroup.Olt.Id == olt.Id)
                                {
                                    //familyType = (Ia.Ngn.Cl.Model.Business.Nokia.Ont.FamilyType)ont.FamilyTypeId;
 
                                    list.Add(Ia.Ngn.Cl.Model.Business.Huawei.Ems.FormatEmsModCommand(EmsOpcode.ModOntAlias, nddOnt));
                                }
                            }
                            else
                            {
                            }
                        }
                    }
                }
 
                // delete descriptions ONTs with missing access info
                if (ontIdWithNullAccessHashtable.Count > 0)
                {
                    foreach (string _ontId in ontIdWithNullAccessHashtable.Keys)
                    {
                        if (ontIdToOntDictionary.ContainsKey(_ontId))
                        {
                            nddOnt = ontIdToOntDictionary[_ontId];
 
                            if (nddOnt.Pon.PonGroup.Olt.Id == olt.Id)
                            {
                                list.Add(Ia.Ngn.Cl.Model.Business.Huawei.Ems.FormatEmsModCommand(EmsOpcode.ModOntAliasAnnul, nddOnt));
                            }
                        }
                    }
                }
            }
 
            return list.ToList();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandToRetrieveSingleOntDefinedInNddDocumentList(string accessName)
        {
            List<string> list;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
 
            list = new List<string>();
 
            if (!string.IsNullOrEmpty(accessName))
            {
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntByAccessName(accessName);
 
                if (nddOnt != null)
                {
                    list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, nddOnt));
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandsToRetrieveOntForOntsDefinedInNddDocumentList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt)
        {
            List<string> list;
 
            list = new List<string>();
 
            if (olt != null)
            {
                foreach (Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup ponGroup in olt.PonGroupList)
                {
                    foreach (Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon in ponGroup.PonList)
                    {
                        foreach (Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont in pon.OntList)
                        {
                            list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, ont));
                        }
                    }
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandsToRetrieveOntForOntsWithAccessList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt)
        {
            List<string> list;
            List<Ia.Ngn.Cl.Model.Access> accessList;
 
            list = new List<string>();
 
            if (olt != null)
            {
                accessList = Ia.Ngn.Cl.Model.Data.Access.List(olt);
 
                var ontAccessIdToOntDictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntDictionary;
 
                foreach (var access in accessList)
                {
                    list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, ontAccessIdToOntDictionary[access.Id]));
 
                    list.Add(FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, ontAccessIdToOntDictionary[access.Id]));
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandsToRetrieveSfuOntAndOntSipInfoOrMduOntAndVoipPstnUserAndVagAndBoardForSingleOntsWithDefinedFamilyTypeOrDefinedMduDevList(string accessName)
        {
            Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mduDev;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
            Ia.Ngn.Cl.Model.Huawei.EmsOnt ont;
            List<string> list, possibleMduNameList;
 
            list = new List<string>();
 
            if (!string.IsNullOrEmpty(accessName))
            {
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntByAccessName(accessName);
 
                if (nddOnt != null)
                {
                    var accessNameToMduDevDictionary = Ia.Ngn.Cl.Model.Data.Huawei.Default.AccessNameToMduDevDictionary;
 
                    if (accessNameToMduDevDictionary.ContainsKey(nddOnt.Access.Name))
                    {
                        mduDev = accessNameToMduDevDictionary[nddOnt.Access.Name];
 
                        list.Add(FormatEmsDevLstCommand(EmsOpcode.LstDevByDev, mduDev.Dev));
 
                        list.Add(FormatEmsBoardLstCommand(EmsOpcode.LstBoard, mduDev.Dev));
 
                        list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, nddOnt));
 
                        list.Add(FormatEmsLstCommand(EmsOpcode.LstVag, mduDev.Did));
 
                        foreach (var fsSnPn in mduDev.PossibleFnSnPnPortList)
                        {
                            list.Add(FormatEmsLstVoipPstnUserCommand(EmsOpcode.LstVoipPstnUser, mduDev.Dev, fsSnPn.Sn, fsSnPn.Pn));
                        }
                    }
                    else
                    {
                        ont = Ia.Ngn.Cl.Model.Data.Huawei.Ont.Read(nddOnt.Id);
 
                        if (ont != null)
                        {
                            if (ont.FamilyType == Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Mdu)
                            {
                                possibleMduNameList = Ia.Ngn.Cl.Model.Business.Huawei.Ems.ConstructPossibleMduNameListFromNddOntAccessName(nddOnt);
 
                                foreach (string s in possibleMduNameList)
                                {
                                    list.Add(FormatEmsDevLstCommand(EmsOpcode.LstDevByDev, s));
 
                                    //list.Add(FormatEmsLstCommand(EmsOpcode.LstVag, mduDev.Did));
 
                                    list.Add(FormatEmsBoardLstCommand(EmsOpcode.LstBoard, s));
                                }
 
                                list.Add(FormatEmsDevLstCommand(EmsOpcode.LstDevByDevIp, ont.IP));
                                // see EmsOnt with Name = 10.133.57.6, and select * from EmsOnts where EQUIPMENTID = '5878'
                            }
                            else
                            {
                                list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, nddOnt));
 
                                list.Add(FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, nddOnt));
                            }
                        }
                    }
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<string> EmsCommandsToRetrieveOntAndOntSipInfoWithDefinedFamilyTypeList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt)
        {
            int did;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
            List<string> list;
            List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> nddOntList;
            List<Ia.Ngn.Cl.Model.Huawei.EmsOnt> ontList;
 
            list = new List<string>();
 
            if (olt != null)
            {
                did = olt.Did;
 
                if (did != 0)
                {
                    ontList = Ia.Ngn.Cl.Model.Data.Huawei.Ont.ListByDid(did);
                    nddOntList = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList where o.Pon.PonGroup.Olt == olt select o).ToList();
 
                    if (ontList != null && ontList.Count > 0 && nddOntList != null && nddOntList.Count > 0)
                    {
                        list = new List<string>(ontList.Count);
 
                        foreach (var ont in ontList)
                        {
                            if (ont.Access != null)
                            {
                                nddOnt = (from o in nddOntList where o.Id == ont.Id select o).SingleOrDefault();
 
                                if (nddOnt != null)
                                {
                                    list.Add(FormatEmsLstCommand(EmsOpcode.LstOnt, nddOnt));
 
                                    list.Add(FormatEmsLstCommand(EmsOpcode.LstOntSipInfo, nddOnt));
                                }
                                else
                                {
 
                                }
                            }
                        }
                    }
                    else
                    {
 
                    }
                }
                else
                {
 
                }
            }
            else
            {
 
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort> PossibleFnSnPnForMduDevList(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mdu)
        {
            int count, port;
            List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort> list;
 
            list = new List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort>();
 
            if (mdu != null)
            {
                port = 1;
 
                /* 1 is the port starting point according to service request service position
                 * 
                 * All Nokia ONTs (SFUs and MDUs) start at port position 1
                 * Huawei ONTs (SFUs) start at port position 1, while Huawei MDUs start at port position 0
                 * All positions in the Customer Department database will start at position 1 (e.g. port 3 in a Huawei MDU is 4 in the Customer Department database)
                 */
 
                foreach (var mduDevBoard in mdu.MduDevBoardList)
                {
                    count = mduDevBoard.TelPortCount;
 
                    for (int pn = 0; pn < count; pn++)
                    {
                        list.Add(new Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort(mduDevBoard.Fn, mduDevBoard.Sn, pn, port++));
                    }
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort FirstFnSnPnForMduDevList(Ia.Ngn.Cl.Model.Business.Huawei.Dev.MduDev mdu)
        {
            return Ia.Ngn.Cl.Model.Business.Huawei.Ems.PossibleFnSnPnForMduDevList(mdu).First();
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort> PossibleFnSnPnForMsanDevList()
        {
            var list = new List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort>();
 
            foreach (var fn in Ia.Ngn.Cl.Model.Business.Huawei.Ems.PossibleFnForMsanDevList)
            {
                foreach (var sn in Ia.Ngn.Cl.Model.Business.Huawei.Ems.PossibleSnForMsanDevList)
                {
                    foreach (var pn in Ia.Ngn.Cl.Model.Business.Huawei.Ems.PossiblePnForMsanDevList)
                    {
                        list.Add(new Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort(fn, sn, pn, Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown));
                    }
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort FirstFnSnPnForMsanDevList()
        {
            return Ia.Ngn.Cl.Model.Business.Huawei.Ems.PossibleFnSnPnForMsanDevList().First();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static List<int> PossibleFnForMsanDevList
        {
            get
            {
                return new List<int>() { 0 };
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static List<int> PossibleSnForMsanDevList
        {
            get
            {
                // these are there EmsDev.BT is PSTN
                return new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18 };
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static List<int> PossiblePnForMsanDevList
        {
            get
            {
                var list = new List<int>();
 
                for (int pn = 0; pn <= 63; pn++) list.Add(pn);
 
                return list;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /*
        ////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Return the ONT family type from the software version
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType FamilyType(string activeSoftware, string plannedSoftware)
        {
            Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType familyType;
            if (activeSoftware != null)
            {
                if (activeSoftware == plannedSoftware)
                {
                    if (activeSoftware.Contains("3FE508")) familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Sfu;
                    else if (activeSoftware.Contains("3FE511")) familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Soho;
                    else if (activeSoftware.Contains("3FE514")) familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Mdu;
                    else familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Undefined;
                }
                else familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Undefined;
            }
            else familyType = Ia.Ngn.Cl.Model.Business.Huawei.Ont.FamilyType.Undefined;
            return familyType;
        }
        */
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Cl.Model.Result UpdateDatabaseWithEmsCommandOutput(string rowData, ref Ia.Ngn.Cl.Model.Client.Huawei.Ems ems, out string systemIsBusyResponseCommand, out string ontLoadingCommandIsBeingExecutedNowResponseCommand)
        {
            string updatedService;
 
            var isUpdated = false;
            var result = new Ia.Cl.Model.Result();
 
            updatedService = string.Empty;
 
            // below: remove all '\' characters from rowData and reset NULL comments to ""
            rowData = rowData.Replace(@"\", "");
            rowData = rowData.Replace(@"NULL", "");
 
            var response = Ia.Ngn.Cl.Model.Business.Huawei.Ems.ParseResponse(rowData);
 
            // don't use if (response.QueryCommand) because if resource did not exist it will set Query command to false
 
            if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LST-DEV:"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Dev.Update(response, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("SAVE-DEV:"))
            {
                result.AddSuccess("SAVE-DEV (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LST-BOARD:"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Board.Update(response, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LST-PORT:"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Port.Update(response, out result);
            }
 
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith(@"LST-ONT::DEV="))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Ont.Update(response, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith(@"LST-ONT::DID="))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Ont.UpdateListWithDid(response, out result);
            }
 
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LST-ONTSIPINFO:"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.OntSipInfo.Update(response, out updatedService, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("CFG-ONTVAINDIV:"))
            {
                result.AddSuccess("CFG-ONTVAINDIV (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
 
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith(@"LST-VOIPPSTNUSER::DEV"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.VoipPstnUser.Update(response, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith(@"LST-VOIPPSTNUSER::DN"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.VoipPstnUser.UpdateByDn(response, out updatedService, out result);
            }
 
 
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("ADD-VOIPPSTNUSER:"))
            {
                result.AddSuccess("ADD-VOIPPSTNUSER (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("DEL-VOIPPSTNUSER:"))
            {
                result.AddSuccess("DEL-VOIPPSTNUSER (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("CFG-VOIPPSTNACCOUNT:"))
            {
                result.AddSuccess("CFG-VOIPPSTNACCOUNT (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LST-VAG:"))
            {
                isUpdated = Ia.Ngn.Cl.Model.Data.Huawei.Vag.Update(response, out result);
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("MOD-ONT:"))
            {
                result.AddSuccess("MOD-ONT (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("RESET-ONT:"))
            {
                result.AddSuccess("RESET-ONT (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("SHAKEHAND:"))
            {
                result.AddSuccess("SHAKEHAND (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LOGIN:"))
            {
                ems.IsLoggedIn = true;
 
                result.AddSuccess("LOGIN (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else if (response.CommandFromCorrelationTagDictionaryByCtag.StartsWith("LOGOUT:"))
            {
                ems.IsLoggedIn = false;
 
                result.AddSuccess("LOGOUT (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
            else
            {
                result.AddError("UpdateDatabaseWithEmsCommandOutput(): No designated opcode to process: (" + response.Ctag + "): " + response.CompletionCode + ", " + response.ResultCode.ToString());
            }
 
            if (response.ResultCode == Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.SystemIsBusy1 || response.ResultCode == Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.SystemIsBusy2) systemIsBusyResponseCommand = Ia.Ngn.Cl.Model.Business.Huawei.Ems.PrepareCtaggedCommand(response.CommandFromCorrelationTagDictionaryByCtag);
            else systemIsBusyResponseCommand = string.Empty;
 
            if (response.ResultCode == Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.OntLoadingCommandIsBeingExecutedNow) ontLoadingCommandIsBeingExecutedNowResponseCommand = Ia.Ngn.Cl.Model.Business.Huawei.Ems.PrepareCtaggedCommand(response.CommandFromCorrelationTagDictionaryByCtag);
            else ontLoadingCommandIsBeingExecutedNowResponseCommand = string.Empty;
 
            if (isUpdated)
            {
                Ia.Ngn.Cl.Model.Data.Msmq.SecretaryApplication.Updated(Ia.Ngn.Cl.Model.Business.Msmq.Application.NceApplication, updatedService);
            }
 
            return result;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Parse the NCE TL1 NBI response by approximatly following the "10.3 Response Format Description standard" in iManager NCE Unified Network Management System Guide.
        /// </summary>
        public static Response ParseResponse(string rowData)
        {
            bool attributeFirstGroupFlag;
            int blockTag, currentBlockCount, totalCount;
            long en;
            string header, responseIdentification, textBlock, endesc, terminator, quotedLine, result, title, attributeValueStringList, ctag, completionCode;
            DataTable dataTable;
            MatchCollection matchCollection;
            Ia.Ngn.Cl.Model.Business.Huawei.Ems.Response response;
            List<string> attributeList;
            List<List<string>> valueListList;
            Dictionary<string, string> attributeValueDictionary;
 
            blockTag = currentBlockCount = totalCount = 0;
 
            title = string.Empty;
            en = 0;
            endesc = string.Empty;
            ctag = string.Empty;
            completionCode = string.Empty;
 
            response = new Response();
 
            attributeList = new List<string>(100);
            valueListList = new List<List<string>>(100);
            attributeValueDictionary = new Dictionary<string, string>(100);
 
            // iManager_NCE_V200R014C60_TL1_NBI_User_Guide_13 document has header start with \r\n\n but there are issues with this I removed it
            matchCollection = Regex.Matches(rowData, @"(   \d+? \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(\r\nM  [\S]+? [\w\d]+?)(\r\n   EN=.+?   ENDESC=.+?)(\r\n[;>])", RegexOptions.Singleline);
            //                                         header                                     response identification   text block                  terminator
 
            foreach (Match match in matchCollection)
            {
                header = match.Groups[1].Value;
                responseIdentification = match.Groups[2].Value;
                textBlock = match.Groups[3].Value;
                terminator = match.Groups[4].Value;
 
                if (!string.IsNullOrEmpty(responseIdentification))
                {
                    matchCollection = Regex.Matches(responseIdentification, @"^\r\nM  ([\S]+?) ([\w\d]+?)$", RegexOptions.Singleline);
 
                    foreach (Match match9 in matchCollection)
                    {
                        ctag = match9.Groups[1].Value;
                        completionCode = match9.Groups[2].Value;
 
                        if (!string.IsNullOrEmpty(textBlock))
                        {
                            matchCollection = Regex.Matches(textBlock, @"^\r\n   EN=(.+?)   ENDESC=(.+?)\r\n   (.+?\r\n)$", RegexOptions.Singleline); // if you do (.+?)$ you will not match the last \n
 
                            if (matchCollection.Count > 0)
                            {
                                foreach (Match match2 in matchCollection)
                                {
                                    en = long.Parse(match2.Groups[1].Value);
                                    endesc = match2.Groups[2].Value;
                                    quotedLine = match2.Groups[3].Value;
 
                                    if (!string.IsNullOrEmpty(quotedLine))
                                    {
                                        response.QueryCommand = true;
 
                                        matchCollection = Regex.Matches(quotedLine, @"^blktag=(.+?)\r\n   blkcount=(.+?)\r\n   blktotal=(.+?)\r\n(.+?\r\n)$", RegexOptions.Singleline); // if you do (.+?)$ you will not match the last \n
 
                                        foreach (Match match3 in matchCollection)
                                        {
                                            blockTag = int.Parse(match3.Groups[1].Value);
                                            currentBlockCount = int.Parse(match3.Groups[2].Value);
                                            totalCount = int.Parse(match3.Groups[3].Value);
 
                                            result = match3.Groups[4].Value;
 
                                            if (!string.IsNullOrEmpty(result))
                                            {
                                                matchCollection = Regex.Matches(result, @"^\r\n(.+?)\r\n-*\r\n(.+?\r\n)-*(\r\n)+$", RegexOptions.Singleline);
 
                                                foreach (Match match4 in matchCollection)
                                                {
                                                    title = match4.Groups[1].Value;
 
                                                    attributeValueStringList = match4.Groups[2].Value;
 
                                                    if (!string.IsNullOrEmpty(attributeValueStringList))
                                                    {
                                                        matchCollection = Regex.Matches(attributeValueStringList, @"(.+?)\r\n", RegexOptions.Singleline);
 
                                                        attributeFirstGroupFlag = true;
 
                                                        foreach (Match match5 in matchCollection)
                                                        {
                                                            if (attributeFirstGroupFlag)
                                                            {
                                                                attributeList = new List<string>(Regex.Split(match5.Groups[1].Value, @"\t"));
 
                                                                attributeFirstGroupFlag = false;
                                                            }
                                                            else valueListList.Add(new List<string>(Regex.Split(match5.Groups[1].Value, @"\t")));
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        response.QueryCommand = false;
                                    }
                                }
                            }
                            else
                            {
                                matchCollection = Regex.Matches(textBlock, @"^\r\n   EN=(.+?)   ENDESC=(.+?)$", RegexOptions.Singleline); // if you do (.+?)$ you will not match the last \n
 
                                foreach (Match match6 in matchCollection)
                                {
                                    en = long.Parse(match6.Groups[1].Value);
                                    endesc = match6.Groups[2].Value;
                                }
                            }
                        }
                    }
                }
            }
 
            // build datatable
 
            dataTable = new DataTable();
            dataTable.Clear();
 
            if (attributeList.Count > 0)
            {
                foreach (string attribute in attributeList) dataTable.Columns.Add(attribute);
 
                if (valueListList.Count > 0)
                {
                    if (attributeList.Count == valueListList[0].Count)
                    {
                        foreach (List<string> valuelist in valueListList)
                        {
                            dataTable.Rows.Add(valuelist.ToArray());
                        }
                    }
                    else
                    {
                        throw new Exception("ParseResponse(): attributeList.Count != valueListList[0].Count. attributeList: " + string.Join(",", attributeList) + "; valueListList: " + string.Join(",", valueListList));
                    }
                }
            }
            else dataTable = null;
 
            response.BlockTag = blockTag;
            response.CurrentBlockCount = currentBlockCount;
            response.TotalCount = totalCount;
 
            if (System.Enum.IsDefined(typeof(Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode), en))
            {
                response.ResultCode = (Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode)en;
            }
            else response.ResultCode = Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.Unknown;
 
            response.Title = title;
            response.En = en;
            response.Endesc = endesc;
            response.Ctag = ctag;
            response.CompletionCode = completionCode;
            response.QueryDataTable = dataTable;
 
            return response;
        }
 
        ////////////////////////////////////////////////////////////////////////////    
        ////////////////////////////////////////////////////////////////////////////    
    }
 
    ////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////   
}