Archive for category Programming

Programming using IOCTL to interface with Linux kernel drivers

IOCTL is a function call that allows you to interface with kernel drivers, allowing you to adjust settings or set parameters from code without compiling a new module.

From a programming perspective, having the linux kernel source is a prerequisite. In this example, I cloned the main kernel:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux

Once I had the source, I specifically wanted to see exactly how I could interface with the driver called usblp. I was using a USB to parallel port converter, and wanted to see if there was any way to force it to operate differently as we needed a non-printer device to work with it.

After opening the kernel source, I found the driver file itself which was under /drivers/usb/class/usblp.c. In this file I found a section of information about which IOCTLs it supported, and put them in a header file for my program called usblp-hack.h:

#ifndef USBLP_HACK_H
#define USBLP_HACK_H

#include <linux/ioctl.h>

/* ioctls: */
#define IOCNR_GET_DEVICE_ID     1
#define IOCNR_GET_PROTOCOLS     2
#define IOCNR_SET_PROTOCOL      3
#define IOCNR_HP_SET_CHANNEL        4
#define IOCNR_GET_BUS_ADDRESS       5
#define IOCNR_GET_VID_PID       6
#define IOCNR_SOFT_RESET        7
/* Get device_id string: */
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* The following ioctls were added for http://hpoj.sourceforge.net: */
/* Get two-int array:
 * [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
 * [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
#define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
#define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
/* Set channel number (HP Vendor-specific command): */
#define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
/* Get two-int array: [0]=bus number, [1]=device address: */
#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
/* Get two-int array: [0]=vendor ID, [1]=product ID: */
#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
/* Perform class specific soft reset */
#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0)
#endif

There are plenty of hints on usage here, and I was able to grab a little more info after searching for some of those defines in google code search. Using these IOCTLs I wanted to know exactly which modes the USB to parallel converter supported, and try to set it in mode 3, which I hoped would give me more options for talking to the device.

Here is my usblp-hack.c which was able to probe and update these settings, although in my case mode 3 didn’t work, but shows an example of exactly how to do it:

#include "usblp-hack.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>		/* open */
#include <unistd.h>		/* exit */
#include <sys/ioctl.h>		/* ioctl */

main()
{
	int fd;
	int twoints[2];

	fd = open("/dev/usblp0", O_RDONLY | O_NONBLOCK);
	if (fd < 0) {
		printf("Cannot open device.\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_GET_PROTOCOLS(sizeof(int[2])), &twoints) >= 0)
		printf("Great success: %d / %d\n", twoints[0], twoints[1]);
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_SET_PROTOCOL, 2) >= 0)
		printf("set protocol to version 2\n");
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_GET_PROTOCOLS(sizeof(int[2])), &twoints) >= 0)
		printf("Great success: %d / %d\n", twoints[0], twoints[1]);
	else {
		printf("Fail!\n");
		exit(-1);
	}

	if(ioctl(fd, LPIOC_SOFT_RESET) >= 0)
	{
		printf("Success reset device\n");
	} else {
		printf("Could not reset device\n");
		exit(-1);
	}

	close(fd);
	exit(0);
}

You can compile the above example just using gcc:

gcc -o usblp-hack usblp-hack.c

You can see in the example above I was able to probe the device to see what mode it was currently in and supports (LPIOC_GET_PROTOCOLS), attempt to set the device mode (LPIOC_SET_PROTOCOL), and soft reset the device (LPIOC_SOFT_RESET).

So in the end, nothing here too complex or mind blowing, but if you are just getting your feet wet it might take you a minute to dig this sort of information up.

Java

It has always been trendy to make fun of Java, and wax poetic about how superior someone’s language of choice is. The fact of the matter is, whether or not you wish to acknowledge it, more users run Java applications on Linux than any other language1.

In the past few years, I have had the opportunity to code multiple enterprise web applications in any language I chose. I made a few in Symfony (php), Django (python), and recently I used Play (java). All of them were fantastic frameworks and languages in their own respect (the only thing people make fun of more than Java is PHP, again generally baseless).

I have used vim for as long as I can remember, but for the Play project I switched over to Eclipse, and that was also a great IDE. A lot of nice features where it would automated a lot of typing, and I found managing multiple files slightly easier.

Point being the language and the tools around it are there, well tested, and ready for prime time. Given the right coder, they are just as effective as any of the trendy languages, and to dismiss that based on outright false statements on most comment threads is absurd.

Performance: Java in no way, in any application I wrote, was limited by the language or jvm in performance. This is generally affected entirely by the coder, not the language.

Adoption: Java is all over my business, and is the clear leader in the enterprise technology stack2

Tools: Tools for Java are abundant, feature rich, and more than adequate to develop complex projects

Criticisms: The only valid criticism is that Java apps are slow to load up initially, for user apps. I think with the innovation we see with respect to JVM performance improvements (JIT compilation etc)3 continuously make that point not even legitimate, but clearly you can make applications load slowly. With that in mind, I have the ability to write a C app that loads slow also.

This post more than anything is to encourage breaking the mold of the group think, “None of us is as dumb as all of us” mentality. No matter how many points you get on reddit for a snarky comment, those points won’t pay your bills, nor give you respect among legitimate coders.

  1. http://www.electronista.com/articles/10/05/26/admob.april.2010.study.has.android.near.even/ []
  2. http://www.forrester.com/rb/Research/of_strategic_languages%2C_javas_adoption_is_highest/q/id/37356/t/2 []
  3. http://www.h-online.com/open/news/item/Android-s-Dalvik-to-be-JIT-boosted-861870.html []

Tags: ,

Pygoocanvas, pygtk etc

I was reading a post about PyGoocanvas, and decided to take a look at some code and see what fun could be had. I haven’t done much yet, but this screenshot of it is pretty entertaining in it’s own right:

A thousand passwords

In this day and age of the internet, we have more content and interaction than ever before. This access generally comes with a price: everything requires a username and password. How does a mere mortal remember their credentials to login to thousands of websites? More importantly, I am not always on the same computer, how do I access my passwords from all of them?

The long term solution would be to see 100% adoption of OpenID. Inevitably many sites will always be behind the curve, so until that day comes, I recommend Revelation.

Revelation is an easy to use, secure and lightweight password manager for Linux. It is written in GTK so those running the GNOME desktop (the default for Ubuntu) will be right at home. You can have several different folders to help organize your passwords, and define actions based on the type of password being stored.

A picture is worth a thousand words, so here is a screenshot of Revelation in action:
revelation

What makes this great is that all of your passwords are stored encrypted. This means if someone takes your computer, without your master password your passwords would be useless. This also means we can store our password using Ubuntu One or Dropbox.

If you are curious about Dropbox I wrote a post with screenshots showing exactly how it works. Simply save your Revelation password file there, and all of your systems that have Dropbox will now have access to those passwords (once you unlock it for that session of course).

Under the preferences window in Revelation you can also adjust your default password size (when you use Revelation you simply randomly generate a new password for each website) for as long as you need, with the longer the better.

If you are running Ubuntu, you can install Revelation by clicking Applications -> Ubuntu Software Center and searching for Revelation. If you would prefer the command line version:

# sudo apt-get install revelation

There are many alternatives out there, but if you are running Linux and just need a simple, no-hassle password manager Revelation is worth five minutes to try it out.

Tags: , ,

Installing Play Framework on OpenBSD 4.6

OpenBSD
OpenBSD is a free, reliable and secure operating system. From a configuration standpoint it is both minimal and simple, which is great for those who want to get started quickly. For the purposes of this tutorial, it is assumed the user has already installed OpenBSD. If not, check out openbsd101.com for guides on installation etc.

Play Framework
The Play Framework is a java based web programming system, that includes the enterprise features of java with the methodology of Ruby on Rails or Django. You can view an introductory screencast at their website which shows just how easy and powerful it is.

Allow your user to sudo
Since this blog is aggregated on many Ubuntu sites, we will use the sudo facility to run commands instead of root. To enable sudo the same way Ubuntu does:

  1. su – # Get root
  2. visudo
  3. Uncomment the line “%wheel ALL=(ALL) SETENV: ALL”

Install packages
For the play framework the launch scripts are in python. Zsh is installed for a better shell, and vim is installed for a full featured editor.

export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.6/packages/i386/
sudo pkg_add zsh jre-1.7.0.00b59p0 wget python-2.6.2p0 vim-7.2.190p1-no_x11 unzip
sudo ln -sf /usr/local/bin/python2.6 /usr/bin/python
sudo ln -sf /usr/local/bin/python2.6-config /usr/bin/python-config
sudo ln -sf /usr/local/bin/pydoc2.6  /usr/bin/pydoc

Install Play Framework

cd /usr/local
sudo wget http://download.playframework.org/releases/play-1.0.zip
sudo unzip play-1.0.zip

Start your project

cd /var
sudo /usr/local/play-1.0/play new ourappname
sudo chown -R ourusername ourappname
cd ourappname
# Set java home -- you can set this permanently in /etc/login.conf or in a startup script
export JAVA_HOME="/usr/local/jre-1.7.0/"
/usr/local/play-1.0/play run

Done
Your test app is now listening on port 9000 of the systems IP. That is all there is to it. Make sure to check out the excellent documentation available for the Play Framework.

play

Tags: , ,