pikopong

it's all about knowledge

Archive for the ‘programming’ Category

How to enable MySQL support in Qt SDK for Windows

without comments

  1. Download Qt SDK for Windows at Qt Software and install.
  2. Download MySQL Community Server (MSI Installer) from MySQL and install.
    mysql
  3. Open Qt Command Prompt from the Start Menu

  4. Run these commands, modify it if you install your MySQL at different path. You just have to set the path to your MySQL library since Qt’s paths will be set automatically based on your installation if you use Qt Command Prompt
    Setting up a MinGW/Qt only environment...
    -- QTDIR set to C:\Qt\2010.02.1\qt
    -- PATH set to C:\Qt\2010.02.1\qt\bin
    -- Adding C:\Qt\2010.02.1\bin to PATH
    -- Adding C:\WINDOWS\System32 to PATH
    -- QMAKESPEC set to win32-g++
    C:\Qt\2010.02.1\qt>set mySQLDIR=C:\PROGRA~1\MySQL\MYSQLS~1.1
    C:\Qt\2010.02.1\qt>cd %QTDIR%\src\plugins\sqldrivers\mysql
    C:\Qt\2010.02.1\qt>qmake "INCLUDEPATH+=%mySQLDIR%\include" "LIBS+=%mySQLDIR%\lib\opt\libmysql.lib" -o Makefile mysql.pro
    C:\Qt\2010.02.1\qt>mingw32-make
  5. Create new project and put these codes to test your new plugin
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #include
    #include 
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
     
        qDebug() << QSqlDatabase::drivers();
     
        return a.exec();
    }

    Make sure you have QtSql Module in your project configuration file (.pro file)

    QT += sql

    You’ll get these outputs showing that your Qt has supports for MySQL:

    ("QSQLITE", "QMYSQL3", "QMYSQL", "QODBC3", "QODBC")

    What matters is that you have QMYSQL in the output.

Written by amree

April 11th, 2010 at 4:38 pm

Posted in programming

Tagged with , , ,

How to enable MySQL support in Qt SDK for Linux

with 5 comments

  1. Download Qt SDK for Linux/X11 at Qt Software.
  2. Install it anywhere you want, just make sure you remember the path.
  3. To build MySQL as a plugin, you need to know two other paths:
    • Your MySQL header files directory. It should be something like this:
      decimal.h   m_string.h      my_dbug.h    my_list.h        my_sys.h     mysql_embed.h    mysqld_error.h  sql_state.h        typelib.h
      errmsg.h    my_alloc.h      my_dir.h     my_net.h         my_xml.h     mysql_time.h     raid.h          sslopt-case.h
      keycache.h  my_attribute.h  my_getopt.h  my_no_pthread.h  mysql.h      mysql_version.h  readline.h      sslopt-longopts.h
      m_ctype.h   my_config.h     my_global.h  my_pthread.h     mysql_com.h  mysqld_ername.h  sql_common.h    sslopt-vars.h
    • Your MySQL lib files directory. Something like this:
      libdbug.a    libmyisammrg.a      libmysqlclient.so@         libmysqlclient_r.a    libmysqlclient_r.so.15@      libmysys.a
      libheap.a    libmysqlclient.a    libmysqlclient.so.15@      libmysqlclient_r.la*  libmysqlclient_r.so.15.0.0*  libvio.a
      libmyisam.a  libmysqlclient.la*  libmysqlclient.so.15.0.0*  libmysqlclient_r.so@  libmystrings.a
  4. For Slackware 12.2, it should be:
    1
    2
    
    /usr/include/mysql	# MySQL header directory
    /usr/lib/mysql		# MySQL libraries
  5. Go to your Qt SDK installation directory, mine is: /opt/qtsdk-2009.03/
    1
    2
    3
    4
    5
    6
    
    cd /opt/qtsdk-2009.03/
    cd qt/src/plugins/sqldrivers/mysql/
    # Replace all the path based on your computer environment. 
    # Make sure 'qmake' can be run from anywhere or you'd have to specify the full path for it.
    qmake -o Makefile "INCLUDEPATH+=/usr/include/mysql" "LIBS+=-L/usr/lib/mysql -lmysqlclient" mysql.pro
    make
  6. You should have new files created for you:
    Makefile
    README
    libqsqlmysql.so*
    main.cpp
    main.o
    moc_qsql_mysql.cpp
    moc_qsql_mysql.o
    mysql.pro
    qsql_mysql.moc
    qsql_mysql.o
  7. Copy MySQL plugin to your Qt’s plugins directory,
    cp libqsqlmysql.so /opt/qtsdk-2009.03/qt/plugins/sqldrivers
  8. Create new project and put these codes to test your new plugin
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #include <QCoreApplication>
    #include <QtSql>
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
     
        qDebug() << QSqlDatabase::drivers();
     
        return a.exec();
    }

    You’ll get these outputs showing that your Qt has supports for MySQL

    ("QSQLITE", "QMYSQL3", "QMYSQL")

Written by amree

July 22nd, 2009 at 3:21 pm

Posted in programming

Tagged with , , ,

Reading Mifare 1K Card using Java in Linux

with 39 comments

At the end of last year, my friends and I were tasked to read our staff card. The main objective was pretty simple, to create a library where we don’t have to depend on the vendor everytime we want to read our own staff card and the library should also be working on Windows and Linux (that means Java to us).

Working Environment

  1. Slackware 12.2
  2. JDK 6 Update 11
  3. Netbeans 6.5
  4. libusb 0.1.12
  5. Windows Binary of JPC/SC Java API 0.8.0
  6. Your contactless smartcard reader’s driver

The Reader

Let’s talk about the reader first. You need to get a reader that supports Mifare 1K card (obviously) which is to be exact a reader that supports ISO14443A/B or ISO15693 (contactless standard). Now, to make your life easier, you should get a reader that can read contactless standards compliant contactless using the same framework as ISO7816 compliant contact cards. In simple terms, you can use APDU to get the data that you want.

So, for this little project, we use OMNIKEY CardMan 5321 RFID reader. It has everything that we need, Linux/Windows supports, APDU calls to the contactless card, it even comes a contact card’s reader too and of course, it’s kinda cheap.

Make sure you choose the correct reader or you won’t be able to use this tutorial. Some reader requires you to read using their own specific code, which means you can only use the code you wrote on that particular reader, unlike readers that support APDU calls to contactless cards.

The Card

1024 byte memory is organised as sixteen sectors, each of which is made up of four blocks and each block is 16 bytes long. The first block in the memory (Block 0) is read-only and is set in the factory to contain the four-byte serial number (UID), check bytes and manufacturers data. The last block of each sector (Blocks 3, 7, 11, 15……59, 63) is the Sector Trailer Block which contains the two security Key codes (KeyA and KeyB) and the Access bits that define how the sector can be accessed.

Taking into account the Serial Number/Manufacturers Block and the Sector Trailer Blocks then there are 752 bytes of free memory for user storage. For all Read and Write operations the Mifare card memory is addressed by Block number (in hexadecimal format).

The Installation

Before you begin coding your codes, you need to make sure your environment is ready for you. To do that, just follow steps from my previous tutorial which is pretty much the same from Step 1 tuntill Step 11. For Step 8, you should install the driver based on your reader. OMNIKEY 5321 users can get your driver here.

General Steps to Read the Card

  1. Load Mifare key
  2. Authenticate
  3. Read

Looks simple right ?

The Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package my.husm.mifare;
 
import java.nio.ByteBuffer;
import java.util.List;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;
 
/**
*
* @author mree
*/
public class Read {
 
   public Read() {
 
       try {
 
           CardTerminal terminal = null;
 
           // show the list of available terminals
           TerminalFactory factory = TerminalFactory.getDefault();
           List<CardTerminal> terminals = factory.terminals().list();
 
           String readerName = "";
 
           for (int i = 0; i < terminals.size(); i++) {
 
               readerName = terminals.get(i).toString().substring(
                                   terminals.get(i).toString().length() - 2);
 
               if (readerName.equalsIgnoreCase("01")) {
                   terminal = terminals.get(i);
               }
           }
 
           // Establish a connection with the card
           System.out.println("Waiting for a card..");
           terminal.waitForCardPresent(0);
 
           Card card = terminal.connect("T=0");
           CardChannel channel = card.getBasicChannel();
 
           // Start with something simple, read UID, kinda like Hello World!
           byte[] baReadUID = new byte[5];
 
           baReadUID = new byte[]{(byte) 0xFF, (byte) 0xCA, (byte) 0x00,
                                  (byte) 0x00, (byte) 0x00};
 
           System.out.println("UID: " + send(baReadUID, channel));
           // If successfull, the output will end with 9000
 
           // OK, now, the real work
           // Get Serial Number
           // Load key
           byte[] baLoadKey = new byte[12];
 
           baLoadKey = new byte[]{(byte) 0xFF, (byte) 0x82, (byte) 0x20,
                                     (byte) 0x1A, (byte) 0x06, (byte) 0xFF,
                                     (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
                                     (byte) 0xFF, (byte) 0xFF};
 
           System.out.println("LOAD KEY: " + send(baLoadKey, channel));
           // If successfull, will output 9000
 
           // Authenticate
           byte[] baAuth = new byte[7];
 
           baAuth = new byte[]{(byte) 0xFF, (byte) 0x88, (byte) 0x00,
                               (byte) 0x09, (byte) 0x60, (byte) 0x00};
 
           System.out.println("AUTHENTICATE: " + send(baAuth, channel));
           // If successfull, will output 9000
 
           // Read Serial
           byte[] baRead = new byte[6];
 
           baRead = new byte[]{(byte) 0xFF, (byte) 0xB0, (byte) 0x00,
                               (byte) 0x09, (byte) 0x10};
 
           System.out.println("READ: " + send(baRead, channel));
           // If successfull, the output will end with 9000
 
       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }
 
   public String send(byte[] cmd, CardChannel channel) {
 
       String res = "";
 
       byte[] baResp = new byte[258];
       ByteBuffer bufCmd = ByteBuffer.wrap(cmd);
       ByteBuffer bufResp = ByteBuffer.wrap(baResp);
 
       // output = The length of the received response APDU
       int output = 0;
 
       try {
 
           output = channel.transmit(bufCmd, bufResp);
 
       } catch (CardException ex) {
           ex.printStackTrace();
       }
 
       for (int i = 0; i < output; i++) {
           res += String.format("%02X", baResp[i]);
           // The result is formatted as a hexadecimal integer
       }
 
       return res;
   }
 
   public static void main(String[] args) {
       new Read();
   }
}

Make sure you set the right connection protocol at line 43, as pointed out by Animesh.

These codes use Java API to read the smartcard, but I suggest you use the jpcsc library, it’s much more robust when it comes to error handling. These codes will generate error response, so, you need to change the commands based on your smartcard.

The APDU Commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Load Key
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   FF   |   82   |   20   |   1A   |   06   |   FF   |   FF   |   FF   |   FF   |   FF   |   FF   |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |   6    |   7    |   8    |   9    |   10   |   11   |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
 
1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Key type, could be 00, 1A, 1B
5   = LC  : Key length, usually 6 for 6 byte
6   = XX  : ----+
7   = XX  :     |
8   = XX  :     |__ The Key (eg. FF FF FF FF FF FF)
9   = XX  :     |
10  = XX  :     |
11  = XX  : ----+
 
# Autenthicate
+--------+--------+--------+--------+--------+--------+
|   FF   |   88   |   00   |   01   |   60   |   00   |
+--------+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |   6    |
+--------+--------+--------+--------+--------+--------+
 
1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Block Number you want to authenticate in Hex
5   = P3  : Mifare Block Number LSB
6   = XX  : Key type, could be 00, 1A, 1B
 
# Read
+--------+--------+--------+--------+--------+
|   FF   |   B0   |   00   |   01   |   10   |
+--------+--------+--------+--------+--------+
|   1    |   2    |   3    |   4    |   5    |
+--------+--------+--------+--------+--------+
 
1   = CLA : (Fixed)
2   = INS : (Fixed)
3   = P1  : (Fixed)
4   = P2  : Block Number that you want to read in Hex
5   = Le  : (Fixed)

So, that’s it, good luck trying !

This project has been abandoned. Thus, I may or may not be able to help if you encountered any problems but thanks for viewing :)

Written by amree

February 11th, 2009 at 4:27 pm

Posted in programming

Tagged with , ,

Auto Resize JTable Column Width

with 10 comments

This code should resize your JTable column width based on the contents of the header and data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    public JTable autoResizeColWidth(JTable table, DefaultTableModel model) {
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setModel(model);
 
        int margin = 5;
 
        for (int i = 0; i < table.getColumnCount(); i++) {
            int                     vColIndex = i;
            DefaultTableColumnModel colModel  = (DefaultTableColumnModel) table.getColumnModel();
            TableColumn             col       = colModel.getColumn(vColIndex);
            int                     width     = 0;
 
            // Get width of column header
            TableCellRenderer renderer = col.getHeaderRenderer();
 
            if (renderer == null) {
                renderer = table.getTableHeader().getDefaultRenderer();
            }
 
            Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0);
 
            width = comp.getPreferredSize().width;
 
            // Get maximum width of column data
            for (int r = 0; r < table.getRowCount(); r++) {
                renderer = table.getCellRenderer(r, vColIndex);
                comp     = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false,
                        r, vColIndex);
                width = Math.max(width, comp.getPreferredSize().width);
            }
 
            // Add margin
            width += 2 * margin;
 
            // Set the width
            col.setPreferredWidth(width);
        }
 
        ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment(
            SwingConstants.LEFT);
 
        // table.setAutoCreateRowSorter(true);
        table.getTableHeader().setReorderingAllowed(false);
 
        return table;
    }

Example:

1
2
3
// Must pass the model
DefaultTableModel model = new DefaultTableModel();
jTable = autoResizeColWidth(jTable, model);

Tested on JRE v5 and JRE v6

Written by amree

August 13th, 2008 at 2:49 pm

Posted in programming

Tagged with , ,

Reading MyKad using Visual Basic

with 19 comments

It seems that a lot of people asking how to read MyKad using Visual Basic, but since I don’t have the slightest idea on how to code in VB, I started to search around. To my surprise, Xenon (the one who reverse engineered MyKad to get the APDU) actually wrote a small application in VB to read MyKad. So, for those who can’t afford to buy SDK from commercial company, you can download the code here for FREE !

VB Application to read MyKad


View the discussion
Download the code

Written by amree

May 28th, 2008 at 12:32 am

Posted in programming

Tagged with , , ,