/// <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(IsoMessage request) { IsoMessage resp = new IsoMessage(_isoHeaders[request.Type + 16]) { Type = request.Type + 16, Etx = _etx }; IsoMessage templ = _typeTemplates[resp.Type]; if (templ != null) { for (int i = 2; i < 128; i++) { if (templ.HasField(i)) { resp.SetField(i, (IsoValue)templ.GetField(i).Clone()); } } } for (int i = 2; i < 128; i++) { if (request.HasField(i)) { resp.SetField(i, (IsoValue)request.GetField(i).Clone()); } } return(resp); }
/// <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 NewMessage(int type) { IsoMessage m = new IsoMessage(_isoHeaders[type]) { Type = type, Etx = Etx }; IsoMessage templ = _typeTemplates[type]; if (templ != null) { for (int 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); } if (AssignDate) { m.SetValue(7, DateTime.Now, IsoType.DATE10, 10); } return(m); }
/// <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); }