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: /// Signaling Service Processing System (SPS) support class for Huawei's Optical Fiber Network (OFN) SPS client model.
12: /// </summary>
13: ///
14: /// <remarks>
15: /// Copyright © 2018-2019 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 Sps
28: {
29: private byte[] buffer = new byte[1024];
30: internal Telnet telnet;
31:
32: /// <summary/>
33: public static int WaitAfterSendInMillisecond { get { return 4000; } }
34:
35: /// <summary/>
36: public static int WaitAfterSendForCfgCommandInMillisecond { get { return 10000; } }
37:
38: /// <summary/>
39: public string LastSentCommand { get; private set; }
40:
41: /// <summary/>
42: public Queue<string> ReceiveQueue { get; set; }
43:
44: /// <summary/>
45: public Queue<string> SendQueue { get; set; }
46:
47: ////////////////////////////////////////////////////////////////////////////
48:
49: /// <summary>
50: ///
51: /// </summary>
52: public enum ResultCode
53: {
54: /*
55: * 9 Collection of Error Codes
56: * 9.1 Collection of NP Service Related Error Codes
57: * Error Code Description
58: */
59:
60: OperationIsSuccessful = 0,
61: InvalidCommand = 1001,
62: InvalidParameterValue__Xxx__For__Yyy__ = 1004,
63: ParameterMissing__Yyy__ = 1009,
64: DatabaseOperationFailed = 5000,
65: LackingOfCompulsoryParameters = 5004,
66: SpecifiedRecordNotFound = 5005,
67: UserNumberRepeated = 5526,
68: TheMnpRouteNumberBeingUsedByMnpUserCanNotBeRemoved = 5579,
69: RoutingNumberTypeDoesNotMatchTheMnpUser = 5591,
70: HlrNumberTypeDoesNotMatchTheMnpUser = 5592,
71: InvalidRnIndex = 5593,
72: AtLeastOneOfTheServicesMustBeRegistered = 5594,
73: HlrAddressReferencedByAMnpUserCanNotBeDeleted = 5600,
74: InvalidHlrIndex = 5602,
75: UserImsiNumberCannotBeSameWithExist = 5855,
76: TheNpRoutingIndexGivenDoesNotMatch = 5878,
77: SystemError = 6000,
78: WhenRouteIndexTypeIsSetToRouteNumberIndex_HlrNumberIndexMustBeSetTo65535 = 6015,
79: RnNumberIndexMustBe65535WhenRoutingIndexTypeIsHlrAddressIndex = 6018,
80: TheNumberOfTheCurrentSubscribersImsisReachesTheLimit = 6300,
81: TheCurrentSubscriberUsesMultipleImsis_IfYouWantToChangeAnImsi_RunRmvSeruattrToDeleteThisImsiAndThenRunAddSeruattrToAddAnImsi = 6301,
82: WhenNumberTypeIsSetTo_GsmNumberPortedToCdma_Or_CdmaNumberPortedToGsm__RoutingIndexTypeMustBeSetToAll = 7001,
83: WhenNumberTypeIsSetTo_LocalFixedNetwork__RoutingIndexTypeMustBeSetTo_RouteNumberIndex = 7300,
84: InvalidRoutingNumber = 7369,
85: TheInputParameterNameCanContainOnlyDigits_0_9__LowerCaseLetters_A_z__UpperCaseLetters_A_z__Dot_Hyphens____Underscore____AndSpace___ItCannotBeSetToNull = 40003,
86: TheIndexAlreadyExists = 40004,
87: AnNpSoftwareParameterDataRecordDoesNotExist_RunSetSesoftcfgToSetNpSoftwareParameters = 40011,
88: TheRangeSpecifiedByBeginMsisdnAndEndMsisdnOverlapsWithAnExistingRange = 40022,
89: TheEnteredValuesOfBeginMsisdnAndEndMsisdnHaveDifferentLengths = 40023,
90: TheEnteredValueOfBeginMsisdnIsNotLessThanThatOfEndMsisdn = 40024,
91: ThePossibleCauseMayBeOneOfTheFollowing_TheLinkBetweenTheUscdbAndTheSpsIsFaulty_TheNpRangeSwitchOnTheSpsIsClose = 40025,
92: ThePossibleCauseMayBeOneOfTheFollowing_ThePpid180PublicParameterOfTheSpsIsSetToASmallValue_ThePpid180PublicParameterOfTheSpsIsSetToTheMaximumValue = 40026,
93: TheNumberOfDataRecordsToBeQueriedExceedsTheLimit = 40027,
94: TheDataRecordToBeDeletedDoesNotExist_AsAResult_TheDeletionFails = 40028,
95: HlrAddressReferencedByAMnp_RangeCanNotBeDeleted = 40029,
96: TheMnpRouteNumberBeingUsedByAMnp_RangeCanNotBeRemoved = 40030,
97: TheHlrIndexCannotBeRemovedBecauseItIsUsedByAServiceSubscriberCommandAdapt = 40031,
98: TheMnpRouteNumberCannotBeRemovedBecauseItIsUsedByAServiceSubscriberCommandAdapt = 40032,
99: LackingOfCompulsoryParameters2 = 45004,
100: SpecifiedRecordNotFound2 = 45005,
101: DescriptionInformationRepeated = 45138,
102: RouteNumberAlreadyExists = 45558,
103: InvalidParameterDesc = 40001,
104: TheValueIsInvalid = 41007,
105: NoMatchingResultIsFound = 43257,
106: TheNumberOfNpUserExceedsTheLicensedNumber = 43435,
107: TheNumberOfFnrUserExceedsTheLicensedNumber = 43436,
108: TheLicenseForNpSubscriberDataStorageOnTheSpsHasExpired_ApplyForANewLicense = 43437,
109: TheLicenseForFnrSubscriberDataStorageOnTheSpsHasExpired_ApplyForANewLicense = 43438,
110: EnsureThatLinksBetweenTheUscdbAndTheSpsAreAvailable_TheP69SoftwareParameterForTheSpsIsCorrectlyConfigured_AndNpSubscriberDataStorageLicenseIsPurchased = 43439,
111: EnsureThatLinksBetweenTheUscdbAndTheSpsAreAvailable_TheP69SoftwareParameterForTheSpsIsCorrectlyConfigured_AndFnrSubscriberDataStorageLicenseIsPurchased = 43440,
112: EnsureThatTheNpSubscriberDataStorageLicenseIsPurchased = 43441,
113: EnsureThatTheFnrSubscriberDataStorageLicenseIsPurchased = 43442
114: }
115:
116: ////////////////////////////////////////////////////////////////////////////
117:
118: /// <summary>
119: ///
120: /// </summary>
121: public Sps()
122: {
123: telnet = new Dart.PowerTCP.Telnet.Telnet();
124:
125: telnet.ClientOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
126: //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
127: 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
128:
129: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.SuppressGoAheads, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
130: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.Echo, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
131: telnet.ServerOptions.Add(new Dart.PowerTCP.Telnet.Option(Dart.PowerTCP.Telnet.OptionCode.OutputPageSize, null, Dart.PowerTCP.Telnet.OptionState.RequestOn));
132:
133: //telnet.TerminalType = "tty";
134: telnet.TerminalType = "xterm";
135:
136: telnet.EndReceive += new Dart.PowerTCP.Telnet.SegmentEventHandler(this.Telnet_EndReceive);
137: telnet.ConnectedChangedEx += new Dart.PowerTCP.Telnet.EventHandlerEx(this.Telnet_ConnectedChangedEx);
138:
139: ReceiveQueue = new Queue<string>(100);
140: SendQueue = new Queue<string>(100);
141:
142: IsLoggedIn = false;
143: }
144:
145: ////////////////////////////////////////////////////////////////////////////
146:
147: /// <summary>
148: ///
149: /// </summary>
150: ~Sps()
151: {
152: Dispose();
153: }
154:
155: ////////////////////////////////////////////////////////////////////////////
156:
157: /// <summary>
158: ///
159: /// </summary>
160: public void Connect(out Ia.Cl.Model.Result result)
161: {
162: result = new Ia.Cl.Model.Result();
163:
164: try
165: {
166: telnet.Connect(Ia.Ngn.Cl.Model.Business.Huawei.Sps.Host, Ia.Ngn.Cl.Model.Business.Huawei.Sps.Port.ToString());
167:
168: // receive using asynchronous technique
169: telnet.ReceiveTimeout = 0;
170: telnet.BeginReceive(buffer);
171:
172: result.AddSuccess("Connected. ");
173: }
174: catch (Exception ex)
175: {
176: result.AddError("Exception: " + ex.Message);
177:
178: telnet.Close();
179: }
180: }
181:
182: ////////////////////////////////////////////////////////////////////////////
183:
184: /// <summary>
185: ///
186: /// </summary>
187: public void Disconnect(out Ia.Cl.Model.Result result)
188: {
189: result = new Ia.Cl.Model.Result();
190:
191: try
192: {
193: telnet.Close();
194:
195: result.AddSuccess("Disconnected. ");
196: }
197: catch (Exception ex)
198: {
199: result.AddError(ex.Message);
200: }
201: }
202:
203: ////////////////////////////////////////////////////////////////////////////
204:
205: /// <summary>
206: ///
207: /// </summary>
208: public bool IsConnected
209: {
210: get
211: {
212: return telnet != null && telnet.Connected;
213: }
214: }
215:
216: ////////////////////////////////////////////////////////////////////////////
217:
218: /// <summary>
219: ///
220: /// </summary>
221: public bool IsLoggedIn { get; set; }
222:
223: ////////////////////////////////////////////////////////////////////////////
224:
225: /// <summary>
226: ///
227: /// </summary>
228: public void Dispose()
229: {
230: telnet.Dispose();
231: }
232:
233: ////////////////////////////////////////////////////////////////////////////
234:
235: /// <summary>
236: ///
237: /// </summary>
238: public void Login()
239: {
240: SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Sps.LoginUser);
241: }
242:
243: ////////////////////////////////////////////////////////////////////////////
244:
245: /// <summary>
246: ///
247: /// </summary>
248: public void Logout()
249: {
250: SendQueue.Enqueue(Ia.Ngn.Cl.Model.Business.Huawei.Sps.LogoutUser);
251: }
252:
253: ////////////////////////////////////////////////////////////////////////////
254:
255: /// <summary>
256: ///
257: /// </summary>
258: public void Send(string text, out Ia.Cl.Model.Result result)
259: {
260: result = new Ia.Cl.Model.Result();
261:
262: try
263: {
264: if (telnet.Connected)
265: {
266: if (text != null)
267: {
268: LastSentCommand = text;
269:
270: // below: I have to put ';' before send or it will not run. I do not know why I have to do this
271: text = Ia.Ngn.Cl.Model.Business.Huawei.Sps.SemiColon + text;
272:
273: telnet.Send(text);
274:
275: Debug.WriteLine("Send() sent text: [" + text + "]");
276:
277: result.AddSuccess("Sent: [" + text + "]");
278: }
279: else
280: {
281: result.AddError("No text to send. ");
282: }
283: }
284: else
285: {
286: result.AddError("No established telnet connection. ");
287: //if(processRunning) waitToConnectionCounter = waitToConnectionCounterSeconds;
288: }
289: }
290: catch (Exception ex)
291: {
292: result.AddError(ex.Message);
293: }
294: }
295:
296: ////////////////////////////////////////////////////////////////////////////
297:
298: /// <summary>
299: ///
300: /// </summary>
301: private void Telnet_EndReceive(object sender, Dart.PowerTCP.Telnet.SegmentEventArgs e)
302: {
303: string receiveString;
304:
305: Debug.WriteLine(" ");
306: Debug.WriteLine("============================================");
307:
308: if (e.Exception == null)
309: {
310: Debug.WriteLine("Telnet_EndReceive(): e.Segment: [" + e.Segment.ToString() + "]");
311:
312: receiveString = e.Segment.ToString();
313:
314: if (!string.IsNullOrEmpty(receiveString) && !string.IsNullOrWhiteSpace(receiveString))
315: {
316: ReceiveQueue.Enqueue(receiveString);
317: }
318: else
319: {
320:
321: }
322:
323: if (telnet.Connected) telnet.BeginReceive(buffer);
324: }
325: else
326: {
327: Debug.WriteLine("Telnet_EndReceive(): Exception: " + e.Exception.Message);
328:
329: // I will not throw or handle the exception from the event handler
330: // https://stackoverflow.com/questions/3114543/should-event-handlers-in-c-sharp-ever-raise-exceptions
331: //throw new Exception("Telnet_EndReceive(): " + e.Exception.Message);
332: }
333:
334: Debug.WriteLine("============================================");
335: Debug.WriteLine(" ");
336: }
337:
338: ////////////////////////////////////////////////////////////////////////////
339:
340: /// <summary>
341: ///
342: /// </summary>
343: private void Telnet_ConnectedChangedEx(object sender, System.EventArgs e)
344: {
345:
346: }
347:
348: ////////////////////////////////////////////////////////////////////////////
349:
350: /// <summary>
351: ///
352: /// </summary>
353: public void Update(string rowData, ref Ia.Ngn.Cl.Model.Client.Huawei.Sps sps, out Ia.Cl.Model.Result result)
354: {
355: Ia.Ngn.Cl.Model.Data.Huawei.Sps.UpdateDatabaseWithSpsCommandOutput(rowData, ref sps, out result);
356: }
357:
358: ////////////////////////////////////////////////////////////////////////////
359: ////////////////////////////////////////////////////////////////////////////
360: }
361:
362: ////////////////////////////////////////////////////////////////////////////
363: ////////////////////////////////////////////////////////////////////////////
364: }