Intro | Starting IrDA | Communicating | Advanced
This tutorial was written by Jean Tourrilhes and adapted for this site. Currently any major Linux distribution have already IrDA support, tools to manage it and some utilities to communicate with various compatible IrDA devices. The following documentation is for die hard kernel & software hackers which want to be on bleeding edge and even to contribute to Linux-IrDA project in general.
A lot of IrDA novices mix up the low level and high level of the IrDA stack. A few words...
Compilation and configuration
Here are the steps to build your own kernel with IrDA paramaters of your choice.
The dongle I use is the Actisys 220L+, and the dongle driver is called actisys (see list above). The setup for other dongles should be very similar. I'm also using the first serial port in this example (ttyS0), you may need to adapt to your case.
Laptop port in SIR mode
SIR (Serial Infrared) is not fast but always work and is easy to set-up, so it's a safe bet. It will work only if the BIOS is set to SIR mode, so don't bother otherwise.
HP Omnibook 6000 in FIR mode
It seems that each laptop has its quirk when it come to FIR mode. I've managed to get my OB6000 to work. Other laptops will be different (different driver, different settings).
Other laptops in FIR mode
There is different FIR hardwares included in the various laptops. Linux-IrDA support some of them (not all) in various degrees (from good to bad). Moreover, it seems that each laptop has its quirk, so it's difficult to list everything here. For this reason, I recommend to make it work first in SIR mode. After that, you can experiement, check the HowTo and query the mailing list... As a rule of thumb, the NSC driver seems to be the most functional (if you set the proper dongle_id, which is either 0x8 or 0x9), and the SMC driver the most problematic.
USB FIR dongles
This driver is included in recent kernel. It's not as efficient as other FIR hardware, but at least is supported and is relatively easy to get working. Also, all the current products are based on the same hardware, and we know most of its bugs. The latest version of the driver has been tested with usb-uhci and usb-ohci.
Recently a new type of USB dongle from SigmaTel has appeared on the market which is not compliant with the IrDA-USB specification, and therefore doesn't work with this driver. On the other hand, SigmaTel has made available the full technical specification, so writing a driver for it is possible.
Important note: in recent kernels, the USB team has added a driver called ir-usb. Not only this driver is not compatible with the IrDA stack (the IrDA driver is called irda-usb), but this driver will load automatically before irda-usb, therefore preventing you to use it. Solution: get rid of ir-usb.
SIR with irport
The standard SIR driver is irtty, which uses the standard serial driver and TTY layer. This is the easiest and safest way to get IrDA working. However, the TTY layer adds some overhead and doesn't understand the IrDA protocol, which make it unsuitable in some case (dongle without echo cancelation) and less performant in others (small packets). That is why there is a second driver, irport, which allow the IrDA stack direct access to the serial port. Unfortunately, the procedure to use irport is more complicated and less well tested. Actually, I personally never managed to make irport work reliably on any of my systems.
Of course, I'm sure that you won't get things smooth the first time. Actually, I'm pretty sure you will struggle a little bit. If you get the Obex stuff out of the loop (so, using Ultra or Socket, as described above), the e-Squirt stuff is so simple that if anything doesn't work you can bet that it's the IrDA stack. The first trick is to check is the modules are loaded:
> cat /proc/modules actisys 1652 1 (autoclean) irtty 7524 2 (autoclean) irda 151905 11 (autoclean) [actisys irtty]This is what a serial dongle setup would look like. If the modules don't show up, check you modules configuration and check the error messages in the log (with dmesg). Then, check the bunch of files in /proc/net/irda:
> cat /proc/net/irda/discovery IrLMP: Discovery log: nickname: Jean, hint: 0x8220, saddr: 0x913b1bbc, daddr: 0x5619b45e > cat /proc/net/irda/irlap irlap0 state: LAP_NDM device name: irda0, hardware name: ttyS0 caddr: 0x52, saddr: 0x913b1bbc, daddr: 0x5619b45e win size: 1, win: 1, line capacity: 4800, bytes left: 4800 tx queue len: 0 win queue len: 0 rbusy: FALSE mbusy: FALSE retrans: 0 vs: 2 vr: 2 va: 0 qos bps maxtt dsize winsize addbofs mintt ldisc comp tx 9600 0 64 1 12 0 0 rx 9600 0 64 1 12 0 0 > cat /proc/net/irda/irias LM-IAS Objects: name: hp:esquirt, id=76371435 - Attribute name: "IrDA:TinyTP:LsapSel", value[IAS_INTEGER]: 96 name: OBEX:ESquirt, id=76371435 - Attribute name: "IrDA:TinyTP:LsapSel", value[IAS_INTEGER]: 95 name: Device, id=0 - Attribute name: "IrLMPSupport", value[IAS_OCT_SEQ]: octet sequence - Attribute name: "DeviceName", value[IAS_STRING]: "lagaffe" name: hp:beacon, id=76371435 - Attribute name: "IrDA:TinyTP:LsapSel", value[IAS_INTEGER]: 97There, you can see that the IrDA stack has discovered my Palm V, that my IrDA port is ttyS0, that I'm not connected, and you can also see that I have an e-Squirt application running that has opened a bunch of server sockets (of course, if you haven't started e-Squirt, the IAS won't contains all those sockets).
The ultimate debugging tool is irdadump. You should run irdadump while attempting to connect and check what's happening. A normal irdadump log with a IrDA device in front of the port (not connected) should show something like this (note that ">>" mean breaking long lines):
> irdadump 22:04:48.000713 xid:cmd 6f1e8511 > ffffffff S=6 s=0 (14) 22:04:48.090705 xid:cmd 6f1e8511 > ffffffff S=6 s=1 (14) 22:04:48.180714 xid:cmd 6f1e8511 > ffffffff S=6 s=2 (14) 22:04:48.270734 xid:cmd 6f1e8511 > ffffffff S=6 s=3 (14) 22:04:48.270698 xid:rsp 6f1e8511 < fb48d412 S=6 s=2 Jean >> Tourrilhes hint=8220 [ PDA/Palmtop IrOBEX ] (32) 22:04:48.360742 xid:cmd 6f1e8511 > ffffffff S=6 s=4 (14) 22:04:48.450733 xid:cmd 6f1e8511 > ffffffff S=6 s=5 (14) 22:04:48.540762 xid:cmd 6f1e8511 > ffffffff S=6 s=* weblab10 >> hint=0400 [ Computer ] (24)
You see my Palm V answering the discoveries of Linux. The Palm shows the infamous "Waiting for sender" pop-up. On the other hand, if the stack is not properly configured (wrong port, wrong driver), or if the device in front is not active, you will get something like this:
22:02:47.988983 xid:cmd 6f1e8511 > ffffffff S=6 s=0 (14) 22:02:48.078981 xid:cmd 6f1e8511 > ffffffff S=6 s=1 (14) 22:02:48.168992 xid:cmd 6f1e8511 > ffffffff S=6 s=2 (14) 22:02:48.258995 xid:cmd 6f1e8511 > ffffffff S=6 s=3 (14) 22:02:48.349018 xid:cmd 6f1e8511 > ffffffff S=6 s=4 (14) 22:02:48.439035 xid:cmd 6f1e8511 > ffffffff S=6 s=5 (14) 22:02:48.529063 xid:cmd 6f1e8511 > ffffffff S=6 s=* weblab10 >> hint=0400 [ Computer ] (24)As you can see, nobody answer us... After that, send a good bug report to the Linux-IrDA mailing list.
The connection just "hang"
One classical problem is the connection hanging just after beeing negociated. The IrDA dump looks like the following:
18:03:28.766071 xid:cmd ffffffff < af28ca67 S=6 s=0 (14) 18:03:28.856067 xid:cmd ffffffff < af28ca67 S=6 s=1 (14) 18:03:28.947685 xid:cmd ffffffff < af28ca67 S=6 s=2 (14) 18:03:29.037383 xid:cmd ffffffff < af28ca67 S=6 s=3 (14) 18:03:29.037549 xid:rsp 977f612c > af28ca67 S=6 s=3 lagaffe >> hint=4400 [ Computer LAN Access ] (23) 18:03:29.126099 xid:cmd ffffffff < af28ca67 S=6 s=4 (14) 18:03:29.216071 xid:cmd ffffffff < af28ca67 S=6 s=5 (14) 18:03:29.316257 xid:cmd ffffffff < af28ca67 S=6 s=* tanguy >> hint=4400 [ Computer LAN Access ] (22) 18:03:29.316433 snrm:cmd ca=fe pf=1 977f612c > af28ca67 new-ca=ba (32) 18:03:29.417508 ua:rsp ca=ba pf=1 977f612c < af28ca67 (31) 18:03:29.417646 rr:cmd > ca=ba pf=1 nr=0 (2) 18:03:29.666173 rr:cmd > ca=ba pf=1 nr=0 (2)If you are on the primary, you will see a series of rr:cmd until it times-out. On the secondary, you won't see anything after the ua:rsp and it will eventually timeout. What most likely happening is that the negociated connection parameters don't match. Usually, one end doesn't implement properly the speed that is beeing negociated, so the two nodes can't hear each other after changing speed. And most likely it happens at FIR speeds. Of course, it would be nice to fix the driver, but in the short term the solution is to force the IrDA stack to negociate a lower speed:
> echo 115200 > /proc/sys/net/irda/max_baud_rateYou can of course try lower values, and there is also other parameters you can tweak in this directory. There is another hang similar to that. You may see the IrDA stack "hanging" on transmitting a large packet. This seems due to a bug in the IrDA-USB dongles.
18:03:30.458569 i:rsp < ca=ba pf=1 nr=6 ns=5 LM >> slsap=12 dlsap=10 CONN_CMD TTP credits=0(12) 18:03:30.458740 i:cmd > ca=ba pf=1 nr=6 ns=6 LM >> slsap=10 dlsap=12 CONN_RSP TTP credits=0(12) 18:03:30.466399 rr:rsp < ca=ba pf=1 nr=7 (2) 18:03:30.516548 rr:cmd > ca=ba pf=1 nr=6 (2) 18:03:30.537423 i:rsp < ca=ba pf=1 nr=7 ns=6 LM >> slsap=12 dlsap=10 TTP credits=0 (29) 18:03:30.537663 rr:cmd > ca=ba pf=1 nr=7 (2) 18:03:30.547328 rr:rsp < ca=ba pf=1 nr=7 (2) 18:03:30.555025 i:cmd > ca=ba pf=1 nr=7 ns=7 LM >> slsap=10 dlsap=12 TTP credits=1 (2050) 18:03:30.566804 i:cmd > ca=ba pf=1 nr=7 ns=7 LM >> slsap=10 dlsap=12 TTP credits=1 (2050) 18:03:30.596405 i:cmd > ca=ba pf=1 nr=7 ns=7 LM >> slsap=10 dlsap=12 TTP credits=1 (2050)It may look a bit different for you, but you get the idea, the packet doesn't goes through and is retried, and the communication just dies there. As we can't fix the hardware, the solution is to force the IrDA stack to transmit smaller packets:
> echo 2000 > /proc/sys/net/irda/max_tx_data_size
irattach print "tcsetattr" in the log
People using FIR drivers (nsc-ircc, smc-ircc...) are often confronted to this simple problem. When they start irattach, it doesn't work and the following message (or similar) is printed in the log&:
irattach: tcsetattr: Invalid argumentThis is due to a conflict between the Linux-IrDA FIR driver and the regular Linux serial driver. Both want to manage the same hardware, the serial driver has registered the FIR port as a pseudo serial port and is owning it, and the kernel rightly prevent the FIR driver to get ownership of it (it's first come first serve). The solution is simple. You need to tell the serial driver that it should not manage this port. The safest way is to remove the serial driver:
> rmmod serialUnfortunately, the trick above doesn't always work (non-modular driver, another serial port in use). Another way is to declare the port invalid:
> setserial /dev/ttyS1 uart none
Compilation problemsSometimes, when you compile the IrDA stack or some various IrDA package, you may have the compiler complaining the things such as IRLMP_HINT_MASK_SET or IRDAPROTO_ULTRA are not defined. This is because of a mess related to kernel headers and the way most distributions deal with it. If you have the 2.4.X kernel source lying around, the fix is simple. Just copy the header irda.h from the kernel to your include directory:
cp /usr/src/linux/include/linux/irda.h /usr/include/linuxThat should fix it.