Archive for October, 2007

AppConference Underflow?

Tuesday, October 30th, 2007

Some weeks ago I wrote about a buffer overflow in app_conference Asterisk application when more than 160 samples per frame were received. I showed how the overflow could be fixed using Asterisk smoothers interface. Two days ago I got an e-mail from a guy in Germany ( Tom ), who had a crash in app_conference and found my blog googling about it. I send him the modified version of app_conference with my fix. Even when Asterisk stopped crashing, audio from chan_mISDN channel going to SIP channel was jittering. After adding some debugging messages to app_conference I sent him a new member.c file so he could try it and send me the resulting logs ( I had no access to his server ). The logs showed that chan_mISDN generated frames with multiple amount of samples, is not that odd? The first voice frame on the call had 640 samples encoded with ALAW ( hence 640 bytes ), that first frame was causing Asterisk crash because of the overflow I showed in my other app_conference post. But what was causing the jitter? Well, if more samples than expected can cause an overflow, what does less samples than expected can cause? yes, jitter. app_conference assume 160 samples per frame, because of 20ms RTP packeting being so common and 8000 samples per second being a telephony standard. So, receiving more samples cause overflow, and receiving less of 160 samples cause the mixing of the audio to be incomplete (zeros in the remaining mix buffer), hence, audio with jitter. As I said, chan_misdn generated frames with different amount of samples, however, most of the audio frames (99%) were being received with 120 samples, and a few ones with less than that.

Solution?

I was tempted to make a simple buffering in app_conference to queue an audio frame until enough samples were received to mix the audio, however, a quick non-code fix was achieved by configuring misdn-init.conf to generate 240 samples. That configuration along with the use of Asterisk smoothers worked like a charm :)

I think I will join iax-devel mailing list to discuss this issue with app_conference developers and possibly integrate a final fix for this issues with more/less samples than expected. I saw code in app_conference that was trying to use smoothers, however the last time I checked it was disabled for some reason.

By the way, Tom nicely offered me some German beer for help with that issue.

Thanks Tom!

Hidden Message? not really, just encoded

Wednesday, October 24th, 2007

Today I read a post in Damog’s blog where he gave a nice PERL tip based in a “hidden message”. Even when some people might argue that the message is really hidden, to me it seems like it is simply encoded, that’s not the same, is it?

In anycase, if some of you were lazy enough to not decode the message here is a program that does just that:


#include <stdio.h>
#include <stdlib.h>

#include <string.h>

int main(int argc, char *argv[])
{

  FILE *handle;
  char char_byte[9], *c;

  long binval;
  if ( argc < 2 ) {
    return -1;
  }
  handle = fopen(argv[1], “r”);
  if ( NULL == handle ) {

    perror(“error”);
    return -1;
  }
  memset(char_byte, ‘0′, sizeof(char_byte) - 1);
  char_byte[8] = 0;

  c = char_byte;
  while ( 0 != fread(c, 1, 1, handle) ) {

    if ( *c != ‘1′ && *c != ‘0′ ) {

      continue;
    }
    if ( !*(c + 1) ) {
      binval = strtol(char_byte, NULL, 2);

      printf(“%c”, binval);
      c = char_byte;

      continue;
    }
    c++;
  }
  printf(“\n”);
  fclose(handle);

  return 0;
}

1. Copy and paste the program.
2. Copy and paste the encoded message in Damog’s post or the other post he mentioned.
3. gcc readasbin.c -o readasbin.exe
4. ./readbin.exe message.txt

Jeez … I should have used PERL :)

SHMConfig

Tuesday, October 23rd, 2007

Well, found the user space configuration to instruct X to grab or not grab the Synaptics touchpad. SHMConfig = off did the trick :)

Linux Input Subsystem and my TouchPad

Sunday, October 21st, 2007

Heck, I hate when things stop working suddenly without apparent reason ( and who doesn’t ? ). But this time I have learned some stuff and finding a workaround has been fun. Some weeks ago my touchpad just stopped working as soon as I logged into Gnome session. The touchpad even worked at the login screen, but it stopped working as soon as I typed my password and the login process started. To add some oddity to this problem, if I typed “CTRL + ALT + F1″ to get a console, my touchpad worked again!, but when I typed “CTRL + ALT + F7″ to get back to my gnome session it stopped working again, WTF???. Fortunately the trackpoint still worked at all times, so, even when I liked more the touchpad I got used to the trackpoint quickly and even I felt it had some advantages. However, I was still puzzled because once in a while I wanted to scroll down without having to press the down arrow in my keyboard. So, as soon as I had some time, I started investigating the issue.

The first thing I did was open the xorg.conf configuration and X logs, probably some IBM Open Client ( IBM Red Hat based distro ) update broke my config or something like that. Did not find errors in the logs but I found that the mouse input device was configured as “/dev/input/mice”, as usual. After googling a couple of minutes I got tired of searching. So I decided to do more low level investigation instead of just blindly tweaking X configuration file and end user stuff like that. I did a small test program a bit like this:


fd = open(“/dev/input/mice”, O_RDONLY);

FD_ZERO(&rfds);
FD_SET(fd);
while ( 1 ) {
    res = select(fd + 1, &rfds, NULL, NULL, NULL);

    if ( FD_ISSET(fd, &rfds) ) {
        res = read(fd, read_buffer, sizeof(read_buffer));

        printf(“got some data\n”);
    }
}

So, this just served the purpose of confirming no event was generated when I moved my finger in the touchpad, and events were generated with the trackpoint. So, was this a driver problem? I did a quick ‘ls -la’ to find out the major and minor of “/dev/input/mice”, however I did not find a way to map the major/minor to the kernel driver that takes care of the file operations ( read(), write(), blah() ). I asked several people and nobody knew how to find out the driver/kernel module that takes care of creating a /dev/ entry given the major and minor. Obviously the kernel can, but I did not find any user space tool for that. In order to try to find the driver I downloaded the kernel sources that closely matched my installed kernel ( 2.6.18 ). After some searching in the kernel tree I found “drivers/input/” directory. I was sure somewhere there it was the answer to my problem. Since every time I entered the graphics mode touchpad stopped working, I thought X was doing some nasty stuff, may be some ioctl() to disable the touchpad if trackpoint was found as well? I found some posts in forums saying some people want to disable touchpad because they accidentally touch it when writing and that disturbs them, so I started considering the possibility of X disabling intentionally my touchpad. I did a “grep” searching for ioctl definitions in the “drivers/input” directory and found several ones, particularly evdev.c was interesting, since events were not being received in user space after all. I did not understand shit of what the ioctl’s were doing there, so I searched for documentation in Documentation/input/input.txt , and voilá!, things started to make sense. I did some googling on the ioctl’s defined in evdev.c because input.txt did not say a word about them. I found this interesting articles:

http://www.linuxjournal.com/article/6396
http://www.linuxjournal.com/article/6429

Interesting, but, still did not say anything about why possibly events could not be received in user space. So, back to the code in evdev.c I paid more attention at the ioctl’s and started experimenting with some of them like EVIOCGVERSION and EVIOCGNAME. I found some documentation in include/linux/input.h . I found a comment about EVIOCGRAB saying “Grab/Release device”. Hum, that sounded interesting, what implications has grabbing a device? The articles did not mention that ioctl, so, Let’s try it!

/* fd is /dev/input/event0 ( my keyboard )*/
ioret = ioctl(fd, EVIOCGVERSION, &version);

ioret = ioctl(fd, EVIOCGNAME(sizeof(device_name)), device_name);

ioret = ioctl(fd, EVIOCGRAB, &grab);
if ( -1 == ioret ) {
  perror(“ioctl()”);
}

printf(“ver: %d, ret = %dn”, version, ioret);
printf(“device name is: %sn”, device_name);

I paid the price of my stupidity, testing with my keyboard was not a smart thing, really. My keyboard stopped working and I had to brute force reboot. So, it seems that EVIOCGRAB ioctl is something like getting exclusive rights over the input events of the specified device, thus, X was not able to get my keyboard events, the only process that was able to receive them was my program, and it was not doing anything useful with them except printing “got some data” message.

I tried next with /dev/input/event1 ( my touchpad ) and got a “Device or resource busy” and tried with /dev/input/event2 ( my trackpoint ) and it succeeded. I connected an USB mouse and it created /dev/input/event3. Tried with that one and it also worked. So, it was clear to me that someone ( X of course ) was grabbing my touchpad for some reason and ignoring events, error or feature?, I still don’t know. So, I did a “touchpad-takeover” program that will not allow X to take control of my touchpad and then, when already logged in, my program will release the device. That way events will start flowing again to any application waiting on /dev/input/event1 and /dev/input/mice ( this device is a mix of all the mouse devices events ), may be that way X will learn to play nice with me :)

Here is how the touchpad-takeover look like:

http://www.moythreads.com/htmlcode/touchpad-takeover.html

Now, everytime my laptop boots, I launch that program, with /dev/input/event1 as argument, in the background. X report an error saying “Synaptics can’t grab event device, errno=16″, aha!, how does that feels X??! hu? … As soon as I start my gnome session I send SIGINT to my program (kill -2) so it will release /dev/input/event1 and I am able to use my touchpad :)

Is not that odd? If X is able to grab my touchpad device, touchpad does not work. If I grab the device first so X cannot grab it, and then, once logged in, I release the device, I can work with my touchpad. Bug or feature? I think some X configuration might alter that behaviour, but I have not found it so far. May be with some more time in my hands I will dig into the X server code to find out what is going on. Even when I am able to use my touchpad, the scroll down feature is missing in my touchpad :( . Before this strange stuff happened, I could move my finger on the right edge of the touchpad and it had the effect of scrolling down my screen/documents, now it does not.

Long post … time to go back to Guadalajara. I arrived at Puebla yesterday to give an Asterisk talk at ENLi, I was planning to get back yesterday at night, however, Tato did not show up to give his Asterisk presentation, fortunately I talked with Sandino this morning and he said Tato is OK, so I gave the presentation this morning in his place. Gotta go, I’m quite tired …