How to send commands to smart card reader (and not to the smart card) while no card present? - javacard

Preface:
I have a dual interface smart card reader that has some extended capabilities (other than sending APDU commands to card and receiving APDU responses).
For example in its document it is mentioned that you can get firmware version of your reader using following command:
GET_FIRMWARE_VERSION: FF 69 44 42 05 68 92 00 05 00
In its tool, there is a button for this function and it works fine:
I even sniffed USB port to see what exactly exchanged in the connection between my PC and my reader for this function:
Command:
Response:
Problem:
I want to get my reader version (and maybe send other extended commands) using other tools or via code, but I must insert a card in the card reader to be able sending commands, otherwise I receive No Card Present exception, while I don't want to send commands to card! (The reader tool answers successfully to GET_FIRMWARE_VERSION without any card available in the reader's slots)
What I did so far:
1.I tried some tools, including OpenSCTool , PyAPDUTool, and another reader's tool.
2.I wrote following python script to send extended commands.
#--- Importing required modules.
import sys
import time
sys.path.append("D:\\PythonX\\Lib\\site-packages")
from smartcard.scard import *
import smartcard.util
from smartcard.System import readers
#---This is the list of commands that we want to send device
cmds =[[,0xFF,0x69,0x44,0x42,0x05,0x68,0x92,0x00,0x04,0x00],]
#--- Let's to make a connection to the card reader
r=readers()
print "Available Readers :",r
print
target_reader = input("--- Select Reader (0, 1 , ...): ")
print
while(True):
try:
print "Using :",r[target_reader]
reader = r[target_reader]
connection=reader.createConnection()
connection.connect()
break
except:
print "--- Exception occured! (Wrong reader or No card present)"
ans = raw_input("--- Try again? (0:Exit/1:Again/2:Change Reader)")
if int(ans)==0:
exit()
elif int(ans)==2:
target_reader = input("Select Reader (0, 1 , ...): ")
#--- An struct for APDU responses consist of Data, SW1 and SW2
class stru:
def __init__(self):
self.data = list()
self.sw1 = 0
self.sw2 = 0
resp = stru()
def send(cmds):
for cmd in cmds:
#--- Following 5 line added to have a good format of command in the output.
temp = stru() ;
temp.data[:]=cmd[:]
temp.sw1=12
temp.sw2=32
modifyFormat(temp)
print "req: ", temp.data
resp.data,resp.sw1,resp.sw2 = connection.transmit(cmd)
modifyFormat(resp)
printResponse(resp)
def modifyFormat(resp):
resp.sw1=hex(resp.sw1)
resp.sw2=hex(resp.sw2)
if (len(resp.sw2)<4):
resp.sw2=resp.sw2[0:2]+'0'+resp.sw2[2]
for i in range(0,len(resp.data)):
resp.data[i]=hex(resp.data[i])
if (len(resp.data[i])<4):
resp.data[i]=resp.data[i][0:2]+'0'+resp.data[i][2]
def printResponse(resp):
print "res: ", resp.data,resp.sw1,resp.sw2
send(cmds)
connection.disconnect()
Output:
>>> ================================ RESTART ================================
Available Readers : ['CREATOR CRT-603 (CZ1) CCR RF 0', 'CREATOR CRT-603 (CZ1) CCR SAM 0']
--- Select Reader (0, 1 , ...): 0
Using : CREATOR CRT-603 (CZ1) CCR RF 0
--- Exception occured! (Wrong reader or No card present)
--- Try again? (0:Exit/1:Again/2:Change Reader)
>>> ================================ RESTART ================================
Available Readers : ['CREATOR CRT-603 (CZ1) CCR RF 0', 'CREATOR CRT-603 (CZ1) CCR SAM 0']
--- Select Reader (0, 1 , ...): 1
Using : CREATOR CRT-603 (CZ1) CCR SAM 0
--- Exception occured! (Wrong reader or No card present)
--- Try again? (0:Exit/1:Again/2:Change Reader)
But both have the mentioned problem!
Questions:
1- How to send extended commands to reader while there is no card available?
2- Why I can't see command header in the sniffed data? (Note that, as Header is a pre-designated fixed value for all extended commands, I think the reader tool doesn't send the header with GET_FIRMWARE_VERSION command and it send only the data! but how does it works?)
Update:
Using trial and error I found something useful.
Assumptions:
Pseudo-APDUs fixed header = FF 69 44 42
Pseudo-APDU data field for GET_READER_FIRMWARE_VERSION = 68 92 00 04 00
Pseudo-APDU data field for CHANGE_SAM_SLOT = 68 92 01 00 03 XX 00 00
(My reader has two SAM slots, so XX can be 01 or 02)
SELECT APDU command = 00 A4 04 00 00
Ok, I wrote the following Java Program:
import java.util.List;
import java.util.Scanner;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;
import javax.xml.bind.DatatypeConverter;
public class TestPCSC {
public static void main(String[] args) throws CardException {
TerminalFactory tf = TerminalFactory.getDefault();
List< CardTerminal> terminals = tf.terminals().list();
System.out.println("Available Readers:");
System.out.println(terminals + "\n");
Scanner scanner = new Scanner(System.in);
System.out.print("Which reader do you want to send your commands to? (0 or 1 or ...): ");
String input = scanner.nextLine();
int readerNum = Integer.parseInt(input);
CardTerminal cardTerminal = (CardTerminal) terminals.get(readerNum);
Card connection = cardTerminal.connect("DIRECT");
CardChannel cardChannel = connection.getBasicChannel();
System.out.println("Write your commands in Hex form, without '0x' or Space charaters.");
System.out.println("\n---------------------------------------------------");
System.out.println("Pseudo-APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("Pseudo-APDU command: (Enter 0 to send APDU command)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
byte[] resp = connection.transmitControlCommand(CONTROL_CODE(), cmdArray);
String hex = DatatypeConverter.printHexBinary(resp);
System.out.println("Response : " + hex + "\n");
}
System.out.println("\n---------------------------------------------------");
System.out.println("APDU Mode:");
System.out.println("---------------------------------------------------");
while (true) {
System.out.println("APDU command: (Enter 0 to exit)");
String cmd = scanner.nextLine();
if (cmd.equals("0")) {
break;
}
System.out.println("Command : " + cmd);
byte[] cmdArray = hexStringToByteArray(cmd);
ResponseAPDU resp = cardChannel.transmit(new CommandAPDU(cmdArray));
byte[] respB = resp.getBytes();
String hex = DatatypeConverter.printHexBinary(respB);
System.out.println("Response : " + hex + "\n");
}
connection.disconnect(true);
}
public static int CONTROL_CODE() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.indexOf("windows") > -1) {
/* Value used by both MS' CCID driver and SpringCard's CCID driver */
return (0x31 << 16 | 3500 << 2);
} else {
/* Value used by PCSC-Lite */
return 0x42000000 + 1;
}
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
In the above program, I can send commands to my reader using both connection.transmitControlCommand and cardChannel.transmit() methods. The point is that, all the commands that send to the reader using first method, are assumed as Pseudo-APDU command and I should not use the Psedo-APDU header for them! And all the commands that send to the reader using second method, are assumed as regular APDU commands, so if I need to send Pseudo-APDU commands via second method, I must add the Pseudo-APDU header to it.
Let see output for the contact-less reader:
run:
Available Readers:
[PC/SC terminal ACS ACR122 0,
PC/SC terminal CREATOR CRT-603 (CZ1) CCR RF 0,
PC/SC terminal CREATOR CRT-603 (CZ1) CCR SAM 0]
Which reader do you want to send your commands to? (0 or 1 or ...): 1
Write your commands in Hex form, without '0x' or Space charaters.
---------------------------------------------------
Pseudo-APDU Mode:
---------------------------------------------------
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
//Based on reader's documents, 0x6800 means "Class byte is not correct"
//As I have a regular java card in the RF field of my reader, I conclude that
//this response is Reader's response (and not card response)
Pseudo-APDU command: (Enter 0 to send APDU command)
6892000400
Command : 6892000400
Response : 433630335F435A375F425F31353038323100039000
Pseudo-APDU command: (Enter 0 to send APDU command)
FF694442056892000400
Command : FF694442056892000400
Response : 6800
//Pseudo-APDU commands doesn't work in Pseudo-APDU mode if I add the Pseudo-APDU header to them.
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
0
---------------------------------------------------
APDU Mode:
---------------------------------------------------
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Response : 6F198408A000000018434D00A50D9F6E061291921101009F6501FF9000
APDU command: (Enter 0 to exit)
6892000400
Command : 6892000400
Response : 6E00
//This is the response of my card. I can't receive Firmware version in APDU mode using this command without Pseudo-APDU header.
APDU command: (Enter 0 to exit)
FF694442056892000400
Command : FF694442056892000400
Response : 433630335F435A375F425F31353038323100099000
//I successfully received Firmware version in APDU mode using the fixed Pseudo-APDU header.
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Response : 6F198408A000000018434D00A50D9F6E061291921101009F6501FF9000
APDU command: (Enter 0 to exit)
0
BUILD SUCCESSFUL (total time: 1 minute 36 seconds)
Is there any problem still?
Yes, two problems!:
1-the above program works fine only for its first run. I mean, if I stop running and rerun it, the second method throw an exception:
run:
Available Readers:
[PC/SC terminal ACS ACR122 0, PC/SC terminal CREATOR CRT-603 (CZ1) CCR RF 0, PC/SC terminal CREATOR CRT-603 (CZ1) CCR SAM 0]
Which reader do you want to send your commands to? (0 or 1 or ...): 1
Write your commands in Hex form, without '0x' or Space charaters.
---------------------------------------------------
Pseudo-APDU Mode:
---------------------------------------------------
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
FF694442056892000400
Command : FF694442056892000400
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
6892000400
Command : 6892000400
Response : 433630335F435A375F425F31353038323100049000
Pseudo-APDU command: (Enter 0 to send APDU command)
00A4040000
Command : 00A4040000
Response : 6800
Pseudo-APDU command: (Enter 0 to send APDU command)
0
---------------------------------------------------
APDU Mode:
---------------------------------------------------
APDU command: (Enter 0 to exit)
00A4040000
Command : 00A4040000
Exception in thread "main" javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: Unknown error 0x16
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
at TestPCSC.main(TestPCSC.java:58)
Caused by: sun.security.smartcardio.PCSCException: Unknown error 0x16
at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:188)
... 2 more
Java Result: 1
BUILD SUCCESSFUL (total time: 39 seconds)
As you see above, I can't use second method anymore and I need to power-off the reader and power on it again to make it work fine again.
2-The contact interface (I mean the SAM reader) throw previous exception always! I mean the second method doesn`t work at all (neither first run, nor second and third .... )
Note that I tried different readers, it seems that this is not limited only ti this reader. Some ACS readers also have a similar or exactly the same problem with rerun
Does anyone have any idea?
And as a side question, does Python have any equal methods for sending Pseudo-APDU like Java?
And finally, from the view of Reader, what's the difference between connection.transmitControlCommand and cardChannel.transmit() methods?

When you stop "Smart Card" service, does the tool still return a firmware version? If yes, then the tool might use raw IOCTL commands (DeviceIoControl) to communicate with the driver.
Also take a look at this question. The author says you have to set SCARD_PROTOCOL_UNDEFINED as protocol parameter:
SCardConnect(hSC,
readerState.szReader,
SCARD_SHARE_DIRECT,
SCARD_PROTOCOL_UNDEFINED,
&hCH,
&dwAP
);
I just tried it and it seems to work for Windows 10 at least. Communication was possible with no card inserted. I did not test for other Windows versions though.

readers() is array index of available readers
reader = r[target_reader]
convert
reader = r[int(target_reader)]
output
Available Readers : ['JAVACOS Virtual Contact Reader 0', 'JAVACOS Virtual Contactless Reader 1', 'OMNIKEY CardMan 3x21 0']
--- Select Reader (0, 1 , ...): 2
Using : OMNIKEY CardMan 3x21 0
ATR : 3B 9E 94 80 1F 47 80 31 A0 73 BE 21 13 66 86 88 02 14 4B 10 19

Related

Groovy Script to find a string in console output and make the build failure

I have the following entry in the Jenkins console "Output: × 35 of 45 failed (78%) 06:13 247 3 38 66 140", I need to grep the number 78 and make the build failure if the number is >=30 with Groovy script.
Can someone please help me with this?
def result= manager.logContains('%)')
println result*.toString() // Read a line which has the failed test cases count
String test = result
def failedtest = test.substring(test.indexOf("%") - 2)
def failednumber = failedtest.split("%")[0].toInteger() as int
println failednumber

How can i get response size of headers REST API

I know in headers we can get content length, which indeed gives Content body length But I need Response size of headers
For example:
API Response =
{
"1": 1
}
If I print console.log(res.getHeader('content-length')); it gives 7 which is content length of body.
But I need response size of header which is 377Bytes(header + body) as shown in postman
One of the possible way to get the bytes of file is to download it , by using curl command in the following mannner:
curl -so /dev http://www.yourip.org/http-your-file/ -w '%{size_download}'
where -w/--write-out
defines what to display after a completed and successful operation
There is a NPM module to get object sizeof, you can install it with npm install object-sizeof
var sizeof = require('object-sizeof');
// 2B per character, 6 chars total => 12B
console.log(sizeof({abc: 'def'}));
// 8B for Number => 8B
console.log(sizeof(12345));
var param = {
'a': 1,
'b': 2,
'c': {
'd': 4
}
};
// 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
console.log(sizeof(param));
You can use it however you want in your code.
Example ::
console.log(sizeof(response.body));

Why I cannot receive data from a CAN message by using kvaser CAN-USB connector?

I am trying to read the data coming from one device with the CAN communication protocol. I am using the Kvaser CAN-USB connector and python-can, but after sending the message I get the following:
Here's the my code:
import can
import time
bus=can.interface.Bus(bustype='kvaser',channel=0, bitrate=250000)
print (bus)
time.sleep(1)
msg =can.Message(arbitration_id=0x032)
print(msg)
time.sleep(1)
while True:
bus.send(msg)
recvMsg = bus.recv(timeout=0.5)
print (recvMsg)
time.sleep(1)
And here's the response i'm getting:
Kvaser Leaf Light v2, S/N 54781 (#1)
Timestamp: 0.000000 ID: 00000032 X DLC: 0
Timestamp: 1546613346.010231 ID: 0000 S E DLC: 4 00 01 00 00 Channel: 0
According to the manual I have to use the following:
Bitrate: 250 kbs
11-bit identifier: 0x031
Default settings TX only
8 byte message structure:
Byte:1,
Description:State of charge [%],
Type: Unsigned char,
Value: 0-200 LSB = 0.5 % SOC.
This is my first time I use this communication protocol and I have read the python-can 3.0 description, but still is not clear to me how to solve the problem. Any recommendation?
ID: 0000 indicates an error frame!
In the script you set the arbitration_id=0x032, but the manual says
11-bit identifier: 0x031
is that a typo?
How does your network look like? How many nodes do you have?
Have you terminated the CAN bus?
Is there any reason why you do not use PyCANlib from Kvaser?

Bittorrent extended message

I cannot find documentation anywhere that will tell me what this message means.
it looks like this in Wireshark.
00 00 00 03 14 03 01
I realize it is a 3 byte message, it is an extended message, ie type 20, but I don't know what 03 01 represent.
The scenario is that I send an 'Interested' message to the peer to unchoke my client, the peer then responds with the above message, followed by the 'Unchoke' message.
It is a extension message with ID = 3 and 01 is message data.
What ID = 3 means in this case, is defined by the previously extended message handshake (ID = 0) your client has sent.
A educated guess is that the message you see means: upload_only = 1. ('Extension for Partial Seeds' - BEP21)
Addendum:
uTorrent and most other clients implementation of upload_only differs from the 'out of date' specification explained here; alus = Greg Hazel
It's defined as a extension message in the extension handshake were the 1 byte message data means: 0x00 = false or < anything else> = true.
This can be verified by using Wireshark.

Qt 5.4 Linux Touchscreen Input with Tslib on Raspberry Pi failing with LinuxFB QPA Platform Plugin

I bought a Tontec 2.4 Inch Touchscreen ( http://elinux.org/MZTX-PI-EXT ) for my Raspberry Pi. The touchscreen controller requires the "tsc2007.ko" and "tsp_raspi.ko" kernel modules as described in the elinux post. The tsc2007.ko module is in the Raspbian Kernel tree but the tsp_raspi.ko can be found here: https://github.com/osandov/raspi/tree/master/tsc2007.
I've cross compiled a new Kernel for the Pi with those modules and they load fine and create a /dev/input/event0 device in Raspbian. If I 'evtest' that device and touch the screen, I get output so I know the events are being delivered in Linux:
pi#raspberry /dev/input $ evtest
Available devices:
/dev/input/event0: TSC2007 Touchscreen
Select the device event number [0-0]: 0
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "TSC2007 Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 1922
Min 0
Max 4095
Fuzz 64
Event code 1 (ABS_Y)
Value 2221
Min 0
Max 4095
Fuzz 64
Event code 24 (ABS_PRESSURE)
Value 0
Min 0
Max 4095
Fuzz 64
Properties:
Testing ... (interrupt to exit)
Event: time 1425521704.199489, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1425521704.199489, type 3 (EV_ABS), code 1 (ABS_Y), value 2085
Event: time 1425521704.199489, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 538
Event: time 1425521704.199489, -------------- SYN_REPORT ------------
Event: time 1425521704.209174, type 3 (EV_ABS), code 0 (ABS_X), value 1455
...
I installed tslib and ran a quick ts_calibrate. I also made sure that ts_test spit out data when I touched the screen.
I added the following environment variables to /etc/profile for tslib support in Qt5:
## For Qt5 Touchscreen Support
export QT_DEBUG_PLUGINS=1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/arm-linux-gnueabihf/
export QT_PLUGIN_PATH=/usr/lib/plugins
export QT_QPA_FONTDIR=/usr/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/platforms
export QT_QPA_PLATFORM=linuxfb
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event0
export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0
export TSLIB_TSEVENTTYPE='INPUT'
export TSLIB_CALIBFILE='/etc/pointercal'
export TSLIB_CONFFILE='/etc/ts.conf'
export TSLIB_CONSOLEDEVICE='none'
export TSLIB_FBDEVICE='/dev/fb0'
export TSLIB_PLUGINDIR='/usr/lib/ts'
export TSLIB_TSDEVICE='/dev/input/event0'
I read up on the Qt5 docs and how to get touch events in my app. I have a main Widget and set the appropriate flags in the constructor:
MainWidget::MainWidget(QLabel *parent)
: QLabel(parent)
{
qDebug() << "Setting WA_AcceptTouchEvents on MainWidget...";
// Accept touch events
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_StaticContents);
}
I setup an event filter to try to catch the touch events:
bool MainWidget::eventFilter( QObject* target, QEvent* e )
{
qDebug() << "Event Type: " << e->type();
return false;
return QLabel::eventFilter(target, e);
}
I launch my app like this:
myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0
I also uncommented a single printf in Qt's source code for the qtslib.cpp:
void QTsLibMouseHandler::readMouseData()
{
ts_sample sample;
while (get_sample(m_dev, &sample, m_rawMode)) {
bool pressed = sample.pressure;
int x = sample.x;
int y = sample.y;
// work around missing coordinates on mouse release
if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) {
x = m_x;
y = m_y;
}
if (!m_rawMode) {
//filtering: ignore movements of 2 pixels or less
int dx = x - m_x;
int dy = y - m_y;
if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed)
continue;
}
QPoint pos(x, y);
//printf("handleMouseEvent %d %d %d %ld\n", m_x, m_y, pressed, sample.tv.tv_usec);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
m_x = x;
m_y = y;
m_pressed = pressed;
}
}
When I launch my Qt app I see the plugins are loading OK ( even shows the correct event0 file ). I also see that the qt tslib plugin is receiving touch events when I touch the screen. The problem is that the event filter is NEVER called!
Here is the app being launched:
Got keys from plugin meta data ("tslib", "tslibraw")
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/generic" ...
loaded library "/usr/lib/qt/plugins/generic/libqtslibplugin.so"
QTsLibMouseHandler "tslib" ""
QTsLibMouseHandler "tslib" "/dev/input/event0"
QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/qt/plugins/styles" ...
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/styles" ...
Setting WA_AcceptTouchEvents on MainWidget...
-----------------------------------------
Waiting for data now...
-----------------------------------------
handleMouseEvent 0 0 1 751196
handleMouseEvent 0 0 1 751196
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
...
I found a few forum posts where people are having problems with touch input with the linuxfb platform plugin:
http://comments.gmane.org/gmane.comp.lib.qt.user/5686
http://qt-project.org/forums/viewthread/35757
http://qt-project.org/forums/viewthread/36120/
I've tried all their suggestions and still have the problem - no touch events are received by my app even though the Qt tslib plugin says it is receiving them.
It seems that the tslib plugin is having problems injecting the event it receives into my app's event loop with this:
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
I also tried the Qt5.4 touch fingerpaint example and see the same behavior - no touch events are received.
I'm not sure where to go from here. I would greatly appreciate any help solving this issue. Thanks!
UPDATE:
I changed my event filter so it looks like this:
bool MainWidget::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "Event received" << obj->metaObject()->className() << event->type();
switch (event->type()) {
case QEvent::TouchBegin:
qDebug() << "TouchBegin";
case QEvent::TouchUpdate:
qDebug() << "TouchUpdate";
case QEvent::TouchEnd:
qDebug() << "TouchEnd";
{
// QTouchEvent *touch = static_cast<QTouchEvent *>(event);
// QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
// foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
// switch (touchPoint.state()) {
// case Qt::TouchPointStationary:
// // don't do anything if this touch point hasn't moved
// continue;
// default:
// {
// }
// break;
// }
// }
// break;
}
//default:
//return QLabel::event(event);
}
//return true;
}
Now I can see 'socket notifier' events intermingled with Qt Tslib Plugin's prints whenever I touch the screen. Any ideas as to why Event Type 50 but no Touch Events?
Event received QSocketNotifier 50
handleMouseEvent 2702 2618 0 557715
Event received QSocketNotifier 50
handleMouseEvent 2698 2612 1 547758
Event received QSocketNotifier 50
handleMouseEvent 2706 2802 1 759928
Event received QSocketNotifier 50
Event received QSocketNotifier 50
UPDATE #2:
I installed the event filter only to try to catch any events. I'm not sure in Qt5 what translates an event type 50 ( QSocketNotifier ) to a QTouch* or QMouse* event.
Here is some more information:
When I run evtest, I see that the screen resolution is huge ( ~2500 x
~2500 ) and the actual screen is 320x240. I tried changed the
/dev/fb0 framebuffer size in /boot/config.txt to 320x240 and
rebooted. But the evtest and ts_calibrate steps still show the huge
resolution.
Because of the large resolution, I tried making my main widget
10000x10000 to see if I would get a touch or mouse event - but I
still only get the QSocketNotifier
I then tried to force the tslib plugin to always inject events at
screen position X=50 Y=50, but I still only get the event type 50
QSocketNotifier.
The problem was solved by making sure the tslib plugins were installed on the RasbperryPi.
TSLIB_PLUGINDIR=/usr/lib/ts
The directory /usr/lib/ts was not present on the Pi.

Resources