Documentation: Update copyrights to 2019.
[pub/lufa.git] / Demos / Device / ClassDriver / CCID / HostTestApp / test_generic_ccid_libusb.js
1 #!/usr/bin/env node
2
3 // LUFA Library
4 // Copyright (C) Dean Camera, 2019.
5 //
6 // dean [at] fourwalledcubicle [dot] com
7 //
8 // www.lufa-lib.org
9
10 // Copyright 2019 Filipe Rodrigues (filipepazrodrigues [at] gmail [dot] com)
11 //
12 // LUFA Generic CCID device demo host test script. This script test multiple
13 // kinds of CCID messages and shows the result to the console
14 //
15 // You have to install the usb and async modules prior to executing this script:
16 // apt-get install libusb-1.0-0-dev
17 // npm install usb async sprintf
18
19 var usb = require('usb');
20 var async = require('async');
21 var sprintf = require('sprintf');
22
23 var deviceVid = 0x03EB;
24 var devicePid = 0x206E;
25
26 var CCID_PC_to_RDR_SetParameters = 0x61;
27 var CCID_PC_to_RDR_GetParameters = 0x6C;
28 var CCID_PC_to_RDR_IccPowerOn = 0x62;
29 var CCID_PC_to_RDR_IccPowerOff = 0x63;
30 var CCID_PC_to_RDR_GetSlotStatus = 0x65;
31 var CCID_PC_to_RDR_XfrBlock = 0x6f;
32
33 function getAndInitCcidDeviceAndInterface()
34 {
35 device = usb.findByIds(deviceVid, devicePid);
36 if (!device) {
37 console.log('No device found');
38 process.exit(1);
39 }
40 device.open();
41
42 var ccidInterface = device.interface(0);
43 if (ccidInterface.isKernelDriverActive()) {
44 ccidInterface.detachKernelDriver();
45 }
46 ccidInterface.claim();
47
48 return {ccidDevice:device, ccidInterface:ccidInterface};
49 }
50
51 function read(ccidInterface, responseSize, callback)
52 {
53 inEndpoint = ccidInterface.endpoints[0];
54 inEndpoint.transfer(responseSize, function(error, data) {
55 if (error) {
56 console.log(error)
57 } else {
58 console.log("Received data:", data);
59 }
60 callback();
61 });
62 }
63
64 function write(ccidInterface, message, callback)
65 {
66 outEndpoint = ccidInterface.endpoints[1]
67 outEndpoint.transfer( // Send a Set Report control request
68 message, // message to be sent
69 function(error) { // callback to be executed upon finishing the transfer
70 callback();
71 }
72 );
73 }
74
75 //CCID functions
76
77 function GetParametersMessage(slot, seq, protocolNum, t0Params)
78 {
79 return [
80 CCID_PC_to_RDR_GetParameters, //message type
81 0, 0, 0, 0, //length
82 slot,
83 seq,
84 0, 0, 0 //RFU
85 ];
86 }
87
88 function SetParametersMessage(slot, seq, protocolNum, t0Params)
89 {
90 return [
91 CCID_PC_to_RDR_SetParameters, //message type
92 t0Params.length, 0, 0, 0, //length
93 slot,
94 seq,
95 protocolNum,
96 0, 0 //RFU
97 ].concat(t0Params);
98 }
99
100
101 function IccPowerOnMessage(slot, seq)
102 {
103 return [
104 CCID_PC_to_RDR_IccPowerOn, //message type
105 0, 0, 0, 0, //length
106 slot,
107 seq,
108 0, //power select: automatic
109 0, 0 //RFU
110 ];
111 }
112
113 function IccPowerOffMessage(slot, seq)
114 {
115 return [
116 CCID_PC_to_RDR_IccPowerOff, //message type
117 0, 0, 0, 0, //length
118 slot,
119 seq,
120 0, 0, 0 //RFU
121 ];
122 }
123
124 function GetSlotStatusMessage(slot, seq)
125 {
126 return [
127 CCID_PC_to_RDR_GetSlotStatus, //message type
128 0, 0, 0, 0, //length
129 slot,
130 seq,
131 0, 0, 0 //RFU
132 ];
133 }
134
135 function XfrBlockMessage(slot, seq, apdu)
136 {
137 return [
138 CCID_PC_to_RDR_XfrBlock, //message type
139 apdu.length, 0, 0, 0, //length: only for < 0xFF
140 slot,
141 seq,
142 0, //BWI
143 0, 0 //level parameter
144 ].concat(apdu);
145
146 }
147
148 function testCcidMessages()
149 {
150 return [
151 function(callback) {
152 write(ccidInterface, new Buffer(IccPowerOnMessage(0, 1)), callback);
153 },
154 function(callback) {
155 read(ccidInterface, 10 + 17, callback);
156 },
157 function(callback) {
158 write(ccidInterface, new Buffer(IccPowerOffMessage(0, 2)), callback);
159 },
160 function(callback) {
161 read(ccidInterface, 10, callback);
162 },
163 function(callback) {
164 write(ccidInterface, new Buffer(GetSlotStatusMessage(0, 3)), callback);
165 },
166 function(callback) {
167 read(ccidInterface, 10, callback);
168 },
169 function(callback) {
170 write(ccidInterface, new Buffer(SetParametersMessage(0, 4, 0, [0x11, 0x00, 0x00, 0x0a, 0x00])), callback);
171 },
172 function(callback) {
173 //must return 82 05 00 00 00 00 04 00 80 00 11 00 00 0a 00
174 read(ccidInterface, 30, callback);
175 },
176 function(callback) {
177 write(ccidInterface, new Buffer(GetParametersMessage(0, 5, 0)), callback);
178 },
179 function(callback) {
180 //must return 82 05 00 00 00 00 04 00 80 00 11 00 00 0a 00
181 read(ccidInterface, 30, callback);
182 }];
183 }
184
185 function startTest()
186 {
187 async.series([]
188 .concat(testCcidMessages())
189 );
190 }
191
192 var ccidDeviceAndInterface = getAndInitCcidDeviceAndInterface();
193 var ccidDevice = ccidDeviceAndInterface.ccidDevice
194 var ccidInterface = ccidDeviceAndInterface.ccidInterface;
195
196 console.log(sprintf("Connected to device 0x%04X/0x%04X - %s [%s]",
197 ccidDevice.deviceDescriptor.idVendor,
198 ccidDevice.deviceDescriptor.idProduct,
199 ccidDevice.deviceDescriptor.iProduct,
200 ccidDevice.deviceDescriptor.iManufacturer));
201
202 startTest();