/// <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="buf">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> public IsoMessage ParseMessage(byte[] buf, int isoHeaderLength, Encoding encoder) { IsoMessage m = new IsoMessage(isoHeaderLength > 0 ? encoder.GetString(buf, 0, isoHeaderLength) : null); int type = ((buf[isoHeaderLength] - 48) << 12) | ((buf[isoHeaderLength + 1] - 48) << 8) | ((buf[isoHeaderLength + 2] - 48) << 4) | (buf[isoHeaderLength + 3] - 48); m.Type = type; //Parse the bitmap bool extended = (HexByteValue(buf[isoHeaderLength + 4]) & 8) > 0; BitArray bs = new BitArray(extended ? 128 : 64); int pos = 0; for (int i = isoHeaderLength + 4; i < isoHeaderLength + 20; i++) { int hex = HexByteValue(buf[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)) { for (int i = isoHeaderLength + 20; i < isoHeaderLength + 36; i++) { int hex = HexByteValue(buf[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 = 36 + isoHeaderLength; } else { pos = 20 + isoHeaderLength; } //Parse each field Dictionary <int, FieldParseInfo> guide = _parseMap[type]; List <int> index = _parseOrder[type]; foreach (int i in index) { FieldParseInfo fpi = guide[i]; if (i <= bs.Count) { // TM extended parsing if (bs.Get(i - 1)) { IsoValue val = fpi.Parse(buf, pos, encoder); m.SetField(i, val); pos += val.Length; if (val.Type == IsoType.LLVAR || val.Type == IsoType.LLVARnp) { pos += 2; //@@@ TAM temporary hardcode, must be a better way to parse Padding F if (val.Type == IsoType.LLVAR && (val.Length % 2 != 0)) { pos += 1; } } else if (val.Type == IsoType.LLLVAR) { //@@@ TAM packe 3 change to 4 for Paymark //pos += 3; pos += 4; } else if (val.Type == IsoType.LLLVARnp) // for NAB the LLLVAR Non packed(ascci codec) will have HEX as length so 6 digits(303139 = 019) { pos += 6; } } } } return(m); }
/// <summary> /// Creates a MessageFactory and configures it from the XML file read /// from the absolute path specified. /// </summary> /// <param name="filename">An absolute path to the XML configuration file.</param> /// <returns>A new configured MessageFactory.</returns> public static MessageFactory CreateFromFile(string filename) { XmlDocument xml = new XmlDocument(); xml.Load(filename); MessageFactory m = new MessageFactory(); foreach (XmlNode node in xml.DocumentElement.ChildNodes) { if (node.NodeType == XmlNodeType.Element) { if ("header".Equals(node.Name)) { string type = node.Attributes["type"].Value; string header = node.ChildNodes[0].Value; m.SetIsoHeader(Convert.ToInt16(type, 16), header); } else if ("template".Equals(node.Name)) { int type = Convert.ToInt16(node.Attributes["type"].Value, 16); IsoMessage templ = new IsoMessage(); templ.Type = type; foreach (XmlNode field in node.ChildNodes) { if (field.NodeType == XmlNodeType.Element && "field".Equals(field.Name)) { int num = Convert.ToInt16(field.Attributes["num"].Value); string ftype = field.Attributes["type"].Value; string length = field.Attributes["length"] == null ? "0" : field.Attributes["length"].Value; string val = field.ChildNodes[0].Value; //Ir creando mensaje con esto templ.SetValue(num, val, (IsoType)Enum.Parse(typeof(IsoType), ftype), Convert.ToInt16(length)); } } m.AddMessageTemplate(templ); } else if ("parse".Equals(node.Name)) { int type = Convert.ToInt16(node.Attributes["type"].Value, 16); Dictionary <int, FieldParseInfo> guide = new Dictionary <int, FieldParseInfo>(); foreach (XmlNode field in node.ChildNodes) { if (field.NodeType == XmlNodeType.Element && "field".Equals(field.Name)) { string num = field.Attributes["num"].Value; string ftype = field.Attributes["type"].Value; XmlAttribute lenAttr = field.Attributes["length"]; int len = 0; if (lenAttr != null) { len = Convert.ToInt16(lenAttr.Value); } //TODO ir creando guia con esto FieldParseInfo fpi = new FieldParseInfo((IsoType)Enum.Parse(typeof(IsoType), ftype), len); guide[Convert.ToInt16(num)] = fpi; } } m.SetParseDictionary(type, guide); } else if ("assign-date".Equals(node.Name)) { string val = node.Attributes["value"].Value; m.AssignDate = "true".Equals(val); } } } return(m); }