Intro | Irda on Toshiba 5100 | Tutorial 1 | 

Linux-IrDA Tutorial 1

While Linux already enjoy an Open Source implementation of IrDA stack there is a real lack of knowledge developing infrared aware applications. This document is a step by step guide to Linux-IrDA programming that make an easy introduction for unexperienced programmers. Alltough, an experienced one will find usefull the paralell between IrDA and TCP/IP protocols.

Starting IrDA stack

IrDA is a protocol stack similar to TCP/IP. It's not surprising that applications to employ IrDA make use of socket() system call. I remember that among TCP/IP, there are many other protocols stacks under Linux: IPX/SPX, DecNet, NetAtalk. Execute:

man socket
As you may see socket() function have 3 parameters. First one specify what protocol stack we want to use. For our case is AF_IRDA (address family IrDA). This is a number. More precisely 23, but who care. Some protocols offer many type of services for applications: reliable data streams, data packets without confirmation etc. The second paramater encode type of service. SOCK_STREAM and SOCK_DGRAM are most common ones. Third parameter tell protocol used. In almost all cases the value is 0.

A socket() call try to initialize a binding between application and IrDA stack from kernel. It's like opening a file before trying to read or write from it. The value returned is a descriptor which refer to our opened connection with stack. Bellow is ir-tut1.c which illustrate what I said above:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/irda.h>

int main(int argc, char **argv) {
  int fd;
  if (fd<0) {
Compile and execute it:
clauc:tutorial# gcc -I/usr/include -o ir-tut1 ir-tut1.c
clauc:tutorial# ./ir-tut1
socket: Address family not supported by protocol
Our program failed. This is good because IrDA stack is not in kernel. This happen if you use an usual Linux distribution. IrDA code is compiled as modules and loaded on demand or at user request. We manually load the IrDA stack and reexecute our program.
clauc:tutorial# modprobe irda
clauc:tutorial# ./ir-tut1
Well, we can see that ir-tut1 has completed succefully by doing nothing. Because for the moment nothing is complicated in first IrDA application lets make a tour arround what Linux IrDA stack show us in virtual /proc filesystem.
clauc:tutorial# ls -1 /proc/net/irda

You can observe 5 files. Information in these files is dynamic and change according to stack functionality. When another IrDA protocol components are loaded, more files will be present here. Just for curiosity look on files using an ordinary text viewer.

clauc:tutorial# ls -1 /proc/sys/net/irda
Above you can view the files that control some IrDA stack parameters. Of some importance when tweaking operation with external IrDA aware devices can be discovery_timeout and/or slot_timeout. I'll not develop an exhaustive discussion about these parameters or what informational files in /proc/net/irda/ contain, but some more info are provided below as need arise.

Playing with local IrIAS

Frankly, our stack is not ready for normal use, but most concepts can be fixed in mind before we start real work. Lets introduce IAS - Information Access Service. IAS is an IrDA built-in application and on top of IrLMP. It's similar to DNS - Domain Name System counterpart. Instead of resolving names to IP addresses, it resolve service names to IrLMP selectors. Oh, lot of complicated info. I'll try to take these step by step. First, an advised person know that DNS not only map names to IPs, but many types of informations. It's like a database. You can put anything you like to make your website, mail server etc. need to function properly and users be happy. Likewise, IAS can store different type o informations: numbers, strings and byte sequences. With these building blocks you or your application can store or read informations in/from IAS, structured by classes (like database records). Every object contain one or more entries of different type.

What a LMP selector it is? Well, it's easy to associate with a TCP or UDP port. A host connected to network have an IP address and in this host a specific service act (listen) on specific port. That way a host can provide multiple services on one data link. Similary, LMP offer a meaning to multiplex many data channels on one infrared link. TCP/IP have a maximum of 65535 ports. IrDA allow 256, but more are reserved and some are special. For example IAS listen on 0x00 selector all the time. Seletor 0x7f, when open, will allow exclusive access to IrDA link. Your application can use selectors in 0x01-0x7e range. IANA, an Internet authority define known services which listen on specific ports. For example mail servers using SMTP protocol use port 25, web servers using HTTP use 80. It's not going to happen with IrDA. Because communications are temporary and selectors are a limited resource, applications which act as a server temporary register their presence in IAS. The listening LMP selector is made known in IAS, along with another informations if application want to provide.

In this lesson you will learn how to set and query informations from IAS. Please keep in mind that every entity which employ IrDA have an IAS service. So, we talk about two IAS entities when come to have a data link: our IAS and peer IAS. We have need for two new system calls: getsockopt() and setsockopt(). To accomodate with it, run:

man getsockopt
man setsockopt
These functions control various IrDA stack parameters or are used to do other than transfering data. Our case is working with IAS. To point in using IrLMP facilities, level argument is set to SOL_IRLMP, which is a number defined in irda.h. Take a look in that file to view various socket options available for Linux IrDA stack. This lesson will make use of IRLMP_IAS_GET and IRLMP_IAS_SET to query and set our IAS database. To query peer IAS there is a IRLMP_IAS_QUERY but for the moment we don't use it because yet is no IrDA link with other device. getsockopt() take a data structure as one of arguments: irda_ias_set.
struct irda_ias_set {
  char irda_class_name[IAS_EXPORT_CLASSNAME];
  char irda_attrib_name[IAS_EXPORT_ATTRIBNAME];
  unsigned int irda_attrib_type;
  union {
    unsigned int irda_attrib_int;
    struct {
      unsigned short len;
      __u8 octet_seq[IAS_MAX_OCTET_STRING];
    } irda_attrib_octet_seq;
    struct {
      __u8 len;
      __u8 charset;
      __u8 string[IAS_MAX_STRING];
    } irda_attrib_string;
  } attribute;
  __u32       daddr;    /* Address of device (for some queries only) */
Before calling getsockopt() we must fill irda_class_name and irda_attrib_name fields. After call remaining fields will be filled with result if any. This system call corespond with GetValueByClass primitive from IrDA stack description. Looking to irda_attrib_type we can tell what type of data had returned: IAS_MISSING (nothing), IAS_INTEGER (an unsigned integer number), IAS_OCT_SEQ (an octet sequence) or IAS_STRING (a string).


Home | About | Contact | Documentation | Applications | Download | Resources 

Copyright 2002-2003 Linux-IrDA Project. Released under GNU FDL license.