/// <summary> /// public method to construct the bworks cdr from the omc cdr /// </summary> /// <param name="ocdr"></param> /// <returns></returns> public Bcdr(OmcCdr ocdr) { // initialize some params Init(); this.RecordId = ocdr.SequenceNumber; if ((ocdr.disc_code.Equals("201")) || (ocdr.disc_code.Equals("202"))) { if (ocdr.A_Party_Type.Equals("1") || ocdr.A_Party_Type.Equals("0")) {// MO this.Direction = CdrDirection.Originating.ToString(); if (ocdr.B_Party_Digits.StartsWith("011")) { DialedDigits = ocdr.B_Party_Digits; CalledNumber = ocdr.B_Party_Digits; NetworkCallType = "in"; CallCategory = "internat"; } else { DialedDigits = "+1" + ocdr.B_Party_Digits; CalledNumber = "+1" + ocdr.B_Party_Digits; } // create the userid based on cellid here string uId = m_dbMgr.GetUserIdForCellId(ocdr.CellId); if (uId.Equals(String.Empty)) // not mapped then we user the MDN UserNumber = "+1" + ocdr.OriginatingMsisdn; else UserNumber = uId; // already with leading +1 UserId = UserNumber; CallingNumber = "+1" + ocdr.A_Party_Num; } else { // MT ( not billing On-Waves for mobile termination this.Direction = CdrDirection.Terminating.ToString(); // not billing mobile termination, don't create the CDR CreateDefaults(); } // get cell id to 700 number mapping // get the calling number // called number StartTime = ConvertTheTime(ocdr.SeizeTime); AnswerTime = ConvertTheTime(ocdr.AnswerTime); ReleaseTime = ConvertTheTime(ocdr.DisconnectTime); } else { CreateDefaults(); return; } }
/// <summary> /// this method parses the OMC CDR files that are in the XML format /// the entire file is parsed so that each CDR is parsed and the OmcCdr object is loaded. /// The OmcCdr is then passed to create CIBER records if it is one of our roaming partners. /// </summary> public List<OmcCdr> ProcessOmcCdrFile(string fileName) { XmlTextReader reader = null; int cdrIndx = 0; int cdrCnt = 0; List<OmcCdr> cdrList = new List<OmcCdr>(); // make sure we have not processed this file before string parsedFileName = this.ParseFileName(fileName); if (!this.CheckDbBeforeProcessingFile(parsedFileName)) { try { // Load the reader with the data file and ignore // all white space nodes. this needs the full path name reader = new XmlTextReader(fileName); reader.WhitespaceHandling = WhitespaceHandling.None; OmcCdr cdr = null; // Parse the file and display each of the nodes. while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: { switch (reader.Name) { case ("CDRecord"): { if (cdrIndx == 0) { cdr = new OmcCdr(); } cdrIndx++; } break; case ("version"): reader.Read(); cdr.version = reader.Value; break; case ("seq_num"): reader.Read(); cdr.seq_num = reader.Value; break; case ("record_type"): reader.Read(); cdr.type = reader.Value; break; case ("a_party_num"): reader.Read(); cdr.a_party_num = reader.Value; break; case ("b_party_num"): reader.Read(); cdr.b_party_num = reader.Value; break; case ("a_party_type"): reader.Read(); cdr.a_party_type = reader.Value; break; case ("b_party_type"): reader.Read(); cdr.b_party_type = reader.Value; break; case ("a_party_digits"): reader.Read(); cdr.a_party_digits = reader.Value; break; case ("b_party_digits"): reader.Read(); cdr.b_party_digits = reader.Value; break; case ("a_party_trunk"): reader.Read(); cdr.a_party_trunk = reader.Value; break; case ("b_party_trunk"): reader.Read(); cdr.b_party_trunk = reader.Value; break; case ("a_party_trkgrp"): reader.Read(); cdr.a_party_trkgrp = reader.Value; break; case ("b_party_trkgrp"): reader.Read(); cdr.b_party_trkgrp = reader.Value; break; case ("seize"): reader.Read(); cdr.seize = reader.Value; break; case ("answer"): reader.Read(); cdr.answer = reader.Value; break; case ("disc"): reader.Read(); cdr.disc = reader.Value; break; case ("disc_code"): reader.Read(); cdr.disc_code = reader.Value; break; case ("disc_reason"): reader.Read(); cdr.disc_reason = reader.Value; break; case ("msc_id"): reader.Read(); cdr.msc_id = reader.Value; break; case ("orig_esn"): reader.Read(); cdr.orig_esn = reader.Value; break; case ("term_esn"): reader.Read(); cdr.TerminatingEsn = reader.Value; break; case ("cell_id"): reader.Read(); cdr.cell_id = reader.Value; break; case ("b_cell_id"): reader.Read(); cdr.b_cell_id = reader.Value; break; case ("a_feature_bits"): reader.Read(); cdr.a_feature_bits = reader.Value; break; case ("b_feature_bits"): reader.Read(); cdr.b_feature_bits = reader.Value; break; case ("o_msisdn"): reader.Read(); cdr.o_msisdn = reader.Value; break; case ("t_msisdn"): reader.Read(); cdr.t_msisdn = reader.Value; break; case ("o_exchange"): reader.Read(); cdr.o_exchange = reader.Value; break; case ("t_exchange"): reader.Read(); cdr.t_exchange = reader.Value; break; case ("o_market_id"): reader.Read(); cdr.o_market_id = reader.Value; break; case ("o_swno"): reader.Read(); cdr.o_swno = reader.Value; break; case ("o_bin"): reader.Read(); cdr.o_bin = reader.Value; break; case ("t_market_id"): reader.Read(); cdr.t_market_id = reader.Value; break; case ("t_swno"): reader.Read(); cdr.t_swno = reader.Value; break; case ("t_bin"): reader.Read(); cdr.t_bin = reader.Value; break; case ("o_billdgts"): reader.Read(); cdr.o_billdgts = reader.Value; break; case ("t_billdgts"): reader.Read(); cdr.t_billdgts = reader.Value; break; case ("o_serviceid"): reader.Read(); cdr.o_serviceid = reader.Value; break; case ("t_serviceid"): reader.Read(); cdr.t_serviceid = reader.Value; break; case ("crg_charge_info"): reader.Read(); cdr.crg_charge_info = reader.Value; break; case ("ocpn"): reader.Read(); cdr.Ocpn = reader.Value; break; case ("icprn"): reader.Read(); cdr.Icprn = reader.Value; break; } } break; case XmlNodeType.Text: break; case XmlNodeType.CDATA: break; case XmlNodeType.ProcessingInstruction: break; case XmlNodeType.Comment: break; case XmlNodeType.XmlDeclaration: break; case XmlNodeType.Document: break; case XmlNodeType.DocumentType: break; case XmlNodeType.EntityReference: break; case XmlNodeType.EndElement: if (reader.Name.Equals("CDRecord")) { // this is the end of the CDR record we are processing cdrIndx = 0; // increment the total number of CDRs we are processing for our Record98 cdrCnt++; // add to the list and then store entire list at once instead of one by one cdrList.Add(cdr); } break; }//switch }// while loop }//try catch (SystemException ex) { WriteToLogFile("OmcCdrHandler::ProcessOmcCdrFile():ECaught:CDR#" + cdrCnt + " \r\n" + ex.Message + ex.StackTrace); } finally { if (reader != null) reader.Close(); } } return cdrList; }
}//private void ProcessFileWatcher(object sender, FileSystemEventArgs e) /// <summary> /// this method parses the OMC CDR files that are in the XML format /// the entire file is parsed so that each CDR is parsed and the OmcCdr object is loaded. /// The OmcCdr is then passed to create CIBER records if it is one of our roaming partners. /// </summary> public List <OmcCdr> ProcessOmcCdrFile(string fileName) { XmlTextReader reader = null; int cdrIndx = 0; int cdrCnt = 0; List <OmcCdr> cdrList = new List <OmcCdr>(); // make sure we have not processed this file before string parsedFileName = this.ParseFileName(fileName); if (!this.CheckDbBeforeProcessingFile(parsedFileName)) { try { // Load the reader with the data file and ignore // all white space nodes. this needs the full path name reader = new XmlTextReader(fileName); reader.WhitespaceHandling = WhitespaceHandling.None; OmcCdr cdr = null; // Parse the file and display each of the nodes. while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: { switch (reader.Name) { case ("CDRecord"): { if (cdrIndx == 0) { cdr = new OmcCdr(); } cdrIndx++; } break; case ("version"): reader.Read(); cdr.version = reader.Value; break; case ("seq_num"): reader.Read(); cdr.seq_num = reader.Value; break; case ("record_type"): reader.Read(); cdr.type = reader.Value; break; case ("a_party_num"): reader.Read(); cdr.a_party_num = reader.Value; break; case ("b_party_num"): reader.Read(); cdr.b_party_num = reader.Value; break; case ("a_party_type"): reader.Read(); cdr.a_party_type = reader.Value; break; case ("b_party_type"): reader.Read(); cdr.b_party_type = reader.Value; break; case ("a_party_digits"): reader.Read(); cdr.a_party_digits = reader.Value; break; case ("b_party_digits"): reader.Read(); cdr.b_party_digits = reader.Value; break; case ("a_party_trunk"): reader.Read(); cdr.a_party_trunk = reader.Value; break; case ("b_party_trunk"): reader.Read(); cdr.b_party_trunk = reader.Value; break; case ("a_party_trkgrp"): reader.Read(); cdr.a_party_trkgrp = reader.Value; break; case ("b_party_trkgrp"): reader.Read(); cdr.b_party_trkgrp = reader.Value; break; case ("seize"): reader.Read(); cdr.seize = reader.Value; break; case ("answer"): reader.Read(); cdr.answer = reader.Value; break; case ("disc"): reader.Read(); cdr.disc = reader.Value; break; case ("disc_code"): reader.Read(); cdr.disc_code = reader.Value; break; case ("disc_reason"): reader.Read(); cdr.disc_reason = reader.Value; break; case ("msc_id"): reader.Read(); cdr.msc_id = reader.Value; break; case ("orig_esn"): reader.Read(); cdr.orig_esn = reader.Value; break; case ("term_esn"): reader.Read(); cdr.TerminatingEsn = reader.Value; break; case ("cell_id"): reader.Read(); cdr.cell_id = reader.Value; break; case ("b_cell_id"): reader.Read(); cdr.b_cell_id = reader.Value; break; case ("a_feature_bits"): reader.Read(); cdr.a_feature_bits = reader.Value; break; case ("b_feature_bits"): reader.Read(); cdr.b_feature_bits = reader.Value; break; case ("o_msisdn"): reader.Read(); cdr.o_msisdn = reader.Value; break; case ("t_msisdn"): reader.Read(); cdr.t_msisdn = reader.Value; break; case ("o_exchange"): reader.Read(); cdr.o_exchange = reader.Value; break; case ("t_exchange"): reader.Read(); cdr.t_exchange = reader.Value; break; case ("o_market_id"): reader.Read(); cdr.o_market_id = reader.Value; break; case ("o_swno"): reader.Read(); cdr.o_swno = reader.Value; break; case ("o_bin"): reader.Read(); cdr.o_bin = reader.Value; break; case ("t_market_id"): reader.Read(); cdr.t_market_id = reader.Value; break; case ("t_swno"): reader.Read(); cdr.t_swno = reader.Value; break; case ("t_bin"): reader.Read(); cdr.t_bin = reader.Value; break; case ("o_billdgts"): reader.Read(); cdr.o_billdgts = reader.Value; break; case ("t_billdgts"): reader.Read(); cdr.t_billdgts = reader.Value; break; case ("o_serviceid"): reader.Read(); cdr.o_serviceid = reader.Value; break; case ("t_serviceid"): reader.Read(); cdr.t_serviceid = reader.Value; break; case ("crg_charge_info"): reader.Read(); cdr.crg_charge_info = reader.Value; break; case ("ocpn"): reader.Read(); cdr.Ocpn = reader.Value; break; case ("icprn"): reader.Read(); cdr.Icprn = reader.Value; break; } } break; case XmlNodeType.Text: break; case XmlNodeType.CDATA: break; case XmlNodeType.ProcessingInstruction: break; case XmlNodeType.Comment: break; case XmlNodeType.XmlDeclaration: break; case XmlNodeType.Document: break; case XmlNodeType.DocumentType: break; case XmlNodeType.EntityReference: break; case XmlNodeType.EndElement: if (reader.Name.Equals("CDRecord")) { // this is the end of the CDR record we are processing cdrIndx = 0; // increment the total number of CDRs we are processing for our Record98 cdrCnt++; // add to the list and then store entire list at once instead of one by one cdrList.Add(cdr); } break; } //switch } // while loop } //try catch (SystemException ex) { WriteToLogFile("OmcCdrHandler::ProcessOmcCdrFile():ECaught:CDR#" + cdrCnt + " \r\n" + ex.Message + ex.StackTrace); } finally { if (reader != null) { reader.Close(); } } } return(cdrList); }// ProcessOmcCdrFile
/// <summary> /// public method to create a bcdr and add it to the list /// to be written to the cdr file later /// </summary> /// <param name="o"></param> public void CreateAndAddCdr( OmcCdr o ) { Bcdr bCdr = new Bcdr( o ); m_cdrMgr.AddCdr(bCdr); }
/// <summary> /// method used to create a CDR from an OMC/MSC CDR /// </summary> /// <param name="omcCdr"></param> /// <returns></returns> public Bcdr CreateCdr( OmcCdr omcCdr ) { // populate the bworks cdr here and return it Bcdr bCdr = new Bcdr( omcCdr ); return bCdr; }
/// <summary> /// method used to create a CDR based on the MSC/OMC CDR and the /// CIBER record type 22. /// </summary> /// <param name="oCdr"></param> /// <param name="r22"></param> /// <returns></returns> public Bcdr CreateCdr(OmcCdr oCdr, Record22 r22 ) { // populate the bworks cdr here and return it Bcdr bCdr = new Bcdr(oCdr); return bCdr; }
/// <summary> /// method to process the SMS OMC CDRs and create a type 32 CIBER record /// </summary> /// <param name="cdr"></param> public void ProcessSmsRecord(OmcCdr cdr) { }
/// <summary> /// method to convert the OMC CDR to a CIBER Type 22 record /// need to keep track of the total charges and taxes here /// </summary> /// <param name="cdr"></param> public void ProcessCallRecord(OmcCdr cdr ) { // 22 0 00 000 01151 2 912223280900000 10 912223280900000 1 0610328563400000000 33333 0000000099 0 00000000000000000000000705022220000000000000000010912223280900000000000000000000000000000000000000001 029000000000189900000000000212127000100000051021000000009900000000000000 000J INCOMING CLUSAJACKSON OHUSA00000000000000000000000000000000000000000000000000000000000000000000000000208040784PIKE 0188 // 220000000115129122232809000001091222328090000010610328563400000000333330000000099000000000000000000000000705022220000000000000000010912223280900000000000000000000000000000000000000001 // record type : 22 // return code : 0 // ciber return reason code 2N : 00 // invalidfieldidentifier 3N : 000 // homecarriersidbid 5N : 01151 // msid indicator 1N = 2 // msid 15N : 912223280900000 // MSISDN/MDN length 2N : 10 // MSISDN/MDN 15N : 912223280900000 // ESN/UIMID/EIMIE/MEID indicator 1N :1 // ESN/UIMID/EIMIE/MEID 19N : 0610328563400000000 // ServingCarrierSidBid 5N :33333 // TotalChargesAndTaxes 10N : 0000000099 /// system reserved filler1 1N : BlankFILL /// total state province taxes 10N // update our running total // cri.BatchTotalChargesAndTaxes // create a CIBER record // for now it is a type 22 record Record22 r22 = new Record22(); r22.ReturnCode = "0"; r22.CiberRecordReturnReasonCode = "00"; r22.InvalidFieldIndentifier = "000"; r22.MsidIndicator = "2"; // MIN baby // if 911 call, don't process it if (cdr.A_Feature_Bits.Equals("EMERGENCY")) { cfw.WriteToLogFile(DateTime.Now.ToShortDateString() + "OmcToCiberCdrConverter::ConvertToCiber():911CallDetectedForCDRSeqNum:" + cdr.SequenceNumber + "\r\n"); return; } try { // if we have a *good* call, then create the CIBER record and for now if it is *bad* call // we log it to the log file. Figure out what to do with it, create the CIBER or not. if ((cdr.disc_code.Equals("201")) || (cdr.disc_code.Equals("202"))) { r22.CallCompletionIndicator = "2"; r22.CallTerminationIndicator = "2"; // 2 = Normal } else { // double check this r22.CallCompletionIndicator = "1"; r22.CallTerminationIndicator = "3"; // 3 = unknown, 4=incomplete call cfw.WriteToLogFile(DateTime.Now.ToShortDateString()+"OmcToCiberCdrConverter::ConvertToCiber():InvalidDisconnectCode-CallNotTerminatedForCDRSeqNum:" + cdr.SequenceNumber + "\r\n"); return; } // look for the mobile party in our scenario we will always have one mobile unit and one // landline, we always grab mobile unit parameters. // MO Case: if (cdr.a_party_type.Equals("1")) { // grab the a party mobile params // MIN r22.Msid = cdr.a_party_num; // MDN ** double check this and might change it to be the cdr.ocpn field ** r22.MsisdnMdnLength = cdr.o_msisdn.Length.ToString(); r22.MsisdnMdn = cdr.o_msisdn; if (cdr.OriginatingEsn.Length == 0) { // ESN/UIMID/IMEI/MEID // If the ESN/IMEI/MEID Indicator equals “0,” // then the ESN/IMEI/MEID field must be zero filled. // If the ESN/IMEI/MEID Indicator equals 1, 2, or 3, then the // ESN/IMEI/MEID field must contain a value within the range of accepted values specified above. r22.EsnUimidImeiMeidIndicator = "0"; // ESN r22.EsnUimidImeiMeid = "000000"; } else { r22.EsnUimidImeiMeidIndicator = "1"; // ESN // add code to convert this according to Appendix B UInt32 starEsn = Convert.ToUInt32(cdr.OriginatingEsn, 16); string esn = CalculateEsnValue(starEsn); r22.EsnUimidImeiMeid = esn; } //The value of the Caller ID is dependent on the call direction. //•For Mobile Originated Calls (Call Direction equals “1”), the Caller ID is equal to the Mobile Directory Number. // which in our case is the following field in the type 22 record r22.CallerIdLength = r22.MsisdnMdnLength; r22.CallerId = r22.MsisdnMdn; // For Mobile Originated Calls, the Called Number Digits represents the Dialed Digits. r22.CalledNumberLength = cdr.b_party_digits.Length.ToString(); r22.CalledNumberDigits = cdr.b_party_digits; // MO no TLDN in our scenario r22.TldnLength = "0"; r22.Tldn = "0"; // set our call direction : mobile roamer originated = 1, mobile roamer terminated = 2 r22.CallDirection = "1"; } else { // MT Case: // assume that b party is the mobile party and we grab the b party mobile params // grab the b party mobile params // MIN r22.Msid = cdr.b_party_num; // MDN r22.MsisdnMdnLength = cdr.t_msisdn.Length.ToString(); r22.MsisdnMdn = cdr.t_msisdn; if (cdr.TerminatingEsn.Length == 0) { // ESN/UIMID/IMEI/MEID // If the ESN/IMEI/MEID Indicator equals “0,” // then the ESN/IMEI/MEID field must be zero filled. // If the ESN/IMEI/MEID Indicator equals 1, 2, or 3, then the // ESN/IMEI/MEID field must contain a value within the range of accepted values specified above. r22.EsnUimidImeiMeidIndicator = "0"; // ESN r22.EsnUimidImeiMeid = "000000"; } else { r22.EsnUimidImeiMeidIndicator = "1"; // ESN // add code to convert this according to Appendix B UInt32 starEsn = Convert.ToUInt32(cdr.TerminatingEsn, 16); string esn = CalculateEsnValue(starEsn); r22.EsnUimidImeiMeid = esn; } //•For Mobile Terminated Calls (Call Direction equals “2”), the Caller ID is the number of the calling party. r22.CallerIdLength = cdr.a_party_num.Length.ToString(); r22.CallerId = cdr.a_party_num; // For Mobile Terminated Calls (Call Direction equals “2”), the Called Number Digits value MUST equal // the Mobile Directory Number value. r22.CalledNumberLength = r22.MsisdnMdnLength; //cdr.t_msisdn.Length.ToString(); r22.CalledNumberDigits = r22.MsisdnMdn; // ** when we have Verizon phones it should be :** cdr.t_msisdn; // landline to Mobile, MT r22.TldnLength = cdr.a_party_digits.Length.ToString(); r22.Tldn = cdr.A_Party_Digits; // set our call direction : mobile roamer originated = 1, mobile roamer terminated = 2 r22.CallDirection = "2"; } // this field is used to indicate the home carrier of the roaming mobile as indicated by the MSID. // The MSID must be valid for the specified home carrier SID/BID. // look up the HomeCarrierSIDBID based on the MSID CarrierInfo ci = GetHomeCarrierSidBid(r22.Msid); if (ci.SidBid.Equals(TechDataEnums.SIDBID_NOT_FOUND.ToString() )) { cfw.WriteToLogFile(DateTime.Now.ToShortDateString() + "OmcToCiberCdrConverter::ProcessCallRecord():SIDBIDNotFoundForMSID: " + r22.Msid); return; } else { r22.HomeCarrierSidBid = ci.SidBid; } // this is the On-Wave SID/BID, use the same one that is in our header r22.ServingCarrierSidBid = cri.SendingCarrierSidBid; // yymmdd r22.CallDate = cdr.answer.Substring(2, 2) + cdr.answer.Substring(5, 2) + cdr.answer.Substring(8, 2); // This field is used to record the routing number associated with a ported or pooled MDN. r22.LocationRoutingNumberLengthIndicator = "0"; r22.LocationRoutingNumber = "0"; r22.CurrencyType = "1"; // original Batch Sequence Number r22.OriginalBatchSequenceNumber = cri.BatchSequenceNumber; r22.InitialCellSite = cdr.cell_id; r22.TimeZoneIndicator = "99"; //=08 Pacific, for this test use the unknown value of "99"; r22.DaylightSavingIndicator = "0"; r22.MessageAccountingDigits = "0"; // This field is used to record the time that the mobile unit successfully connected to a wireless system. // HHMMSS: HH = 00-23, MM = 00-59, SS = 00-59 r22.AirConnectTime = cdr.answer.Substring(11, 2) + cdr.answer.Substring(14, 2) + cdr.answer.Substring(17, 2); // fill these in : ( disc time - seize time ) // This field is used to record the billable elapsed time used to calculate air time charges string ChargeableTime = CalculateAirChargeTime(cdr.DisconnectTime, cdr.SeizeTime); r22.AirChargeableTime = ChargeableTime; // "0001030"; // contains the billable elapsed time in MMMM=0000-9999, SS=00-59 // This field is used to record the elapsed time associated with a call. // MMMMSS: MMMM = 0000-9999, SS = 00-59 r22.AirElapsedTime = ChargeableTime; // "000545"; // this should be disconnect - answer // this needs to be determined r22.AirRatePeriod = "02"; r22.AirMultiRatePeriod = "1";// 1 = single rate period // This field is used to record the charges associated with the air time portion of a call. // This field must not contain any taxes; $$$$$$$$¢¢ format. string rAirChargeTime = cr.CalculateAirTimeChargeAmount( r22.AirChargeableTime, ci.Carrier ); r22.AirCharge = rAirChargeTime; // "99"; // ** calculate this as well r22.OtherChargeNumberOneIndicator = "0"; r22.OtherChargeNumberOne = "0"; r22.PrintedCall = "0"; // determine how we determine if it is fraudulent or not r22.FraudIndicator = "00"; r22.FraudSubIndicator = "0"; // special condition when it is a zero, properties get/set take care of this r22.SpecialFeaturesUsed = "0"; // ** fix this to the following // this field contains the service call descriptor, section 8 table 18 OR the geographic name of the // called place. // called place depends on the call direction // for MO, calledDirection=1, the called place is the place that the mobile sub // is calling // for MT, calledDirection=2, the called place is the place where the mobile sub answered the call if ( r22.CallDirection.Equals("2") ) { // MT CALLs // Mobile terminated calls all MT calls are airtime only charges Rate = 1.49 r22.CalledPlace = "INCOMING"; r22.CalledStateProvince = "CL"; r22.CalledCountry = "USA"; // **check to see if we are going to make this International r22.SpecialFeaturesUsed = "J"; // no toll r22.TollTariffDescriptor = "00"; // na r22.TollRateClass = "0"; // 0-when no toll associated with this call // No TOLL CHARGES for MT r22.TollConnectTime = "000000"; r22.TollElapsedTime = "000000"; r22.TollChargeableTime = r22.TollElapsedTime; r22.TollRatePeriod = "00"; // not applicable r22.TollMultiRatePeriod = "0"; // not applicable r22.TollRatingPointLengthIndicator = "0"; r22.TollRatingPoint = "0"; r22.TollCharge = "00"; // } else if ( r22.CallDirection.Equals("1") ) { // MO CALLs // check for 411 call ** add others here or in separate function // see section 8 table 18 if (r22.CalledNumberDigits.Equals("411000000000000")) { // MO:411 r22.CalledPlace = "DIR ASST"; r22.CalledStateProvince = "CL"; r22.CalledCountry = "USA"; r22.SpecialFeaturesUsed = "0"; // shows no toll charges applied r22.PrintedCall = "411"; // rated as local/ld call including toll r22.TollTariffDescriptor = "02"; // interstate interlata r22.TollRateClass = "1"; // 0-when no toll associated with this call r22.TollConnectTime = r22.AirConnectTime; r22.TollElapsedTime = r22.AirElapsedTime; r22.TollChargeableTime = r22.AirChargeableTime; r22.TollRatePeriod = "01";// day, 02=evening, 03=night, 05=latenight, 06 =weekend r22.TollMultiRatePeriod = "1"; r22.TollRatingPointLengthIndicator = "00"; r22.TollRatingPoint = "0"; // when TollRatingPointLengthIndicator=0, this = 0 string rTollChargeTime = cr.CalculateLocalLdTollChargeAmount(r22.TollChargeableTime); r22.TollCharge = rTollChargeTime; } else if (r22.CalledNumberDigits.StartsWith("8")) { // MO:TOLL FREE r22.CalledPlace = "TOLL FREE"; r22.CalledStateProvince = "CL"; r22.CalledCountry = "USA"; r22.SpecialFeaturesUsed = "J"; r22.PrintedCall = "TOLL FREE"; r22.TollTariffDescriptor = "00"; // interstate interlata r22.TollRateClass = "0"; // 0-when no toll associated with this call // *** figure out charges for TOLL FREE r22.TollConnectTime = "000000"; r22.TollElapsedTime = "000000"; r22.TollChargeableTime = r22.TollElapsedTime; // no toll r22.TollRatePeriod = "00"; // not applicable r22.TollMultiRatePeriod = "0"; // not applicable r22.TollRatingPointLengthIndicator = "0"; r22.TollRatingPoint = "0"; // when TollRatingPointLengthIndicator=0, this = 0 r22.TollCharge = "00"; // no toll } else { // MO : International or Local/LD case // this should map to table 31 State/Province mapping NpaNxxData n = npaNxxRdr.GetNpaNxxInfo(r22.CalledNumberDigits.Substring(0, 6)); // check International scenario if (n.NpaNxx.Equals(String.Empty)) { // MO:International Rate = 1.49 AirTime + 0.80 Toll // International Call Scenario // add the international tables mapped to table 32 if (r22.CalledNumberDigits.Contains("0118522810")) { r22.CalledPlace = "Hong Kong"; r22.CalledStateProvince = "ZZ"; r22.CalledCountry = "HKG"; r22.SpecialFeaturesUsed = "D"; // International, but not required. // 01 = International : Originating from a NANP and terminating to Non-NANP // 15 = International : Originating from a NANP and terminating to NANP // 17 = International : Originating from a Non-NANP and terminating to NANP // 18 = International : Originating from and terminating to Non-NANP r22.TollTariffDescriptor = "01"; // see above r22.TollRateClass = "1"; // dial station, normal completed, 0-when no toll associated with this call // toll charges r22.TollConnectTime = r22.AirConnectTime; r22.TollElapsedTime = r22.AirElapsedTime; r22.TollChargeableTime = r22.AirChargeableTime; r22.TollRatePeriod = "01";// day, 02=evening, 03=night, 05=latenight, 06 =weekend r22.TollMultiRatePeriod = "1"; r22.TollRatingPointLengthIndicator = "00"; r22.TollRatingPoint = "0"; // when TollRatingPointLengthIndicator=0, this = 0 string rTollChargeTime = cr.CalculateInternationalTollChargeAmount(r22.TollChargeableTime); r22.TollCharge = rTollChargeTime; } else if (r22.CalledNumberDigits.Contains("01181354")) { r22.CalledPlace = "Tokyo"; r22.CalledStateProvince = "ZZ"; r22.CalledCountry = "JPN"; r22.SpecialFeaturesUsed = "D"; // International, but not required. // 01 = International : Originating from a NANP and terminating to Non-NANP // 15 = International : Originating from a NANP and terminating to NANP // 17 = International : Originating from a Non-NANP and terminating to NANP // 18 = International : Originating from and terminating to Non-NANP r22.TollTariffDescriptor = "01"; // see above r22.TollRateClass = "1"; // dial station, normal completed, 0-when no toll associated with this call // toll charges r22.TollConnectTime = r22.AirConnectTime; r22.TollElapsedTime = r22.AirElapsedTime; r22.TollChargeableTime = r22.AirChargeableTime; r22.TollRatePeriod = "01";// day, 02=evening, 03=night, 05=latenight, 06 =weekend r22.TollMultiRatePeriod = "1"; r22.TollRatingPointLengthIndicator = "00"; r22.TollRatingPoint = "0"; // when TollRatingPointLengthIndicator=0, this = 0 string rTollChargeTime = cr.CalculateInternationalTollChargeAmount(r22.TollChargeableTime); r22.TollCharge = rTollChargeTime; } else { cfw.WriteToLogFile(DateTime.Now.ToShortDateString() + "OmcToCiberCdrConverter::ProcessCallRecord():NPANXXNotFoundFor: " + r22.CalledNumberDigits); return; } } else { // MO:Local/LD case : Rate = 1.49 AirTime + 0.50 Toll r22.CalledPlace = n.City; r22.CalledStateProvince = n.State; r22.CalledCountry = "USA"; r22.SpecialFeaturesUsed = "0"; // none r22.TollTariffDescriptor = "02"; // interstate interlata r22.TollRateClass = "1"; // 0-when no toll associated with this call // toll charges r22.TollConnectTime = r22.AirConnectTime; r22.TollElapsedTime = r22.AirElapsedTime; r22.TollChargeableTime = r22.AirChargeableTime; r22.TollRatePeriod = "01";// day, 02=evening, 03=night, 05=latenight, 06 =weekend r22.TollMultiRatePeriod = "1"; r22.TollRatingPointLengthIndicator = "00"; r22.TollRatingPoint = "0"; // when TollRatingPointLengthIndicator=0, this = 0 string rTollChargeTime = cr.CalculateLocalLdTollChargeAmount(r22.TollChargeableTime); r22.TollCharge = rTollChargeTime; } } } // description designed by the serving carrier and may range from a city name to a cell site or a trunk/circuit name. r22.ServingPlace = "Strata8"; // for MO , called direction =1, this is the state that is providing service to the mobile subscriber // for MT, this is the state/province providing service to the called party // must contain a value given in section 8 , table 31 r22.ServingStateProvince = "WA"; r22.ServingCountry = "USA"; r22.TollStateProvinceTaxes = "0"; r22.TollLocalTaxes = "0"; r22.TollNetworkCarrierId = "00000"; // this is other ** TBD ** see section 8, table 10, and appendix H // let's get the total state/province taxes associated with this record r22.TotalStateProvinceTaxes = r22.TollStateProvinceTaxes; r22.TotalLocalTaxes = r22.TollLocalTaxes; // total charges is the sum of all the charge fields and taxes in this ciber record // r22.TotalChargesAndTaxes = r22.TotalLocalTaxes + r22.TotalStateProvinceTaxes + r22.AirCharge + r22.TollCharge; // need to convert to an int int intTotalLocalTaxes = Convert.ToInt32(r22.TotalLocalTaxes); int intTotalStateProvinceTaxes = Convert.ToInt32(r22.TotalStateProvinceTaxes); int intAirCharge = Convert.ToInt32(r22.AirCharge); int intTollCharge = Convert.ToInt32(r22.TollCharge); int totalChargesAndTaxesThisRecord = intTotalLocalTaxes + intTotalStateProvinceTaxes + intAirCharge + intTollCharge; // calculate new charges for this file and maintain the total // cri.BatchTotalChargesAndTaxes = cri.BatchTotalChargesAndTaxes + ... for out trailer // increment the record count if a valid record cri.TotalNumberOfRecordsInBatch++; //cri.BatchTotalChargesAndTaxes = cri.BatchTotalChargesAndTaxes + r22. cri.BatchTotalChargesAndTaxes = cri.BatchTotalChargesAndTaxes + totalChargesAndTaxesThisRecord; r22.TotalChargesAndTaxes = totalChargesAndTaxesThisRecord.ToString(); // finally write this cdr to the file // cfw.WriteToFile(r22.ToCiberStringFormat()); } catch (ApplicationException ae) { cfw.WriteToLogFile(DateTime.Now.ToShortDateString() + ae.Message + "\r\n" + ae.StackTrace); } catch (IOException ioe) { cfw.WriteToLogFile(DateTime.Now.ToShortDateString() + ioe.Message + "\r\n" + ioe.StackTrace); } }