Saturday, September 3, 2011

Auto hangup

Dear user,

If auto hang up does not work in your mobile please try the following instructions that a user shared with me  in order to have auto hangup working in CallTimerPro:

1. Go to Settings -> Accessibility and a dialog will come up asking you to download a complement.
2. Accept the dialog andyou will be redirected to the Android Market to download the application Talk Back.
* It seems that this application has been removed from the Android Market but it is also available in:
http://code.google.com/p/eyes-free/downloads/detail?name=com.google.android.marvin.talkback-v2.7.5_signed_market.apk%20%09.apk

3. Once the application is installed go again to Settings -> Accessibility and enable the check-boxes Accessibility and Hang up.
4. Go to CallTimerPro and hit the menu button, select Global settings and enter to Hang up Mode.
5. Select Default Mode.
6. In CallTimerPro configure a contact to perform a test and make sure Hang up is enabled.

These instructions were tested in a LG Optimus Black mobile but I think it might work for other mobiles as well.

If this worked for you and you have a different handset or the steps you followed are different I will appreciate if you leave a comment to help other people with the same issue.

So far the only mobiles where users have commented that auto hang up does not work are LG handsets. If you have a different hand set you can give this a try but it might be something different such as a configuration issue in the application.

Regards,
Juan Garibay

Auto colgado

Que tal,

En este post presento una sugerencia que funciona en la mayoría de los teléfonos LG donde el colgado automático no funciona por default (originalmente compartida por un usuario).

1. Entra a Ajustes -> Accesibilidad y un diálogo va a aparecer con un mensaje indicando que se necesita instalar un complemento.
2. Da clic en aceptar y seras redirigido al Android Market donde tendrás que descargar la aplicación Talk Back.
* Si por alguna razón no te deja abrir la aplicación, también la puedes descargar de este link:
http://code.google.com/p/eyes-free/downloads/detail?name=com.google.android.marvin.talkback-v2.7.5_signed_market.apk%20%09.apk

3. Una vez instalada esta aplicación entra otra vez a Ajustes -> Accesibilidad y activa la casilla Accesibilidad y Colgar.
4. Entra a CallTimerPro persiona el botón menú, selecciona Configuración Global y da clic en Modo de colgar.
5. Selecciona la opción Modo default.
6. Entra a la aplicación selecciona un contacto para hacer la aprueba y habilita Auto Colgar.

De acuerdo a los comentarios esto funciona en la mayoría de teléfonos LG, si no te funciona puedes intentar configurar el modo colgado en modo avión dentro de la aplicación y si funciona te agradecemos un comentario en:

Versión gratis
https://play.google.com/store/apps/details?id=com.gary.NoTePases&hl=es


Versión de paga:
https://play.google.com/store/apps/details?id=com.TouchSpots.CallTimerPro&hl=es
Si tienes dudas con gusto te apoyo en soporte@calltimerpro.com.


Saludos,
Juan Garibay

Wednesday, July 6, 2011

Sending encrypted http requests from Android to a web server that requires basic authentication.

Lately I have been busy ramping up in in php, web services, json, encryption and other web related topics so I can make available an Android app I have been working on to the world.

Here I will write a brief example of how to send encoding http requests from an Android device to a php file in an Apache web server that requires basic authentication, I will omit the code in php but if you need a sample please let me know and I will send it to you.

Everything starts with a call to updateUser() and then you just have to follow the code.

boolean updateUser() throws JSONException{ 

    // In my case the web service I am communicating with expects a JSON message
    // with specific structure, it could have been xml or plain text.

    JSONObject root = new JSONObject();
    JSONObject user = new JSONObject();



    user.put("user_id", "12345");
    user.put("age", "25");
    user.put("name", "Juan G.");
       
    root.put("user_info",user);
    root.put("action","update_user");
        

    //Encrypting the JSON message.
    String jsonEncrypted = encrypt(root.toString());
    String[] result = postCommand(jsonEncrypted);
       
    int statusCode = Integer.parseInt(result[0]);
    if(statusCode>=200 && statusCode<300){
        logd(TAG,"Server returned OK in updateUser()");
        return true;
    }else {           
        logd(TAG,"Server returned ERROR "+ statusCode + " in updateUser()");
    }
   
    return false;        

}

private String[] postCommand(String jsonString){
       
    DefaultHttpClient client = new DefaultHttpClient();

    URI uri = null;
    try {
        uri = URIUtils.createURI(    "http",
                "www.example.com",
                -1,
                "/exampleDir/exampleFile.php",
                null,
                null);
     }catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
     }    

    //This code is needed to authenticate in the web server.
    //If your server does not need authentication you can remove it.
    AuthScope as = new AuthScope(uri.getHost(), uri.getPort(), null);
    Credentials creds = new UsernamePasswordCredentials("ctp_client", "xuGiL1Nu3b=3");       
    client.getCredentialsProvider().setCredentials(as,creds);        
   
    client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);
       
    HttpPost post = new HttpPost(uri);
    post.addHeader("Accept", "json");                         

    if(jsonString == null){
        return null;
    }
       
    String jsonEncoded = null;
    int statusCode = 0;
       
    try {       
        StringEntity requestEntity = new StringEntity(jsonString,"UTF-8");
        post.setEntity(requestEntity);
           
        HttpResponse response = client.execute(post);
                       
        statusCode = response.getStatusLine().getStatusCode();                                 
        HttpEntity entity = response.getEntity();                   
                               
        if(entity != null){
            InputStream in  = entity.getContent();
            try{
                                  
                DataInputStream dis = new DataInputStream(in);
                           
                StringBuilder sb = new StringBuilder();
                while( (jsonEncoded = dis.readLine()) !=null){
                    sb.append(jsonEncoded +"\n");                                              }
                   
                jsonEncoded = sb.toString();
                logd(TAG,jsonEncoded);
                   
            }finally{
                client.getConnectionManager().shutdown();
                in.close();
            }
        }
    }catch (SocketException e) {
        /*No route to host*/
        statusCode = -1;                   
    }catch(IOException e){
        e.printStackTrace();
    }finally{
        client.getConnectionManager().shutdown();
    }
       
    return new String[]{String.valueOf(statusCode),jsonEncoded};    
}
   
private String encrypt(String plaintext){
       
    int length = plaintext.length();
    int padding = length%16;           
    if(padding != 0){
        plaintext=padRight(plaintext, 16*(length+1));       
    }
       
    byte[] iv = {-27, -49, 25, 63, -91, 15, -88, 60, 96, 27, -78, 48, -35, -71, -24, -99};       
    byte[] key ={17, 25, 38, -74, -41, -110, 17, 21, 16, 108, -98, -89, 12, 72, 80, 3};
       
    SecretKeySpec keyspec = new SecretKeySpec(key, "AES");       
    IvParameterSpec ivspec = new IvParameterSpec(iv);               
           
    byte[] encrypted = null;
    byte[] decrypted = null;
   
    Cipher cipher;       
       
    try {
        cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        encrypted = cipher.doFinal( plaintext.getBytes("UTF8"));   
   
    /*
        This is to decrypt the encrypted text but not needed for this example.    
        cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
        decrypted = cipher.doFinal(encrypted);       
    */
 
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
               
    return new String(toHexString(encrypted));        
}
   
public static String toHexString(byte[] bytes) {
    char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for ( int j = 0; j < bytes.length; j++ ) {
        v = bytes[j] & 0xFF;
        hexChars[j*2] = hexArray[v/16];
        hexChars[j*2 + 1] = hexArray[v%16];
    }
    return new String(hexChars);
}
   
public static String padRight(String s, int n) {
    return String.format("%1$-" + n + "s", s); 
}


Be careful with the encryption algorithm you choose, for this example the plain text is no more than 200 bytes and after encrypting it the size went to +6K bytes (for this example I omitted other information I am sending in the request). 

Now I am reconsidering whether the value of the information I am transmitting is worth the increasing in size and processing mainly in the server because I have thousands of users that will be communicating with it.

Hope you find it useful!

Friday, May 27, 2011

CallTimerPro

Hi, in this post I will describe the features available in this app so you can get the most of it:

What is the goal of this app?
This application allows you to be aware of the time of incoming and outgoing calls. It allows you to set alarms for all the contacts or only for the contacts that you need as well as to configure the type of notification (sound or vibration), the time of the alarm, auto hang-up, auto dial and deactivate the application in a day basis.

Default settings:
- Vibration and sound notifications for incoming and outgoing calls.
- Time of the alarm set to 4.5 minutes for incoming and outgoing calls.
- Hang-up mode set manual.
- Application enabled all days.
- The entry "All contacts" which will notify you for all incoming and outgoing calls according to the configured time.
You can disable the alerts in "All contacts" and only add the contacts you are interested in.
You can pick the numbers in a contact where you want to be notified.

When does the alarm time start?
THE TIME OF INCOMING CALLS STARTS WHEN YOUR MOBILE RECEIVES A CALL (not when the call is answered) and THE TIME OF OUTGOING CALLS STARTS WHEN YOU CLICK THE CALL BUTTON.

How do I know if the alarm is configured for the current call?
If the application icon is in the notification bar it means the alarm is configured for the current call. Once you are notified the icon will vanish.

How do I cancel the alarm for the current call?
Open the notifications and click the application notification.

How do I add a new contact?
Press the menu button, select "Add Contact" and pick the contact you want to add. A dialog is going to pop up where you can select the phone numbers where you want to be alerted.
When a new contact is added the alert configuration for this contact is going to be used rather than the configuration for "All Contacts".

How do I remove a contact?
Press the contact you want to delete for 3 seconds and dialog will pop up, select "Remove contact".

How do I configure the alerts for a contact?
Press the contact where you want to configure the alert and a menu will come up. In this menu you can enable or disable alerts for incoming and outgoing calls as well as configure the time for the alerts.
IMPORTANT. If the time is set to zero or the alert is disabled you will not be notified and will not see the application icon in the notification bar

How do I activate auto dial?
Press the contact where you want to configure this option and in the menu that comes up select enable or disable auto dial.
NOTE. If the auto dial option is activated, it will only have effect if the call is hanged (either automatically or manually) after you were notified. For example, if you have configured the alarm at 4 minutes and the call is finished before 4 minutes, auto dial wont have effect.

How do I hang-up automatically the calls?
Press the button menu and select "Global Settings". Click in the hang-up option and select a mode.
When you receive or place calls, after that the time of the alarm is displayed in the notifications bar, it will be displayed the mode of hang-up that was configured.

How do I configure the alert type?
Press the button menu and select "Global Settings". Adjust according to your preferences the options available in the section "Sound and vibration".
IMPORTANT. If vibration and sound alerts are disabled you will not be notified when the alert expires even if the application icon is displayed in the notifications bar.
NOTE. The alert type you choose will be used for all the notifications.

How do I disable the application in a days basis?
Press the button menu and select "Global Settings". Click "Active Days" and enable or disable the application according to your needs.
IMPORTANT. The days that are not selected you wont receive any notification. It will be as if the app had not been installed.

Why are all those permissions required?
android.permission.PROCESS_OUTGOING_CALLS
Detect outgoing calls.

android.permission.VIBRATE
Notify the user that the time of the alarm expired.

android.permission.CALL_PHONE
Re-dial.

android.permission.READ_CONTACTS
Add new contacts.

android.permission.WAKE_LOCK
Avoid the device to sleep when the application is tracking the time of a call.

android.permission.WRITE_SETTINGS
It seems it is not needed anymore, I am going to double check it and remove it in the next release if that is the case.

android.permission.ACCESS_FINE_LOCATION
android.permission.INTERNET
Currently these permissions are not used but I included them because I am going to add advertisements to this application. The location permission is going to be used to deliver ads related to your location and the Internet permission to let you click the advertisement and go to the page of the site.
I am going to publish a paid application that will not require the ACCESS_FINE_LOCATION but first I want to introduce the remaining features, bug fixes and make sure it is stable in most mobiles.

For doubts or comments please post here and I will reply back or send a mail to support@calltimerpro.com

Thanks again and hope you find it useful!

Wednesday, March 30, 2011

Hacking Android Input Subsystem

After my previous post "Overcoming Video timing issue with Nec display" I was able to display the resolutions I was interested in but my excitement last a few minutes, once Android finished booting on my BeagleBoard (BB) I realized the touch sensor was not working at all! In this post I am going to describe the changes I had to do to the Android input subsystem to enable the touch sensor.

The touch sensor integrated with the display is a DST sensor from 3M that is connected via USB to a computer (in this case the BB) and is HID compliant (no need for special drivers). Before it is used it has to be calibrated to tell the touch controller what is the resolution of the screen so it can report the coordinates accordingly. I calibrated it in Windows (with a SW provided by 3M) for a720p resolution and then I was able to use it seamlessly in Ubuntu once I set the resolution of the screen to 720p. The good news, the HW works and is a SW problem...

When I connected the touch sensor to the BB, I learned the following from the kernel log and Android logcat:
usb 2-1.2: new full speed USB device using musb_hdrc and address 3
usb 2-1.2: device v0596 p0300 is not supported
input: 3M 3M MicroTouch USB controller as /devices/platform/musb_hdrc/usb2/2-1/2-1.2/2-1.2:1.0/input/input1
generic-usb 0003:0596:0300.0001: input: USB HID v1.10 Pointer [3M 3M MicroTouch USB controller] on usb-musb_hdrc-1.2
E/EventHub(  868): could not get driver version for /dev/input/mouse0, Not a typewriter
I/EventHub(  868): New device: path=/dev/input/event1 name=3M 3M MicroTouch USB controller id=0x10001 (of 0x2) index=2 fd=29 classes=0x0
I/KeyInputQueue(  868): Ignoring non-input device: id=0x10001, name=3M 3M MicroTouch USB controller

First I checked the E/EventHub error but I realized the same message was displayed when I connected a mouse to the BB and it worked fine so I ignored it. Then I realized that the last message was different for the mouse, instead of displaying "... Ignoring non-input device...", the log for the mouse was as follow:

I/KeyInputQueue(  868): Device added: id=0x10002, name=Genius NetScroll + Mini Traveler, classes=40

This is the snipet of code from where this print comes from: androidRoot/frameworks/base/services/java/com/android/server/KeyInputQueue.java:

if (ev.type == RawInputEvent.EV_DEVICE_ADDED) {
    synchronized (mFirst) {
        di = newInputDevice(ev.deviceId);
        if (di.classes != 0 ) {
        // If this device is some kind of input class,
        // we care about it.
            mDevices.put(ev.deviceId, di);
            if ((di.classes & RawInputEvent.CLASS_TOUCHSCREEN) 
                 != 0) {
                readVirtualKeys(di.name);
            }
       // The configuration may have changed because
       // of this device.
       configChanged = true;
       } else {
       // We won't do anything with this device.
       mIgnoredDevices.put(ev.deviceId, di);
       Slog.i(TAG, "Ignoring non-input device: id=0x"
                   + Integer.toHexString(di.id)
                   + ", name=" + di.name);
       }
    }
}
else if (ev.type == RawInputEvent.EV_DEVICE_REMOVED) {
        /*handle device removals*/
   }
else{
    di = getInputDevice(ev.deviceId);
    if (di == null) {
        Slog.i(TAG, "getInputDevice() null device!");
        // This may be some junk from an ignored device.
        continue;
    }
    /*handle any other kind of events (mouse moved, 
    key pressed, etc.)*/
}

If the event type corresponds to RawInputEvent.EV_DEVICE_ADDED, a new input device is created and then the classes field is checked. If it is different to zero the new input device is put in a List otherwise is ignored. When a event type different to EV_DEVICE_ADDED or  EV_DEVICE_REMOVED arrives (the else at the bottom) it is checked whether the device that generated the event is in that list, if it is not the event is just ignored.

Then I went to the file androidRoot/frameworks/base/libs/ui/EventHub.cpp to the function open_device (called when the input device is created). Here a file descriptor is opened using the argument passed to this function and then the capabilities of the device are determined using the ioctl EVIOCGBIT. Depending on the device capabilities is the value of the field di.classes, if the device does not have the capabilities that Android is looking for this field is never set and its value remains zero.

First thing I did was to determine what were the capabilities supported by the touch sensor. The types of features supported by the event interface are:
  • EV_KEY: absolute binary results, such as keys and buttons.
  • EV_REL: relative results, such as the axes on a mouse.
  • EV_ABS: absolute integer results, such as the axes on a joystick or for a tablet.
  • EV_MSC: miscellaneous uses that didn't fit anywhere else.
  • EV_LED: LEDs and similar indications.
  • EV_SND: sound output, such as buzzers.
  • EV_REP: enables autorepeat of keys in the input core.
  • EV_FF: sends force-feedback effects to a device.
  • EV_FF_STATUS: device reporting of force-feedback effects back to the host.
  • EV_PWR: power management events.
From these set, the  features supported by the touch sensor are: EV_SYN, EV_KEY, EV_ABS & EV_MSC.
These were pretty much the same capabilities supported by the mouse I was using to compare configuration differences except for EV_ABS, instead of this feature the mouse has EV_REL.

In the open_device function the following logic takes place:

/*check whether the device has support for buttons. If it does, flags representing the buttons supported are set in the key_bitmask array.
The value of these flags is under  androidRoot/frameworks/base/core/java/android/view/RawInputEvent.java*/
if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0){
   ... /*code to check if it is a keyboard*/
}

/*check if the flag that corresponds to the mouse button (left button) was set. If it did, it means it is a mouse kind device*/
if (test_bit(BTN_MOUSE, key_bitmask)) {
    /*For the touch sensor only the mouse button was
    present, for he mouse the right, middle and mouse
    button were present.
    However, inside this if it was checked only if the
    device had support for EV_REL. Which the touch 
    sensor did not. */
    if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)),
              rel_bitmask) >= 0){ 
        /*code to set mouse or trackball class*/
    }

    /*I had to add the logic to detect if the device had
    support for EV_ABS*/
    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)),
        abs_bitmask) && (device->classes == 0) ){
        if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y,
            abs_bitmask)) {                  
                device->classes |=CLASS_MOUSE;
               }
    }
}

After doing so the touch sensor was added to the list of devices. The mouse cursor was now displayed in the upper left corner but it did not respond to touches due to the handling routine was surrounded by an if statement to only handle events related to EV_REL.

A brief comment, the difference with EV_REL and EV_ABS is that EV_ABS returns the cordinate where the click or movement happened i.e (500x700) and the EV_REL returns the cordinate relative to the previous coordinate i.e (5,4).

In the event handling routine I added the following code to take care of movment events generated by the touch sensor.

else if (ev.type == RawInputEvent.EV_ABS && 
         (classes&RawInputEvent.CLASS_MOUSE) != 0 ) {
    if (ev.scancode == RawInputEvent.ABS_X) {
        int xvalue = ev.value;
        di.mAbs.changed = true;   
        xvalue =   (xvalue*mDisplayWidth)/1023;
        di.mAbs.mNextData[MotionEvent.SAMPLE_X] = xvalue;  
        Slog.i(TAG,"mDisplayWidth " + mDisplayWidth + 
               " xvalue " + xvalue);                  
    } else if (ev.scancode == RawInputEvent.ABS_Y) {
        int yvalue =ev.value;
        di.mAbs.changed = true;
        yvalue = (yvalue*mDisplayHeight)/1023;
        Slog.i(TAG,"mDisplayHeight " + mDisplayHeight + 
               " yvalue " + yvalue);                 
        di.mAbs.mNextData[MotionEvent.SAMPLE_Y] = yvalue;
    }
}

The X and Y coordinate values were always in the range from 0 to 1023 no matter that I calibrated the touch screen so I had to do some maths to adjust the coordinates with the display resolution.

Click events were handled correctly with the original code so I did not have to modify anything there.

To give a better illusion of a touch screen I "removed" the mouse cursor displayed in the screen (I guess this cursor was displayed because the touch sensor was identified as some kind of mouse) by making the cursor transparent in the file:
androidRoot/frameworks/base/services/java/com/android/server/WindowManagerService.java
In the function performLayoutAndPlaceSurfacesLockedInner() set alpha blending to zero in the lines:
tPaint.setColor(0x00ffff);   //black color for the cursor
mCanvas.drawColor(0x00000000);  // white color for the 
                                // border of the cursor

Some extra tips to build only the libraries you need in BeagleBoard/Android enviroment:
$ cd $path/to/androidRoot
$ source build/envsetup.sh
$ lunch beagleboard-eng   //this is the target device for which I am building
$ cd path/to/the/file/modified
$ mm
...
Install: out/target/product/beagleboard/system/framework/services.jar

Once the build finished replace the output file (.so or .jar) in your file system and reboot.
$ sudo cp $androidRoot/out/target/product/beagleboard/system/framework/services.jar /media/linus_fs_sdcard/system/framework

Check out the following video of the touch screen working:

Wednesday, March 2, 2011

Adding custom video timings in kernel display subsystem.

Early this year I got a 42'' NEC display with a touchscreen sensor integrated to test with my BeagleBoard (BB) C2 rev. I had tested it with an Android FS gotten from rowboat in other displays (LG and ViewSonic) just setting up the video bootargs and it worked nicely with all standard resolutions. To my surprise the NEC display only was supporting one standard resolutions, for the rest of the resolutions I was getting "input not supported" message in the display. In this post I am going to go over the steps I followed to overcome this issue (rather than copy-paste info from other sites I will use links to give them credit).

This is an example of the video bootargs I use to set a resolution of 720p:
vram=4M omapdss.def_disp=dvi omapfb.mode=dvi:1280x720MR-16@60

For more info about these params take a look at frame buffer documentation.

First thing I did was to set these resolutions  (1280x1024, 720p, 800x600, etc) from Ubuntu just to make sure there were no HW limitations from the display. In Ubuntu all resolutions work as expected.

Then using the program moninfo in Windows I got the EDID information from the display to make sure that the modelines that were getting set by the BB were within the operation range.

More information about modelines and calculating timing parameters can be found in the following links:
http://www.epanorama.net/documents/vga2rgb/timings.html
http://sgf-dma.blogspot.com/2011/01/notes-for-xfree86-video-timings-howto.html
http://groups.google.com/group/beagleboard/browse_thread/thread/155dc4da296be2e9/2bfbaa25cd74c913?lnk=gst&q=fbmode#2bfbaa25cd74c913

To get the current modeline configured by the video driver I used the following command:
 # cat /sys/devices/platform/omapdss/display0/timings
 Which returns the video timings in the following format:
<pixel_clock>,<xres/hfp/hbp/hsw>,<yres/vfp/vbp/vsw>

Other useful commands can be found at:
http://processors.wiki.ti.com/index.php/DSS2_SYSFS_Examples

The output of the timing information was compliant with the EDID requirements from the Display so not sure why the display was so picky.

Looking at modedb.c and fbcvt.c (in androidRoot/kernel/drivers/video) I realized that when the omapfb.mode argument had "MR" option specified the video subsystem dinamically computed the timings based on CVT standard. Using "MR" the only video bootarg that worked was omapfb.mode=dvi: 1440x1050MR-16@60'. However it did not worked quiet good, when I queried the timing information the following was returned:
86400,1440/80/48/32,1050/3/17/10

Pixel clock 86.4 MHz,
Total Horizontal pixels 1440+80+48+32 = 1600
Total Vertical pixels  1050+3+17+10= 1080
So the frame rate is 86.4MHz/(1600*1080) = 50Hz  but the frame rate I specified was 60Hz!.. any way at least I was happy one resolution was working.

If "MR" is not specified in the omapfb.mode bootarg, the video subsystem tries different entries from the array modedb in modedb.c and uses the best match. I tested again all the resolution without including "MR" and only omapfb.mode=dvi:800x600-16@60 worked correctly.


Then I realized that if I generated modelines based on the timings
from the modelines of the working resolutions ( 1440x1050@50 or
800x600@60) any resolution (smaller than the base resolution) can be
displayed:
i.e., if I want 720p I base on:
"1440x1050" 86.4 1440 1520 1552 1600 1050 1053 1063 1080
and just modify the horizontal and vertical front porch:
"1280x720" 86.4 1280 1520 1552 1600 720 1053 1063 1080
To get a resolution of 640x480@60 I did something similar, I based on: "800x600" 40 800 888 1016 1056 600 623 627 628
And modify it to:
"640x480" 40 640 888 1016 1056 480 623 627 628

Following this approach, I added new entries to the structure modedb in modedb.c.

This works, but it has at least three drawbacks I have had identified:

1. The pixel clock is higher than the ideal.
2. When I use 1440x1050 as the base resolution the best refresh rate I can get is 50 fps which could cause flicker effect.
3. Without "MR" CVT is not used. CVT as I understand has features to reduce the blanking period (this is needed for CRT monitors to do the retrace from right to left) and thus reducing the video bandwidth.

My next step is to identify what is the modeline set by Windows or Ubuntu for the resolutions I want to use and then add those entries to the modedb array. In this link it is explained how to get the current modelines from Windows and Ubuntu but I have not tried it yet:
http://www.x.org/wiki/FAQVideoModes#ObtainingmodelinesfromWindowsprogramPowerStrip

If you have other ideas, please let me know.

P.O. I did three programs to convert among the video timing formats return by the:
1) cat /sys/devices/platform/omapdss/display0/timings
2) modeline format in modedb array
3) output returned by cvt command.
 I did not find a way to attach the files here but if you need them I will be glad to share them.