1: using Dart.PowerTCP.Telnet;
2: using System;
3: using System.Collections.Generic;
4: using System.Diagnostics;
5: using System.Text.RegularExpressions;
6:
7: namespace Ia.Ngn.Cl.Model.Client.Huawei
8: {
9: ////////////////////////////////////////////////////////////////////////////
10:
11: /// <summary publish="true">
12: /// U2020 Northbound Interface IP (SoftX) support class for Huawei's Optical Fiber Network (OFN) client model.
13: /// </summary>
14: ///
15: /// <remarks>
16: /// Copyright © 2018-2020 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
17: ///
18: /// 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
19: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
20: ///
21: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23: ///
24: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
25: ///
26: /// Copyright notice: This notice may not be removed or altered from any source distribution.
27: /// </remarks>
28: public class SoftX
29: {
30: private byte[] buffer = new byte[1024];
31: private string receiveString;
32: internal Telnet telnet;
33:
34: /// <summary/>
35: public static int WaitAfterSendInMillisecond { get { return 4000; } }
36:
37: /// <summary/>
38: public static int WaitAfterSendForCfgCommandInMillisecond { get { return 10000; } }
39:
40: /// <summary/>
41: public string LastSentCommand { get; private set; }
42:
43: /// <summary/>
44: public Queue<string> ReceiveQueue { get; set; }
45:
46: /// <summary/>
47: public Queue<string> SendQueue { get; set; }
48:
49: ////////////////////////////////////////////////////////////////////////////
50:
51: /// <summary>
52: ///
53: /// </summary>
54: public enum ResultCode
55: {
56: OperationSucceeded = 0,
57: InvalidCommand = 999,
58: InsufficientAuthority = 1515,
59: InformationForThisMgwAlreadyExists = 63029,
60: TheUserDoesNotExist = 96013
61: }
62:
63: ////////////////////////////////////////////////////////////////////////////
64:
65: /// <summary>
66: ///
67: /// </summary>
68: public SoftX()
69: {
70: telnet = new Dart.PowerTCP.Telnet.Telnet();
71:
72: telnet.ClientOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
73: //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)); // tty
74: telnet.ClientOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.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.PowerTCP.Telnet.OptionState.RequestOn)); // xterm
75:
76: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
77: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.Echo, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
78: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.OutputPageSize, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
79:
80: //telnet.TerminalType = "tty";
81: telnet.TerminalType = "xterm";
82:
83: telnet.EndReceive += new Dart.PowerTCP.Telnet.SegmentEventHandler(this.Telnet_EndReceive);
84: telnet.ConnectedChangedEx += new Dart.PowerTCP.Telnet.EventHandlerEx(this.Telnet_ConnectedChangedEx);
85:
86: receiveString = string.Empty;
87: ReceiveQueue = new Queue<string>(100);
88: SendQueue = new Queue<string>(100);
89:
90: IsLoggedIn = false;
91: }
92:
93: ////////////////////////////////////////////////////////////////////////////
94:
95: /// <summary>
96: ///
97: /// </summary>
98: ~SoftX()
99: {
100: Dispose();
101: }
102:
103: ////////////////////////////////////////////////////////////////////////////
104:
105: /// <summary>
106: ///
107: /// </summary>
108: public void Connect(out Ia.Cl.Model.Result result)
109: {
110: result = new Ia.Cl.Model.Result();
111:
112: try
113: {
114: telnet.Connect(Ia.Ngn.Cl.Model.Business.Huawei.SoftX.Host, Ia.Ngn.Cl.Model.Business.Huawei.SoftX.Port.ToString());
115:
116: // receive using asynchronous technique
117: telnet.ReceiveTimeout = 0;
118: telnet.BeginReceive(buffer);
119:
120: result.AddSuccess("Connected. ");
121: }
122: catch (Exception ex)
123: {
124: result.AddError("Exception: " + ex.Message);
125:
126: telnet.Close();
127: }
128: }
129:
130: ////////////////////////////////////////////////////////////////////////////
131:
132: /// <summary>
133: ///
134: /// </summary>
135: public void Disconnect(out Ia.Cl.Model.Result result)
136: {
137: result = new Ia.Cl.Model.Result();
138:
139: try
140: {
141: telnet.Close();
142:
143: result.AddSuccess("Disconnected. ");
144: }
145: catch (Exception ex)
146: {
147: result.AddError(ex.Message);
148: }
149: }
150:
151: ////////////////////////////////////////////////////////////////////////////
152:
153: /// <summary>
154: ///
155: /// </summary>
156: public bool IsConnected
157: {
158: get
159: {
160: return telnet.Connected;
161: }
162: }
163:
164: ////////////////////////////////////////////////////////////////////////////
165:
166: /// <summary>
167: ///
168: /// </summary>
169: public bool IsLoggedIn { get; set; }
170:
171: ////////////////////////////////////////////////////////////////////////////
172:
173: /// <summary>
174: ///
175: /// </summary>
176: public void Dispose()
177: {
178: telnet.Dispose();
179: }
180:
181: ////////////////////////////////////////////////////////////////////////////
182:
183: /// <summary>
184: ///
185: /// </summary>
186: public void Login()
187: {
188: SendQueue.Enqueue("\r\n");
189: SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.SoftX.LoginUser);
190: }
191:
192: ////////////////////////////////////////////////////////////////////////////
193:
194: /// <summary>
195: ///
196: /// </summary>
197: public void Logout()
198: {
199: SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.SoftX.LogoutUser);
200: }
201:
202: ////////////////////////////////////////////////////////////////////////////
203:
204: /// <summary>
205: ///
206: /// </summary>
207: public void Send(string text, out Ia.Cl.Model.Result result)
208: {
209: result = new Ia.Cl.Model.Result();
210:
211: try
212: {
213: if (telnet.Connected)
214: {
215: if (text != null)
216: {
217: LastSentCommand = text;
218:
219: // below: I have to put ';' before send or it will not run. I do not know why I have to do this
220: //text = Ia.Ngn.Cl.Model.Business.Huawei.SoftX.SemiColon + text;
221:
222: telnet.Send(text);
223: telnet.Send("\r\n"); // important
224:
225: Debug.WriteLine("Send() sent text: [" + text + "]");
226:
227: //result.AddSuccess("Sent: [" + text + "]");
228: }
229: else
230: {
231: result.AddError("No text to send. ");
232: }
233: }
234: else
235: {
236: result.AddError("No established telnet connection. ");
237: //if(processRunning) waitToConnectionCounter = waitToConnectionCounterSeconds;
238: }
239: }
240: catch (Exception ex)
241: {
242: result.AddError(ex.Message);
243: }
244: }
245:
246: ////////////////////////////////////////////////////////////////////////////
247:
248: /// <summary>
249: ///
250: /// </summary>
251: private void Telnet_EndReceive(object sender, Dart.PowerTCP.Telnet.SegmentEventArgs e)
252: {
253: string message;//, entry;
254:
255: Debug.WriteLine(" ");
256: Debug.WriteLine("============================================");
257:
258: if (e.Exception == null)
259: {
260: /*
261: Debug.WriteLine("Telnet_EndReceive(): e.Segment: [" + e.Segment.ToString() + "]");
262:
263: receiveString = e.Segment.ToString();
264:
265: if (!string.IsNullOrEmpty(receiveString) && !string.IsNullOrWhiteSpace(receiveString))
266: {
267: ReceiveQueue.Enqueue(receiveString);
268: }
269: else
270: {
271:
272: }
273: */
274:
275: receiveString += e.Segment.ToString();
276:
277: Debug.WriteLine("Telnet_EndReceive(): e.Segment: [" + e.Segment.ToString() + "], receiveString: [" + receiveString + "]");
278:
279: if (!string.IsNullOrEmpty(receiveString) && !string.IsNullOrWhiteSpace(receiveString))
280: {
281: var match = Regex.Match(receiveString, @"\+\+\+(.+?)\-\-\-\s+END", RegexOptions.Singleline);
282:
283: if (match.Success)
284: {
285: message = match.Value;
286:
287: ReceiveQueue.Enqueue(message);
288:
289: receiveString = string.Empty;
290:
291: Debug.WriteLine("Telnet_EndReceive(): ReceiveQueue.Enqueue(message): [" + message + "]");
292: }
293:
294: Debug.WriteLine("Telnet_EndReceive(): receiveString: [" + receiveString + "]");
295: }
296: else
297: {
298:
299: }
300:
301: if (telnet.Connected) telnet.BeginReceive(buffer);
302: }
303: else
304: {
305: Debug.WriteLine("Telnet_EndReceive(): Exception: " + e.Exception.Message);
306:
307: // I will not throw or handle the exception from the event handler
308: // https://stackoverflow.com/questions/3114543/should-event-handlers-in-c-sharp-ever-raise-exceptions
309: //throw new Exception("Telnet_EndReceive(): " + e.Exception.Message);
310: }
311:
312: Debug.WriteLine("============================================");
313: Debug.WriteLine(" ");
314: }
315:
316: ////////////////////////////////////////////////////////////////////////////
317:
318: /// <summary>
319: ///
320: /// </summary>
321: private void Telnet_ConnectedChangedEx(object sender, System.EventArgs e)
322: {
323:
324: }
325:
326: ////////////////////////////////////////////////////////////////////////////
327:
328: /// <summary>
329: ///
330: /// </summary>
331: public void Update(string rowData, ref Ia.Ngn.Cl.Model.Client.Huawei.SoftX softX, out Ia.Cl.Model.Result result)
332: {
333: Ia.Ngn.Cl.Model.Data.Huawei.SoftX.UpdateDatabaseWithSoftXCommandOutput(rowData, ref softX, out result);
334: }
335:
336: ////////////////////////////////////////////////////////////////////////////
337: ////////////////////////////////////////////////////////////////////////////
338: }
339:
340: ////////////////////////////////////////////////////////////////////////////
341: ////////////////////////////////////////////////////////////////////////////
342: }