Tag Archives: hack

N900, Erminig and Google Calendar – the battle for the battery

The latest N900 update (PR1.2) is already history – some are happy (like me) others are completely devastated. I, like many others, decided to make full reset of the device, as was abusing it allot. This meant that the new firmware together with the latest eMMC contents was reflashed. After that I’ve started fresh to reconfigure my device, and following the KISS approach, I wanted to restore only the apps that I really use. Having that in mind there was one thing that really bugged me – MfE. It was used only to sync my Google Calendars through nyevasync and in order to be always in sync I had to enable autoconnect WiFi – that way the calendar was able to sync on the given interval of time. But staying always online drains the battery allot. Maybe this is the biggest power drain source together with the 3G connectivity. Clearly a solution that connects-syncs-disconnects would be greatly appreciated. Below you’ll find the way I did it.

The first thing I’ve needed was an alternative to MfE  – I don’t like the sync-only-one calendar with google and the fact that I have a Exchange Mail account that just sits in my Modest configuration. As always the maemo community helped and thanks, thanks, thanks to lorelei from maemo.org – I was able to use Erminig for that purpose. The application in the current stage is quite feature complete IMHO. It offers syncing in both directions for local calendars to/from Google calendars and supports *multiple* calendars. The other great thing about Erminig is that you can sync from command line 🙂 which opens the path to quite simple script implementing the connect-sync-disconnect philosophy. The script itself is quite simple. It respects the situations in which the WiFi was already active – it drops the connection only when it was initiated from the script itself:

/opt/mybin/synccal

#!/bin/sh
# Autor: Todor Tsankov (2010)
#
# 2010-05-28 - initial release

RETRIES=3
CONNECTED=false
DROPCONN=false

# check for existing wifi connectivity
if [ "$(/sbin/route | awk '/au/ {print $1}')" == "default" ]; then
	CONNECTED=true
else
  for i in $(seq 1 $RETRIES); do
    # try to connect to any known wifi
    run-standalone.sh dbus-send --system --type=method_call --dest=com.nokia.icd /com/nokia/icd com.nokia.icd.connect string:"[ANY]" uint32:0
    sleep 20
    if [ "$(/sbin/route | awk '/au/ {print $1}')" == "default" ]; then
      CONNECTED=true
      DROPCONN=true
      break
    fi
  done
fi

if [ "$CONNECTED" == "true" ]; then
  # sync erminig if having connectivity
  /usr/bin/erminig -a

  # sync MfE
  # run-standalone.sh dbus-send --print-reply --type=method_call --session --dest=com.nokia.asdbus /com/nokia/asdbus com.nokia.asdbus.fullSync

  sleep 5

  # drop the wifi connection if it was initiated by this script (saves battery)
  if [ "$DROPCONN" == "true" ]; then
    run-standalone.sh dbus-send --system --dest=com.nokia.icd /com/nokia/icd_ui com.nokia.icd_ui.disconnect boolean:true
  fi
fi

All that is left now is to save that script somewhere and invoke it in certain interval of time – how you’ll do it – it’s up to you. You can invoke it manually through X-terminal and tools like “Desktop Command Widget” or automate it with tools like Alarmed and fcron.

MfE comment: As you can see the MfE can be forced to sync from command line also, so if you prefer it, but still would like to minimize your wifi usage and optimize battery life – just comment erminig sync line and uncomment the MfE one.

Warning: the script is it’s infancy and although it makes some state checks it may misbehave.

Tagged , ,

Receiving static routes through DHCP in Fedora 12

So, today I had this very simple problem – to add static route to a certain network on my laptop 🙂 It really is as simple as:

ip route add network/mask via gateway

But as I’m quite lazy, to add this every time I need access to that network (the laptop is using NetworkManager + DHCP), I’ve decided to push this config through the DHCP server.

Here started the funny part – it seems that at this point this is not so trivial and you need to make modifications to BOTH the server and the client.

The Server

Let’s start with the server as this was the easy part. The only thing that is needed there is to add an DHCP option 121. In my case, as I’m using dnsmasq, this was the relevant option that should be added in /etc/dnsmasq.conf:

dhcp-option=121,10.10.0.0/24,172.16.1.100

This option defines all classless static routes that will be advertised by the DHCP server. If you need more than one route, the above can be changed like this:

dhcp-option=121,10.10.0.0/24,172.16.1.100,192.168.1.0/24,172.16.1.200

The Client

Now let’s go on the client side. There seems to be ALLOT of misunderstandings between NetworkManager and dhclient configurations. I took me quite a lot of time to figure it out, where what should be changed in order the NetworkManager to get the proper configuration from dhclient.

The first thing that should be done is to inform dhclient that you need this DHCP option 121 requested from the server. In order this  configuration to be picked up from NetworkManager also, you’ll have to edit (most probably create) /etc/dhclient-eth0.conf, where eth0 is the interface where the static routes should be added:

option classless-routes code 121 = array of unsigned integer 8;
script "/usr/local/sbin/dhclient-script-networkmanager";
also request classless-routes;

Note, that adding this config to /etc/dhclient.conf didn’t work for me. NM picked the config after the file was moved to /etc/dhclient-eth0.conf.

So now, the server is ready to send static routes, the client is ready and is hopefully at this point receiving these routes. But, but this by itself does not do anything to modify the routing table. You’ll need to add /etc/dhcp/dhcp-exit-hook file for dhclient, that will parse the DHCP option 121. I found how this could be done here on this blog. You can copy the file from there, or below here:

#!/bin/bash
#
# /etc/dhcp/dhclient-exit-hooks
#
# This file is called from /sbin/dhclient-script after a DHCP run.
#
#
# parse_option_121:
# @argv: the array contents of DHCP option 121, separated by spaces.
# @returns: a colon-separated list of arguments to pass to /sbin/ip route
#

function parse_option_121() {
result=""
while [ $# -ne 0 ]; do
mask=$1
shift
# Is the destination a multicast group?

if [ $1 -ge 224 -a $1 -lt 240 ]; then
multicast=1
else
multicast=0
fi

# Parse the arguments into a CIDR net/mask string
if [ $mask -gt 24 ]; then
destination="$1.$2.$3.$4/$mask"
shift; shift; shift; shift
elif [ $mask -gt 16 ]; then
destination="$1.$2.$3.0/$mask"
shift; shift; shift
elif [ $mask -gt 8 ]; then
destination="$1.$2.0.0/$mask"
shift; shift
else
destination="$1.0.0.0/$mask"
shift
fi

# Read the gateway
gateway="$1.$2.$3.$4"
shift; shift; shift; shift
# Multicast routing on Linux
#  - If you set a next-hop address for a multicast group, this breaks with Cisco switches
#  - If you simply leave it link-local and attach it to an interface, it works fine.

if [ $multicast -eq 1 ]; then
temp_result="$destination dev $interface"
else
temp_result="$destination via $gateway dev $interface"
fi

if [ -n "$result" ]; then
result="$result:$temp_result"
else
result="$temp_result"
fi
done
echo "$result"
}

function modify_routes() {
action=$1
route_list="$2"
IFS=:
for route in $route_list; do
unset IFS
/sbin/ip route $action $route
IFS=:
done
unset IFS
}

if [ "$reason" = "BOUND" -o "$reason" = "REBOOT" -o "$reason" = "REBIND" -o "$reason" = "RENEW" ]; then

# Delete old routes, if they exist
if [ -n "$old_classless_routes" ]; then
modify_routes delete "$(parse_option_121 $old_classless_routes)"
fi

# Add new routes, if they exist...
if [ -n "$new_classless_routes" ]; then
modify_routes add "$(parse_option_121 $new_classless_routes)"
fi
fi

Next you’ll need to modify the dhclient dhclient-script, so that the NetworkManager actually executes the hooks defined in /etc/dhcp/dhclient-exit-hooks. The information was found on this blog. I’ve modified the script found on that blog so that it would work on Fedora 12. Put this file in /usr/local/sbin/dhclient-script-networkmanager (If you’ve noticed we’ve already modified the dhclient-eth0.conf file and instructed the dhclient to use this script instead of the default one located in /sbin/dhclient-script):

#!/bin/bash
NM_DHCLIENT_SCRIPT=/usr/libexec/nm-dhcp-client.action


# dhclient-script for Linux. Dan Halbert, March, 1997.
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
# Modified for Debian.  Matt Zimmerman and Eloy Paris, December 2003
# Modified to remove useless tests for antiquated kernel versions that
# this doesn't even work with anyway, and introduces a dependency on /usr
# being mounted, which causes cosmetic errors on hosts that NFS mount /usr
# Andrew Pollock, February 2005
# Modified to work on point-to-point links. Andrew Pollock, June 2005
# Modified to support passing the parameters called with to the hooks. Andrew Pollock, November 2005
# The alias handling in here probably still sucks. -mdz


run_hook() {
local script="$1"
local exit_status
shift       # discard the first argument, then the rest are the script's


if [ -f $script ]; then
. $script "$@"
fi


if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then
logger -p daemon.err "$script returned non-zero exit status $exit_status"
save_exit_status=$exit_status
fi
}


run_hookdir() {
local dir="$1"
local exit_status
shift       # See run_hook


if [ -d "$dir" ]; then
for script in $(ls -1 $dir); do
run_hook $script "$@" || true
exit_status=$?
done
fi


return $exit_status
}


# Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
exit_with_hooks() {
exit_status=$1


# Source the documented exit-hook script, if it exists
if ! run_hook /etc/dhcp/dhclient-exit-hooks "$@"; then
exit_status=$?
fi


# Now run scripts in the Debian-specific directory.
if ! run_hookdir /etc/dhcp/dhclient-exit-hooks.d "$@"; then
exit_status=$?
fi


exit $exit_status
}


# The action starts here
# Invoke the local dhcp client enter hooks, if they exist.
run_hook /etc/dhcp/dhclient-enter-hooks
run_hookdir /etc/dhcp/dhclient-enter-hooks.d


$NM_DHCLIENT_SCRIPT
exit_with_hooks 0
return $exit_status

Finally, if you are running SELinux like me, you’ll need to change the security context of the file, so that the dhclient could execute it:

chcon -t dhcpc_exec_t /usr/local/sbin/dhclient-script-networkmanager

And thats all – you done and good go to 🙂

Tagged , , , ,

GTD notebook calculator

Today I’ve stumbled upon a great post on The Art of Manliness site: How to make a moleskine PDA. Not that there are not other great posts on the subject, but this one has two things that grabbed my attention.

First – this is the idea of having blank stamps in front/on the back of the notebook for writing notes/ideas without even having to open the notebook! – I think this is pretty neat idea and I’m going to try it.

The second interesting thing that is mentioned in the article is about a GTD notebook calculator. This is a flash application that can help you deciding how to split the notebook for the different contexts that you need. It has a saving option, so you can update the notebook layout later if you find out that certain sections are oversized or does not fit in the current allocated pages. That way the next notebook that you start using will be better divided and that way will be better utilized 🙂

Have fun!

Tagged , , ,