Sunday, December 6, 2009

{DAY-2}- FSF, TN Conf @ SSN : Take the Plunge....Breath Free!!!



{Day-2} @ SSN started with Ajax followed by most exciting Linux Distribution Making and Hands-On lab on making Linux distros. After the lunch, we had sessions on Patents and then came the most awaited project session where each team were assigned a project under FSF and brief timelines where given to us on project submission. What's more than these fabulous sessions, we had our refreshments and concluded FSF Conf.



I really enjoyed these two days and I thank all those who were behind this initative. HariShankar (my jnr) and I had a really log drive in his Passion+ and finally he dropped me @ Guindy while other 3 guys had SSN Route Buses to drop them home.



Working Technologies into projects is more important than learing them through Workshops and Conference. In this context, FSF and SSN has helped us to work on technology rather than just learning them. I have no words explaining these days in my life rather than start working on projects told to me on these two days, which I feel is the real way in which I can thank SSN Engg college and FSF Team.


FSF Rockzz!!!

Saturday, December 5, 2009

FSF Conference @ SSN {DAY-1} - An Splendid Start


It was 6:15AM, 5th December, 2009 when I started from my home to take the Route Bus to SSN. I reached the college @ 8:15AM and the Greens and aesthetic beauty of the campus greeted me as I entered. I was joined by 4 of my college guys (my jrs) and we made ourself present at Mini-Auditorium for the sessions.

Previewing Big-Bucks Bunny Movie the session began by a fabulous talk from Mr.Siddharth (Core FSF Member, Cognizant Employee). His talk helped us to know better what Free S/w is and what Open Source software is. He explained how important not to patent our innovation, as it prevents development of Science for the next 20 years from our date of patent. His talk made us to visualize the generations of human development from primitive-industrial-modern.




Next we had a talk from Mr.Praveen Chandrahas, IITian aand FSF Promoter, where he briefed out Filesystem and their implementation and steped down Ubuntu Installation process.



We had an Community person from Tamil Computing Team, Ubuntu Mr.Thangamani Arun briefing us on Android Architecture and its SDK's. He showcased a demo on how to work on Android Development Toolkit in Eclipse IDE and to use a Emulator.

Android session was followed by Shell Scripting by Mr.Bharathi Subramanian, FOSS Evangelist, ILUG Team. This session was really gr8 as I explored the basics of SHELL programming. I will surely work on this scripting a lot more than just listening to it.

We were served with refreshments in-between the sessions and {DAY-1} was really excellent. Tomorrow {DAY-2}, I am waiting for even more exciting stuffs @ FSF.


FSF RockZZZ!!!

Thursday, December 3, 2009

All you wanted to know about hacking!!!

Hacking has always inspired me from my schooling, and knowing on it from an Computer Security Consultant Ankit Fadia, who at the age 15 wrote his book on 'Ethical Hacking' is still more awakening..Here are the questions put to Ankit and his views on them...



When did you realise that you could hack?
I got interested in hacking at 12, but it took a while before I figured out how to do it. My first hack was quite interesting. I defaced a magazine site and put my own profile, pictures and e-mail id on it. But then I thought I might get into trouble, so I sent a mail to the editor with the solution on how to prevent hacking the website. He got back to me with a job offer but when he learnt that I was 13, he asked me to wait till I turned 18. I learnt my lesson. I never did an illegal hack after that.

Is hacking cool because it allows entry into forbidden territory?
It is. It gives you the power to do something that most people can't do, that too in the confines of your room. It gives a false sense of security.

What exactly is 'ethical hacking'?
You need to have the same knowledge as cyber criminals, but you put that knowledge to positive use. You go to sites, find out their flaws and correct them. I coined the term when I wrote my first book, Ethical Hacking, at 15.

You have worked with the FBI too. Isn't that a heady feeling?
I started working with them at 16, when a Pakistani group was planning to attack an Indian site. I traced the chat transcript and the site was saved. Then, this was like a game for me. But now I realise that there's a lot of responsibility involved in what I do.

Why did you take up the show, What The Hack?
Last year, I won the MTV Youth Icon award and was introduced to the programming head of the channel. I asked him if they wanted to do a show on hacking. They agreed. There are lots of channels which air tech shows that review technology and gadgets. But this show stands out because we teach people cool things that they can do in the virtual world.

Give us some tips on how to become good hackers?
You have to know the programming well and also think like a criminal. You have to get into the criminal's mind to become a security system expert.

-An Interview by Yahoo India

Plan your Calendar for Mozilla Free Cultural Roadshow @ Chennai

I am eagerly looking for the Free Cultural Roadshow @ Chennai, through which I am planning to associate with my fellow Mozilla Campus Representatives and I believe this is an excellent platform for us to discuss on Open Web and its future. Talk your way in the Festival and Win a trip to Mozilla Drumbeat Festival,Amsterdam on June 2010. Catch me @ Mozilla free Cultural Roadshow,Anna University this Tuesday (8-12-2009) :)




Mozz Rockz!!!!

Mozilla Free Cultural RoadShow - Catch the Excitement @ CEG and IIT

We love the web, and you do too. It creates huge opportunities along with new tensions.
What will the web look like in 5, 10, or 25 years? Will it still be a platform for creativity, self-expression, and open commerce? Or will it be enclosed by private interests and enveloped by surveillance and censorship?
Mozilla is traveling from city to city to celebrate the open web and remix culture. Join some illuminating talks, to speak your mind, and to meet new friends. Prepare a 5minutes of Talk which adds to your fame @ Mozilla Drumbeat!!!



Next dates

 The Roadshow events are 100% free and open to everyone.

Joomla User Group- Welcome Chennai, Fabulous Start-Up Meet

Today 3rd December, 2009, I prepared Slides for my JUG presentation @ 3:00 PM and headed straight to Mary Brown @ Anna Nagar. It was 4:30 PM when Gokoul and JayaPrakash from P.M.R.I.T , Bro Rajesh, Swamy from Jaya Engineering College and his friend accompanied me at the venue for the meet. We were 6 , started with  FOSS talk , CMS , then I presented my ideas on JUG and its purpose and activities to be conducted. Everyone shared their ideas which helped us to better plan JUG Activities.



 It was a wonderful day, where the meet had everything from Joomla to Nuggets and Burgers. Soon a new web-portal for Joomla User Group, chennai will be hosted (http://jug-chennai.co.cc will be our temporary webspace) We shared many issues on Joomla and our user group activities @ the meet. I hope JUG always stays active and contribute for Joomla in all possible ways it can, becoz Open Source Matters...

 

From Left: Gokoul (P.M.R.I.T), JayaPrakash(P.M.R.I.T), Santhosh.V (Arunai Engg), Mr.Rajesh(E-ndicusInfo Tech), Swamy(Jaya Engg), Swamy Friend(Jaya Engg),

Monday, November 30, 2009

Joomla User Group - Start-Up Meet on 3rd December,2009



Here is the Invite for our first JUG meeting to be held at Anna Nagar. Celebration is about to Start!!! Get ready for the Exciting Stuffs to be explored through JUG Chennai!!!!

Sunday, November 29, 2009

Free Software Foundation, Tamil Nadu Workshop @ SSN on Dec 5th and 6th - Book your Seats...

Wow..!!! Its now FSF, TN who will make my holidays more enjoyable. A Cup of Scripting , Linux Customization Salads, Python Feast...whats more to special this December!!!  Here goes the Invite...


Hurry up Students !!! Click here http://fsftn.org/content/workshopssn2 to  register to the workshop. Only 120 Seats available !!!! 


*Automatic enrollment to projects* of Free Software Foundation on  registering to the workshop. In the workshop you would learn : 


   - Business Models in Free Software
   - How to configure Linux for your day-to-day use?
   - Scripting Languages !!
   - Learn all these on-hands at Lab.
   - Learn Ajax.
   - Ever thought of having your own Operating System? Learn it, Build it!!!
   - Start working on Free Software projects with guidance from experts in Software industry. 



*This is the ideal way to use your holidays !!! Fun, Learn, Hack !!!!!!!*

ChennaiPy Session - I @ AUKBC-MIT

This is really a good start for chennaipy as it conducted its 1st session @ AUKBC- MIT Campus. This time, I reached the campus early and had my seat prior to the session start-up. 14 Members were in the session as it went and the session was filled with novice python group. Ms.Rajeshwari took the web-scrapping session and Mr.Jaganadh took Bio-Medical Text processing with python.

To my surprise, the talks were over very soon and I was given a chance to share my experience in python programming. I was not prepared to face the audience, but still,  I managed to brief out my D-Bus Project and we had good discussions from all the attendees.


I am happy that from now ChennaiPy will regularly conduct session and I shall be a part in bringing out the sessions @ MIT which complements to better understanding of the language.



This was a draft posted by Mr.Jaganadh, Professor @ MIT on the session:

"This months chennaipy meet started at 3.10 p.m 28-11-09 at AU-KBC Research Centre MIT Campus of Anna University Chennai. Total 14 people attended the meeting. The first talk was given by Rajeswari S on WebScraping with Python, Santhosh give a talk on D-Bus programming with Python and Bio-medical text processing with python by Jaganadh G. There was discussion on IDE for Python, python web programming etc... The meeting ended by 04.50 p.m"


I thank Mr.Jaganadh, Mr.Surendar, MIT and NRCFOSS without them this session would have not been successful platform for us learn. I wish we must continue these session in future and bring out the best Python programmers in Chennai Region.

Tuesday, October 27, 2009

Tuesday, September 8, 2009

How to obtain the latest version of LAMP on Ubuntu:

(Apache 2.2 + MySQL 5.1 + PHP 5.2 + PERL 5.10 +PEAR + SQLite + ProFTPD + phpMyAdmin + Webalizer + phpSQLiteAdmin + XAMPP Control Panel)
http://www.ubuntuforums.org/223410
http://www.apachefriends.org/f/viewtopic.php?t=21531#108517

The commands in this HOWTO must be entered in the terminal:
Applications -> Accessories -> Terminal

Download XAMPP to your desktop and extract the files:
http://apachefriends.org/xampp-linux
cd ~/Desktop
wget http://www.apachefriends.org/download.php?xampp-linux-1.7.1.tar.gz
sudo tar xvfz xampp-linux*.tar.gz -C /opt

Create a XAMPP start menu entry:
cd ~/.local/share/applications
gedit xampp-control-panel.desktop

Paste the following into the open file:
[Desktop Entry]
Comment=Start/Stop XAMPP
Name=XAMPP Control Panel
Exec=gksudo "python /opt/lampp/share/xampp-control-panel/xampp-control-panel.py"
Icon[en_CA]=/usr/share/icons/Tango/scalable/devices/network-wired.svg
Encoding=UTF-8
Terminal=false
Name[en_CA]=XAMPP Control Panel
Comment[en_CA]=Start/Stop XAMPP
Type=Application
Icon=/usr/share/icons/Tango/scalable/devices/network-wired.svg

[Desktop Entry]
Comment=Start/Stop XAMPP
Name=XAMPP Control Panel
Exec=gksudo /opt/lampp/share/xampp-control-panel/xampp-control-panel
Icon[en_CA]=/opt/lampp/htdocs/xampp/img/logo-small.gif
Encoding=UTF-8
Terminal=false
Name[en_CA]=XAMPP Control Panel
Comment[en_CA]=Start/Stop XAMPP
Type=Application
Icon=/opt/lampp/htdocs/xampp/img/logo-small.gif

Save and close the file.

Publish:
XAMPP uses /opt/lampp/htdocs as the root web directory, but you can publish pages in your home directory this way.
cd ~
mkdir public_html
sudo ln -s ~/public_html /opt/lampp/htdocs/$USER

Now any files and folders you place in ~/public_html will be
published to your personal webserver.

Start XAMPP via the terminal:
cd /opt/lampp
sudo ./lampp start

Stop XAMPP (if necessary):
cd /opt/lampp
sudo ./lampp stop

Via the XAMPP Control Panel:
Applications -> Other -> XAMPP Control Panel

If Apache2 or MySQL is already running, then XAMPP will not start. You must stop these applications, if you want to use XAMPP:
sudo /etc/init.d/apache2 stop
sudo /etc/init.d/mysql stop

PHP5 is the default, but you can switch between PHP4 and PHP5, if you like:
cd /opt/lampp
sudo ./lampp php4
sudo ./lampp php5

Open your new webpages at:
http://localhost/username/

Security:
http://apachefriends.org/xampp-linux/381

1. The MySQL root user has a blank password.
2. MySQL is accessible via your local network.
3. ProFTPD has user “nobody” with password “lampp”.
4. PhpMyAdmin is accessible via the local network.
5. Examples are accessible via the local network.
6. MySQL and Apache running under the same user “nobody”.

To configure some of the security features of xampp:
cd /opt/lampp
sudo ./lampp security

The Origins of Linux - Linus Trovalds

Google Wave!!!! - The Wave of the Future!!!!

Delighted to hear another new makings of Google!!!! Email+IM+Wiki+RealTimeCollaboration+Documents+Workflows+ServerSideBots+GoogleMagic+OpenStandards = Google Wave

This is the "Wave" of the Future ;)

Check this out!!!!


Ride the D-Bus, Control your Linux desktop from the shell

What is the D-Bus?

From the D-Bus documentation: "D-Bus is an inter-process communication mechanism—a medium for local communication between processes running on the same host. (Inter-host connects may be added in the future, but that is not what D-Bus is meant for). D-Bus is meant to be fast and lightweight, and is designed for use as a unified middleware layer underneath the main free desktop environments"

So for the non technically inclined (why are you reading this anyway) ;) basically a simple way to think of D-Bus, is that it's a way for processes on an operating system to communicate with each other. That's probably a simple and non accurate enough wording, but it should help grasp the concept. Many utilities nowadays are implementing D-Bus connectivity. It is especially interesting (well for me anyway) to script some GUI elements like for example my KDE-4 desktop from the command line. This would help automate some tasks and is cool anyways. Let's see how to begin talking on the D-Bus

In order to communicate with running applications on the D-Bus, we need a front end CLI application, or we could use a language binding (say python bindings). However, we will choose a CLI application. It is possible to use "dbus-launch", or the "qdbus" command part of Qt4. I will be using qdbus since it demonstrates the point and is faster to use. So, let's launch qdbus, and list the running communications buses.


# qdbus
:1.1
org.kde.klauncher
:1.10
org.freedesktop.ScreenSaver
org.kde.krunner
org.kde.screensaver
:1.12
org.kde.plasma
:1.1249
... List continues



So basically, qdbus now contacts the running session D-Bus and lists available buses. The buses are named in a reverse DNS style names as you can see. Some buses do not have names, but rather numbers, as far as I can see those represent specific sessions of some applications. Now we need to pick an interesting bus to talk on. I will run the following command to list only freedesktop dbuses, as I believe those should work whether you're running Gnome or KDE. So, it should help any reader follow along


#qdbus | grep freedesktop
org.freedesktop.ScreenSaver
org.freedesktop.Notifications
org.freedesktop.PowerManagement
org.freedesktop.DBus


so, let's pick the ScreenSaver bus. In order to list the available objects on any specific bus, we call it like so:


#qdbus org.freedesktop.ScreenSaver
/
/App
/Interface
/KBookmarkManager
/KBookmarkManager/konqueror
/KDebug
/MainApplication
/ManagerIface_contact
/ScreenSaver


I mostly find only one "useful" object, in this case "/ScreenSaver". Let's contact that object, and list its avialable "methods". The methods of an object for those who have not done any object oriented coding before, is basically the list of actions or "things" this object can "do". So listing the methods:


# qdbus org.freedesktop.ScreenSaver /ScreenSaver
signal void org.freedesktop.ScreenSaver.ActiveChanged(bool)
method bool org.freedesktop.ScreenSaver.GetActive()
method uint org.freedesktop.ScreenSaver.GetActiveTime()
method uint org.freedesktop.ScreenSaver.GetSessionIdleTime()
method uint org.freedesktop.ScreenSaver.Inhibit(QString application_name, QString reason_for_inhibit)
method void org.freedesktop.ScreenSaver.Lock()
method bool org.freedesktop.ScreenSaver.SetActive(bool e)
method void org.freedesktop.ScreenSaver.SimulateUserActivity()
method uint org.freedesktop.ScreenSaver.Throttle(QString application_name, QString reason_for_inhibit)
method void org.freedesktop.ScreenSaver.UnInhibit(uint cookie)
method void org.freedesktop.ScreenSaver.UnThrottle(uint cookie)
method void org.kde.screensaver.configure()
method void org.kde.screensaver.saverLockReady()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()



Hmm, interesting stuff. Can you see the following method:
org.freedesktop.ScreenSaver.GetSessionIdleTime
Obviously it gives you the session idle time, i.e. how long has the interactive user not touched his keyboard or mouse. This piece of information is interesting if you want your shell script to only do certain things when the user is not interactively using his machine. Without D-Bus, getting this kind of information would be almost impossible, or too tricky. Now how do we call this method you ask? easy! just append it to the command line:


#qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime
0


So, the output from this command is a "0". Meaning the session idle time is zero! Everytime you execute this command, you get the same answer. Starting to guess why ? :) Basically, as you hit "enter" to run this command, you reset the session idle time back to zero! So, what do we do to test the functionality, try this:


# sleep 5 ; qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime
4


So, that previous combo command sleeps for 5 seconds .. then executes the D-Bus query without touching any further keyboard keys, so this time we get an answer of "4" seconds. Don't know where that extra second slipped though :)

Ok, as a second example let's focus on the following method:
method bool org.freedesktop.ScreenSaver.SetActive(bool e)

This method sets the screen saver active, i.e. it launches the screen saver from your shell command or script. Let's test it out:


# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive
Error: org.freedesktop.DBus.Error.UnknownMethod
No such method 'SetActive' in interface 'org.freedesktop.ScreenSaver' at object path '/ScreenSaver' (signature '')


Oops, this time we got an error. Why? Basically the error is telling us that it cannot find that method we're calling with that "signature". A method signature usually means the arguments you pass to it and the return type. This simply means we're not calling the method the way it's meant to be called. The sharp shooters are going to instantly know this is because we missed the (bool e) at the end of the method. This means the method call is expecting a boolean (true/false) argument. So, let's call the screensaver method correctly this time:


# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive True
true


Cool! We're now launching the screensaver from the command line. Let's see what else we can do:


# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Lock


Yep, that locks the screen on demand, cool! I'm hungry for more. Let's see. Let's call that inhibit method. This will basically inhibit the screensaver from kicking in, even if your computer is idle. Why would that be useful ? Say you're watching a You-tube longish video, and AFAIK, Flash doesn't yet communicate that to the system, and thus the screensaver will kick in to interrupt the video playback. So, let's do it:


# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit "$$" "Testing D-Bus Interface"
5822


Let's explain those arguments we passed, the first one should be the application name, in my case, the special shell variable $$ is the PID for the currently executing shell. The second string is the "reason for inhibit"! The method call returns a cookie, i.e. a magic number that identifies my request. This is useful when you want to turn off the inhibit, i.e. return the system to its normal state. You would need to pass back that magic cookie. This is used by the system to identify the different inhibit requests. So finally let's uninhibit our screensaver using that cookie number


# qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit 5822


Cool! Are you starting to see the possibilities just yet? Hope you had fun on this D-Bus tour

Detecting Network Connectivity Using D-Bus

Preface

The Intel® Mobile Internet Device (MID) platform provides a full internet experience in a pocket-sized form factor. Combining Moblin-based operating systems with the Intel® Atom™ processor, MIDs are able to run any application that has been built for the x86 architecture, including Adobe Flash 10* and Adobe AIR 1.5*. While the features of the devices that are and will be on the market vary depending on OEM and target market, there are several features that the devices share in common; small form factor, emphasis on internet connectivity rather than extensive storage, and alternate input methods.

Although there are ultra-mobile computing devices in the market that run Microsoft Windows XP* or Windows Vista* and that are built on the same hardware platform as those running a Moblin-based operating systems such as Midinux* or Ubuntu* Mobile Edition, this series of whitepapers focuses entirely on Moblin-based MIDs. For information on how to retrieve this information from Windows operating systems, please consult that platform’s documentation, or see the Intel® Mobile Platform SDK.

The functionality described in this paper is also provided via the Platform Awareness Service, a light-weight, D-Bus initiated platform information provider. However, because the final software stack for each device is influenced heavily by the OEM and Service Providers, this service may not be pre-installed on some Moblin-based devices. We have therefore written these whitepapers in order to simplify access to this information on platforms that do not have this service installed.

For further information on how to use D-Bus to retrieve information from the Platform Awareness Service, please refer to the Platform Awareness Service documentation.

Introduction

With the advances of computer networking within the last decade, devices can be connected via a myriad of technologies and protocols, wired and wireless. This connectivity has become so prevalent that many applications can’t function without it. Some application functions take advantage of network communications such as email, network gaming, web browser, etc. Some real-time applications, especialy networking games, require a large bandwidth and high network reliability. These applications must be aware of the network connectivity. Mobile computing devices such as a laptop or Mobile Internet Device (MID), frequently use wireless technology and thus network awareness becomes even more important. Instead of letting each application write its own connectivity awareness code, we propose a uniform way to convey the connectivity information to applications. Laptop/MID applications can then refer to our system to get information on network connectivity and make proper decisions at run time.

As part of a whole project, MID Platform Awareness, this paper shows how we can call connectivity awareness methods and get event notifications.

The system was developed on Moblin[4], a Linux* platform, and uses D-Bus communication[1] to transport information to users [1]. Applications which want to get connectivity information need to use D-Bus as well. In the following sections, we briefly describe D-Bus and how we implement network connectivity awareness service using D-Bus. We show examples of how an application can retrieve the network connectivity information; (1)whether or not the device is connecting to a network, (2)whether or not the device can reach a given website, (3)the latency of the network when the device does connect, (4)the data rate involved when the device reaches a website, (5)the media type of the current network, and (6)the link speed of the network.

Background on D-Bus

D-Bus is a fast, lightweight message system which allows applications to communicate one on one or to broadcast messages to subscribers, (inter-process communication). [2]. D-Bus can be used as low-level API or via a higher level binding, such as Qt, Python*, Java*, C#, or Perl. This paper shows an application written in C using Glib bindings. Glib is the base library of GNOME and provides an object-based, event-driven environment.

Two buses are defined in D-Bus: the system bus and the session bus. The system bus allows communication between an application and the operating system while the session bus is designed to allow communication between two applications.

In order to use D-Bus, we need to understand a few basics. First, an object is an endpoint on the bus that is created by an application in the context of that application’s connection to the bus. Objects have names, and these names are called object paths. We can find an object via its path. A proxy allows clients to reference objects on the bus. Once we find an object, we usually keep a proxy to that object so we can subsequently refer to that object without searching again.

An object can perform specific operations, referred to as methods. Thus, a client can send a request to an object and ask the object to invoke a method. The object then executes the method (if the method exists) and the result is sent back to the client. If a method requires input parameters, these parameters are passed with the request. The result can be one or more output parameters, which are sent back to the client in the reply message. At the D-Bus layer, this method invocation/message passing sequence occurs asynchronously; the glib wrapper for the D-Bus object proxy allows the methods to be called either synchronously or asynchronously.

An object can also emit an event, or signal. When a signal is generated by an object, it is broadcasted to any interested observers. Signals can also carry parameters. Methods and Signals are embedded members of an object that can be grouped into an interface. An object can declare one or many interfaces.

In order to generate dbus-glib binding code, we use a tool called dbus-binding-tool. We first create an XML file, referred to as an Introspection XML file, in which we describe the methods and signals. Defining the interface this way ensures that clients can discover and introspect our D-Bus service. An example of the introspection XML is shown below:

- collapse sourceview plaincopy to clipboardprint?

1.
2. 3. "-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
4. "http://standards.freedesktop.org/dbus/1.0/introspect.dtd">
5.
6.
7.
8.
9.
10.
11.

12.
13.
14.
15.
16.

17.
18.
19.
20.
21.

22.
23.
24.
25.
26.

27.
28.
29.
30.

31.
32.
33.
34.

35.
36.
37.
38.

39.



"-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
"http://standards.freedesktop.org/dbus/1.0/introspect.dtd">





































In this introspection XML file, an interface called org.moblin.Platform.Connection defines six methods:
IsConnected, IsReachable, GetLatency, GetDatRate, GetMediaType and GetLinkSpeed. The annotation XML tags tell dbus-binding-tool what the name of the implementing C function should be. For example, IsConnected is the name of the method that will be visible to users over D-Bus. Internally, we need to implement a C function called isConnected. Method parameters and return values are both specified using the arg XML tag. The direction attribute for a parameter is "in"; for return values, the direction attribute is "out". Note that parameters and return values both have name attributes.

The type attribute of the arg XML tag indicates the data type of the parameter or return value. For example, the value "b" in the IsConnected method return value indicates that the method returns a Boolean. The second method, IsReachable, takes a string parameter representing the target URI (Uniform Resource Identifier) and returns a Boolean value. The next two methods, GetLatency and GetDataRate, also take a string parameter representing the URI and return a double representing seconds and kilobytes per second, respectively. The output of GetMediaType is a string. Finally, the output of the last method, GetLinkSpeed, is a Double data type, representing the number of kilobits per second.

Two signals are defined in the introspection XML file. The signal "Connected" is generated when the system changes state from having no connection to having at least one connection. The "Disconnected" signal is generated when the when the system changes state from having at least one connection to having no connections.

Below are primary steps to implement a D-Bus service. For more details, look here.

* Run dbus-binding-tool for an introspection XML file to generate dbus-glib binding code
* Acquire the D-Bus GObject wrapper
* Implement the instance initialization
* Implement the methods
* Register the object on the D-Bus

To call the methods implemented on a remote object, a client needs to follow the following steps:

* Connect to the bus
* Create a proxy object
* Invoke the methods on the proxy object.

The connectivity awareness service below uses D-Bus as a communication channel to send information to clients regarding network connectivity. Clients can thus use D-Bus to get connectivity information by querying the methods provided by the connectivity service. Client applications can also listen for the signals that the connectivity awareness service generates. The methods and events mentioned in the introspection file are implemented by the connectivity awareness service.

Getting Network Connectivity Information

The connectivity awareness service provides the means to query the following connectivity information on the computer where the service is installed.

Detecting the network connection

A networked application obviously requires an established network connection. Before allocating resources for a network transaction, it is useful to know whether or not the system has an established network connection. Therefore, the network connectivity service provides a method called IsConnected, which returns a Boolean value confirming the status of the network. The network connectivity service checks the status of all network devices on the computer. If at least one network device has an established connection, the Boolean value TRUE is returned. If all network devices on the computer are not running, the Boolean value FALSE is returned. To query the connectivity, the application first must bind to D-Bus service as shown in the following example

- collapse sourceview plaincopy to clipboardprint?

1. #include
2. #include
3. #include
4. #include
5. #include
6. #include
7.
8. #define PLATFORM_SERVICE "org.moblin.Platform"
9. #define PLATFORM_PATH "/org/moblin/Platform"
10. #define PLATFORM_CONNECTION_IF "org.moblin.Platform.Connection"
11.
12. int main(int argc, char** argv)
13. {
14. DBusGConnection* conn;
15. GError *error;
16. DBusGProxy *platformProxy;
17.
18. g_type_init();
19. error = NULL;
20. conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
21.
22. // Create the proxy Platform
23. platformProxy = dbus_g_proxy_new_for_name(conn,
24. PLATFORM_SERVICE, // target for the method call
25. PLATFORM_PATH, // object to call on
26. PLATFORM_CONNECTION_IF); // interface to call on
27.
28. gboolean result;
29.
30. if (!dbus_g_proxy_call(platformProxy, "IsConnected", &error,
31. G_TYPE_INVALID,
32. G_TYPE_BOOLEAN, &result,
33. G_TYPE_INVALID))
34. {
35. g_printerr("Failed to call remotely: %s\n",
36. error->message);
37. g_error_free(error);
38. }
39. else
40. printf ("Remote call successes with returned value: %s\n", result? "TRUE" : "FALSE");
41.
42. . . . . . . . . . . . . . . . . . . . . . .
43. . . . . . . . . . . . . . . . . . . . . . .
44. . . . . . . . . . . . . . . . . . . . . . .
45.
46. return 0;
47. }

#include
#include
#include
#include
#include
#include

#define PLATFORM_SERVICE "org.moblin.Platform"
#define PLATFORM_PATH "/org/moblin/Platform"
#define PLATFORM_CONNECTION_IF "org.moblin.Platform.Connection"

int main(int argc, char** argv)
{
DBusGConnection* conn;
GError *error;
DBusGProxy *platformProxy;

g_type_init();
error = NULL;
conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);

// Create the proxy Platform
platformProxy = dbus_g_proxy_new_for_name(conn,
PLATFORM_SERVICE, // target for the method call
PLATFORM_PATH, // object to call on
PLATFORM_CONNECTION_IF); // interface to call on

gboolean result;

if (!dbus_g_proxy_call(platformProxy, "IsConnected", &error,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &result,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %s\n", result? "TRUE" : "FALSE");

. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .

return 0;
}


Note that the application invokes the method IsConnected implemented in the connectivity awareness service: no input is required, and the method returns TRUE if the computer is connected to a network.

The back-end implementation of this method basically computes the list of network adapters available, and confirms the connection status if there is at least one network adapter running. The function detecting whether or not a network adapter is running, is shown below

- collapse sourceview plaincopy to clipboardprint?

1. netdev_ret netdev_get_running(netdev_dev *dev, // in
2. netdev_running *running) // out
3. {
4. struct ifreq ifr;
5. if(_get_ifreq(dev->ifname, SIOCGIFFLAGS, &ifr) != NETDEV_SUCCESS)
6. {
7. running = RUNNING_UNKNOWN;
8. return NETDEV_ERROR;
9. }
10.
11. short flags = ifr.ifr_flags;
12. if(flags & IFF_RUNNING)
13. {
14. *running = RUNNING_RUN;
15. }
16. else
17. {
18. *running = RUNNING_STOP;
19. }
20.
21. return NETDEV_SUCCESS;
22. }
23.

netdev_ret netdev_get_running(netdev_dev *dev, // in
netdev_running *running) // out
{
struct ifreq ifr;
if(_get_ifreq(dev->ifname, SIOCGIFFLAGS, &ifr) != NETDEV_SUCCESS)
{
running = RUNNING_UNKNOWN;
return NETDEV_ERROR;
}

short flags = ifr.ifr_flags;
if(flags & IFF_RUNNING)
{
*running = RUNNING_RUN;
}
else
{
*running = RUNNING_STOP;
}

return NETDEV_SUCCESS;
}



Detecting HTTP reachability

The second method queries the reachability of a specified website. When getting this request, the connectivity service forms a HTTP GET message[5] and sends it to the specified address (web address) at port 80 (the typical port for HTTP protocol). The socket timeout is set to 3 seconds in this implementation: the service will wait for a HTTP response with status 200[5] before disconnecting the socket. This method, IsReachable, requires a string parameter as the target address (web address) and returns a Boolean value confirming whether or not the web address can be reachable within the socket timeout. The format of the valid entry takes the protocol (http in this case) follows it with the URI. Examples of valid inputs are shown below

"http://www.intel.com/", "http://www.google.com/", "http://www.yahoo.com/", etc ...

The third method, GetLatency, computes the time delay between sending a HTTP GET message and receiving the reply. This method takes an input parameter which is the URI of the website and returns a value of type double, representing the time in seconds. If the socket timeout expires, this method returns a null value.

The fourth method, GetDataRate, calculates the data rate when sending a HTTP GET message and receiving the reply. This method takes an input parameter which is the URI of the website and returns a value of type double representing kilobyte per second (kBps). If the socket timeout expires, this method returns a null value. Data rate is computed using the following formula:

(length of HTTP GET sent + length of HTTP reply) / latency

Code referring to these D-Bus methods is shown below.

- collapse sourceview plaincopy to clipboardprint?

1. int result1;
2.
3. if (!dbus_g_proxy_call(platformProxy, "IsReachable", &error,
4. G_TYPE_STRING, "http://www.intel.com/",
5. G_TYPE_INVALID,
6. G_TYPE_BOOLEAN, &result1,
7. G_TYPE_INVALID))
8. {
9. g_printerr("Failed to call remotely: %s\n",
10. error->message);
11. g_error_free(error);
12. }
13. else
14. printf ("Remote call successes with returned value: %s\n", result1? "TRUE" : "FALSE");
15.
16. gdouble result2;
17.
18. if (!dbus_g_proxy_call(platformProxy, "GetLatency", &error,
19. G_TYPE_STRING, "http://www.intel.com/",
20. G_TYPE_INVALID,
21. G_TYPE_DOUBLE, &result2,
22. G_TYPE_INVALID))
23. {
24. g_printerr("Failed to call remotely: %s\n",
25. error->message);
26. g_error_free(error);
27. }
28. else
29. printf ("Remote call successes with returned value: %6.3f seconds\n", result2);
30.
31.
32. if (!dbus_g_proxy_call(platformProxy, "GetDataRate", &error,
33. G_TYPE_STRING, "http://www.intel.com/",
34. G_TYPE_INVALID,
35. G_TYPE_DOUBLE, &result2,
36. G_TYPE_INVALID))
37. {
38. g_printerr("Failed to call remotely: %s\n",
39. error->message);
40. g_error_free(error);
41. }
42. else
43. printf ("Remote call successes with returned value: %8.2f KB/sec\n", result2);

int result1;

if (!dbus_g_proxy_call(platformProxy, "IsReachable", &error,
G_TYPE_STRING, "http://www.intel.com/",
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &result1,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %s\n", result1? "TRUE" : "FALSE");

gdouble result2;

if (!dbus_g_proxy_call(platformProxy, "GetLatency", &error,
G_TYPE_STRING, "http://www.intel.com/",
G_TYPE_INVALID,
G_TYPE_DOUBLE, &result2,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %6.3f seconds\n", result2);


if (!dbus_g_proxy_call(platformProxy, "GetDataRate", &error,
G_TYPE_STRING, "http://www.intel.com/",
G_TYPE_INVALID,
G_TYPE_DOUBLE, &result2,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %8.2f KB/sec\n", result2);



The back-end implementation of the above three methods shares a common function: this function parses the input URI and then searches for the URI reachability using HTTP protocol. The parsing function validates the URI and retrieves the target IP address. The reachability function forms a HTTP GET message and sends to the target IP address at port 80. The reachability is confirmed if a HTTP reply message is received within a timeout limit. Readers are encouraged to refer to the source code of the MID Platform Awareness project for the implementation. For illustration, only the reachability function is shown below

- collapse sourceview plaincopy to clipboardprint?

1. bool HTTPIsReachable(
2. unsigned int *pTime, // in msec
3. double *pRate, // in KB/sec
4. PURI_INFO pUri)
5. {
6. bool bRet = false;
7. unsigned long StartTime, StopTime;
8. int dwStatusCode;
9. int conn;
10. int Len = 0;
11.
12. if (pTime)
13. *pTime = 0;
14.
15. if ( pUri->Port == 0 )
16. pUri->Port = HTTPPORT;
17.
18. StartTime = getTime();
19. if (pUri->DestPath)
20. conn = (int)socketClient( pUri->pHostIP, pUri->Port, 0);
21.
22. if (conn < 0)
23. {
24. printf("conn<0\n");
25. goto GracefulExit;
26. }
27.
28. char req[1024];
29. sprintf( req, "GET /%s HTTP/1.0\r\nHost: %s\r\n", pUri->FileName, pUri->DestPath);
30. strcat( req, "User-Agent: hget/" LIBHTTP_VERSION "\r\n");
31. strcat( req, "Pragma: no-cache\r\n" );
32. strcat( req, "Accept: */*\r\n\r\n" );
33. dwStatusCode = HttpRequest(conn, &Len, req); // in Bytes
34. close(conn);
35.
36. StopTime = getTime();
37.
38. printf("return code %d\n", dwStatusCode);
39. if ( dwStatusCode == 200 || pUri->FileName == 0 )
40. {
41. bRet = true;
42. if (pTime)
43. {
44. unsigned int st;
45. st = StopTime - StartTime; // in msec
46. *pTime = st;
47. *pRate = (double)Len / (double)st; // in KB/sec
48. }
49. }
50.
51. GracefulExit:
52. return bRet;
53. }
54.

bool HTTPIsReachable(
unsigned int *pTime, // in msec
double *pRate, // in KB/sec
PURI_INFO pUri)
{
bool bRet = false;
unsigned long StartTime, StopTime;
int dwStatusCode;
int conn;
int Len = 0;

if (pTime)
*pTime = 0;

if ( pUri->Port == 0 )
pUri->Port = HTTPPORT;

StartTime = getTime();
if (pUri->DestPath)
conn = (int)socketClient( pUri->pHostIP, pUri->Port, 0);

if (conn < 0)
{
printf("conn<0\n");
goto GracefulExit;
}

char req[1024];
sprintf( req, "GET /%s HTTP/1.0\r\nHost: %s\r\n", pUri->FileName, pUri->DestPath);
strcat( req, "User-Agent: hget/" LIBHTTP_VERSION "\r\n");
strcat( req, "Pragma: no-cache\r\n" );
strcat( req, "Accept: */*\r\n\r\n" );
dwStatusCode = HttpRequest(conn, &Len, req); // in Bytes
close(conn);

StopTime = getTime();

printf("return code %d\n", dwStatusCode);
if ( dwStatusCode == 200 || pUri->FileName == 0 )
{
bRet = true;
if (pTime)
{
unsigned int st;
st = StopTime - StartTime; // in msec
*pTime = st;
*pRate = (double)Len / (double)st; // in KB/sec
}
}

GracefulExit:
return bRet;
}



Detecting the media and speed of the network connection

The last two methods, GetMediaType and GetLinkSpeed, return the network media type and the link speed of the network. In the current implementation, only Ethernet and WiFi are supported. The output of GetMediaType is a string (i.e., "802.03", "802.11g"… etc) and the output of GetLinkSpeed is a value of type double, representing the number of kbps (kilobits per second).

- collapse sourceview plaincopy to clipboardprint?

1. char *result3;
2.
3. if (!dbus_g_proxy_call(platformProxy, "GetMediaType", &error,
4. G_TYPE_INVALID,
5. G_TYPE_STRING, &result3,
6. G_TYPE_INVALID))
7. {
8. g_printerr("Failed to call remotely: %s\n",
9. error->message);
10. g_error_free(error);
11. }
12. else
13. printf ("Remote call successes with returned value: %s\n", result3);
14.
15. double result4;
16.
17. if (!dbus_g_proxy_call(platformProxy, "GetLinkSpeed", &error,
18. G_TYPE_INVALID,
19. G_TYPE_DOUBLE, &result4,
20. G_TYPE_INVALID))
21. {
22. g_printerr("Failed to call remotely: %s\n",
23. error->message);
24. g_error_free(error);
25. }
26. else
27. printf ("Remote call successes with returned value: %10.1f Kbps (kbit per sec)\n", result4);
28.

char *result3;

if (!dbus_g_proxy_call(platformProxy, "GetMediaType", &error,
G_TYPE_INVALID,
G_TYPE_STRING, &result3,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %s\n", result3);

double result4;

if (!dbus_g_proxy_call(platformProxy, "GetLinkSpeed", &error,
G_TYPE_INVALID,
G_TYPE_DOUBLE, &result4,
G_TYPE_INVALID))
{
g_printerr("Failed to call remotely: %s\n",
error->message);
g_error_free(error);
}
else
printf ("Remote call successes with returned value: %10.1f Kbps (kbit per sec)\n", result4);



The back-end implementation of the method GetMediaType is shown below.

- collapse sourceview plaincopy to clipboardprint?

1. char* RetrieveMediaType(void)
2. {
3. netdev_dev netdev_list[MAX_DEVICE];
4. int numInterface = 0;
5.
6. if(netdev_get_devices(netdev_list, &numInterface) == NETDEV_SUCCESS)
7. {
8. int i;
9. netdev_dev *net_devPtr = netdev_list;
10.
11. for (i=0; i= Frequency802_11a1) &&
12. (freq <= Frequency802_11a2) &&
13. (rate <= MaxRate802_11a))
14. return ("802.11a");
15.
16. if ((freq >= Frequency802_11b1) &&
17. (freq <= Frequency802_11b2) &&
18. (rate <= MaxRate802_11b))
19. return ("802.11b");
20.
21. if ((freq >= Frequency802_11g1) &&
22. (freq <= Frequency802_11g2) &&
23. (rate <= MaxRate802_11g))
24. return ("802.11g");
25.
26. return ("Unknown");
27. break;
28. }
29.
30. default:
31. return ("Unknown");
32. break;
33. }
34.
35. }
36.
37. else
38. return ("Unknown");
39.
40. }
41. }
42. net_devPtr++;
43. }
44.
45. }
46.
47. return ("Unknown");
48. }
49.

char* RetrieveMediaType(void)
{
netdev_dev netdev_list[MAX_DEVICE];
int numInterface = 0;

if(netdev_get_devices(netdev_list, &numInterface) == NETDEV_SUCCESS)
{
int i;
netdev_dev *net_devPtr = netdev_list;

for (i=0; i= Frequency802_11a1) &&
(freq <= Frequency802_11a2) &&
(rate <= MaxRate802_11a))
return ("802.11a");

if ((freq >= Frequency802_11b1) &&
(freq <= Frequency802_11b2) &&
(rate <= MaxRate802_11b))
return ("802.11b");

if ((freq >= Frequency802_11g1) &&
(freq <= Frequency802_11g2) &&
(rate <= MaxRate802_11g))
return ("802.11g");

return ("Unknown");
break;
}

default:
return ("Unknown");
break;
}

}

else
return ("Unknown");

}
}
net_devPtr++;
}

}

return ("Unknown");
}



The back-end implementation of the method GetLinkSpeed is shown below.

- collapse sourceview plaincopy to clipboardprint?

1. double RetrieveLinkSpeed(void) // in bps
2. {
3. netdev_dev netdev_list[MAX_DEVICE];
4. int numInterface = 0;
5.
6. if(netdev_get_devices(netdev_list, &numInterface) == NETDEV_SUCCESS)
7. {
8. int i;
9. netdev_dev *net_devPtr = netdev_list;
10.
11. for (i=0; i

double RetrieveLinkSpeed(void) // in bps
{
netdev_dev netdev_list[MAX_DEVICE];
int numInterface = 0;

if(netdev_get_devices(netdev_list, &numInterface) == NETDEV_SUCCESS)
{
int i;
netdev_dev *net_devPtr = netdev_list;

for (i=0; i



Readers are encouraged to refer to the source code of the MID Platform Awareness project for more details.

Monitoring Network Connectivity Change

An application can query the network connectivity information by invoking the methods above. However, instead of constantly invoking the method to query the network connectivity status, sometimes it is more practical that an application just subscribe to network events, or signals. The application will be notified whenever the network connectivity changes status. Two network events are defined: Connected and Disconnected. The Connected event is emitted by the network connectivity service when the network suddenly becomes available. Similarly, the Disconnected event is emitted by the network connectivity service when the network suddenly becomes unavailable. The following code shows how to use D-Bus signals for monitoring network connectivity.

- collapse sourceview plaincopy to clipboardprint?

1. DBusMessage* msg;
2. DBusConnection* conn;
3. DBusError err;
4.
5. printf("Listening for signals\n");
6.
7. // initialise the errors
8. dbus_error_init(&err);
9.
10. // connect to the bus and check for errors
11. conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
12. if (dbus_error_is_set(&err))
13. {
14. fprintf(stderr, "Connection Error (%s)\n", err.message);
15. dbus_error_free(&err);
16. }
17.
18. if (NULL == conn)
19. exit(1);
20.
21. dbus_bus_add_match(conn, "type='signal',interface='org.moblin.Platform.Connection'", &err);
22. dbus_connection_flush(conn);
23.
24. if (dbus_error_is_set(&err))
25. {
26. fprintf(stderr, "Match Error (%s)\n", err.message);
27. exit(1);
28. }
29.
30. printf("Match rule sent\n");
31.
32. // loop listening for signals being emmitted
33. while (true)
34. {
35. // non blocking read of the next available message
36. dbus_connection_read_write(conn, 0);
37. msg = dbus_connection_pop_message(conn);
38.
39. // loop again if we haven't read a message
40. if (NULL == msg)
41. {
42. sleep(1);
43. continue;
44. }
45.
46. if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_CONNECTED_SIGNAL))
47. printf("Received signal %s\n", CONN_CONNECTED_SIGNAL);
48.
49. if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_DISCONNECTED_SIGNAL))
50. printf("Received signal %s\n", CONN_DISCONNECTED_SIGNAL);
51.
52. // free the message
53. dbus_message_unref(msg);
54. }
55.
56.

DBusMessage* msg;
DBusConnection* conn;
DBusError err;

printf("Listening for signals\n");

// initialise the errors
dbus_error_init(&err);

// connect to the bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}

if (NULL == conn)
exit(1);

dbus_bus_add_match(conn, "type='signal',interface='org.moblin.Platform.Connection'", &err);
dbus_connection_flush(conn);

if (dbus_error_is_set(&err))
{
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}

printf("Match rule sent\n");

// loop listening for signals being emmitted
while (true)
{
// non blocking read of the next available message
dbus_connection_read_write(conn, 0);
msg = dbus_connection_pop_message(conn);

// loop again if we haven't read a message
if (NULL == msg)
{
sleep(1);
continue;
}

if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_CONNECTED_SIGNAL))
printf("Received signal %s\n", CONN_CONNECTED_SIGNAL);

if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_DISCONNECTED_SIGNAL))
printf("Received signal %s\n", CONN_DISCONNECTED_SIGNAL);

// free the message
dbus_message_unref(msg);
}



Conclusion

D-Bus is a lightweight Remote Procedure Call (RPC) which is suitable for many applications running on a desktop. Because D-Bus is simple and relative small, yet powerful, we can adapt this technology for Mobile Internet Devices (MID). In this paper, we introduced a platform service for MID using D-Bus technology. We briefly described the six connectivity-related methods and two signals provided by the MIDPlatformSvc.

Although this implementation has been tested on the Moblin stack, this technology should also work on a Windows platform as well: therefore, with minimum change, this application should work on other form factors like UMPC, which run Windows* instead.

References

[1] D-Bus, http://www.freedesktop.org/wiki/Software/dbus
[2] D-Bus Tutorial, http://dbus.freedesktop.org/doc/dbus-tutorial.html
[3] http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php
[4] Mobile and Internet Linux Project, http://moblin.org/
[5] RFC 1945 "Hypertext Transfer Protocol – HTTP/1.0"

Convergence 09: Developing Power Aware Application using D-Bus

Introduction


Computer power consumption has become a passionate subject; hardware engineers trying to minimize the power consumed by devices, and software engineers trying to optimize their code to reduce the power consumed by their applications. Power is an even more important issue with Mobile Internet Devices (MIDs) since the small form factor limits the size of the battery. Applications running on MID's must therefore be very sensitive to power, and use power information to make smart decisions. For example, before beginning a lengthy transaction (such as downloading a video, or running an update), an application should check to see if the device is running on external power, and if not, determine whether or not there is sufficient power remaining to complete the transaction.

Background on D-Bus

D-Bus is a fast, lightweight message bus system which allows applications to communicate each other (Inter-process communication) [2]. It has a so-called D-Bus message bus (dbus deamon) which can accept messages from multiples applications and forward messages to them. D-Bus can be used as low-level API or higher level binding, such as Qt, Python*, Java*, C#, or Perl. This paper shows an application written in C using Glib bindings. Glib is the base library of GNOME, it provides an object system, object-based and event-driven programming.

Two buses are defined in D-Bus: system bus and session bus. The system bus allows communication between an application and the operating system while the session bus is designed to serve the communication between two applications.

In order to use D-Bus, we need to explore some concepts about D-Bus. First, an object is an endpoint on the bus, an object is created by an application in the context that the application's connection to the bus (either system bus or session bus). Objects have names, and these names are called object paths. A proxy is an object on the bus that can be accessed through references. We can find an object by searching the bus name and the object living in that bus connection. Once we find it, we usually keep a proxy to that object so we can refer to that object again without searching again.

An object can perform some specific operations. Each operation is referred as method. Thus, a client can send a request to an object and ask the object to invoke a method. The object then executes the method (if the method exists) and the result is sent back to the client. If a method requires input parameters, these parameters have to be passed with the request. The result can be one or more output parameters, these parameters are sent back to the client in the reply message.

An object can also emit an event, or signal. When a signal is generated by an object, it will be broadcasted to any observers who are interested in that particular signal. Signals can carry parameters too. Methods and Signals are embedded members of an object. They can be grouped. An Interface of an object is just a group of its members. An object can declare one or many interfaces - its members are then classified in these interfaces.

Instead of forming a D-Bus method call message and sending to the remote object using Glib bindings, one can instantiate a proxy object representing the remote object and then just invoke the methods of that object.

In order to generate dbus-glib binding code, we can use a tool called dbus-binding-tool. We first create an XML file, referred as Introspection XML file, in which we describe the methods and signals. An example of the introspection XML is shown below:

  1. "1.0" encoding="UTF-8" ?>

  2. "-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
  3. "http://standards.freedesktop.org/dbus/1.0/introspect.dtd">
  4. "/org/moblin/Platform">
  5. "org.moblin.Platform.Power">
  6. "org.freedesktop.DBus.GLib.CSymbol" value="org_moblin_platform_power"/>
  7. "IsUsingExternalPowerSource">
  8. "org.freedesktop.DBus.GLib.CSymbol" value="isUsingExternalPowerSource" />
  9. "b" name="usingExternalPowerSource" direction="out" />

  10. "GetTimeRemaining">
  11. "org.freedesktop.DBus.GLib.CSymbol" value="getTimeRemaining"/>
  12. "i" name="minutesRemaining" direction="out" />

  13. "GetPercentRemaining">
  14. "org.freedesktop.DBus.GLib.CSymbol" value="getPercentRemaining"/>
  15. "u" name="percentRemaining" direction="out" />





In this introspection XML file (named MIDPlatformSvcInterfaceDefinition.xml), an interface called org.moblin.Platform.Power defines three methods: IsUsingExternalPowerSource, GetTimeRemaining and GetPerCentRemaining. The output of the first method is a Boolean value. The output of the second method is an integer value representing the value in minutes, while the output of the third method is an unsigned integer value representing the percentage.

Below are primary steps to implement a service with methods to be exposed. More details are explained in [3].
  • Run dbus-binding-tool for an introspection XML file to generate dbus-glib binding code
  • Create a simple GObject for D-Bus
  • Implement the instance initialization
  • Implement the methods
  • Register the object to the D-Bus
To call the methods implemented on a remote object, a client needs to follow the following steps:
  • Connect to the bus
  • Create a proxy object
  • Invoke the methods on the proxy object

Using D-Bus as a Communication Channel


We designed the power service application which uses D-Bus as a communication channel to send information on battery. Other applications which are interested in power awareness can use D-Bus to get power information by querying the methods that the power service provided. These applications can also listen for the events that the power service generated. Figure 1 illustrates the usage model:

Figure 1. Usage Model: A Client Registers to D-Bus to Get the Information Provided by the MISPlatformSvc



Gathering Battery Information


We will present the implementation of three methods that are part of a simple library that provides battery information. The first method queries the percent of battery power remaining (getPercentRemaining). This method returns the percent of power currently available in the battery.

The second method queries the time remaining until the MID runs out of battery power (getTimeRemaining). This method returns the remaining time in minutes.

The third method queries whether or not the MID is using an external power source (IsUsingExternalPowerSource). This method returns a Boolean: TRUE means the MID is currently using an external power source (e.g., AC), FALSE means that the MID is using its battery (DC).

The first method calculates the percent of battery power remaining in a MID. In Linux, the file /proc/acpi/ contains power-related information. In particular, the file /proc/acpi/battery/BAT1/state contains the current remaining capacity in the field "remaining capacity". The file /proc/acpi/battery/BAT1/info contains the maximum capacity information in the "last full capacity" field. From these entries, we can deduce the percent of power remaining as shown below:

  1. gboolean computePercentPowerRemaining(guint *result)
  2. {
  3. DIR *d;
  4. struct dirent *de;
  5. char *acpi_path = "/proc/acpi";
  6. char *device_type = "battery";
  7. char *stateFile = "state";
  8. char *infoFile = "info";
  9. FILE *file;
  10. char filename[PATH_LENGTH];
  11. char line[LINE_LENGTH];
  12. *result = 0;
  13. double power_left = 0.0;
  14. double power_full = 0.0;
  15. gboolean rc = FALSE;

  16. // First, check if the ACPI path exists
  17. if (chdir(acpi_path) <>
  18. {
  19. dbg("ACPI is not supported (\"%s\").\n", acpi_path);
  20. return rc;
  21. }
  22. else
  23. dbg("Path %s is found \n", acpi_path);

  24. // Check if battery directory exists
  25. if (chdir(device_type) <>
  26. {
  27. dbg("No support for device type: %s\n", device_type);
  28. return rc;
  29. }
  30. else
  31. dbg("Device %s is supported \n", device_type);

  32. // /proc/acpi/battery is found. Now search for available batteries
  33. d = opendir(".");
  34. if (!d) {
  35. dbg("Cannot open directory!\n");
  36. return rc;
  37. }

  38. while ((de = readdir(d))) {
  39. // Search for real directory ("BAT0", ...), not ".", ".."
  40. if (!strcmp(de->d_name, "."))
  41. continue;

  42. if (!strcmp(de->d_name, ".."))
  43. continue;

  44. dbg("device found: %s\n", de->d_name);

  45. // Open file "state".
  46. sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de->d_name, stateFile);
  47. file = fopen(filename, "r");
  48. if (!file)
  49. {
  50. closedir(d);
  51. return rc;
  52. }

  53. memset(line, 0, LINE_LENGTH);
  54. while (fgets(line, LINE_LENGTH, file) != NULL) {
  55. if (strstr(line, "remaining capacity:") &&
  56. (strstr(line, "mWh") || strstr(line, "mAh")))
  57. {
  58. // Search the value
  59. char *c;

  60. c = strchr(line, ':');
  61. c++;

  62. power_left = strtoull(c, NULL, 10); // in mWh or mAh

  63. // Cannot perform conversion
  64. if ((0 == power_left) && (EINVAL == errno))
  65. {
  66. closedir(d);
  67. return rc;
  68. }
  69. break;
  70. }
  71. }

  72. fclose(file);

  73. // Open file "info".
  74. sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de->d_name, infoFile);
  75. file = fopen(filename, "r");
  76. if (!file)
  77. {
  78. closedir(d);
  79. return rc;
  80. }

  81. memset(line, 0, LINE_LENGTH);
  82. while (fgets(line, LINE_LENGTH, file) != NULL) {
  83. if (strstr(line, "last full capacity:") &&
  84. (strstr(line, "mWh") || strstr(line, "mAh")))
  85. {
  86. // Search the value
  87. char *c;

  88. c = strchr(line, ':');
  89. c++;

  90. power_full = strtoull(c, NULL, 10); // in mWh or mAh

  91. // Cannot perform conversion
  92. if (0 == power_full)
  93. {
  94. closedir(d);
  95. return rc;
  96. }

  97. *result = (power_left/power_full)*100; // in %
  98. break;
  99. }
  100. }

  101. rc = TRUE;
  102. fclose(file);

  103. // Exit while loop
  104. break;
  105. }
  106. closedir(d);

  107. return rc;
  108. }


The second method queries the time remaining until the MID is out battery power (getTimeRemaining). This method returns the remaining time in minutes. As mentioned above, the file /proc/acpi/battery/BAT1/state contains the current remaining capacity in the "remaining capacity" field. The "present rate" field in the same file contains the rate at which the battery capacity is changing. This field is significant only if the battery is discharging. From this information, we can deduce the remaining time in minutes as shown below:

  1. int computeTimeRemaining(void)
  2. {
  3. DIR *d;
  4. struct dirent *de;

  5. char *acpi_path = "/proc/acpi";
  6. char *device_type = "battery";
  7. char *stateFile = "state";

  8. FILE *file;
  9. char filename[PATH_LENGTH];
  10. char line[LINE_LENGTH];
  11. int result = -1;
  12. double power_left = 0.0;
  13. double power_full = 0.0;
  14. double dischargeRate = 0.0;
  15. int find = 0;

  16. // First, check if the ACPI path exists
  17. if (chdir(acpi_path) <>
  18. {
  19. dbg("ACPI is not supported (\"%s\").\n", acpi_path);
  20. return result;
  21. }
  22. else
  23. dbg("Path %s is found \n", acpi_path);

  24. // Check if battery directory exists
  25. if (chdir(device_type) <>
  26. {
  27. dbg("No support for device type: %s\n", device_type);
  28. return result;
  29. }
  30. else
  31. dbg("Device %s is supported \n", device_type);

  32. // /proc/acpi/battery is found. Now search for available batteries
  33. d = opendir(".");
  34. if (!d) {
  35. dbg("Cannot open directory!\n");
  36. return result;
  37. }

  38. while ((de = readdir(d))) {
  39. // Search for real directory ("BAT0", ...), not ".", ".."
  40. if (!strcmp(de->d_name, "."))
  41. continue;

  42. if (!strcmp(de->d_name, ".."))
  43. continue;

  44. dbg("device found: %s\n", de->d_name);

  45. // Open file "state".
  46. sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de->d_name, stateFile);
  47. file = fopen(filename, "r");
  48. if (!file)
  49. {
  50. closedir(d);
  51. return result;
  52. }

  53. memset(line, 0, LINE_LENGTH);

  54. while (fgets(line, LINE_LENGTH, file) != NULL) {
  55. if (strstr(line, "charging state:") &&
  56. strstr(line, "discharging"))
  57. {
  58. find++;
  59. }

  60. if (strstr(line, "present rate:") &&
  61. (strstr(line, "mW") || strstr(line, "mA")))
  62. {
  63. // Search the value
  64. char *c;

  65. c = strchr(line, ':');
  66. c++;

  67. dischargeRate = strtoull(c, NULL, 10); // in mW or mA

  68. // Cannot perform conversion
  69. if ((0 == dischargeRate) && (EINVAL == errno))
  70. {
  71. closedir(d);
  72. return result;
  73. }

  74. find++;
  75. }

  76. if (strstr(line, "remaining capacity:") &&
  77. (strstr(line, "mWh") || strstr(line, "mAh")))
  78. {
  79. // Search the value
  80. char *c;

  81. c = strchr(line, ':');
  82. c++;

  83. power_left = strtoull(c, NULL, 10); // in mWh or mAh

  84. // Cannot perform conversion
  85. if ((0 == power_left) && (EINVAL == errno))
  86. {
  87. closedir(d);
  88. return result;
  89. }

  90. find++;
  91. }


  92. }

  93. fclose(file);

  94. // Exit while loop
  95. break;
  96. }
  97. closedir(d);

  98. if (find == 3)
  99. {
  100. result = 0;

  101. if (dischargeRate > 0)
  102. result = (power_left/dischargeRate)*60; // convert to minutes
  103. }

  104. return result;
  105. }


The third method queries whether or not the MID is using an external power source. The information in the file /proc/acpi/ac_adaptor/ACAD/state shows the status of the battery. Below shows the implementation.

  1. int computePowerSource()
  2. {
  3. DIR *d;
  4. struct dirent *de;
  5. char *acadaptor_path = "/proc/acpi/ac_adapter";
  6. char *stateFile = "state";
  7. FILE *file;
  8. int result = -1;
  9. char filename[PATH_LENGTH];

  10. // First, check if the ac_adaptor path exists
  11. if (chdir(acadaptor_path) <>
  12. {
  13. return result;
  14. }

  15. // /proc/acpi/ac_adaptor is found. Now search for available entry
  16. d = opendir(".");
  17. if (!d) {
  18. return result;
  19. }

  20. while ((de = readdir(d))) {
  21. char line[LINE_LENGTH];
  22. // Search for real directory (not ".", ".."
  23. if (!strcmp(de->d_name, "."))
  24. continue;

  25. if (!strcmp(de->d_name, ".."))
  26. continue;

  27. sprintf(filename, "%s/%s/%s", acadaptor_path, de->d_name, stateFile);
  28. file = fopen(filename, "r");
  29. if (!file)
  30. {
  31. closedir(d);
  32. return result;
  33. }

  34. memset(line, 0, LINE_LENGTH);
  35. while (fgets(line, LINE_LENGTH, file) != NULL) {
  36. if (strstr(line, "state:") && strstr(line, "off-line"))
  37. result = 0; // AC (battery)
  38. else if (strstr(line, "state:") && strstr(line, "on-line"))
  39. result = 1; // DC
  40. }

  41. fclose(file);
  42. }

  43. closedir(d);

  44. return result;
  45. }


Putting Things Together


First, the introspection XML in previous section clearly defined the three methods for battery. We can now generate a D-Bus binding header file using the D-Bus binding tool.

  1. % dbus-binding-tool --mode=glib-server -–prefix=MIDPlatformSvc --output=MIDPlatformSvc-dbus-glue.h MIDPlatformSvcInterfaceDefinition.xml


Then, we create a platform service object by following standard steps in [3]. We don't show it here since it is straightforward. In the final step, we just glue the three methods above to the implementation.

Each interface method has three parameters: the called object, the return value, and the error. Inside the interface method we glue the return value to its implementation.

  1. gboolean getPercentRemaining(MIDPlatformSvc *obj, guint *percentRemaining, GError **error)
  2. {
  3. gboolean rc = FALSE;

  4. rc = computePercentPowerRemaining(percentRemaining);

  5. if (rc)
  6. return TRUE;
  7. else
  8. {
  9. g_set_error(error,
  10. G_FILE_ERROR,
  11. G_FILE_ERROR_NOENT,
  12. "Failed to open file /proc/acpi/battery");
  13. return FALSE;
  14. }
  15. }

  16. gboolean getTimeRemaining(MIDPlatformSvc *obj, gint *timeRemaining, GError **error)
  17. {
  18. *timeRemaining = computeTimeRemaining();

  19. if (*timeRemaining > 0)
  20. {
  21. return TRUE;
  22. }
  23. else if (*timeRemaining == 0)
  24. {
  25. g_set_error(error,
  26. G_FILE_ERROR,
  27. G_FILE_ERROR_NOENT,
  28. "Cannot determine since information is missing!");
  29. return FALSE;
  30. }
  31. else
  32. {
  33. g_set_error(error,
  34. G_FILE_ERROR,
  35. G_FILE_ERROR_NOENT,
  36. "Failed to open file or directory");
  37. return FALSE;
  38. }
  39. }

  40. gboolean isUsingExternalPowerSource(MIDPlatformSvc *obj, gboolean *onExternalSource, GError **error)
  41. {
  42. int t = computePowerSource();

  43. if (t == 0)
  44. {
  45. *onExternalSource = FALSE;
  46. return TRUE;
  47. }
  48. else if (t == 1)
  49. {
  50. *onExternalSource = TRUE;
  51. return TRUE;
  52. }
  53. else
  54. {
  55. g_set_error(error,
  56. G_FILE_ERROR,
  57. G_FILE_ERROR_NOENT,
  58. "Failed to open file or directory");

  59. return FALSE;
  60. }
  61. }


A Test Client


To test the interface power, we write a simple test client using D-Bus as well. The test client invokes the remote methods of object MIDPlatformSvc in order to retrieve battery information on the MID.

  1. #define PLATFORM_SERVICE "org.moblin.Platform"
  2. #define PLATFORM_PATH "/org/moblin/Platform"
  3. #define PLATFORM_POWER_IF "org.moblin.Platform.Power"
  4. #define POWER_SRC_CHANGED_SIGNAL "PowerSourceChanged"

  5. void queryMethod(char* param)
  6. {
  7. DBusGConnection* conn;
  8. GError *error;
  9. DBusGProxy *platformProxy;
  10. DBusError err;

  11. printf("Calling remote method: %s\n", param);

  12. g_type_init();
  13. error = NULL;
  14. conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);

  15. // Create the proxy Platform
  16. platformProxy = dbus_g_proxy_new_for_name(conn,
  17. PLATFORM_SERVICE, // target for the method call
  18. PLATFORM_PATH, // object to call on
  19. PLATFORM_POWER_IF); // interface to call on

  20. // Now call the metjod "IsUsingExternalPowerSource"
  21. if (param == "GetPercentRemaining")
  22. {
  23. uint result;

  24. if (!dbus_g_proxy_call(platformProxy, param, &error,
  25. G_TYPE_INVALID,
  26. G_TYPE_UINT, &result,
  27. G_TYPE_INVALID))
  28. {
  29. g_printerr("Failed to call remotely: %s\n",
  30. error->message);
  31. g_error_free(error);
  32. }
  33. else
  34. printf ("Remote call successes with returned value: %d%\n", result);
  35. }
  36. else if (param == "GetTimeRemaining")
  37. {
  38. int result;

  39. if (!dbus_g_proxy_call(platformProxy, param, &error,
  40. G_TYPE_INVALID,
  41. G_TYPE_INT, &result,
  42. G_TYPE_INVALID))
  43. {
  44. g_printerr("Failed to call remotely: %s\n",
  45. error->message);
  46. g_error_free(error);
  47. }
  48. else
  49. {
  50. printf ("Remote call successes with returned value: %d minutes\n",result);
  51. }
  52. }
  53. else if (param == "IsUsingExternalPowerSource")
  54. {
  55. gboolean result;

  56. if (!dbus_g_proxy_call(platformProxy, param, &error,
  57. G_TYPE_INVALID,
  58. G_TYPE_BOOLEAN, &result,
  59. G_TYPE_INVALID))
  60. {
  61. g_printerr("Failed to call remotely: %s\n",
  62. error->message);
  63. g_error_free(error);
  64. }
  65. else
  66. printf ("Remote call successes with returned value: %s\n", result? "TRUE" : "FALSE");
  67. }

  68. }

  69. int main(int argc, char** argv)
  70. {
  71. char* methodName[3] = {"GetPercentRemaining",
  72. "GetTimeRemaining",
  73. "IsUsingExternalPowerSource"};

  74. int i;

  75. for (i = 0; i <= 2; i++)
  76. queryMethod(methodName[i]);

  77. return 0;
  78. }


Below is the result when running the test client.

Calling remote method: IsUsingExternalPowerSource

% ./clientTester
Calling remote method: GetPercentRemaining
Remote call successes with returned value: 96%
Calling remote method: GetTimeRemaining
Remote call successes with returned value: 235 minutes
Calling remote method: IsUsingExternalPowerSource
Remote call successes with returned value: FALSE


Conclusion


Because the MID form factor limits the size of the battery, applications that run on the platform must be aware of power state information in order to make smart decisions. Knowing how much power is remaining, how much time is remaining, and whether or not the system is running on external power can help software make wise use of the MID's resources. D-Bus is a lightweight Remote Procedure Call (RPC) which is suitable for many applications running on desktop. Because D-Bus is simple and relative small, yet powerful, we can adapt this technology for Mobile Internet Device (MID). In this paper, we introduced a platform service for MID using D-Bus technology. We showed how to implement three power-related methods provided by the MIDPlatformSvc. A sample test client is also shown to illustrate how we can use D-Bus to invoke these methods. As D-Bus not only supports methods, it can also support signals; we can also extend this application to include signals. In the feature, this platform service can be extended to include other interfaces such as network, location, CPU utilization...

References


[1] D-Bus, http://www.freedesktop.org/wiki/Software/dbus
[2] D-Bus Tutorial, http://dbus.freedesktop.org/doc/dbus-tutorial.html
[3] http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php
[4] Mobile and Internet Linux Project, http://moblin.org/