About the IT Department in Hospital Universiti Sains Malaysia
Information System Unit of HUSM was established in year 2000 due to the specific needs of IT implementation in hospital. At that moment, there were only 4 people working, but today, the numbers has grown up to 25 people. Since the beginning of establishment, the unit has extensively developing applications software for the hospital. Lead by En. Azuddin Bin AB Rahman and his team consisting of 7 IT Officers, 13 programmers and 4 technicians, they have delivered more than 10 systems for various purposes. As computer science graduates, the team believes that they can build any application without the needs to acquire one from external sources. With that mindset, the software development alone has saved the hospital millions of ringgit.
We are using these frameworks/tools/languages/technologies in HUSM:
- Linux Slackware
- J2SE
- MySQL
- MySQL Replication
- Perl and Bash
- Python
- Apache
- XHTML, PHP & CSS
- jQuery
- ZPL II
- Subversion
- Smart Card (Mifare & MyKad)
- JasperReport
These are the applications that has been developed and still being maintained everyday by us:
LIFELINE
The core application in HUSM to manage patient’s demographic information and patients appointments records and patients accounting.
LIS (Lab Information System)
A lab information system, class of software which handles receiving, processing and storing information generated by medical laboratory processes. As one of the biggest applications developed, it is being used in 13 various labs with different modules for each one, this application is also being converted from Delphi to open source Java on Linux.
E-Folder
One of the applications in the hospital that utilize the use of human input device as in Tablet PC, Touch Screen Monitors and PDA. It is still in the early phase of development.
AMS (Asset Management System)
Used mainly to keep track of items such as stationary and others. This application is used extensively by the administrative department in order to ensure better inventory management.
POLS (Pharmacy Online Prescription)
A new application that is still being tested vigorously everyday. All prescriptions will be done through computers as opposed to the old style which subsequently will be better for the management to keep track of all procedures, minimizing mistakes, controlling the amount of drugs prescribed and so on.
SPIFU & SPIFA (Sistem Pengurusan Inventori Farmasi Ubat/Alat)
Another inventory application focusing on drugs and clinical items such as syringe, glove, and others. It is used to manage the purchasing process, tracking and updating inventory information and many more.
CSSD (Central Sterile Supply Department)
Keeping track of all the in and out records of surgery items in the hospital. This application will minimize the loss of the items. The cost for this application in the market from a German company is about RM 5 millions.
Sticker
In order to get a HUSM’s sticker, every vehicle needs to be registered in this application. It is being used by the Safety Department.
FIRAS (Film Information Reject Analisyst)
An application used by the Radiology Department to keep track of the rejected x-ray films and at the same time will generate various reports including any mishandling done by the radiology staff.
ICD 10 (International Classification of Diseases Version 10)
It is a disease coding encyclopedia and is much more efficient search can be made on any disease easily. This is an offline application.
Attendance
Using 100% opensource tools, we manage to create a Mifare Card based application to record daily attendance. In the future, fingerprints will be used to identify the staff.
Transfusion
The newest application for our Blood Bank Department which is still being developed. This application will incorporate open source MyKad reading algorithm (also was built at HUSM) to cut the time for the donors to fill out the form. There’s also a portable version for mobile usage.
Mortuary
Keeps track of deceased patients in the hospital.
HUSM Formulary
Another new application for the pharmacy department that will be used as the drugs information database. At this moment, HUSM is maintaining a bigger list of drugs than the list from Ministry of Health. Pharmacist should be able to see all the information in tree view and data from its database can be used in other applications as well such as Online Prescription.
Diet Management System
Developed by our newest IT Officer, this system is used to manage all the meal’s menu for our patients. It will be used in all patient wards when it’s completed successfully
Top 5 Subtitle Websites
These are my favourite websites for movies/tvseries subtitles.
For TV Series, I recommend the first site, usually subtitle will be released on the day of the scene release, easier to see too if you want to see the latest release (just keep hitting the Reload button). For movies, use the third one, and the 6th will provide you with an automatic app to download your subtitle. If you have other good website, just post it in the commment, thanks :)
Reading Mifare 1K Card using Java in Linux
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
- Slackware 12.2
- JDK 6 Update 11
- Netbeans 6.5
- libusb 0.1.12
- Windows Binary of JPC/SC Java API 0.8.0
- 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
- Load Mifare key
- Authenticate
- 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 !
My First Experience using Canon 40D
On the 5th of September 2008, I bought my first DSLR gears during my trip to Kuala Lumpur. The items are Canon 40D, Canon Speedlite 580EX II, Canon 50mm f/1.8 and some other things for about RM 5,000 which I don’t think is a really good bargain, but definitely better than what I’ll get if I bought them in Kelantan.
Ever since that purchase, I’ve been reading the manual whenever I got free time as I thought how am I supposed to be a better photographer if I don’t know the full potential of my camera ? I also managed to get some pirated book about the camera such as Canon EOS 40D Digital Field Guide. I was actually preparing myself for my uncle’s engagement event on the 3rd day of Hari Raya Aidilfitri. However, another event added to my list which is my cousin’s wedding event. I’m pretty happy that I finally had the chance to try whatever I learnt to the real world since using the chair in my room as a model is getting boring.
So, fast forward to my cousin’s wedding day. The main event that day was “Akad Nikah” which took place at a mosque near her house. Sadly, on my first try out as a photographer using my new camera, I made a lot of mistakes, lots of them. These are the mistakes that I knew (there are definitely more):
- I didn’t identify the main characters for the event thus there are only a few photos of them.
- Overuse of f/1.8 resulting a very bad group photos.
- Always beware with the additional characters such as children playing around which spoiled my shot with their blur movement.
- Wrong setting for shutter speed whenever I want to capture a candid moment such as hugging, shaking hands and so on.
- I need to ask them to look at me whenever I want to take photos (yes, I forgot to ask them to do that every time there are other photographers around).
- I need to know in advance the settings for the indoor and outdoor. Almost all of my outdoor shots after the event (which took place indoor) were overexposed as I didn’t have the time to test the correct settings.
- Always test other flash exposures even though the initial setting is OK at the first try.
- I should’ve known the limitation of my 50mm lens.
- I should not feel shy whenever I want to get close the subject.
So, what about the mistakes that I’ve done during my uncle’s engagement day ? This is the list:
- All the previous mistakes ;)
However, one thing for sure, I really need to start saving and buy a wide angle lens. 50mm is great for portrait shots, but not for group shots or even two people at some distance in a cramp room. *Sigh*, there’re still so many things to learn.
Printing to PDF Using CUPS
- Install CUPS-PDF based on your distro, you can download if from here.
- Click this link http://localhost:631 or type it into your browser.
- If the page requested a username and password, just enter your root username and password.
- Go the “Administration” tab and select “Add Printer” in the Printer section.
- For “Add Printer” page, put a name for your virtual PDF printer, any name will do. Then click “Continue”.
- For the second page, that is “Device for a”, you should select “CUPS-PDF (Virtual PDF Driver)”. If it’s not there, then you haven’t execute Step 1 successfully.
- In the 3rd page, choose “Generic” as the Make and then click “Continue”.
- 4th page, choose “Generic CUPS-PDF Printer (en)” as the model and then click “Add Printer”. You’re done, but we need to customize where the file will be located when you printed it.
- Edit /etc/cups/cups-pdf.conf in your favourite editor.
- Put these lines at the end of the file and save it (both can be customized):
1 2 | Out /home/${USER}/Desktop
Label 1 |
- The first line actually tell CUPS to print your file to the Desktop and the second line will make sure your file won’t be overwritten by the newer one.
- Restart your CUPS, for Slackware users, you can type this command /etc/rc.d/rc.cups restart
- So, that’s all and good luck !
Tested on Slackware 12.1, CUPS 1.3.7
