1: using System;
2: using System.Collections.Generic;
3: using System.IO;
4: using System.Linq;
5: using System.Text.RegularExpressions;
6:
7: namespace Ia.Ngn.Cl.Model.Business.Nokia
8: {
9: ////////////////////////////////////////////////////////////////////////////
10:
11: /// <summary publish="true">
12: /// Nokia's Siemens EWSD support class of Next Generation Network'a (NGN's) business model.
13: /// </summary>
14: ///
15: /// <remarks>
16: /// Copyright © 2018-2019 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 SiemensEwsd
29: {
30: private static Queue<int> serviceQueue = new Queue<int>();
31:
32: /// <summary/>
33: public enum Opcode { Dispsub, Cansub }
34:
35: public static List<string> ServiceSymbolList { get; } = new List<string>();
36:
37: ////////////////////////////////////////////////////////////////////////////
38:
39: /// <summary>
40: ///
41: /// </summary>
42: public enum ResultCode
43: {
44: OperationIsSuccessful = 0,
45: OperationFailed = 1,
46: ObjectNotASubscriber = 2,
47: ObjectNotConnected = 3
48: }
49:
50: ////////////////////////////////////////////////////////////////////////////
51:
52: /// <summary>
53: ///
54: /// </summary>
55: public SiemensEwsd() { }
56:
57: ////////////////////////////////////////////////////////////////////////////
58:
59: /// <summary>
60: ///
61: /// </summary>
62: public static int ProperlySelectedSingleServiceQueueServiceNumber(List<string> pstnSiteNameList)
63: {
64: int service;
65: List<int> list;
66:
67: service = 0;
68:
69: if (serviceQueue.Count == 0)
70: {
71: list = new List<int>();
72:
73: foreach (string pstnSiteName in pstnSiteNameList)
74: {
75: list.AddRange(AllPossiblePstnServiceNumbersWithinPstnSite(pstnSiteName));
76: }
77:
78: serviceQueue = new Queue<int>(list.Shuffle()); //.OrderBy(o => o));
79: }
80:
81: if (serviceQueue.Count > 0) service = serviceQueue.Dequeue();
82:
83: return service;
84: }
85:
86: ////////////////////////////////////////////////////////////////////////////
87:
88: /// <summary>
89: ///
90: /// </summary>
91: public static List<int> AllPossiblePstnServiceNumbersWithinPstnSite(string pstnSiteName)
92: {
93: List<int> servicelist;
94: HashSet<int> hashSet;
95:
96: servicelist = Ia.Ngn.Cl.Model.Data.Service.AllPossiblePstnServiceNumbersWithinPstnSite(pstnSiteName);
97:
98: hashSet = new HashSet<int>(servicelist);
99:
100: return hashSet.OrderBy(u => u).ToList();
101: }
102:
103: ////////////////////////////////////////////////////////////////////////////
104:
105: /// <summary>
106: ///
107: /// </summary>
108: public static Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService ServiceSupplementaryServiceStateFromServiceNetManagerOutputString(string outputContent)
109: {
110: string matchedText, line;
111: Match m;
112: Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService serviceSupplementaryService;
113:
114: serviceSupplementaryService = new Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService();
115:
116: /*
117: ******************************************************************************************************
118: Sample Subscriber Information:
119:
120: QRN/QRN/KUWCPK1V5140P047/106 19-06-26 10:39:40
121: 3324 NetM ROMMEL07 2816/03800
122:
123: DISPSUB:DN=25421113;
124:
125: MASKNO:03800
126: LAC = 01 DN = 25421113 EQN = 20- 2-12-14
127: CAT = MS MASKNO:03774
128: OPTRCL = 2 MASKNO:03798
129: SUBTRCL = 2
130: NUMCAL = 1 MASKNO:08641
131: ORIG1 = 5
132: TRARSTR = TRACLACT MASKNO:03803
133: LNATT = PB MASKNO:03787
134: COS = CLIP FSK MASKNO:03777
135: ADDINF = KEYWORD MASKNO:03772
136:
137: END JOB 3324
138:
139:
140: ******************************************************************************************************
141:
142: OPTRCL = 2 ---> WITHOUT INTERNATIONAL CALL ENTERED BY OPERATOR
143: OPTRCL = 0 ---> WITH INTERNATIONAL CALL ENTERED BY OPERATOR
144:
145: SUBTRCL = 2 ---> WITHOUT INTERNATIONAL CALL MODIFIED BY SUBSCRIBER
146: SUBTRCL = 0 ---> WITH INTERNATIONAL CALL MODIFIED BY SUBSCRIBER
147:
148: TRARSTR = ACTTRACL TRACLACT ---> TRAFFIC RESTRATION FEATURES IS ACTIVATED (SUBSCRIBER CAN OPEN AND CLOSE INTERNATIONAL CALL)
149:
150: DIV = DIVI DIVIMOD DDVIN ---> DIVERSATION IMMIDIATE FEATURES IS ASSIGNED TO SUBSCRIBER
151: DIV = ACTDIVI -9793XXXX ---> SUBSCRIBER IMMEDIATELY DIVERTED TO GIVEN NUMBER
152:
153: COS = ACTCW ---> CALL WAITING FEATURE ACTIVATED
154: COS = CWACT ---> CALL WAITING ACTIVATION/DEACTIVATION VIA SUBSCRIBER CONTROL INPUT
155: COS = CONF3 ---> 3 PARTY CALLFERENCING FEATURE ACTIVATED
156: COS = PROP8 ---> ALARM CALL SERVICE FEATURE IS ACTIVATED
157: COS = CLIP FSK ---> CALLER ID FEATURES IS ACTIVATED
158:
159: ADDINF = KEYWORD ---> SUBSCRIBER HAS PIN
160: NOTE: TO CHECK THE SUBSCRIBER PIN (PASSWORD) THE COMMAND IS
161: DISPKEYWORD:DN=25421113;
162:
163: BLK = ACCSUSP ---> SUBSCRIBER ACCOUNT SUSPENDED NOT PAYING THE BILL
164: BLK = ADMIN ---> SUBSCRIBER ACCOUNT SUSPENDED NOT PAYING THE BILL
165: BLK = ADMIN1, ADMIN2, ADMIN3 ---> SUBSCRIBER ACCOUNT SUSPENDED OTHER REASON
166: */
167:
168:
169: /*
170: 2019-07-25 08:52:54: ServiceSymbolList(): Service symbol list: CAT = MS, LTT = COSLAC2, OPTRCL = 2,NUMCAL = 1, ORIG1 = 5, LNATT = PB, COS = CLIP FSK, SUBTRCL = 2, DIV = DIVI DIVIMOD DDVIN, BLK = ACCSUSP, TRARSTR = ACTTRACL TRACLACT, COS = ACTCW CONF3 CWACT PROP8 CLIP, OPTRCL = 0, TRARSTR = TRACLACT, COS = CONF3 CWACT PROP8 CLIP FSK, ADDINF = KEYWORD, BLK = ACCSUSP ADMIN1, TRARSTR = REQSPORI REQSPTER, DIV = ACTDIVI -25435105, LTT = COSLAC1, DIV = ACTDIVI -97669578, BLK = ADMIN2, BLK = ADMIN1, DIV = ACTDIVI -23847000, COS = ACTCW CWACT, DIV = ACTDIVI -99199951, DIV = ACTDIVI -50229969, DIV = ACTDIVI -25430752, DIV = DIVI -1999, DIV = ACTDIVI -50867669, DIV = ACTDIVI -22255495, SUBTRCL = 5, DIV = ACTDIVI -94130075, DIV = ACTDIVI -22210169, DIV = ACTDIVI -96608155, DIV = ACTDIVI -96006498, DIV = ACTDIVI -98941899, BLK = ADMIN3, DIV = ACTDIVI -99000064, DIV = ACTDIVI -22255406, DIV = ACTDIVI-99235351, DIV = ACTDIVI -22255409, DIV = ACTDIVI -50674818, DIV = ACTDIVI -22210925, TRARSTR = ACTTRACL TRACLACT TRACLMOD, DIV = ACTDIVI -22255407, DIV = ACTDIVI -50495160, DIV = ACTDIVI -55157777,OPTRCL = 5, BLK = ACCSUSP ADMIN2, DIV = ACTDIVI -1885050, TRARSTR = ACTTRACL REQSPORI REQSPTER TRACL
171: ACT
172: */
173:
174: m = Regex.Match(outputContent, @"DISPSUB:DN=(\d{8});");
175:
176: if (m.Success)
177: {
178: matchedText = m.Groups[1].Value;
179:
180: if (int.TryParse(matchedText, out int dn))
181: {
182: serviceSupplementaryService.Service = dn;
183:
184: using (StringReader reader = new StringReader(outputContent))
185: {
186: while ((line = reader.ReadLine()) != null)
187: {
188: // COS = CLIP FSK ---> CALLER ID FEATURES IS ACTIVATED
189: m = Regex.Match(line, @"COS.+CLIP.+FSK");
190: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallerId);
191:
192: // COS = ACTCW ---> CALL WAITING FEATURE ACTIVATED
193: m = Regex.Match(line, @"COS.+ACTCW");
194: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallWaiting);
195:
196: // COS = CWACT ---> CALL WAITING ACTIVATION/DEACTIVATION VIA SUBSCRIBER CONTROL INPUT
197: m = Regex.Match(line, @"COS.+CWACT");
198: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallWaiting);
199:
200: // COS = CONF3 ---> 3 PARTY CALLFERENCING FEATURE ACTIVATED
201: m = Regex.Match(line, @"COS.+CONF3");
202: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ConferenceCall);
203:
204: // COS = PROP8 ---> ALARM CALL SERVICE FEATURE IS ACTIVATED
205: m = Regex.Match(line, @"COS.+PROP8");
206: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.WakeupCall);
207:
208: // DIV = DIVI DIVIMOD DDVIN ---> DIVERSATION IMMIDIATE FEATURES IS ASSIGNED TO SUBSCRIBER
209: m = Regex.Match(line, @"DIV.+DIVI.+DIVIMOD.+DDVIN");
210: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.CallForwarding);
211:
212: // DIV = ACTDIVI -9793XXXX ---> SUBSCRIBER IMMEDIATELY DIVERTED TO GIVEN NUMBER
213: m = Regex.Match(line, @"DIV\s+=.+ACTDIVI.+-(\d{8})");
214: if (m.Success) serviceSupplementaryService.Pin = m.Value;
215:
216: // OPTRCL = 0 ---> WITH INTERNATIONAL CALL ENTERED BY OPERATOR
217: // OPTRCL = 2 ---> WITHOUT INTERNATIONAL CALL ENTERED BY OPERATOR
218: m = Regex.Match(line, @"OPTRCL\s+=\s+0");
219: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCalling);
220:
221: // TRARSTR = ACTTRACL TRACLACT ---> TRAFFIC RESTRATION FEATURES IS ACTIVATED (SUBSCRIBER CAN OPEN AND CLOSE INTERNATIONAL CALL)
222: m = Regex.Match(line, @"TRARSTR.+ACTTRACL.+TRACLACT");
223: if (m.Success) serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.InternationalCallingUserControlled);
224:
225: // SUBTRCL = 0 ---> WITH INTERNATIONAL CALL MODIFIED BY SUBSCRIBER
226: // SUBTRCL = 2 ---> WITHOUT INTERNATIONAL CALL MODIFIED BY SUBSCRIBER
227: m = Regex.Match(line, @"SUBTRCL\s+=\s+0");
228: if (m.Success) serviceSupplementaryService.InternationalCallingUserControlledActivated = true;
229:
230: // BLK = ACCSUSP ---> SUBSCRIBER ACCOUNT SUSPENDED NOT PAYING THE BILL
231: // BLK = ADMIN ---> SUBSCRIBER ACCOUNT SUSPENDED NOT PAYING THE BILL
232: // BLK = ADMIN1, ADMIN2, ADMIN3 ---> SUBSCRIBER ACCOUNT SUSPENDED OTHER REASON
233: m = Regex.Match(line, @"BLK\s+=.+[ACCSUSP|ADMIN]");
234: if (m.Success)
235: {
236: serviceSupplementaryService.ServiceAdministrativelySuspendedByBillingDepartment = true;
237: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
238: }
239: m = Regex.Match(line, @"BLK\s+=.+[ADMIN1|ADMIN2|ADMIN3]");
240: if (m.Success)
241: {
242: serviceSupplementaryService.ServiceAdministrativelySuspendedForOtherReasons = true;
243: serviceSupplementaryService.SupplementaryServiceList.Add(Ia.Ngn.Cl.Model.Business.Service.SupplementaryService.ServiceSuspension);
244: }
245:
246: // ADDINF = KEYWORD ---> SUBSCRIBER HAS PIN
247: m = Regex.Match(line, @"ADDINF\s+=.+KEYWORD");
248: if (m.Success) serviceSupplementaryService.SubscriberHasPin = true;
249: }
250: }
251:
252: Ia.Ngn.Cl.Model.Business.Nokia.SiemensEwsd.ExtractAndUpdateUniqueEwsdServiceSymbolListFromOutputContent(outputContent);
253: }
254: else
255: {
256: }
257: }
258: else
259: {
260: }
261:
262: return serviceSupplementaryService;
263: }
264:
265: ////////////////////////////////////////////////////////////////////////////
266:
267: /// <summary>
268: /// Response of Siemens EWSD
269: /// </summary>
270: public class Response
271: {
272: public int Service { get; set; }
273: /// <summary/>
274: public bool IsSuccess { get { return ReturnCode == Ia.Ngn.Cl.Model.Business.Nokia.SiemensEwsd.ResultCode.OperationIsSuccessful; } }
275: /// <summary/>
276: public bool IsProvisioned { get; set; }
277: /// <summary/>
278: public Ia.Ngn.Cl.Model.Business.Nokia.SiemensEwsd.ResultCode ReturnCode { get; set; }
279: /// <summary/>
280: //public string Ctag { get; set; } // no need because the commad string is included in response body
281: /// <summary/>
282: public DateTime DateTime { get; set; }
283: /// <summary/>
284: public string CommandString { get; set; }
285:
286: public Ia.Ngn.Cl.Model.Business.Service.ServiceSupplementaryService ServiceSupplementaryService { get; set; }
287:
288: /// <summary/>
289: public Response() { }
290: }
291:
292: ////////////////////////////////////////////////////////////////////////////
293:
294: /// <summary>
295: ///
296: /// </summary>
297: public static string NetManagerCommand(Opcode opcode, int dn)
298: {
299: string command;
300:
301: if (opcode == Opcode.Dispsub) command = "DISPSUB:DN=" + dn + ";";
302: else if (opcode == Opcode.Cansub) command = "CANSUB:DN=" + dn + ";";
303: else
304: {
305: throw new System.ArgumentOutOfRangeException("NetManagerCommand(): Opcode unrecognized. ");
306: }
307:
308: return command;
309: }
310:
311: ////////////////////////////////////////////////////////////////////////////
312:
313: /// <summary>
314: ///
315: /// </summary>
316: public static string NetManagerDisplayTimeCommand
317: {
318: get
319: {
320: return "DISPTIME;";
321: }
322: }
323:
324: ////////////////////////////////////////////////////////////////////////////
325:
326: /// <summary>
327: /// Extract unique EWSD service symbols into array
328: /// </summary>
329: public static void ExtractAndUpdateUniqueEwsdServiceSymbolListFromOutputContent(string outputContent)
330: {
331: string s;
332: MatchCollection matchCollection;
333:
334: matchCollection = Regex.Matches(outputContent, @"\r\n [\w]{1,}\s+= .+[^\r\n]");
335:
336: if (matchCollection.Count > 0)
337: {
338: foreach (Match match in matchCollection)
339: {
340: s = Regex.Replace(match.Value, @"MASKNO:\d+", "");
341: s = Regex.Replace(s, @"\s+", " ");
342: s = s.Trim();
343:
344: if (!ServiceSymbolList.Contains(s))
345: {
346: ServiceSymbolList.Add(s);
347: }
348: }
349: }
350: }
351:
352: ////////////////////////////////////////////////////////////////////////////
353: ////////////////////////////////////////////////////////////////////////////
354:
355: /// <summary>
356: ///
357: /// </summary>
358: public static string SpecialHandlingAndModificationOfPstnSiteName(string pstnSiteName)
359: {
360: // change JPL to QRN because JBL is just an RSU following QRN
361: string modifiedPstnSiteName;
362:
363: if (pstnSiteName == "JBL") modifiedPstnSiteName = "QRN";
364: else modifiedPstnSiteName = pstnSiteName;
365:
366: return modifiedPstnSiteName;
367: }
368:
369: ////////////////////////////////////////////////////////////////////////////
370: ////////////////////////////////////////////////////////////////////////////
371: }
372: }
373: