Skip to content

Commit 23f6ada

Browse files
feat: add ioProx tag type support (#841)
1 parent ed18d4e commit 23f6ada

10 files changed

Lines changed: 108 additions & 5 deletions

File tree

chameleonultragui/lib/bridge/chameleon.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,16 @@ class ChameleonCommunicator {
571571
return VikingCard.fromBytes(resp.data);
572572
}
573573

574+
Future<IoProxCard?> readIoProx() async {
575+
var resp = await sendCmd(ChameleonCommand.scanIoProxTag);
576+
577+
if (resp!.data.isEmpty) {
578+
return null;
579+
}
580+
581+
return IoProxCard.fromBytes(resp.data);
582+
}
583+
574584
Future<void> setEM410XEmulatorID(Uint8List uid) async {
575585
await sendCmd(ChameleonCommand.setEM410XemulatorID, data: uid);
576586
}
@@ -583,6 +593,10 @@ class ChameleonCommunicator {
583593
await sendCmd(ChameleonCommand.setVikingEmulatorID, data: uid);
584594
}
585595

596+
Future<void> setIoProxEmulatorID(Uint8List uid) async {
597+
await sendCmd(ChameleonCommand.setIoProxEmulatorID, data: uid);
598+
}
599+
586600
Future<void> writeEM410XtoT55XX(
587601
Uint8List uid, Uint8List newKey, List<Uint8List> oldKeys) async {
588602
List<int> keys = [];
@@ -631,6 +645,20 @@ class ChameleonCommunicator {
631645
data: Uint8List.fromList([...uid, ...newKey, ...keys]));
632646
}
633647

648+
Future<void> writeIoProxToT55XX(
649+
Uint8List uid, Uint8List newKey, List<Uint8List> oldKeys) async {
650+
List<int> keys = [];
651+
652+
keys.addAll(newKey);
653+
654+
for (var oldKey in oldKeys) {
655+
keys.addAll(oldKey);
656+
}
657+
658+
await sendCmd(ChameleonCommand.writeIoProxToT5577,
659+
data: Uint8List.fromList([...uid, ...newKey, ...keys]));
660+
}
661+
634662
Future<void> setSlotTagName(
635663
int index, String name, TagFrequency frequency) async {
636664
await sendCmd(ChameleonCommand.setSlotTagNick,
@@ -963,6 +991,11 @@ class ChameleonCommunicator {
963991
(await sendCmd(ChameleonCommand.getVikingEmulatorID))!.data);
964992
}
965993

994+
Future<IoProxCard> getIoProxEmulatorID() async {
995+
return IoProxCard.fromBytes(
996+
(await sendCmd(ChameleonCommand.getIoProxEmulatorID))!.data);
997+
}
998+
966999
Future<DeviceSettings> getDeviceSettings() async {
9671000
var resp = (await sendCmd(ChameleonCommand.getDeviceSettings))!.data;
9681001
if (resp[0] != 5) {

chameleonultragui/lib/gui/menu/dialogs/slot/edit.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ class SlotEditMenuState extends State<SlotEditMenu> {
9393
await appState.communicator!.getVikingEmulatorID();
9494
uidController.text = bytesToHexSpace(vikingCard.uid);
9595
} catch (_) {}
96+
} else if (selectedType! == TagType.ioProx) {
97+
try {
98+
IoProxCard ioProxCard =
99+
await appState.communicator!.getIoProxEmulatorID();
100+
uidController.text = bytesToHexSpace(ioProxCard.uid);
101+
} catch (_) {}
96102
} else if (isMifareClassic(selectedType!) ||
97103
isMifareUltralight(selectedType!)) {
98104
try {
@@ -189,6 +195,9 @@ class SlotEditMenuState extends State<SlotEditMenu> {
189195
await appState.communicator!
190196
.setHIDProxEmulatorID(hexToBytes(hidCard.toString()));
191197
} catch (_) {}
198+
} else if (selectedType! == TagType.ioProx) {
199+
await appState.communicator!.setIoProxEmulatorID(
200+
hexToBytes(uidController.text.replaceAll(' ', '')));
192201
} else if (isMifareClassic(selectedType!) ||
193202
isMifareUltralight(selectedType!)) {
194203
var cardData = CardData(

chameleonultragui/lib/gui/menu/dialogs/slot/export.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class SlotExportMenuState extends State<SlotExportMenu> {
5959
name: widget.names.lf,
6060
tag: widget.slotTypes.lf,
6161
);
62+
} else if (widget.slotTypes.lf == TagType.ioProx) {
63+
return CardSave(
64+
uid: (await appState.communicator!.getIoProxEmulatorID()).toString(),
65+
name: widget.names.lf,
66+
tag: widget.slotTypes.lf,
67+
);
6268
}
6369
} else {
6470
CardData data = await appState.communicator!.mf1GetAntiCollData();

chameleonultragui/lib/gui/page/home.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class HomePageState extends State<HomePage> {
5353
// Checks that firmware supports all functions of current app
5454
// If not, prompt user to update firmware (as outdated firmware might break app)
5555

56-
int ultraCapability = ChameleonCommand.setVikingEmulatorID.value;
57-
int liteCapability = ChameleonCommand.setVikingEmulatorID.value;
56+
int ultraCapability = ChameleonCommand.setIoProxEmulatorID.value;
57+
int liteCapability = ChameleonCommand.setIoProxEmulatorID.value;
5858

5959
var appState = context.read<ChameleonGUIState>();
6060
List<int> capabilities;

chameleonultragui/lib/gui/page/read_card.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class ReadCardPageState extends State<ReadCardPage> {
127127
LFCard? card = await appState.communicator!.readEM410X();
128128
card ??= await appState.communicator!.readHIDProx();
129129
card ??= await appState.communicator!.readViking();
130+
card ??= await appState.communicator!.readIoProx();
130131

131132
if (card != null) {
132133
setState(() {

chameleonultragui/lib/gui/page/slot_manager.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,22 @@ class SlotManagerPageState extends State<SlotManagerPage> {
202202
await appState.communicator!.saveSlotData();
203203
appState.changesMade();
204204
refreshSlot();
205+
} else if (card.tag == TagType.ioProx) {
206+
close(context, card.name);
207+
await appState.communicator!.setReaderDeviceMode(false);
208+
await appState.communicator!
209+
.enableSlot(gridPosition, TagFrequency.lf, true);
210+
await appState.communicator!.activateSlot(gridPosition);
211+
await appState.communicator!.setSlotType(gridPosition, card.tag);
212+
await appState.communicator!.setDefaultDataToSlot(gridPosition, card.tag);
213+
await appState.communicator!.setIoProxEmulatorID(hexToBytes(card.uid));
214+
await appState.communicator!.setSlotTagName(
215+
gridPosition,
216+
(card.name.isEmpty) ? localizations.no_name : card.name,
217+
TagFrequency.lf);
218+
await appState.communicator!.saveSlotData();
219+
appState.changesMade();
220+
refreshSlot();
205221
} else if (isMifareUltralight(card.tag)) {
206222
close(context, card.name);
207223
setUploadState(0);

chameleonultragui/lib/helpers/definitions.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ enum ChameleonCommand {
8383
writeHIDProxToT5577(3003),
8484
scanVikingTag(3004),
8585
writeVikingToT5577(3005),
86+
scanIoProxTag(3010),
87+
writeIoProxToT5577(3011),
8688

8789
mf1LoadBlockData(4000),
8890
mf1SetAntiCollision(4001),
@@ -136,7 +138,10 @@ enum ChameleonCommand {
136138
getHIDProxEmulatorID(5003),
137139

138140
setVikingEmulatorID(5004),
139-
getVikingEmulatorID(5005);
141+
getVikingEmulatorID(5005),
142+
143+
setIoProxEmulatorID(5008),
144+
getIoProxEmulatorID(5009);
140145

141146
const ChameleonCommand(this.value);
142147
final int value;
@@ -151,6 +156,7 @@ enum TagType {
151156
em410XElectra(104),
152157
viking(170),
153158
hidProx(200),
159+
ioProx(201),
154160
mifareMini(1000),
155161
mifare1K(1001),
156162
mifare2K(1002),
@@ -576,3 +582,18 @@ class VikingCard extends LFCard {
576582
required super.uid,
577583
});
578584
}
585+
586+
class IoProxCard extends LFCard {
587+
factory IoProxCard.fromBytes(Uint8List bytes) {
588+
return IoProxCard(uid: bytes);
589+
}
590+
591+
factory IoProxCard.fromUID(String uid) {
592+
return IoProxCard.fromBytes(hexToBytes(uid));
593+
}
594+
595+
IoProxCard({
596+
super.type = TagType.ioProx,
597+
required super.uid,
598+
});
599+
}

chameleonultragui/lib/helpers/general.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ String chameleonTagToString(TagType tag, AppLocalizations localizations) {
165165
return "HID Prox";
166166
} else if (tag == TagType.viking) {
167167
return "Viking";
168+
} else if (tag == TagType.ioProx) {
169+
return "ioProx";
168170
} else if (tag == TagType.ntag210) {
169171
return "NTAG210";
170172
} else if (tag == TagType.ntag212) {
@@ -449,7 +451,8 @@ List<TagType> getTagTypesByFrequency(TagFrequency frequency) {
449451
TagType.em410X64,
450452
TagType.em410XElectra,
451453
TagType.hidProx,
452-
TagType.viking
454+
TagType.viking,
455+
TagType.ioProx
453456
];
454457
}
455458

@@ -543,6 +546,10 @@ LFCard getLFCardFromUID(TagType type, String uid) {
543546
return VikingCard.fromUID(uid);
544547
}
545548

549+
if (type == TagType.ioProx) {
550+
return IoProxCard.fromUID(uid);
551+
}
552+
546553
return EM410XCard.fromUID(uid, type: type);
547554
}
548555

@@ -555,6 +562,8 @@ int uidSizeForLfTag(TagType type) {
555562
return 5;
556563
} else if (type == TagType.viking) {
557564
return 4;
565+
} else if (type == TagType.ioProx) {
566+
return 16;
558567
}
559568

560569
return 0;

chameleonultragui/lib/helpers/t55xx/write/base.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ class BaseT55XXCardHelper extends AbstractWriteHelper {
161161
hexToBytes(newKey), [hexToBytes(currentKey), Uint8List(4)]);
162162
var newCard = await communicator.readViking();
163163
return newCard.toString() == card.uid;
164+
} else if (card.tag == TagType.ioProx) {
165+
await communicator.writeIoProxToT55XX(hexToBytes(card.uid),
166+
hexToBytes(newKey), [hexToBytes(currentKey), Uint8List(4)]);
167+
var newCard = await communicator.readIoProx();
168+
return newCard.toString() == card.uid;
164169
}
165170

166171
return false;

chameleonultragui/lib/helpers/write.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ abstract class AbstractWriteHelper {
6161
return BaseMifareUltralightWriteHelper(appState.communicator!);
6262
}
6363

64-
if (isEM410X(type) || type == TagType.hidProx || type == TagType.viking) {
64+
if (isEM410X(type) ||
65+
type == TagType.hidProx ||
66+
type == TagType.viking ||
67+
type == TagType.ioProx) {
6568
return BaseT55XXCardHelper(appState.communicator!);
6669
}
6770

0 commit comments

Comments
 (0)