PoempelFox Blog

[..] [RSS Feed]
 

Sun, 20. Mar 2011


S2API and the complete lack of documentation Created: 20.03.2011 11:04
While adding support for DVB-S2 to getstream-poempel, i had the joy of having to figure out how S2API works.
S2API is the new API for DVB on linux, and it is the only way to tune DVB-S2 channels, as the old API (that still exists) cannot do that. It also supports other standards, but DVB-S2 was the first and the one it was developed for, hence the name. It is in the vanilla linux kernel since 2.6.28.
S2API is a nice redesign of the API: Instead of having to add new structures for every new DVB standard like with the old API, it uses flexible name-value pairs. This is not a bad idea, and it seems to work well. What doesn't work so well is the fact that there is still no trace of any documentation anywhere. Many applications have at least experimental support for S2API by now, but it seems they all implemented it by copying from each other. I basically had to do the same and found it pretty annoying. The S2API article on the linuxtv.org Wiki offers an interesting read on the history of the new API and the "API wars" that lead to it, but actually providing info on how to use the new API would be better.
 
So, here is a writeup of my findings, in the hope that it will be useful to others that face the same problem. I also hope that the linux dvb guys get their act together and provide some useful documentation soon.
The first thing to check is whether the kernel (or rather, the kernel headers you're compiling with) supports the new API. For that, you need to #include <linux/dvb/version.h>. It defines DVB_API_VERSION. As the S2API has been given the version number 5, you need to check for DVB_API_VERSION >= 5. Please don't overdo the checking: While trying to compile scan-s2, a version of scan modified for S2 support, I could "admire" that they check for the API version to be _exactly_ 5.0 - which is of course nonsense and makes the compile fail on every current kernel, as they have reached API version 5.1.
Up next is the basic concept of the new API: You give it a list of "commands" that it will execute. Those commands can either change settings, or actually do stuff. For example, for tuning you'll usually send some settings, like the frequency, and then send a "tune" command as the last one, that will then tune to the settings you gave before. The "commands" are given in an array of type struct dtv_property. That struct contains a command ID, and parameters for the command in an union. Like with the old API, everything needed is defined in <linux/dvb/frontend.h>. Some example:

#include <linux/dvb/frontend.h> struct dtv_property myproperties[] = { { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBS2 }, /* Select DVB-S2 */ { .cmd = DTV_FREQUENCY, .u.data = frequency }, /* Set frequency */ { .cmd = DTV_SYMBOL_RATE, .u.data = srate }, /* Set symbol rate */ { .cmd = DTV_TUNE }, /* now actually tune to that frequency (no parameters needed) */ };

The last line will start the actual tuning. To get that command array into the kernel, you will first need another structure of type struct dtv_properties. This tells the kernel how long the array is, it's therefore a very simple structure with only two members: an uint32_t num giving the number of commands in the array, and props which is a pointer to the array with the commands. You then pass this struct to the kernel with an ioctl. Like this:

struct dtv_properties mydtvproperties = { .num = 4, /* The number of commands in the array */ .props = myproperties /* Pointer to the array */ }; if ((ioctl(myfd, FE_SET_PROPERTY, &mydtvproperties)) == -1) { perror("FE_SET_PROPERTY failed"); }

The last thing is a mystery I haven't solved yet: Although the new API does seem to offer commands for setting voltage and 22 kHz tone, namely DTV_VOLTAGE and DTV_TONE, all programs I looked at still did those two settings through the old API, by calling the extra ioctls FE_SET_VOLTAGE and FE_SET_TONE. One the one hand this isn't surprising, as due the lack of documentation they had to copy off each other, but on the other hand I'm wondering whether there perhaps is a real reason for this. Perhaps that functions weren't in the very first version of the new API?
2 comments
Thanks for publishing this, it's really helpful.

Let's hope the DVB API guys get their act together and actually document this stuff.
Mister Fishfinger 03.01.2013 15:57

Thanks! Very useful!
Ferranti 14.11.2014 16:10

write a new comment:
name or nickname
eMail adress (optional)
Your comment:
calculate: (2 times 10) plus 3
 

EOPage - generated with blosxom