/// <summary> /// Parses a byte buffer containing an ISO8583 message. The buffer must /// not include the length header. If it includes the ISO message header, /// then its length must be specified so the message type can be found. /// </summary> /// <param name="mti_bitmap">The byte buffer containing the message, starting /// at the ISO header or the message type.</param> /// <param name="isoHeaderLength">Specifies the position at which the message /// type is located, which is algo the length of the ISO header.</param> /// <param name="encoder">The encoder to use for reading string values.</param> /// <returns>The parsed message.</returns> private IsoMessage ParseMessage(CaseBusiness.CC.Global.MensagemInterfaceDados interfaceDados, Byte[] mti_bitmap, Byte[] messageData, Int32 isoHeaderLength, Encoding encoder, ParseMode parseMode) { Int32 pos = 0; IsoMessage m = (isoHeaderLength > 0) ? new IsoMessage(interfaceDados.MensagemInterfaceHeader.TipoCodificacao, encoder.GetString(mti_bitmap, 0, isoHeaderLength)) : new IsoMessage(EncodingType.NotDefined, null); m.isValid = true; m.MapFields = interfaceDados.MensagemInterfaceHeader.MapaCamposVAR; m.IdInterface = interfaceDados.MensagemInterfaceHeader.IdMensagemInterfaceHeader; Int32 type = ((mti_bitmap[isoHeaderLength] - 48) << 12) | ((mti_bitmap[isoHeaderLength + 1] - 48) << 8) | ((mti_bitmap[isoHeaderLength + 2] - 48) << 4) | (mti_bitmap[isoHeaderLength + 3] - 48); m.Type = type; //Parse the bitmap BitArray bs = ((HexByteValue(mti_bitmap[isoHeaderLength + ConfigParser.ISOLengthMTI]) & 8) > 0) ? new BitArray(128) : new BitArray(64); Int32 tamanhoMensagemAtePrimeiroMapaDeBits = ConfigParser.ISOLengthMTI + ConfigParser.ISOLengthBitMap; for (Int32 i = isoHeaderLength + ConfigParser.ISOLengthMTI; i < isoHeaderLength + tamanhoMensagemAtePrimeiroMapaDeBits; i++) { Int32 hex = HexByteValue(mti_bitmap[i]); bs.Set(pos++, (hex & 8) > 0); bs.Set(pos++, (hex & 4) > 0); bs.Set(pos++, (hex & 2) > 0); bs.Set(pos++, (hex & 1) > 0); } //Extended bitmap if (bs.Get(0)) { Int32 tamanhoMensagemAteSegundoMapaDeBits = tamanhoMensagemAtePrimeiroMapaDeBits + ConfigParser.ISOLengthBitMap; for (Int32 i = isoHeaderLength + tamanhoMensagemAtePrimeiroMapaDeBits; i < isoHeaderLength + tamanhoMensagemAteSegundoMapaDeBits; i++) { Int32 hex = HexByteValue(mti_bitmap[i]); bs.Set(pos++, (hex & 8) > 0); bs.Set(pos++, (hex & 4) > 0); bs.Set(pos++, (hex & 2) > 0); bs.Set(pos++, (hex & 1) > 0); } } pos = 0; m.BitArray = bs; foreach (KeyValuePair <Int32, FieldParseInfo> i in interfaceDados.MensagemInterfaceHeader.MapaCamposVAR) { try { if (!bs.Get(i.Key - 1)) //Sу efetua checagem se o field do mapa existe na mensagem, caso nгo tenha, pula pro proximo field ou gera exception e pula pro proximo. Class BitArray nгo tem opзгo para checar se um bit estб ligado/desligado { continue; } } catch (ArgumentOutOfRangeException) { continue; } FieldParseInfo fpi = i.Value; IsoValue val = fpi.Parse(interfaceDados.MensagemInterfaceHeader.TipoCodificacao, messageData, pos, encoder, false); if (val.OriginalValue != null) { if (parseMode == ParseMode.Complete) { if (fpi.SubDataElements_Fields != null) { if (fpi.SubDataElements_Fields.Count > 0) { val = parseDataElement_Field(interfaceDados.MensagemInterfaceHeader.TipoCodificacao, fpi.Base, fpi.SubDataElements_Fields, val, encoder, ref pos); } if (val == null) { m.isValid = false; return(m); } } } if (interfaceDados.MensagemInterfaceHeader.TipoCodificacao == EncodingType.EBCDIC && fpi.Base == ConfigParser.Base.Hexadecimal) { pos += val.Length / 2; } else { pos += val.Length; } if (val.Type == IsoType.LLVAR) { pos += 2; } else if (val.Type == IsoType.LLLVAR) { pos += 3; } m.SetField(i.Key, val); if (fpi.Required && !bs.Get(i.Key - 1)) { m.isValid = false; } } } return(m); }
/// <summary> /// Creates a new message of the given type. If there is a template /// for the message type, then it is used to set all the values in the /// new message (the values will be copied from the original messages, /// not referred to directly, to avoid affecting the templates if a value /// in a message created this way is modified). If the factory has an /// ITraceGenerator set, it uses it to assign a new trace number as a /// NUMERIC value of length 6 in field 11; if AssignDate is true, /// then the current DateTime is stored in field 7 as a DATE10 type. /// </summary> /// <param name="type"></param> /// <returns></returns> //public IsoMessage NewTemplateMessage(Int32 type) //{ // IsoMessage m = (ConfigParser.ISOHeaders.ContainsKey(type)) ? new IsoMessage(ConfigParser.ISOHeaders[type]) : new IsoMessage(null); // m.Type = type; // m.Etx = Etx; // if (ConfigParser.ISOTypeTemplates.ContainsKey(type)) // { // IsoMessage templ = ConfigParser.ISOTypeTemplates[type]; // for (Int32 i = 2; i < 128; i++) // { // if (templ.HasField(i)) // m.SetField(i, (IsoValue)templ.GetField(i).Clone()); // } // } // if (TraceGenerator != null) // { // m.SetValue(11, TraceGenerator.NextTrace(), IsoType.NUMERIC, 6, TypeElement.Field); // } // if (ConfigParser.ISOAssignDate) // { // m.SetValue(7, DateTime.Now, IsoType.DATE10, 10, TypeElement.Field); // } // return m; //} /// <summary> /// Creates a new message of the given type. If there is a template /// for the message type, then it is used to set all the values in the /// new message (the values will be copied from the original messages, /// not referred to directly, to avoid affecting the templates if a value /// in a message created this way is modified). If the factory has an /// ITraceGenerator set, it uses it to assign a new trace number as a /// NUMERIC value of length 6 in field 11; if AssignDate is true, /// then the current DateTime is stored in field 7 as a DATE10 type. /// </summary> /// <param name="type"></param> /// <returns></returns> //public IsoMessage NewParseMessage(Int32 type) //{ // IsoMessage m = (ConfigParser.ISOHeaders.ContainsKey(type)) ? new IsoMessage(ConfigParser.ISOHeaders[type]) : new IsoMessage(null); // m.Type = type; // m.Etx = Etx; // if (ConfigParser.ISOParseMap.ContainsKey(type)) // { // Dictionary<Int32, FieldParseInfo> guide = ConfigParser.ISOParseMap[type]; // List<Int32> index = ConfigParser.ISOParseOrder[type]; // foreach (Int32 i in index) // { // FieldParseInfo fpi = guide[i]; // if (fpi.SubData.Count > 0) // { // Dictionary<Int32, IsoValue> subFieldList = new Dictionary<int, IsoValue>(); // IsoValue subField = null; // foreach (KeyValuePair<Int32, FieldParseInfo> fpiSub in fpi.SubData) // { // switch (fpiSub.Value.Type) // { // case IsoType.NUMERIC: // subField = new IsoValue(fpiSub.Value.Type, "0".PadRight(fpiSub.Value.Length, '0'), fpiSub.Value.Length, "0".PadRight(fpiSub.Value.Length, '0'), fpiSub.Value.TypeElement); // break; // case IsoType.ALPHA: // subField = new IsoValue(fpiSub.Value.Type, "0".PadRight(fpiSub.Value.Length, '0'), fpiSub.Value.Length, "0".PadRight(fpiSub.Value.Length, '0'), fpiSub.Value.TypeElement); // break; // case IsoType.LLVAR: // subField = new IsoValue(fpiSub.Value.Type, "00", "00"); // break; // case IsoType.LLLVAR: // subField = new IsoValue(fpiSub.Value.Type, "000", "000"); // break; // case IsoType.DATE10: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("MMddHHmmss")); // break; // case IsoType.DATE12: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("yyMMddHHmmss")); // break; // case IsoType.DATE6: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("yyMMdd")); // break; // case IsoType.DATE4: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("MMdd")); // break; // case IsoType.DATE_EXP: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("YYmm")); // break; // case IsoType.TIME: // subField = new IsoValue(fpiSub.Value.Type, DateTime.Now, DateTime.Now.ToString("HHmmss")); // break; // case IsoType.AMOUNT: // subField = new IsoValue(fpiSub.Value.Type, "000000000000", "000000000000"); // break; // } // subFieldList.Add(fpiSub.Key, subField); // } // m.SetField(i, new IsoValue(fpi.Type, "0".PadRight(fpi.Length, '0'), fpi.Length, "0".PadRight(fpi.Length, '0'), "", subFieldList)); // } // else // { // switch (fpi.Type) // { // case IsoType.NUMERIC: // m.SetField(i, new IsoValue(fpi.Type, "0".PadRight(fpi.Length, '0'), fpi.Length, "0".PadRight(fpi.Length, '0'), fpi.TypeElement)); // break; // case IsoType.ALPHA: // m.SetField(i, new IsoValue(fpi.Type, "0".PadRight(fpi.Length, '0'), fpi.Length, "0".PadRight(fpi.Length, '0'), fpi.TypeElement)); // break; // case IsoType.LLVAR: // m.SetField(i, new IsoValue(fpi.Type, "00", "00")); // break; // case IsoType.LLLVAR: // m.SetField(i, new IsoValue(fpi.Type, "000", "000")); // break; // case IsoType.DATE10: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("MMddHHmmss"))); // break; // case IsoType.DATE12: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("yyMMddHHmmss"))); // break; // case IsoType.DATE6: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("yyMMdd"))); // break; // case IsoType.DATE4: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("MMdd"))); // break; // case IsoType.DATE_EXP: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("YYmm"))); // break; // case IsoType.TIME: // m.SetField(i, new IsoValue(fpi.Type, DateTime.Now, DateTime.Now.ToString("HHmmss"))); // break; // case IsoType.AMOUNT: // m.SetField(i, new IsoValue(fpi.Type, "000000000000", "000000000000")); // break; // } // } // } // } // if (TraceGenerator != null) // { // m.SetValue(11, TraceGenerator.NextTrace(), IsoType.NUMERIC, 6, TypeElement.Field); // } // if (ConfigParser.ISOAssignDate) // { // m.SetValue(7, DateTime.Now, IsoType.DATE10, 10, TypeElement.Field); // } // return m; //} /// <summary> /// Creates a response for the specified request, by creating a new /// message with a message type of the original request type plus 16. /// If there is a template for the resulting type, its values are copied /// onto the new message; after that, all the values from the original /// request that are not already in the response are copied to it. /// </summary> /// <param name="request">An ISO8583 request.</param> /// <returns>A new ISO8583 message with the corresponding response /// type for the request and with values already copied from its /// template (if any) and the request.</returns> public IsoMessage CreateResponse(CaseBusiness.CC.Global.MensagemInterfaceDados interfaceDados, IsoMessage request) { Int32 responseType = request.Type + 16; IsoMessage resp = (ConfigParser.ISOHeaders.ContainsKey(responseType)) ? new IsoMessage(interfaceDados.MensagemInterfaceHeader.TipoCodificacao, ConfigParser.ISOHeaders[responseType]) : new IsoMessage(); IsoMessage templ = null; resp.Type = responseType; resp.Etx = etx; if (ConfigParser.ISOTypeTemplates.ContainsKey(resp.Type)) { templ = ConfigParser.ISOTypeTemplates[resp.Type]; } if (templ != null) { for (Int32 i = 2; i < 128; i++) { if (templ.Has(i)) { resp.SetField(i, (IsoValue)templ.Get(i).Clone()); if (request.Has(i)) { IsoValue field = request.Get(i); if (field.SubData != null) { if (field.SubData.Count > 0) { foreach (KeyValuePair <Int32, IsoValue> subValue in field.SubData) { if (templ.Has(i, subValue.Key)) { IsoValue v = (IsoValue)templ.Get(i, subValue.Key).Clone(); resp.SetSubData(i, subValue.Key, new IsoValue(v.Type, field.Base, subValue.Value, subValue.Value.ToString().Length, subValue.Value.ToString(), v.Requirements, v.TypeElement, v.SubElementIDLength, v.LengthOfLengthSubElement)); } } } else { resp.SetField(i, field); } } else { resp.SetField(i, field); } } else { if (templ.Get(i).Requirements == "CE") { resp.SetField(i, null); } } } } } else { resp = new IsoMessage(); } return(resp); }