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

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

U2020 Northbound Interface IP (SoftX) support class for Huawei's Fixed Telecommunications Network (FTN) client model.

    1: using Dart.Telnet;
    2: using System;
    3: using System.Collections.Generic;
    4: using System.Diagnostics;
    5: using System.Security.Cryptography.X509Certificates;
    6: using System.Text.RegularExpressions;
    7:  
    8: namespace Ia.Ftn.Cl.Models.Client.Huawei
    9: {
   10:     ////////////////////////////////////////////////////////////////////////////
   11:  
   12:     /// <summary publish="true">
   13:     /// U2020 Northbound Interface IP (SoftX) support class for Huawei's Fixed Telecommunications Network (FTN) client model.
   14:     /// </summary>
   15:     /// 
   16:     /// <remarks> 
   17:     /// Copyright © 2018-2025 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   18:     /// </remarks> 
   19:     public class SoftX
   20:     {
   21:         private string receiveString;
   22:  
   23:         private byte[] buffer = new byte[1024];
   24:         private TelnetModel telnetModel;
   25:         private Dart.Telnet.Telnet telnet;
   26:         private X509CertificateCollection clientCertificates = new X509CertificateCollection();
   27:         private System.ComponentModel.IContainer components;
   28:  
   29:         /// <summary/>
   30:         public static int WaitAfterSendInMillisecond { get { return 4000; } }
   31:  
   32:         /// <summary/>
   33:         public static int WaitAfterSendForCfgCommandInMillisecond { get { return 10000; } }
   34:  
   35:         /// <summary/>
   36:         public string LastSentCommand { get; private set; }
   37:  
   38:         /// <summary/>
   39:         public Queue<string> ReceiveQueue { get; set; }
   40:  
   41:         /// <summary/>
   42:         public Queue<string> SendQueue { get; set; }
   43:  
   44:         ////////////////////////////////////////////////////////////////////////////
   45:  
   46:         /// <summary>
   47:         ///
   48:         /// </summary>
   49:         public enum ResultCode
   50:         {
   51:             /// <summary/>
   52:             OperationSucceeded = 0,
   53:  
   54:             /// <summary/>
   55:             InvalidCommand = 999,
   56:  
   57:             /// <summary/>
   58:             InsufficientAuthority = 1515,
   59:  
   60:             /// <summary/>
   61:             InformationForThisMgwAlreadyExists = 63029,
   62:  
   63:             /// <summary/>
   64:             TheUserDoesNotExist = 96013
   65:         }
   66:  
   67:         ////////////////////////////////////////////////////////////////////////////
   68:  
   69:         /// <summary>
   70:         ///
   71:         /// </summary>
   72:         public SoftX()
   73:         {
   74:             components = new System.ComponentModel.Container();
   75:  
   76:             Dart.Telnet.Option option1 = new Dart.Telnet.Option();
   77:             Dart.Telnet.Option option2 = new Dart.Telnet.Option();
   78:             Dart.Telnet.Option option3 = new Dart.Telnet.Option();
   79:             Dart.Telnet.Option option4 = new Dart.Telnet.Option();
   80:             Dart.Telnet.Option option5 = new Dart.Telnet.Option();
   81:  
   82:             telnet = new Dart.Telnet.Telnet(components);
   83:  
   84:             option1.Code = Dart.Telnet.OptionCode.SuppressGoAheads;
   85:             option2.Code = Dart.Telnet.OptionCode.WindowSize;
   86:             option2.SubOption = new byte[] { 0, 80, 0, 24 };
   87:             option3.Code = Dart.Telnet.OptionCode.TerminalType;
   88:             option3.SubOption = new byte[] { 0, 116, 116, 121 };
   89:             telnet.ClientOptions.AddRange(new Dart.Telnet.Option[] { option1, option2, option3 });
   90:  
   91:             option4.Code = Dart.Telnet.OptionCode.SuppressGoAheads;
   92:             option5.Code = Dart.Telnet.OptionCode.Echo;
   93:             telnet.ServerOptions.AddRange(new Dart.Telnet.Option[] { option4, option5 });
   94:  
   95:             telnet.SocketOption.ReceiveTimeout = 1000;
   96:             telnet.SynchronizingObject = null;
   97:             telnet.ClientOptionChanged += Telnet_ClientOptionChanged;
   98:             telnet.ServerOptionChanged += Telnet_ServerOptionChanged;
   99:             telnet.Data += Telnet_Data;
  100:             telnet.StateChanged += Telnet_StateChanged;
  101:             telnet.Log += Telnet_Log;
  102:             telnet.Error += Telnet_Error;
  103:  
  104:             telnetModel = new TelnetModel();
  105:  
  106:             // set non-serializable Telnet component
  107:             telnetModel.Telnet = telnet;
  108:             telnetModel.ReceiveLoopRequired = true;
  109:  
  110:             // subscribe to certificate events
  111:             telnetModel.CertificateRequested += new EventHandler<LocalCertificateEventArgs>(TelnetModel_CertificateRequested);
  112:             telnetModel.CertificatePresented += new EventHandler<RemoteCertificateEventArgs>(TelnetModel_CertificatePresented);
  113:             /*
  114:             telnet = new Dart.Telnet.Telnet();
  115: 
  116:             telnet.ClientOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.SuppressGoAheads, null, Dart.Telnet.OptionState.RequestOn));
  117:             //telnet.ClientOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.TerminalType, new System.Byte[] { ((System.Byte)(0)), ((System.Byte)(116)), ((System.Byte)(116)), ((System.Byte)(121)) }, Dart.Telnet.OptionState.RequestOn)); // tty
  118:             telnet.ClientOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.TerminalType, new System.Byte[] { ((System.Byte)(0)), ((System.Byte)(120)), ((System.Byte)(116)), ((System.Byte)(101)), ((System.Byte)(114)), ((System.Byte)(109)) }, Dart.Telnet.OptionState.RequestOn)); // xterm
  119: 
  120:             telnet.ServerOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.SuppressGoAheads, null, Dart.Telnet.OptionState.RequestOn));
  121:             telnet.ServerOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.Echo, null, Dart.Telnet.OptionState.RequestOn));
  122:             telnet.ServerOptions.Add(new Dart.Telnet.Option(Dart.Telnet.OptionCode.OutputPageSize, null, Dart.Telnet.OptionState.RequestOn));
  123:             */
  124:  
  125:             //telnet.TerminalType = "tty";
  126:             //telnet.TerminalType = "xterm";
  127:  
  128:             ////telnet.EndReceive += new Dart.Telnet.SegmentEventHandler(this.Telnet_EndReceive);
  129:             ////telnet.ConnectedChangedEx += new Dart.Telnet.EventHandlerEx(this.Telnet_ConnectedChangedEx);
  130:  
  131:             receiveString = string.Empty;
  132:             ReceiveQueue = new Queue<string>(100);
  133:             SendQueue = new Queue<string>(100);
  134:  
  135:             IsLoggedIn = false;
  136:         }
  137:  
  138:         ////////////////////////////////////////////////////////////////////////////
  139:  
  140:         /// <summary>
  141:         ///
  142:         /// </summary>
  143:         ~SoftX()
  144:         {
  145:             Dispose(true);
  146:         }
  147:  
  148:         ////////////////////////////////////////////////////////////////////////////
  149:  
  150:         /// <summary>
  151:         ///
  152:         /// </summary>
  153:         public Ia.Cl.Models.Result Connect()
  154:         {
  155:             var result = new Ia.Cl.Models.Result();
  156:  
  157:             // if a model with a matching server exists, remove it, then add it so that it is first in the list
  158:             telnetModel.Session.RemoteEndPoint = new IPEndPoint(Ia.Ftn.Cl.Models.Business.Huawei.SoftX.Host, Ia.Ftn.Cl.Models.Business.Huawei.SoftX.Port);
  159:             telnetModel.Credentials.Username = string.Empty; // txtUsername.Text;
  160:             telnetModel.Credentials.Password = string.Empty; // txtPassword.Text;
  161:             telnetModel.Credentials.CommandPrompt = string.Empty; // txtCommandPrompt.Text;
  162:             telnetModel.Credentials.UsernamePrompt = string.Empty; // txtLoginPrompt.Text;
  163:             telnetModel.Credentials.PasswordPrompt = string.Empty; // txtPasswordPrompt.Text;
  164:             telnetModel.SecurityType = SecurityType.None; // (SecurityType)cboSecurity.SelectedIndex;
  165:             telnetModel.SaveSession();
  166:  
  167:             if (telnetModel.Session.RemoteEndPoint.Port == 23)
  168:             {
  169:                 telnetModel.Telnet.ClientOptions.Add(new Option(OptionCode.SuppressGoAheads, null, OptionState.RequestOn));
  170:                 telnetModel.Telnet.ClientOptions.Add(new Option(OptionCode.WindowSize, new System.Byte[] { ((System.Byte)(0)), ((System.Byte)(80)), ((System.Byte)(0)), ((System.Byte)(24)) }, OptionState.RequestOn));
  171:                 telnetModel.Telnet.ClientOptions.Add(new Option(OptionCode.TerminalType, new System.Byte[] { ((System.Byte)(0)), ((System.Byte)(116)), ((System.Byte)(116)), ((System.Byte)(121)) }, OptionState.RequestOn));
  172:  
  173:                 telnetModel.Telnet.ServerOptions.Add(new Option(OptionCode.SuppressGoAheads, null, OptionState.RequestOn));
  174:                 telnetModel.Telnet.ServerOptions.Add(new Option(OptionCode.Echo, null, OptionState.RequestOn));
  175:                 telnetModel.Telnet.ServerOptions.Add(new Option(OptionCode.OutputPageSize, null, OptionState.RequestOn));
  176:             }
  177:             else
  178:             {
  179:                 telnetModel.Telnet.ClientOptions.Clear();
  180:                 telnetModel.Telnet.ServerOptions.Clear();
  181:             }
  182:  
  183:             // connect and receive data on a separate thread
  184:             telnet.Start(telnetModel.Connect, null);
  185:  
  186:             result.AddSuccess("Connected");
  187:  
  188:             return result;
  189:         }
  190:  
  191:         ////////////////////////////////////////////////////////////////////////////
  192:  
  193:         /// <summary>
  194:         ///
  195:         /// </summary>
  196:         public Ia.Cl.Models.Result Disconnect()
  197:         {
  198:             var result = new Ia.Cl.Models.Result();
  199:  
  200:             try
  201:             {
  202:                 telnetModel.Telnet.Close();
  203:  
  204:                 result.AddSuccess("Disconnected");
  205:             }
  206:             catch (Exception ex)
  207:             {
  208:                 result.AddError(ex.Message);
  209:             }
  210:  
  211:             return result;
  212:         }
  213:  
  214:         ////////////////////////////////////////////////////////////////////////////
  215:  
  216:         /// <summary>
  217:         ///
  218:         /// </summary>
  219:         public bool IsConnected
  220:         {
  221:             get
  222:             {
  223:                 return telnetModel.IsConnected;
  224:             }
  225:         }
  226:  
  227:         ////////////////////////////////////////////////////////////////////////////
  228:  
  229:         /// <summary>
  230:         ///
  231:         /// </summary>
  232:         public bool IsLoggedIn { get; set; }
  233:  
  234:         ////////////////////////////////////////////////////////////////////////////
  235:  
  236:         /// <summary>
  237:         ///
  238:         /// </summary>
  239:         protected /*override*/ void Dispose(bool disposing)
  240:         {
  241:             if (disposing)
  242:             {
  243:                 if (components != null)
  244:                 {
  245:                     components.Dispose();
  246:                 }
  247:             }
  248:  
  249:             //base.Dispose(disposing);
  250:         }
  251:  
  252:         ////////////////////////////////////////////////////////////////////////////
  253:  
  254:         /// <summary>
  255:         ///
  256:         /// </summary>
  257:         public void Login()
  258:         {
  259:             SendQueue.Enqueue("\r\n");
  260:             SendQueue.Enqueue(Ia.Ftn.Cl.Models.Business.Huawei.SoftX.LoginUser);
  261:         }
  262:  
  263:         ////////////////////////////////////////////////////////////////////////////
  264:  
  265:         /// <summary>
  266:         ///
  267:         /// </summary>
  268:         public void Logout()
  269:         {
  270:             SendQueue.Enqueue(Ia.Ftn.Cl.Models.Business.Huawei.SoftX.LogoutUser);
  271:         }
  272:  
  273:         ////////////////////////////////////////////////////////////////////////////
  274:  
  275:         /// <summary>
  276:         ///
  277:         /// </summary>
  278:         public Ia.Cl.Models.Result Send(string text)
  279:         {
  280:             var result = new Ia.Cl.Models.Result();
  281:  
  282:             try
  283:             {
  284:                 if (telnetModel.IsConnected)
  285:                 {
  286:                     if (!string.IsNullOrEmpty(text))
  287:                     {
  288:                         LastSentCommand = text;
  289:  
  290:                         // below: I have to put ';' before send or it will not run. I do not know why I have to do this
  291:                         //text = Ia.Ftn.Cl.Model.Business.Huawei.SoftX.SemiColon + text;
  292:  
  293:                         ////telnet.Send(text);
  294:                         telnetModel.WriteData(text + "\r\n"); // I added "\r\n", not sure if it will work with read server
  295:  
  296:                         ////telnet.Send("\r\n"); // important
  297:                         //telnetModel.WriteData("\r\n");
  298:  
  299:                         Debug.WriteLine("Send() sent text: [" + text + "]");
  300:  
  301:                         //result.AddSuccess("Sent: [" + text + "]");
  302:                     }
  303:                     else result.AddError("No text to send");
  304:                 }
  305:                 else
  306:                 {
  307:                     result.AddError("No established telnet connection.");
  308:                     //if(processRunning) waitToConnectionCounter = waitToConnectionCounterSeconds;
  309:                 }
  310:             }
  311:             catch (Exception ex)
  312:             {
  313:                 result.AddError(ex.Message);
  314:             }
  315:  
  316:             return result;
  317:         }
  318:  
  319:         ////////////////////////////////////////////////////////////////////////////
  320:  
  321:         /// <summary>
  322:         ///
  323:         /// </summary>
  324:         private void Telnet_Data(object sender, DataEventArgs e)
  325:         {
  326:             string message;//, entry;
  327:  
  328:             Debug.WriteLine(" ");
  329:             Debug.WriteLine("============================================");
  330:  
  331:             /*
  332:             Debug.WriteLine("Telnet_EndReceive(): e.Segment: [" + e.Segment.ToString() + "]");
  333: 
  334:             receiveString = e.Segment.ToString();
  335: 
  336:             if (!string.IsNullOrEmpty(receiveString) && !string.IsNullOrWhiteSpace(receiveString))
  337:             {
  338:                 ReceiveQueue.Enqueue(receiveString);
  339:             }
  340:             else
  341:             {
  342: 
  343:             }
  344:             */
  345:  
  346:             receiveString += e.Data.ToString();
  347:  
  348:             Debug.WriteLine("Telnet_Data(): e.Segment: [" + e.Data.ToString() + "], receiveString: [" + receiveString + "]");
  349:  
  350:             if (!string.IsNullOrEmpty(receiveString) && !string.IsNullOrWhiteSpace(receiveString))
  351:             {
  352:                 var match = Regex.Match(receiveString, @"\+\+\+(.+?)\-\-\-\s+END", RegexOptions.Singleline);
  353:  
  354:                 if (match.Success)
  355:                 {
  356:                     message = match.Value;
  357:  
  358:                     ReceiveQueue.Enqueue(message);
  359:  
  360:                     receiveString = string.Empty;
  361:  
  362:                     Debug.WriteLine("Telnet_Data(): ReceiveQueue.Enqueue(message): [" + message + "]");
  363:                 }
  364:  
  365:                 Debug.WriteLine("Telnet_Data(): receiveString: [" + receiveString + "]");
  366:             }
  367:             else
  368:             {
  369:  
  370:             }
  371:  
  372:             ////if (telnet.Connected) telnet.BeginReceive(buffer);
  373:  
  374:             Debug.WriteLine("============================================");
  375:             Debug.WriteLine(" ");
  376:         }
  377:  
  378:         ////////////////////////////////////////////////////////////////////////////
  379:  
  380:         /// <summary>
  381:         ///
  382:         /// </summary>
  383:         private void Telnet_StateChanged(object sender, EventArgs e)
  384:         {
  385:             // always raised when connection is established or closed (state property changes)
  386:             switch (telnetModel.Telnet.State)
  387:             {
  388:                 case ConnectionState.Connected:
  389:                 case ConnectionState.ConnectedAndSecure: break;
  390:                 case ConnectionState.Closed: break;
  391:             }
  392:         }
  393:  
  394:         ////////////////////////////////////////////////////////////////////////////
  395:  
  396:         /// <summary>
  397:         ///
  398:         /// </summary>
  399:         private void Telnet_ClientOptionChanged(object sender, OptionEventArgs e)
  400:         {
  401:         }
  402:  
  403:         ////////////////////////////////////////////////////////////////////////////
  404:  
  405:         /// <summary>
  406:         ///
  407:         /// </summary>
  408:         private void Telnet_ServerOptionChanged(object sender, OptionEventArgs e)
  409:         {
  410:         }
  411:  
  412:         ////////////////////////////////////////////////////////////////////////////
  413:  
  414:         /// <summary>
  415:         ///
  416:         /// </summary>
  417:         private void Telnet_Error(object sender, Dart.Telnet.ErrorEventArgs e)
  418:         {
  419:         }
  420:  
  421:         ////////////////////////////////////////////////////////////////////////////
  422:  
  423:         /// <summary>
  424:         ///
  425:         /// </summary>
  426:         private void Telnet_Log(object sender, DataEventArgs e)
  427:         {
  428:             // e.Data;
  429:         }
  430:  
  431:         ////////////////////////////////////////////////////////////////////////////
  432:  
  433:         /// <summary>
  434:         ///
  435:         /// </summary>
  436:         void TelnetModel_CertificateRequested(object sender, LocalCertificateEventArgs e)
  437:         {
  438:         }
  439:  
  440:         ////////////////////////////////////////////////////////////////////////////
  441:  
  442:         /// <summary>
  443:         ///
  444:         /// </summary>
  445:         void TelnetModel_CertificatePresented(object sender, RemoteCertificateEventArgs e)
  446:         {
  447:         }
  448:  
  449:         ////////////////////////////////////////////////////////////////////////////
  450:  
  451:         /// <summary>
  452:         ///
  453:         /// </summary>
  454:         public void Update(string rowData, ref Ia.Ftn.Cl.Models.Client.Huawei.SoftX softX, out Ia.Cl.Models.Result result)
  455:         {
  456:             Ia.Ftn.Cl.Models.Data.Huawei.SoftX.UpdateDatabaseWithSoftXCommandOutput(rowData, ref softX, out result);
  457:         }
  458:  
  459:         ////////////////////////////////////////////////////////////////////////////
  460:         ////////////////////////////////////////////////////////////////////////////
  461:     }
  462:  
  463:     ////////////////////////////////////////////////////////////////////////////
  464:     ////////////////////////////////////////////////////////////////////////////
  465: }