Skip to content

Commit

Permalink
Added more fields and standardized few others.
Browse files Browse the repository at this point in the history
  • Loading branch information
xclud committed Jun 26, 2024
1 parent 82e9f63 commit 9816ae3
Showing 1 changed file with 128 additions and 30 deletions.
158 changes: 128 additions & 30 deletions lib/src/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Message {
day = int.parse(dd);
} else if (o == 24) {
final niiString = data.substring(0, 4);

data = data.substring(4);

final nii = int.parse(niiString, radix: 16);
Expand Down Expand Up @@ -102,27 +103,38 @@ class Message {
final terminalString = data.substring(0, 16);
data = data.substring(16);

message.terminalId = terminalString;
final tidBytes = hex.decode(terminalString);
final tid = String.fromCharCodes(tidBytes);
message.terminalId = tid;
} else if (o == 48) {
final len = _readLength4Hex(data) * 2;
data = data.substring(4);

final f48 = data.substring(0, len);
data = data.substring(len);

message._f48DataElement = hex.decode(f48);
message.dataElement =
hex.decode((len ~/ 2).toString().padLeft(4, '0')) + hex.decode(f48);
} else if (o == 49) {
final currencyCodeString = data.substring(0, 6);
data = data.substring(6);

final currencyCode =
int.parse(String.fromCharCodes(hex.decode(currencyCodeString)));
message.currency = currencyCode;
} else if (o == 62) {
final len = _readLength4(data) * 2;
data = data.substring(4);

message.field62 = hex.decode(data.substring(0, len));
data = data.substring(len);
} else if (o == 64) {
final macString = data.substring(0, 16);
data = data.substring(16);

message.mac = Uint8List.fromList(hex.decode(macString));
} else {
print('NOT IMPLEMENTED: $o');
}
}

Expand Down Expand Up @@ -165,6 +177,11 @@ class Message {
copy._f49Currency = _f49Currency;
copy._f52PinBlock =
f52PinBlock == null ? null : Uint8List.fromList(f52PinBlock);

copy.field53 = field53;
copy.field61 = field61;
copy.field62 = field62;

copy._mac = _mac;

copy._bmp.addAll(_bmp);
Expand All @@ -178,7 +195,7 @@ class Message {
final fmac = alg != null ? calcmac(alg) : (mac ?? Uint8List(0));

final bdy = _body();
final bmp = _bitmap();
final bmp = _bitmap(alg != null);

final xx = mti + hex.encode(bmp) + bdy + hex.encode(fmac);
return xx;
Expand All @@ -202,6 +219,9 @@ class Message {
int? _f49Currency;

List<int>? _f52PinBlock;
List<int>? _f53;
List<int>? _f61;
List<int>? _f62;
List<int>? _mac;

/// PAN, the Card Number.
Expand Down Expand Up @@ -270,7 +290,8 @@ class Message {
}
}

/// Systems trace audit number.
/// Systems Trace Audit Number (STAN).
///
/// Field 11.
///
/// Must be in (1,9999) range.
Expand Down Expand Up @@ -477,14 +498,8 @@ class Message {
List<int>? get dataElement => _f48DataElement;
set dataElement(List<int>? value) {
final v = value;

if (v == null) {
_bmp[48] = false;
_f48DataElement = null;
} else {
_bmp[48] = true;
_f48DataElement = value;
}
_bmp[48] = v != null;
_f48DataElement = v;
}

/// Currency.
Expand Down Expand Up @@ -522,6 +537,33 @@ class Message {
}
}

/// Field 53.
List<int>? get field53 => _f53;
set field53(List<int>? value) {
final v = value;

_bmp[53] = v != null;
_f53 = value;
}

/// Field 61.
List<int>? get field61 => _f61;
set field61(List<int>? value) {
final v = value;

_bmp[61] = v != null;
_f61 = value;
}

/// Field 62.
List<int>? get field62 => _f62;
set field62(List<int>? value) {
final v = value;

_bmp[62] = v != null;
_f62 = value;
}

/// MAC.
/// Field 64 or 128.
///
Expand Down Expand Up @@ -649,8 +691,12 @@ class Message {
final p = nii;

if (p != null) {
final bt = ByteData(4);
bt.setUint32(0, p, Endian.big);

final f24 = p.toRadixString(16).padLeft(4, '0');
strBits.add(f24);
final s24 = hex.encode(f24.codeUnits);
strBits.add(s24);
}

continue;
Expand Down Expand Up @@ -685,16 +731,16 @@ class Message {
final p = responseCode;

if (p != null) {
strBits.add(p);
strBits.add(hex.encode(p.codeUnits));
}

continue;
} else if (i == 41) {
final p = terminalId;

if (p != null) {
final pp = p.padLeft(8, '0');
strBits.add(hex.encode(pp.codeUnits));
//final pp = p.padLeft(8, '0');
strBits.add(hex.encode(p.codeUnits));
}

continue;
Expand Down Expand Up @@ -737,10 +783,33 @@ class Message {
}

continue;
} else if (i == 64) {
final p = mac;
} else if (i == 53) {
final p = field53;

if (p != null) {
strBits.add(hex.encode(p));
}

continue;
}
// else if (i == 61) {
// final p = field61;

// if (p != null) {
// final length = p.length * 2;
// strBits.add(p.length.toString().padLeft(4, '0'));
// strBits.add(hex.encode(p));
// }

// continue;
// }
else if (i == 62) {
final p = field62;

if (p != null) {
final length = p.length;

strBits.add(length.toString().padLeft(4, '0'));
strBits.add(hex.encode(p));
}

Expand All @@ -751,7 +820,7 @@ class Message {
return v;
}

Uint8List _bitmap() {
Uint8List _bitmap(bool forceMac) {
final bits = <String>[];

for (var i = 1; i <= 64; i++) {
Expand All @@ -761,6 +830,11 @@ class Message {
bits.add('0');
}
}

if (forceMac) {
bits[63] = '1';
}

final v = int.parse(bits.join(), radix: 2);
return _getBytes(v);
}
Expand All @@ -769,21 +843,19 @@ class Message {
Uint8List calcmac(Uint8List Function(List<int> message) algorithm) {
final c = clone();
c.mac = Uint8List(8);
final bmp = c._bitmap();
final bmp = c._bitmap(true);
c.mac = null;

final List<Uint8List> v = [];
final List<String> v = [];

v.add(Uint8List.fromList(hex.decode(c.mti)));
v.add(bmp);
//v.add(c._body());
v.add(c.mti);
v.add(hex.encode(bmp));
v.add(c._body());

final vv = v.expand((element) => element).toList();
final vv = hex.decode(v.join());
final en = algorithm(vv);

final mc = en.skip((en.length ~/ 8 - 1) * 8).take(8).toList();

return Uint8List.fromList(mc);
return Uint8List.fromList(en);
}

/// Converts the [Message] object to JSON.
Expand All @@ -809,14 +881,20 @@ class Message {
final mCurrency = currency;
final mDataElement = dataElement;
final mPinBlock = pinBlock;
final mField53 = field53;
final mField61 = field61;
final mField62 = field62;

final mMac = mac;

if (mPan != null) {
map['pan'] = mPan;
}

if (mProcessCode != null) {
map['processCode'] = mProcessCode;
final processCodeHex =
mProcessCode.toRadixString(16).padLeft(8, '0').substring(2);
map['processCode'] = '0x$processCodeHex';
}

if (mAmount != null) {
Expand Down Expand Up @@ -879,8 +957,21 @@ class Message {
map['pinBlock'] = '0x${hex.encode(mPinBlock).toUpperCase()}';
}

if (mField53 != null) {
map['field53'] = '0x${hex.encode(mField53).toUpperCase()}';
}

if (mField61 != null) {
map['field61'] = '0x${hex.encode(mField61).toUpperCase()}';
}

if (mField62 != null) {
map['field62'] = '0x${hex.encode(mField62).toUpperCase()}';
}

if (mMac != null) {
map['MAC'] = mMac;
final macHex = hex.encode(mMac).toUpperCase();
map['MAC'] = '0x$macHex';
}

return map;
Expand All @@ -904,6 +995,13 @@ int _readLength2(String data) {
return v;
}

int _readLength4(String data) {
final sub = data.substring(0, 4);
final v = int.parse(sub);

return v;
}

int _readLength4Hex(String data) {
final sub = data.substring(0, 4);
final v = int.parse(sub);
Expand Down

0 comments on commit 9816ae3

Please sign in to comment.