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

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:

Optical Fiber Network's Operations Support System Management Intranet (OFN OSS) client support class for Huawei's Optical Fiber Network (OFN) EMS client model.

   1:  using Dart.PowerTCP.Telnet;
   2:  using System;
   3:  using System.Collections.Generic;
   4:  using System.Diagnostics;
   5:   
   6:  namespace Ia.Ngn.Cl.Model.Client.Huawei
   7:  {
   8:      ////////////////////////////////////////////////////////////////////////////
   9:   
  10:      /// <summary publish="true">
  11:      /// Optical Fiber Network's Operations Support System Management Intranet (OFN OSS) client support class for Huawei's Optical Fiber Network (OFN) EMS client model.
  12:      /// </summary>
  13:      /// 
  14:      /// <remarks> 
  15:      /// Copyright © 2017-2022 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
  16:      ///
  17:      /// 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
  18:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  19:      ///
  20:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  21:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  22:      /// 
  23:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  24:      /// 
  25:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  26:      /// </remarks> 
  27:      public class Ems
  28:      {
  29:          private bool isLoggedIn;
  30:   
  31:          // interactive Telnet does not require a very large buffer, so 1024 is fine
  32:          private readonly byte[] buffer = new byte[1024];
  33:          private string receiveString;
  34:          internal Telnet telnet;
  35:   
  36:          /// <summary/>
  37:          public static int WaitAfterSendInMillisecond { get { return 4000; } }
  38:   
  39:          public static int WaitAfterSendForCfgCommandInMillisecond { get { return 10000; } }
  40:   
  41:          public string LastSentCommand { get; private set; }
  42:   
  43:          public Queue<string> ReceiveQueue { get; set; }
  44:   
  45:          public Queue<string> SendQueue { get; set; }
  46:   
  47:          public Queue<string> SystemIsBusyResendQueue { get; set; }
  48:   
  49:          public Queue<string> OntLoadingCommandIsBeingExecutedNowResendQueue { get; set; }
  50:   
  51:          public Dictionary<string, DateTime> OntSipInfoCommandAgainAfterNSecondsToDateTimeDictionary { get; set; }
  52:   
  53:          public Queue<string> OntSipInfoCommandAgainAfterNSecondsResendQueue { get; set; }
  54:   
  55:          ////////////////////////////////////////////////////////////////////////////
  56:   
  57:          /// <summary>
  58:          /// 
  59:          /// </summary>
  60:          public enum ResultCode : long
  61:          {
  62:              // I'm basically using the almost exact document phrasing of error codes
  63:              Unknown = -1,
  64:              Succeeded = 0,
  65:              DeviceDoesNotExist1 = 2686058531,
  66:              DeviceDoesNotExist2 = 15658136501,
  67:              ResourceDoesNotExist = 2686058552,
  68:              OntIsNotOnline = 2689012370,
  69:              CommunicatingWithDmFailed = 2686058603,
  70:              OntIsOffline = 2689014724,
  71:              OntLoadingCommandIsBeingExecutedNow = 2689014933,
  72:              SystemIsBusy1 = 2686058516,
  73:              SystemIsBusy2 = 2689017157,
  74:              AttempetingTimeout = 2686058596,
  75:              CommandSyntaxError = 2686058497,
  76:              UnknownCommand = 2686058499,
  77:              TaskTimeout = 2686058508,
  78:              ValueOfParameterIsWrong = 2686058500,
  79:              DbaProfileDoesNotExist1 = 102690820,
  80:              DbaProfileDoesNotExist2 = 2689014791,
  81:              NodeParameterSetFailed = 1615069195,
  82:              VersionDoesNotMatchOrCommunicationWithDeviceFailed = 1615462437,
  83:              FailedToCommunicateWithDevice1 = 1610614842,
  84:              FailedToCommunicateWithDevice2 = 1616445483,
  85:              FailedToCommunicateWithDevice3 = 1616445484,
  86:              FailedToCommunicateWithDevice4 = 1616445485,
  87:              LoginAddressIsNotInUserAcl = 76546022,
  88:              LoginAddressIsNotInSystemAcl = 76546023,
  89:              DeviceOfflineError = 1610612765,
  90:              OperationIsNotSupported = 2689008176,
  91:              ParametersConflictWithVasProfile = 1615069206,
  92:              ProfileAlreadyExists = 2689023090,
  93:              TrafficProfileDoesNotExist = 2689020327,
  94:              MgParameterIsConflicting = 2688880284,
  95:              NoOnuTypeIsSetInGeneralProfile = 1618280538,
  96:              OntIsUsedByOthers = 1618214927,
  97:              UserDoesNotLogIn = 2686058521,
  98:              PortDoesNotExist = 2689015666,
  99:              TelephoneNumberAlreadyExists = 2689015764,
 100:              ThePasswordHasExpiredOrNeedsToBeChangedOnNextLogin = 1618280766,
 101:              TheUserAccountIsLocked = 76546024,
 102:              TheOntDoesNotSuppportConfigeringValueAddedServiceWithoutBindingGeneralVasProfile = 1615069214,
 103:              NoMatchingPortPleaseCheckTheDataSetting = 2686059269,
 104:              AnInstanceUnknownToTheAgentIsDesignated = 2689007637,
 105:              ThePortIsNotConfiguredMgUserData = 2689015732,
 106:              PortHasBeenConfiguredWithUserData = 2689015744,
 107:              TheCpeIsNotExistent = 161503642,
 108:              TheVersionIsNotConfigurable = 1615069190,
 109:          }
 110:   
 111:          ////////////////////////////////////////////////////////////////////////////
 112:   
 113:          /// <summary>
 114:          ///
 115:          /// </summary>
 116:          public static string ResultCodeString(long _resultCode)
 117:          {
 118:              // see: ColoredResultCodeString()
 119:              string resultCodeString;
 120:              Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode resultCode;
 121:   
 122:              resultCode = (Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode)_resultCode;
 123:   
 124:              resultCodeString = resultCode.ToString();
 125:              resultCodeString = Ia.Cl.Model.Default.CamelToProperCase(resultCodeString);
 126:              resultCodeString = Ia.Cl.Model.Default.ToTitleCase(resultCodeString);
 127:              resultCodeString = resultCodeString.Replace("Ont", "ONT");
 128:   
 129:              return resultCodeString;
 130:          }
 131:   
 132:          ////////////////////////////////////////////////////////////////////////////
 133:   
 134:          /// <summary>
 135:          ///
 136:          /// </summary>
 137:          public static string ColoredResultCodeString(long _resultCode)
 138:          {
 139:              // see: ResultCodeString()
 140:              string resultCodeString, coloredResultCodeString;
 141:              Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode resultCode;
 142:   
 143:              resultCode = (Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode)_resultCode;
 144:   
 145:              resultCodeString = resultCode.ToString();
 146:              resultCodeString = Ia.Cl.Model.Default.CamelToProperCase(resultCodeString);
 147:              resultCodeString = Ia.Cl.Model.Default.ToTitleCase(resultCodeString);
 148:              resultCodeString = resultCodeString.Replace("Ont", "ONT");
 149:   
 150:              switch (resultCode)
 151:              {
 152:                  case Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.Succeeded: coloredResultCodeString = "<span style=\"color:Green\">" + resultCodeString + "</span>"; break;
 153:                  case Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.SystemIsBusy2: coloredResultCodeString = "<span style=\"color:MediumPurple\">" + resultCodeString + "</span>"; break;
 154:                  case Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.OntIsOffline: coloredResultCodeString = "<span style=\"color:OrangeRed\">" + resultCodeString + "</span>"; break;
 155:                  case Ia.Ngn.Cl.Model.Client.Huawei.Ems.ResultCode.DeviceOfflineError: coloredResultCodeString = "<span style=\"color:Red\">" + resultCodeString + "</span>"; break;
 156:                  default: coloredResultCodeString = "<span style=\"color:Blue\">" + resultCodeString + "</span>"; break;
 157:              }
 158:   
 159:              return coloredResultCodeString;
 160:          }
 161:   
 162:          ////////////////////////////////////////////////////////////////////////////
 163:   
 164:          /// <summary>
 165:          ///
 166:          /// </summary>
 167:          public Ems()
 168:          {
 169:              this.telnet = new Dart.PowerTCP.Telnet.Telnet(); // this.components);
 170:   
 171:              this.telnet.ClientOptions.AddRange(new Dart.PowerTCP.Telnet.Option[] {
 172:              new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn),
 173:              new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.WindowSize, new byte[] {((byte)(0)),((byte)(80)),((byte)(0)),((byte)(24))}, Dart.PowerTCP.Telnet.OptionState.RequestOn),
 174:              new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.TerminalType, new byte[] {((byte)(0)),((byte)(120)),((byte)(116)),((byte)(101)),((byte)(114)),((byte)(109))}, Dart.PowerTCP.Telnet.OptionState.RequestOn)});
 175:   
 176:              this.telnet.ServerOptions.AddRange(new Dart.PowerTCP.Telnet.Option[] {
 177:              new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn),
 178:              new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.Echo, null, Dart.PowerTCP.Telnet.OptionState.RequestOn)});
 179:   
 180:              //this.telnet.SynchronizingObject = this;
 181:              this.telnet.TerminalType = "xterm";
 182:              //this.telnet.WindowSize = new System.Drawing.Size(80, 24);
 183:              this.telnet.EndReceive += new Dart.PowerTCP.Telnet.SegmentEventHandler(this.Telnet_EndReceive);
 184:              this.telnet.ConnectedChangedEx += new Dart.PowerTCP.Telnet.EventHandlerEx(this.Telnet_ConnectedChangedEx);
 185:   
 186:              receiveString = string.Empty;
 187:   
 188:              ReceiveQueue = new Queue<string>();
 189:              SendQueue = new Queue<string>();
 190:              SystemIsBusyResendQueue = new Queue<string>();
 191:              OntLoadingCommandIsBeingExecutedNowResendQueue = new Queue<string>();
 192:   
 193:              OntSipInfoCommandAgainAfterNSecondsToDateTimeDictionary = new Dictionary<string, DateTime>();
 194:              OntSipInfoCommandAgainAfterNSecondsResendQueue = new Queue<string>();
 195:   
 196:              isLoggedIn = false;
 197:          }
 198:   
 199:          ////////////////////////////////////////////////////////////////////////////
 200:   
 201:          /// <summary>
 202:          ///
 203:          /// </summary>
 204:          ~Ems()
 205:          {
 206:              Dispose();
 207:          }
 208:   
 209:          ////////////////////////////////////////////////////////////////////////////
 210:   
 211:          /// <summary>
 212:          ///
 213:          /// </summary>
 214:          public void Connect(out Ia.Cl.Model.Result result)
 215:          {
 216:              result = new Ia.Cl.Model.Result();
 217:   
 218:              try
 219:              {
 220:                  telnet.ClientOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
 221:                  telnet.ClientOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.TerminalType, new System.Byte[] { ((System.Byte)(0)), ((System.Byte)(116)), ((System.Byte)(116)), ((System.Byte)(121)) }, Dart.PowerTCP.Telnet.OptionState.RequestOn));
 222:                  telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
 223:                  telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.Echo, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
 224:                  telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.OutputPageSize, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
 225:   
 226:                  telnet.Connect(Ia.Ngn.Cl.Model.Business.Huawei.Ems.Host, Ia.Ngn.Cl.Model.Business.Huawei.Ems.Port.ToString());
 227:   
 228:                  // receive using asynchronous technique
 229:                  telnet.ReceiveTimeout = 0;
 230:                  telnet.BeginReceive(buffer);
 231:   
 232:                  result.AddSuccess("Connected. ");
 233:              }
 234:              catch (Exception ex)
 235:              {
 236:                  result.AddError("Exception: " + ex.Message);
 237:   
 238:                  telnet.Close();
 239:              }
 240:          }
 241:   
 242:          ////////////////////////////////////////////////////////////////////////////
 243:   
 244:          /// <summary>
 245:          ///
 246:          /// </summary>
 247:          public void Disconnect(out Ia.Cl.Model.Result result)
 248:          {
 249:              result = new Ia.Cl.Model.Result();
 250:   
 251:              try
 252:              {
 253:                  telnet.Close();
 254:   
 255:                  result.AddSuccess("Disconnected. ");
 256:              }
 257:              catch (Exception ex)
 258:              {
 259:                  result.AddError(ex.Message);
 260:              }
 261:          }
 262:   
 263:          ////////////////////////////////////////////////////////////////////////////
 264:   
 265:          /// <summary>
 266:          ///
 267:          /// </summary>
 268:          public bool IsConnected
 269:          {
 270:              get
 271:              {
 272:                  return telnet.Connected;
 273:              }
 274:          }
 275:   
 276:          ////////////////////////////////////////////////////////////////////////////
 277:   
 278:          /// <summary>
 279:          ///
 280:          /// </summary>
 281:          public bool IsLoggedIn { get { return isLoggedIn; } set { isLoggedIn = value; } }
 282:   
 283:          ////////////////////////////////////////////////////////////////////////////
 284:   
 285:          /// <summary>
 286:          ///
 287:          /// </summary>
 288:          public void Dispose()
 289:          {
 290:              telnet.Dispose();
 291:          }
 292:   
 293:          ////////////////////////////////////////////////////////////////////////////
 294:   
 295:          /// <summary>
 296:          ///
 297:          /// </summary>
 298:          public void Login()
 299:          {
 300:              // sendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Ems.Semicolon); did not make any different
 301:   
 302:              // below: I need this because NCE somehow needs to be triggered before I send login information
 303:              SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Ems.EmsKeepAliveCommand);
 304:              SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Ems.EmsKeepAliveCommand);
 305:   
 306:              SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Ems.LoginUser);
 307:          }
 308:   
 309:          ////////////////////////////////////////////////////////////////////////////
 310:   
 311:          /// <summary>
 312:          ///
 313:          /// </summary>
 314:          public void Logout()
 315:          {
 316:              SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Ems.LogoutUser);
 317:          }
 318:   
 319:          ////////////////////////////////////////////////////////////////////////////
 320:   
 321:          /// <summary>
 322:          ///
 323:          /// </summary>
 324:          public void Send(string text, bool skipSleep, out Ia.Cl.Model.Result result)
 325:          {
 326:              result = new Ia.Cl.Model.Result();
 327:   
 328:              try
 329:              {
 330:                  if (telnet.Connected)
 331:                  {
 332:                      if (text != null)
 333:                      {
 334:                          LastSentCommand = text;
 335:   
 336:                          //this.textBox.AppendText("\r\n/* Sending: " + text + " */\r\n");
 337:   
 338:                          telnet.Send(text);
 339:   
 340:                          result.AddSuccess("Sent: [" + text + "]");
 341:                      }
 342:                      else
 343:                      {
 344:                          result.AddError("No text to send.");
 345:                      }
 346:                  }
 347:                  else
 348:                  {
 349:                      result.AddError("No established telnet connection.");
 350:                      //if(processRunning) waitToConnectionCounter = waitToConnectionCounterSeconds;
 351:                  }
 352:              }
 353:              catch (Exception ex)
 354:              {
 355:                  //if(processRunning) waitToConnectionCounter = waitToConnectionCounterSeconds;
 356:   
 357:                  result.AddError(ex.Message);
 358:              }
 359:   
 360:              if (!skipSleep)
 361:              {
 362:                  // this is meant to give the Telnet_EndReceive() time to receive and process data from session
 363:                  // we will wait according to the type of commands send
 364:   
 365:                  if (Ia.Ngn.Cl.Model.Business.Huawei.Ems.IsACfgCommand(LastSentCommand))
 366:                  {
 367:                      System.Threading.Thread.Sleep(Ia.Ngn.Cl.Model.Client.Huawei.Ems.WaitAfterSendForCfgCommandInMillisecond);
 368:                  }
 369:                  else
 370:                  {
 371:                      System.Threading.Thread.Sleep(Ia.Ngn.Cl.Model.Client.Huawei.Ems.WaitAfterSendInMillisecond);
 372:                  }
 373:              }
 374:          }
 375:   
 376:          ////////////////////////////////////////////////////////////////////////////
 377:   
 378:          /// <summary>
 379:          ///
 380:          /// </summary>
 381:          private void Telnet_EndReceive(object sender, Dart.PowerTCP.Telnet.SegmentEventArgs e)
 382:          {
 383:              string message, entry;
 384:              string[] receiveStringSplit;
 385:   
 386:              Debug.WriteLine(" ");
 387:              Debug.WriteLine("============================================");
 388:   
 389:              if (e.Exception == null)
 390:              {
 391:                  receiveString += e.Segment.ToString();
 392:   
 393:                  Debug.WriteLine("Telnet_EndReceive(): e.Segment: [" + e.Segment.ToString() + "], receiveString: [" + receiveString + "]");
 394:   
 395:                  if (!string.IsNullOrEmpty(receiveString))
 396:                  {
 397:                      receiveStringSplit = receiveString.Split(new string[] { "\r\n;" }, StringSplitOptions.None);
 398:   
 399:                      if (receiveStringSplit.Length > 0)
 400:                      {
 401:                          for (int i = 0; i < receiveStringSplit.Length; i++)
 402:                          {
 403:                              entry = receiveStringSplit[i];
 404:   
 405:                              if (!string.IsNullOrEmpty(entry) && !string.IsNullOrWhiteSpace(entry))
 406:                              {
 407:                                  // will not enqueue an empty entry
 408:   
 409:                                  if (i == receiveStringSplit.Length - 1)
 410:                                  {
 411:                                      // if there is a non empty last entry that means its incomplete and we will assign it to receiveString
 412:   
 413:                                      receiveString = entry;
 414:                                  }
 415:                                  else
 416:                                  {
 417:                                      message = entry + "\r\n;"; // important
 418:   
 419:                                      if (!ReceiveQueue.Contains(message))
 420:                                      {
 421:                                          // will not enqueue duplicate
 422:   
 423:                                          ReceiveQueue.Enqueue(message);
 424:   
 425:                                          Debug.WriteLine("Telnet_EndReceive(): ReceiveQueue.Enqueue(message): [" + message + "]");
 426:                                      }
 427:   
 428:                                      receiveString = string.Empty;
 429:                                  }
 430:                              }
 431:                          }
 432:                      }
 433:   
 434:                      Debug.WriteLine("Telnet_EndReceive(): receiveString: [" + receiveString + "]");
 435:                  }
 436:                  else
 437:                  {
 438:   
 439:                  }
 440:   
 441:                  if (telnet.Connected) telnet.BeginReceive(buffer);
 442:              }
 443:              else
 444:              {
 445:                  Debug.WriteLine("Telnet_EndReceive(): Exception: " + e.Exception.Message);
 446:   
 447:                  // I will not throw or handle the exception from the event handler
 448:                  // https://stackoverflow.com/questions/3114543/should-event-handlers-in-c-sharp-ever-raise-exceptions
 449:                  //throw new Exception("Telnet_EndReceive(): " + e.Exception.Message);
 450:              }
 451:   
 452:              Debug.WriteLine("============================================");
 453:              Debug.WriteLine(" ");
 454:          }
 455:   
 456:          ////////////////////////////////////////////////////////////////////////////
 457:   
 458:          /// <summary>
 459:          ///
 460:          /// </summary>
 461:          private void Telnet_ConnectedChangedEx(object sender, System.EventArgs e)
 462:          {
 463:              // always raised when Connection is established or closed (Connected property changes)
 464:   
 465:              //UpdateToolStripStatusLabel();
 466:          }
 467:   
 468:          ////////////////////////////////////////////////////////////////////////////
 469:   
 470:          /// <summary>
 471:          ///
 472:          /// </summary>
 473:          public Ia.Cl.Model.Result Update(string rowData, ref Ia.Ngn.Cl.Model.Client.Huawei.Ems ems, out string systemIsBusyResponseCommand, out string ontLoadingCommandIsBeingExecutedNowResponseCommand)
 474:          {
 475:              return Ia.Ngn.Cl.Model.Business.Huawei.Ems.UpdateDatabaseWithEmsCommandOutput(rowData, ref ems, out systemIsBusyResponseCommand, out ontLoadingCommandIsBeingExecutedNowResponseCommand);
 476:          }
 477:   
 478:          ////////////////////////////////////////////////////////////////////////////
 479:          ////////////////////////////////////////////////////////////////////////////
 480:      }
 481:   
 482:      ////////////////////////////////////////////////////////////////////////////
 483:      ////////////////////////////////////////////////////////////////////////////
 484:  }