<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><!-- Generated on Thu, 09 Jul 2009 16:53:47 -0700 --><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    
    <title>Intel Software Network articles feed</title>
    <link>http://software.intel.com/en-us/articles/mobility/all</link>
    <description />
    <language>en-us</language>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ISNMobility" type="application/rss+xml" /><feedburner:emailServiceId>ISNMobility</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Intel Software Network TV Goes Live June 9th</title>
      <description>&lt;p&gt;Social Media Release:&lt;/p&gt;
&lt;p class="sectionHeading"&gt;&lt;strong&gt;Intel® Software Network TV - Live, Interactive TV for Developers - Launches June 9, 2009.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;On June 9, &lt;a href="http://intel.com/software/tv/"&gt;Intel® Software Network TV,&lt;/a&gt;&lt;/strong&gt; a new 24/7 live, interactive TV channel for software developers will go "on the air" at the &lt;a href="http://intel.com/software/tv"&gt;Intel Software Network&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://intel.com/software/tv/"&gt;&lt;strong&gt;http://intel.com/software/tv/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://intel.com/software/tv"&gt;Intel Software Network TV &lt;/a&gt;launches with a lineup of regularly-scheduled live interactive shows on software and developer topics including Parallel Programming and Visual Computing, along with "behind the scenes" access and special event coverage. Additional shows are planned for later in the year. For live shows, you can interact with the show hosts and with other viewers via the chat feature. If a live show isn't currently on air, you'll see encore presentations of previous shows, and you can always browse the On Demand area to watch any past episode.&lt;/p&gt;
&lt;p&gt;Here is a sample of a previously recorded show, &lt;em&gt;Visualize This!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
&lt;object height="360" width="640" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"&gt;
&lt;param name="src" value="http://blip.tv/play/g5FLgYboSZXafg%2Em4v" /&gt;
&lt;param name="allowfullscreen" value="true" /&gt;&lt;embed height="360" width="640" allowfullscreen="true" src="http://blip.tv/play/g5FLgYboSZXafg%2Em4v" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Subscribe to &lt;a href="http://feeds2.feedburner.com/ISNTV"&gt;the RSS feed&lt;/a&gt; in &lt;a href="itpc://feeds2.feedburner.com/ISNTV"&gt;iTunes&lt;/a&gt; (or your podcaster of choice) to automatically receive high-quality downloads of new show episodes as they become available. Watch them whenever and wherever you want.&lt;/p&gt;
&lt;p&gt;Follow &lt;a href="http://twitter.com/isntv"&gt;@isntv&lt;/a&gt; on Twitter to be alerted when a show or special live event is about to go live. Don't miss out!&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;&lt;span class="sectionHeadingText"&gt;&lt;strong&gt;Come join us live for our big launch day on June 9!&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are the shows and specials we have lined up:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;June 9, 8 AM Pacific:&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;Parallel Programming Talk&lt;/em&gt;&lt;/strong&gt; with &lt;em&gt;hosts &lt;/em&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/aaron-tersteeg/"&gt;&lt;em&gt;Aaron Tersteeg&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://software.intel.com/en-us/blogs/author/clay-breshears/"&gt;&lt;em&gt;Dr. Clay Breshears&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and special guest &lt;/em&gt;&lt;a href="http://www.eecs.berkeley.edu/~pattrsn/"&gt;&lt;em&gt;David Patterson of UC Berkeley&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and UPCRC. Aaron, Clay and David will be discussing the challenges developers face in Parallel Computing today. The radio version of this show has been broadcast since July 2008, with over 14,000 cumulative listeners. &lt;strong&gt;Parallel Programming Talk&lt;/strong&gt; can be seen live every Tuesday at 8AM Pacific on &lt;a href="http://intel.com/software/tv/"&gt;Intel Software Network TV&lt;/a&gt; or via &lt;a href="http://www.blogtalkradio.com/multicoresoftware"&gt;podcast &lt;/a&gt;. &lt;br /&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="314" valign="top"&gt;
&lt;p&gt;&lt;a href="http://www.blogtalkradio.com/multicoresoftware"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;img title="Picture1.png" src="http://software.intel.com/file/19514" alt="Picture1.png" width="294" height="172" /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="216" valign="top"&gt;
&lt;p&gt;&lt;img title="David_patterson.jpg" src="http://software.intel.com/file/19515" alt="David_patterson.jpg" width="198" height="170" /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="314" valign="top"&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;em&gt;Hosts &lt;/em&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/aaron-tersteeg/"&gt;&lt;em&gt;Aaron Tersteeg&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and &lt;/em&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/clay-breshears/"&gt;&lt;em&gt;Dr. Clay Breshears&lt;/em&gt;&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="216" valign="top"&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;em&gt;Special guest &lt;/em&gt;&lt;a href="http://www.eecs.berkeley.edu/~pattrsn/"&gt;&lt;em&gt;David Patterson of UC Berkeley&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;June 9, 10 AM Pacific: Teach Parallel, &lt;/strong&gt;a new show for parallel programming in academia. Hosts &lt;a href="http://software.intel.com/en-us/blogs/author/paul-steinberg/"&gt;Paul Steinberg&lt;/a&gt; and &lt;a href="http://software.intel.com/en-us/blogs/author/wolfmurphy/"&gt;Professor Tom Murphy&lt;/a&gt; of Contra Costa College will tackle the challenges of teaching Parallel Programming in academia and computer science.&lt;em&gt; Teach Parallel can be seen live on alternate Tuesdays at 10AM Pacific on Intel Software Network TV.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="133" valign="top"&gt;
&lt;p style="text-align: center;"&gt;&lt;img title="TOM_Murphy.jpg" src="http://software.intel.com/file/19519" alt="TOM_Murphy.jpg" width="108" height="95" /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="120" valign="top"&gt;&lt;img title="Paul_Steinberg.jpg" src="http://software.intel.com/file/19518" alt="Paul_Steinberg.jpg" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="133" valign="top"&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/wolfmurphy/"&gt;Professor Tom Murphy&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="120" valign="top"&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/paul-steinberg/"&gt;Paul Steinberg&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;June 9, 12 PM Pacific: &lt;/strong&gt;A special chat with guest and Intel Software Network blogging hero, &lt;a href="http://software.intel.com/en-us/blogs/author/doug-holland/"&gt;Doug Holland&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;June 9, 2:30 PM Pacific: &lt;em&gt;Visualize This!&lt;/em&gt;&lt;/strong&gt; Show host and Intel Software Network Game Development Community Manager &lt;a href="http://software.intel.com/en-us/blogs/author/arti-gupta/"&gt;Arti Gupta&lt;/a&gt; will talk to Visual Computing Community Manager, &lt;a href="http://software.intel.com/en-us/blogs/author/steve-pitzel/"&gt;Steve Pitzel&lt;/a&gt;. Steve will introduce the new &lt;a href="http://www.intel.com/software/artist"&gt;Artists/Animators community&lt;/a&gt; and showcase resources available. &lt;em&gt;This show will focus on what is new and exciting in the world of graphics, animation, and game development. Visualize This! can be seen live on alternate Tuesdays at 2:30PM on Intel Software Network TV.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="116" valign="top"&gt;
&lt;p style="text-align: center;"&gt;&lt;img title="Pitz.jpg" src="http://software.intel.com/file/19520" alt="Pitz.jpg" /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="119" valign="top"&gt;
&lt;p style="text-align: center;"&gt;&lt;img title="ArtI_GUPTA.jpg" src="http://software.intel.com/file/19521" alt="ArtI_GUPTA.jpg" /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="116" valign="top"&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/steve-pitzel/"&gt;Steve Pitzel&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td width="119" valign="top"&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/arti-gupta/"&gt;Arti Gupta&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;June 9, &lt;span style="text-decoration: line-through;"&gt;4:00&lt;/span&gt; 3:30 PM Pacific: &lt;/strong&gt;A chat with special guest &lt;a href="http://software.intel.com/en-us/blogs/author/david-stewart"&gt;David Stewart&lt;/a&gt; on the recently released Moblin 2.0 beta, with hands on demos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network TV: &lt;a href="http://intel.com/software/TV"&gt;http://intel.com/software/TV&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short URL (for Twitter, etc.): &lt;a href="http://bit.ly/isntv"&gt;http://bit.ly/isntv&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Parallel Programming Talk show episodes: &lt;a href="http://software.intel.com/en-us/blogs/author/aaron-tersteeg/"&gt;http://software.intel.com/en-us/blogs/author/aaron-tersteeg/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Teach Parallel show episodes: &lt;a href="http://software.intel.com/en-us/blogs/author/paul-steinberg/"&gt;http://software.intel.com/en-us/blogs/author/paul-steinberg/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Visualize This show episodes: &lt;a href="http://software.intel.com/en-us/blogs/author/arti-gupta/"&gt;http://software.intel.com/en-us/blogs/author/arti-gupta/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Parallel Programming and Multicore Community: &lt;a href="http://www.intel.com/software/multicore"&gt;http://www.intel.com/software/multicore&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Visual Computing Community: &lt;a href="http://software.intel.com/en-us/visual-computing/"&gt;http://software.intel.com/en-us/visual-computing/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Academic Community: &lt;a href="http://software.intel.com/en-us/academic/"&gt;http://software.intel.com/en-us/academic/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Manageability Community: &lt;a href="http://software.intel.com/en-us/manageability"&gt;http://software.intel.com/en-us/manageability&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Mobile Community: &lt;a href="http://software.intel.com/en-us/mobility"&gt;http://software.intel.com/en-us/mobility&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network Main Home Page: &lt;a href="http://intel.com/software/"&gt;http://intel.com/software/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SUGGESTED TAGS: Intel, software, developer, code, community, live, video, tv, shows, ISNTV&lt;/strong&gt;&lt;strong&gt;, parallel programming, multicore, visual computing, graphics, manageability, moblin, mobile, academic, podcast&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Producer:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://software.intel.com/file/19552" alt="" width="90" height="90" /&gt;&lt;/p&gt;
&lt;p&gt;Josh Bancroft - &lt;a href="mailto:joshua.bancroft@intel.com"&gt;joshua.bancroft@intel.com&lt;/a&gt;, &lt;a href="http://twitter.com/jabancroft"&gt;@jabancroft&lt;/a&gt; on Twitter&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Media Resources: &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network TV RSS feed (subscribe to high quality downloads of show episodes) - &lt;a href="http://feeds2.feedburner.com/ISNTV"&gt;http://feeds2.feedburner.com/ISNTV &lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intel Software Network TV Twitter Account: &lt;a href="http://twitter.com/isntv"&gt;http://twitter.com/isntv&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intel Software Network Bloggers:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/aaron-tersteeg/"&gt;&lt;em&gt;Aaron Tersteeg - Multicore and Parallel Programming Community Manager&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://www.twitter.com/tersteeg"&gt;@tersteeg&lt;/a&gt; on Twitter&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/clay-breshears/"&gt;&lt;em&gt;Clay Breshears&lt;/em&gt;&lt;/a&gt;&lt;em&gt; -Content Concierge for the Intel Developer Network Organization&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/arti-gupta/"&gt;&lt;em&gt;Arti Gupta&lt;/em&gt;&lt;/a&gt;&lt;em&gt; - Community Manager, Game Development, &lt;a href="http://www.twitter.com/artigupta"&gt;@artigupta&lt;/a&gt; on Twitter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/steve-pitzel/"&gt;&lt;em&gt;Steve Pitzel&lt;/em&gt;&lt;/a&gt;&lt;em&gt; - Community Manager, Visual Computing Community &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/paul-steinberg/"&gt;&lt;em&gt;Paul Steinberg&lt;/em&gt;&lt;/a&gt; - Academic Community Manager &lt;a href="http://twitter.com/psteinb"&gt;@psteinb &lt;/a&gt;on Twitter&lt;br /&gt;&lt;a href="http://software.intel.com/en-us/blogs/author/amy-barton/"&gt;&lt;em&gt;&lt;br /&gt;Amy Barton - New Media Communications&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://twitter.com/amybarton"&gt;@amybarton&lt;/a&gt; on Twitter&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Additional pre-recorded Intel Software Network Videos:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Take Five Videos: &lt;a href="http://www.intel.com/software/videos"&gt;www.intel.com/software/videos&lt;/a&gt; &lt;a href="http://software.intel.com/media/images/small_icons/rss.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take Five Video YouTube channel: &lt;a href="http://www.youtube.com/user/intelswnetwork"&gt;http://www.youtube.com/user/intelswnetwork&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/qBbdMqdGS6Q" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/qBbdMqdGS6Q/intel-software-network-tv-goes-live</link>
      <pubDate>Thu, 04 Jun 2009 22:25:01 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/intel-software-network-tv-goes-live#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/intel-software-network-tv-goes-live</guid>
      <category>Mobility</category>
      <category>Parallel Programming and Multi-Core</category>
      <category>ISN General</category>
      <category>Intel® Atom™ Software Developer Community</category>
      <category>Visual Computing</category>
      <category>Intel Software Network communities</category>
      <category>Events</category>
      <category>Intel® Software Network TV</category>
      <category>Software News</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/intel-software-network-tv-goes-live</feedburner:origLink></item>
    <item>
      <title>Developing for Mobile Internet Devices, Part 2: Designing, Coding and Testing a Twitter* Location-Based Application</title>
      <description>By Paul Ferrill&lt;br /&gt;&lt;br /&gt;In&lt;strong&gt; &lt;/strong&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration/"&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;part 1&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt; of this series, I showed you what it takes to build applications for the Mobile Internet Device (MID) platform. I covered the basic issues of setting up a development workstation, choosing a programming language, and making good choices in terms of external libraries. I also discussed issues like device emulation, the importance of working through a prototype “hello world” application, and common problems to avoid.&lt;br /&gt;&lt;br /&gt;This installment gets down to the business at hand and walks through the process of designing and coding a working application. I chose a Twitter* application that will report the user’s current location as a way to exercise as many of the MID features as possible. Although it’s a simple application in terms of what it does, it has many of the parts you’d need to build any general-purpose user application.
&lt;p class="sectionHeading"&gt;&lt;br /&gt;Design Choices&lt;/p&gt;
&lt;p&gt;Many of the functional parts of this application are foundational to everyday applications, requiring features such as user authentication, configuration storage and retrieval, network communications, and user interaction. It’s important to modularize the design as much as possible to both break the overall project down into manageable pieces and to make it easier to reuse the code.&lt;/p&gt;
&lt;p&gt;The application checks each time it runs to see whether any user credential information has been entered. If not, it presents a typical user name/password login dialog box and stores the information in an encrypted local configuration file. A preferences dialog box makes it possible to change the user name and password after initial setup along with other program options.&lt;/p&gt;
&lt;p&gt;For the initial release of this program, I assume that there is an active network connection. This is a bit of a stretch for the Compal JAX10* MID I tested on: It did not have an active 3G radio, so there was no “always-on” Internet connection. I was able to simulate having a consistent connection by using Wi-Fi, instead. Later versions might check for connectivity and, if currently disconnected, queue up the message to send the next time a connection to the Internet is available.&lt;/p&gt;
&lt;p&gt;Another design consideration for the mobile form factor is deciding what happens when a button is pressed. With this particular application, there is a consequence for choosing single-key action; every time the user presses one of the action buttons, a message is sent to Twitter. If you assume the user won’t inadvertently press a button or do something like put the device in a back pocket with the application running, it shouldn’t be a problem. Alternatives might include adding a confirmation dialog box to each action (“Really send message?”), adding a button or a timer to lock the screen, or exiting the program by default after the message is sent.&lt;/p&gt;
&lt;p class="sectionHeading"&gt;Building a UI for the Small Screen&lt;/p&gt;
&lt;p&gt;One of nice things about Python* is the abundance of libraries to do just about anything you need to do. The Compal* MID used for this project has a number of useful libraries installed as a part of the base operating system, and I chose to take advantage of them. The GTK+* user interface (UI) library contains a wealth of resources for building everything from a simple dialog box to a complex data-entry form. PyGTK is a wrapper around the GTK+ library and provides access to virtually every routine through standard Python objects.&lt;br /&gt;Building a login dialog using PyGTK consists of creating a simple window with individual text boxes for username and password. You can find a good example and explanation of these techniques on the &lt;a href="http://www.pygtk.org/pygtk2tutorial/sec-TextEntries.html"&gt;PyGTK tutorial page&lt;/a&gt;. In the following code snippet the pass_input.set_visibility(False) line causes the password to be blanked by a dot symbol:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre name="code" class="cpp"&gt;def login(self):&lt;br /&gt;        dialog = gtk.Dialog('Login', &lt;br /&gt;                            self.window,&lt;br /&gt;                            flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,&lt;br /&gt;                            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,&lt;br /&gt;                                     gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))&lt;br /&gt;        dialog.set_default_response(gtk.RESPONSE_ACCEPT)&lt;br /&gt;        &lt;br /&gt;        userbox = gtk.HBox(False)&lt;br /&gt;        &lt;br /&gt;        user_label = gtk.Label('Username:')&lt;br /&gt;        userbox.pack_start(user_label)&lt;br /&gt;        &lt;br /&gt;        user_input = gtk.Entry()&lt;br /&gt;        user_input.set_activates_default(True)&lt;br /&gt;        userbox.pack_start(user_input)&lt;br /&gt;        &lt;br /&gt;        dialog.vbox.pack_start(userbox)&lt;br /&gt;    &lt;br /&gt;        passbox = gtk.HBox(False)&lt;br /&gt;        &lt;br /&gt;        pass_label = gtk.Label('Password:')&lt;br /&gt;        passbox.pack_start(pass_label)&lt;br /&gt;&lt;br /&gt;        pass_input = gtk.Entry()&lt;br /&gt;        pass_input.set_activates_default(True)&lt;br /&gt;        pass_input.set_visibility(False)&lt;br /&gt;        passbox.pack_start(pass_input)&lt;br /&gt;	  dialog.vbox.pack_start(passbox)&lt;br /&gt;&lt;/pre&gt;
Another chore for the small screen is creating a finger-friendly interface. For this application, that means buttons appropriately sized and spaced so that an adult‘s finger can easily press the button of choice. It is possible to code the button sizes specifically for the Compal screen size and resolution, but a more general approach would be to use the available system information to calculate the appropriate dimensions.
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A second option with GTK+ is to create a table that fills the screen with a matrix of buttons that essentially takes up all the screen real estate. Although doing so might not be as visually appealing, it does accomplish the task of building a finger-friendly interface in which you can easily “click” the right button. It also provides a few more options for adding descriptive text to the button for the Twitter application. In Python, the matrix would look something like this:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre name="code" class="cpp"&gt;def create_table(self):&lt;br /&gt;        self.table = gtk.Table(3,4,True) # Create a 3 row by 4 column table&lt;br /&gt;        button1 = gtk.Button("Button 1") # Create a button named button1&lt;br /&gt;        self.table.attach(button1,0,1,0,1) # put button 1 in location 0,1&lt;br /&gt;        button2 = gtk.Button("Button 2")&lt;br /&gt;        self.table.attach(button2,1,2,0,1)	&lt;br /&gt;        button3 = gtk.Button("Button 3")&lt;br /&gt;        self.table.attach(button3,1,2,0,1)&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.	&lt;br /&gt;        button12 = gtk.Button("Button 12")&lt;br /&gt;        self.table.attach(button12,1,2,0,1)&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The lines with a single period are meant to indicate that the sequence repeats down to the final definition of button12.&lt;/p&gt;
&lt;p class="sectionHeading"&gt;Coding Practices&lt;/p&gt;
&lt;p&gt;Python is a language that allows you to write code by the brute-force method, as in the lines above, or in a more elegant way using concepts like iteration. If you were to define all 12 buttons in a linear fashion, you would need 26 lines of code. Using the Python for construct, you can accomplish the same task in a mere seven lines of code. That equates to less than one-third of the code for this simple example, but the difference would be substantial for a larger table. Here’s the code in a more “Pythonic” way:&lt;/p&gt;
&lt;pre name="code" class="cpp"&gt;    def create_table(self):&lt;br /&gt;        self.table = gtk.Table(3,4,True)&lt;br /&gt;        for row in range(3):&lt;br /&gt;            for col in range(4):&lt;br /&gt;            	name = 'Twitter %i' % (row*4 + col + 1)&lt;br /&gt;            	button = gtk.Button(name)&lt;br /&gt;            	self.table.attach(button, col, col+1, row, row+1)&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Keeping your code manageable is important when scripts start to get large. Python functions are a good way to break down your code into small, manageable pieces. It’s also important to point out that everything in Python is an object. You can see this to some extent in the create_table function through the use of the self construct. The function create_table creates a gtk.Table and returns it as an object—hence, the use of self to refer to the object being created. There is an abundance of resources on the Web if you’re not familiar with object-oriented programming concepts.&lt;/p&gt;
&lt;p&gt;Taking advantage of all the built-in language features and functions is another way to keep your source code manageable. Python has a module for reading and writing configuration files named ConfigParser. This module provides all the tools you need to save and read program configuration information. It supports different sections and creates a file of name–value pairs within each section. There are even individual methods to retrieve specific types, such as getboolean, getint, and getfloat.&lt;/p&gt;
&lt;p&gt;If you can’t find what you need in the Python standard library, chances are that someone else has already written what you need. A quick Google* search typically returns multiple choices for a specific tool. Python-Twitter is a good example of a helper library to accomplish the heavy lifting of sending messages to the Twitter service. It’s hosted on Google Code* and even comes with several sample applications.&lt;/p&gt;
&lt;strong&gt;Testing and Debugging&lt;/strong&gt;
&lt;p&gt;You can test code on the Compal MID in several ways. File transfer over a USB port is drop-dead simple and works well.  Optionally, you could attach a USB keyboard to the Compal MID and use the VI editor directly on the device for your editing and the Python interpreter for testing. This method works okay for small proof-of-concept efforts but gets out of control for anything but small, simple programs. Another, similar approach is to use Virtual Network Computing* (VNC) to remotely view the screen on the device through your workstation.&lt;/p&gt;
&lt;p&gt;Another way is to use the emulator approach.  The Moblin* project has a tool called the Moblin Image Creator* (MIC) for building platform-specific images. With MIC you can also use the Xephyr* emulator tool to launch an independent session for testing purposes. This method has the advantage of a rapid build / test cycle to help work the bugs out of your code in short order.&lt;/p&gt;
&lt;p&gt;A final way might be to test the initial version of the software on your Linux* desktop.  The advantage is that you don’t need MIC.  The disadvantages are that you may need additional hardware for your desktop (GPS, for example) and that you can’t test MID specific functionality (such as screen characteristics).&lt;/p&gt;
&lt;p class="sectionHeading"&gt;Lessons Learned&lt;/p&gt;
&lt;p&gt;Don’t get bogged down in the details too early in the process. It’s important to completely flesh out your requirements in the beginning, then make some design decisions based on a clear picture of what you’re trying to accomplish. Get comfortable with your development tools—especially the debugging portion—as you’ll probably use them more than you think.&lt;/p&gt;
&lt;p&gt;The easier it is for you to test and debug your code, the quicker you’ll get it running.&lt;/p&gt;
&lt;p&gt;Have a convenient way to transfer files to your device that doesn’t require a lot of motion. This could be as simple as keeping an easily accessible USB cable plugged into your workstation. When you get down to squashing bugs, it helps to make the process as smooth and painless as possible, especially if you’re editing all the code on a workstation and have to move it over to the device for testing.&lt;/p&gt;
&lt;p class="sectionHeading"&gt;Summary&lt;/p&gt;
&lt;p&gt;Building a solid application for the MID platform requires the same set of disciplined steps you would use in any software project. Be sure you don’t skip steps like these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take your time on the design process, and consider alternatives.&lt;/li&gt;
&lt;li&gt;Think through the UI design from a user’s perspective before you start coding.&lt;/li&gt;
&lt;li&gt;Write your code with testing in mind.&lt;/li&gt;
&lt;li&gt;Have a clear set of requirements that you can test.&lt;/li&gt;
&lt;li&gt;Use tools such as source code control, and check in your code frequently.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;p class="sectionHeading"&gt;About Author&lt;/p&gt;
&lt;p&gt;Paul Ferrill has been writing in the computer trade press for more than 20 years. He got his start writing networking reviews for PC Magazine on products like LANtastic and early versions of Novell Netware. Paul holds both BSEE and MSEE degrees and has written software for more computer platforms and architectures than he can remember.&lt;/p&gt;
&lt;br /&gt;&lt;span class="sectionHeading"&gt;&lt;br /&gt;Link to Part 1 of this series&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration/"&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Tools, Choices, and Development Environment Configuration&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/jEbC6933hsg" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/jEbC6933hsg/developing-for-mobile-internet-devices-part-2-designing-coding-and-testing-a-twitter-location-based-application</link>
      <pubDate>Tue, 05 May 2009 11:05:45 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-2-designing-coding-and-testing-a-twitter-location-based-application#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-2-designing-coding-and-testing-a-twitter-location-based-application</guid>
      <category>Mobility</category>
      <category>Intel® Atom™ Software Developer Community</category>
      <category>MID</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-2-designing-coding-and-testing-a-twitter-location-based-application</feedburner:origLink></item>
    <item>
      <title>Developing for Mobile Internet Devices, Part 1: Tools, Choices, and Development Environment Configuration</title>
      <description>&lt;strong&gt;By Paul Ferrill&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Developing applications for Mobile Internet Devices (MIDs) requires a new mindset on the part of developers. While it is possible to take an existing application and port it to a MID, it probably will not work well without some tweaking. Building a new application from the ground up to take advantage of MID features opens a world of possibilities.&lt;br /&gt;&lt;br /&gt;Targeting a specific MID might limit the usefulness of the application. It makes a lot more sense to build in platform awareness for things like display size, network connectivity, Global Positioning System (GPS) availability, and storage. This will take a little extra coding but should make for a much more robust application. It will also make the code work on more platforms.&lt;br /&gt;&lt;br /&gt;Making the right choices when it comes to programming language, support libraries, and user interface (UI) will determine the overall success of the project. Most open source projects typically start out as a pet project written in someone's favorite language or as an exercise to learn something new. For this article series, I use the Python language and attempt to keep the supporting libraries to a minimum.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeadingText"&gt;Hardware Possibilities&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The current crop of MIDs, based on the Intel® Atom™ processor, provides a combination of CPU power, graphics performance, and memory not previously available in small devices. When you add in GPS, Wi-Fi, and 3G connectivity (on some models), you have the potential for a truly always-connected device capable of delivering precision location information. This combination of hardware functionality opens up a whole new world of possibilities for applications.&lt;br /&gt;&lt;br /&gt;This series of articles uses the Compal* JAX10 MID as the target platform. It is based on an 800-MHz Intel® Atom™ processor with 512 MB of memory, 4 GB of solid-state disk configured as two 2-GB devices, two built-in cameras on the front and back for video conferencing and taking pictures or video, GPS, Bluetooth* technology, and 802.11b/g Wi-Fi. The model tested did not have 3G wireless installed.&lt;br /&gt;&lt;br /&gt;Powering up the Compal* JAX10 MID reveals the Midinux* operating system from Red Flag Software. A version of Moblin* specifically for the JAX10 is available from &lt;a href="http://www.moblin.org" target="_blank"&gt;Moblin.org&lt;/a&gt;. It requires a bit of tweaking to get the touch screen and wireless to work, but it is doable. One other option is Ubuntu* Mobile and Embedded (UME), although it is based on an older version of Ubuntu.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;UI Constraints and Choices&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One of the problems developers inevitably face with small form factor devices is in designing the right UI to be both visually appealing and finger functional. Crafting a small-screen UI is one of the most important things you have to take into consideration when developing for the MID form factor. The Compal JAX10 MID has a display size of 800 × 480, which can chop off the lower portion of some fixed-sized dialog boxes.&lt;br /&gt;&lt;br /&gt;Choosing a flexible and easy-to-use UI foundation library helps keep your development struggles to a minimum. Which library you select depends a great deal on the type of application you're looking to build. The &lt;a href="http://www.gtk.org/" target="_blank"&gt;GTK+* framework &lt;/a&gt;comes as a standard part of both Midinux and Moblin, so you won't have to include or require any additional libraries should you choose to go that route. Moblin has also decided to standardize on &lt;a href="http://clutter-project.org/" target="_blank"&gt;Clutter*&lt;/a&gt; for graphics-intensive applications.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Development Environment&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Although you could do the development work on either a Windows* or Linux*-based computer, it really makes the most sense to use a Linux system for a number of reasons. The build-test-build cycle goes more quickly when you run on the same operating system. The only exception might be when using a language like Python* that doesn't really require compilation. In addition, Linux target device emulation has the best support from the Linux operating system.&lt;br /&gt;&lt;br /&gt;Choosing a stable, popular distribution like Ubuntu makes it easier to get the tools you need up and running quickly. It also increases your chances of finding help for problems you might run into, as more often than not, someone else has already found a solution. Ubuntu is also one of the distributions-along with Fedora* 9-directly supported by the Moblin project. We chose Ubuntu 8.10 to use on our development system for this project.&lt;br /&gt;&lt;br /&gt;Consider using a fairly recent computer with hardware virtualization support as your primary machine. Some of the virtualization software packages require hardware virtualization support to work properly. Others will work without it but obviously run faster if the support is available. You should max out your memory, as well, although a 32-bit machine can't really use more than 3 GB.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Developer Tools&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Most seasoned developers have a preferred set of tools they feel most comfortable using. For many in the open source world, this toolset equates to Eclipse* and some number of add-ins. Although Eclipse was built on Java* technology and counts Java developers as its largest user base, it does support other languages quite well. Nokia* uses Eclipse as the foundation of its developer tools to deliver a high-end experience complete with emulation and target device deployment for the Nokia* N810 family of devices.&lt;br /&gt;&lt;br /&gt;Anjuta* is another integrated development environment (IDE) with a substantial following. Anjuta is written in the C language and uses C for its application programming interface (API) and plug-in architecture. It does provide decent support for both C++ and Python, as well. Support for other languages, including C#, is in the works. Of particular interest to UI designers is the integrated Glade* tool, with tight support for editing and creating Glade files.&lt;br /&gt;&lt;br /&gt;Intel has a number of open source tools available to developers serious about squeezing the most out of their applications. New power-management profiling tools make it possible for developers to determine exactly how much power individual pieces of their code consume. The &lt;a href="http://software.intel.com/en-us/articles/application-energy-toolkit/"&gt;Application Energy Toolkit &lt;/a&gt;evaluates applications to determine how "power aware" they are. Versions for Windows, Linux, and Mac OS* X version 10.5 Leopard are available. Specifically for mobile developers, the Intel® Mobile Platform Software Development Kit (Intel® Mobile Platform SDK) offers a number of different tools to facilitate building "mobile aware" applications.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Emulation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One of the best ways to test your software without actually loading it onto the target device is through emulation. A number of emulation tools work only in the Linux environment. Red Flag* Software uses Xnest* in conjunction with chroot in its SDK for Midinux, which makes it possible to run in virtually the same environment you would be running on the target device. For our purposes, there's a how-to on the Red Flag site for configuring its SDK to work with Xnest.&lt;br /&gt;&lt;br /&gt;The Moblin project uses a similar approach with its Moblin Image Creator* (MIC) tool. This graphical user interface (GUI) application helps you create a target Moblin image for a specific platform, then test it by using Kernel-based Virtual Machine* (KVM). MIC can also build VMware* VMDK* images for use with VMware's player application, which gives you the option of running completely inside a virtual environment without making any modifications to your host machine.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Getting Started&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The best place to start with any project is the beginning. Developing a set of requirements that meet your goals helps determine the overall direction of the project. Even if the project is fairly simple, it always helps to write down what your application will do. For this effort, I focus on an application that will take advantage of a number of the MID features, including the GPS and Wi-Fi connectivity.&lt;br /&gt;&lt;br /&gt;It's a good idea to go through the process of creating the typical "hello world" application after you have your development environment configured to your liking. This might seem like a trivial exercise, but it confirms your ability to build your code then deploy it to your target platform. It might also help you think through how best to automate the process to save time in the future.&lt;br /&gt;&lt;br /&gt;Be sure to enable Secure Shell (SSH) on the target platform to make it possible to enter commands remotely. For the JAX10 notebook, you must type a command in a terminal window on the device to start the SSH daemon. Launching a terminal window requires you to press the Fn and P keys simultaneously (Function P), which brings up a prompt similar to this:&lt;br /&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;[root@CompalMID~]#

To start the SSH daemon you must type:

[root@CompalMID~]# /etc/init.d/sshd start

You should see:

Starting sshd:  								[OK]
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;When that's done, you'll be able to use an SSH client tool to connect remotely to the device. You need the IP address to connect: You can find that information with the &lt;span style="font-family: courier new;"&gt;IFCONFIG&lt;/span&gt; command.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Avoid Common Problems&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Don't get bogged down in the details too early in the process. Trying to write code to accomplish a task you don't understand well is not a good idea. Reading the documentation and studying example source code for any library or packaged code you choose to use could actually save you time in the long run. Reading through forums or old IRC logs can help answer questions and provide some insight as to how others have approached similar problems in the past.&lt;br /&gt;&lt;br /&gt;Don't be afraid to build small "proof of concept" applications to figure out how something works-say, how to connect to the GPS or how to properly size a button based on the display dimensions of the device. Look for other code that accomplishes the same thing. Don't be too proud to learn from someone else's work. The Python community has a large body of code to do just about anything you can think of. You can find a wealth of searchable code examples on the &lt;a href="http://code.activestate.com/recipes/langs/python/" target="_blank"&gt;ActiveState Python Cookbook&lt;/a&gt; site.&lt;br /&gt;&lt;br /&gt;Do use some type of source control system for tracking revisions and keeping your source code backed up. It's a good idea to either use a hosted service or run the main source code repository on separate machine from your development computer. Then, you'll always have a way to recover should something happen to that machine. Concurrent Versions System* (CVS) has been around forever, while Subversion* (SVN) and Git* are more recent possibilities.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Summary&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Building software applications for the MID platform requires a new mindset and a good set of tools to do the job right. Keep these things in mind when starting out:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Choose a good IDE that you're comfortable with.&lt;/li&gt;
&lt;li&gt;Use a popular Linux distribution like Ubuntu for the operating system of your development computer.&lt;/li&gt;
&lt;li&gt;Don't skimp on your development hardware, and do get a machine with a recent processor and ample memory.&lt;/li&gt;
&lt;li&gt;Use good software development practices, like gathering requirements and using a source code control tool.&lt;/li&gt;
&lt;/ul&gt;
&lt;span class="sectionHeading"&gt;About the Author&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Paul Ferrill has been writing in the computer trade press for more than 20 years. He got his start writing networking reviews for PC Magazine on products like LANtastic and early versions of Novell Netware. Paul holds both BSEE and MSEE degrees and has written software for more computer platforms and architectures than he can remember.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;&lt;br /&gt;Link to Part 2 of this series&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Designing Code and Testing (coming soon).&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/A8v1AqfsVKA" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/A8v1AqfsVKA/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration</link>
      <pubDate>Tue, 05 May 2009 10:45:26 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration</guid>
      <category>Mobility</category>
      <category>Intel® Atom™ Software Developer Community</category>
      <category>MID</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/developing-for-mobile-internet-devices-part-1-tools-choices-and-development-environment-configuration</feedburner:origLink></item>
    <item>
      <title>An Edge By Design for MID Applications</title>
      <description>&lt;em&gt;Design research and design-driven best practices can help your application development get an edge.&lt;br /&gt;&lt;br /&gt;By Knut Graf.  Knut is a Principal Designer at &lt;a href="http://www.frogdesign.com/" target="_blank"&gt;frog design&lt;/a&gt;, a global innovation firm. &lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Abstract&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The Mobile Internet Device (MID) platform has to establish a following of users and a set of high quality applications, which presents a kind of chicken and egg challenge. The lack of a track record to refer to, along with other factors that are common to emerging platforms, makes application development on MIDs challenging. Yet, high-quality applications are critical to the platform's success. Design, as expertise and as a set of practices, can address many of the risk factors that characterize this situation.&lt;br /&gt;&lt;br /&gt;Design ensures that the product vision is relevant to the user by gathering knowledge about the user and the application's usage environment through informal discovery activities and through formal research. Based on the knowledge gained in this discovery phase, a crisp feature definition lays the groundwork for a great user experience, which is built out through a compelling look and feel. A prototype confirms the product vision amongst team members and guides implementation and testing, thereby reducing the need for lengthy and tedious traditional requirements documentation.&lt;br /&gt;&lt;br /&gt;The guidance and streamlining that design brings to an application development process allows the core development team members to devote proper amounts of attention to technical challenges and quality, greatly improving the odds that the project will be completed and successful.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The software industry has established a track record over the last few decades of slowly making its development practices more efficient and effective. Even so, software projects are still burdened with high failure risks. The quality of projects that make it to market is hard to predict. For example, in consumer-facing applications, for every well-rounded product, there is another one full of bugs and quirks. Properly introducing "design" into a software project is one way to increase its odds of success.&lt;br /&gt;&lt;br /&gt;Many processes and best practices address risk and quality concerns in software projects. In practice however, such practices compete with established habits and the temptation to take shortcuts.&lt;br /&gt;&lt;br /&gt;Design has a variety of effects. Approached naively, design can raise expectations and then confuse and complicate the actual process, inundating unprepared developers with distractions and implicit requirements. On the other hand, a proper approach to harnessing design for software development can ensure that the end product is both relevant and beautiful. Along the way, the collaborative aspects of design process can align stakeholder's expectations and even save development time by using prototypes to communicate project goals.&lt;br /&gt;&lt;br /&gt;Design - whether it be "Interaction Design," "User Interface Design," or "Experience Design" - is not retrofitting a screen with pretty graphics. Applying design to an existing project provides limited value. Design in software development is much more valuable when applied as a way to discover, refine, and execute proper success criteria.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Addressing the MID Form Factor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Mobile Internet Device, or MID, is a low-power mobile device with many of the capabilities of a full PC. It employs a small, high-resolution touch screen and a reduced keypad. The MID platform provides unique new usage opportunities and advantages that translate into an exciting new market opportunity. MIDs offers new capabilities in terms of computing power, display quality, touch-input quality, and connectivity, along with a high amount of energy invested in the software tools. &lt;br /&gt;&lt;br /&gt;The way the platform's promise translates into value to the end user is through the software running on it. Software turns abstract capabilities into user-facing features. Software applications will decide the fate of the platform: Compelling usefulness will give mobile internet devices a place in our everyday lives, bringing success to the platform. Falling short, MIDs will join our Palm* Pilots in the gadgets drawer, awaiting their fate at the next garage sale.&lt;br /&gt;&lt;br /&gt;The platform's promise does not guarantee success. MIDs faces some specific challenges in terms of application development - challenges that design can help address.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Thinking Small&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;With or without all the power delivered by a MID, the small device form factor limits the gamut of interactions that people will want to engage in. Comparing the same task on a small device and a large device, the small device requires more dexterity and concentration from the user. Simplifying tasks for small devices means challenging the user's habits and expectations.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Lean Teams&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The limited out-of-the-gate user base constrains the economically sensible investment to be made. Development teams will be lean and schedules will be short, even as the application development community is still familiarizing itself with the MID development environment.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Porting&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Many projects are ported from existing implementations on other platforms. Considerable updates to such projects are often required to allow them to take full advantage of the specific conditions offered by MIDs.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Device Definition&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Smart phones, with ever-growing capabilities, and the booming netbook contest the space for the MID platform. Acceptance for MIDs depends on unique value which neither of these other device classes can offer.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Establishing a Target Design&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In software application development, challenges are not unusual. Any software development project, regardless of the platform, comes with challenges. The way to mitigate the risk associated with these challenges is to decide upon a focused, valuable target, and to stay on this target. &lt;br /&gt;&lt;br /&gt;At the heart of a software application is the basic idea, "does it do something useful?" For the application to be successful, the answer must be "yes." A software project starts with existing ideas for specific features, or with general goals. These existing goals are formalized, to arrive at an implementable specification. During this process of formalization, the goals are examined, refined and adjusted.&lt;br /&gt;&lt;br /&gt;The first step towards the feature definition is learning who the end user is, what the end user likes, and what the end user does.&lt;br /&gt;&lt;br /&gt;A certain amount of general knowledge about users can be derived from the MID platform goals as a whole, as well as from interpreting the usage opportunities offered by target devices appearing on the market. Beyond this common sense approach, design provides a set of tools to get a clear picture of the end user and of the opportunities for application usage afforded to the user.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;User Personas&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A user persona provides a description of an imaginary, but specific person who would use the application. A user persona is meant to be realistic and robust. A user persona describes the habits, preferences and environment of the target character, to provide a framework from which the character would make judgments and decisions. The user persona is a conceptual simulator for the practical value of new features.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Idealized Personas&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The practical use of an application is not the only question to consider. An application can be an enabler to the user, providing functionality that is socially attractive and desirable, regardless of its usefulness in a traditional sense. &lt;em&gt;Idealized personas&lt;/em&gt; provide a handle on defining this type of functionality. Idealized personas are traditionally used in the discipline of marketing, not in the more "down to earth" context of usability. Actual people aspire to the attributes the idealized persona embodies. The idealized persona is more sophisticated then a real person, bound by fewer constraints. Some stereotypes might be used to define this persona. The idealized persona provides a sounding board for empowering, uncommon feature possibilities.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Scenarios&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A scenario describes a situation, and a sequence of events, in which the device and the software application running on it are used. The scenario is meant to be realistic, to provide a background to judge the value of the planned application and its features. The more detailed the scenario is, the more it can serve as a source and validation point for specific ideas.&lt;br /&gt;&lt;br /&gt;Other, less standardized forms of documentation can be used as a basis for feature definition. The assumptions and conclusions in any feature documentation can be tested and strengthened by personas and scenarios as verification points.&lt;br /&gt;&lt;br /&gt;Personas and scenarios are speculative in nature: they are based on assumptions. To add a grounding in realism to these assets, we recommend that design research activities be performed. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Mining Reality for Knowledge: Research&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Design research mines real life for project-relevant information. Common methods include surveys, user interviews, and contextual inquiry, in which the researcher engages with a user one-on-one to observe activities. Ranging from simple to very involved, the value of the research results grows with the depth of user-engagement. &lt;br /&gt;&lt;br /&gt;Design research requires preparation time and careful analysis of data. The schedule impact must be weighed against the benefits to the project. Consider that often the benefit is a drastic reduction of risk. &lt;br /&gt;&lt;br /&gt;For applications that provide narrow specialized feature sets for vertical markets, the value of research is fairly obvious: it provides knowledge of the problem domain to the team. For common applications with mass-market, mainstream functionality, the value proposition is more subtle: while the team is familiar with the domain, the deeper examination can provide insights into key differentiators that escape the naked eye.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Generating the Design&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Equipped with a picture of a target user, and solid knowledge of the real-world context, designers unearth feature opportunities for the application. Some opportunities will be obvious from looking at a scenario. Interpreting research data and applying abductive reasoning to the problem space knowledge uncovers further opportunities.&lt;br /&gt;&lt;br /&gt;Designers define features by mapping the opportunities and constraints to an actual software structure. To arrive at valid results, design principles are applied to guide this exercise. In absence of specific native design principles for MID devices, proven design principles from other small platforms can be used.&lt;br /&gt;&lt;br /&gt;The actual feature definition is expressed as a vision of the resulting program, and this is done in the form of diagrams, wireframes, and visual mock-ups. Abstract features are given a concrete expression. This documentation provides a moment of truth for project stakeholders. It serves as the first concrete shared picture of "the design" and a glance at the project outcome. As the project continues, collaborative discussions will adjust this picture. &lt;br /&gt;&lt;br /&gt;The design addresses core features first, and then it takes on secondary features such as peripheral details. One after another, parts of the application get addressed, designed, documented, designed and adjusted.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Design Principles for Mobile Platforms&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;For relevance to the MID form factor, Table 1 lists a set of design principles that are relevant and apply to mobile platforms.&lt;br /&gt;&lt;br /&gt;
&lt;table class="tableformat1" border="0" cellspacing="0" cellpadding="10"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;Mobile Platforms Design Principal&lt;/td&gt;
&lt;td valign="top"&gt;Description&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Immediate Results&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;Small, mobile devices offer themselves to be used spontaneously, whenever opportunity beckons. Such an opportunity for using the device, especially when occurring in a mobile situation, may not last long, as other things compete for the user's attention. To ensure a successful user experience, the application accessed by the user must waste no time in providing results. The tasks offered by the application must be straightforward, leading to immediate results. Long sessions that require continuous user attention are better suited for a full-size PC.&lt;br /&gt;&lt;br /&gt;The home screen application of the HP* Mini 1000 MI (Mobile Internet) Edition netbook is an example for focus on immediate results. The HP MI Edition is the Linux* version of this product. Its home screen accumulates recent e-mail, web shortcuts and thumbnails for favorite music and photos. The traditional "launch and dig" sequence to get to content is eliminated. In contrast to this approach, most other netbooks just offer collections of program icons on their home screen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Adequate Feature Density&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;Besides being short, the path to results must also be obvious. Few users will tolerate forced way-finding exercises. Given the constrained screen real-estate, this principle is applied by carefully designing decision trees to present clear decision points, and by limiting the amount of inputs asked of the user. Full-size PC applications have more leeway for less-clear structure. Feature density is an important consideration especially when porting existing full-size applications to a MID.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Adequate Information Density&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;While the small, high-resolution screen is a brilliant display, it is still, and foremost, simply small. The number of concurrently displayed content items should be more limited, to avoid intolerably microscopic text and graphics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;Since not every interaction can be reduced to a few buttons on a few screens, the user will inevitably spend time completing non-trivial tasks. Those tasks may be necessary sequences, such as forms that must be filled, or voluntary sequences, such as meandering through a media library. In either case, the immersion that is achieved by presenting a steady stream of simple choices, creates a level of comfort. The immersion must not be interrupted trivially by modal alerts or dead-end flows. This is a general design principle, but on a small form factor platform, the temptation to present such interruptions is higher then on full-size PC applications, because fewer opportunities are available to communicate secondary information in more subtle ways.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Interruptability&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;It is a common full-size PC experience ritual to launch an application, and then to open a document, or to perform some other initiation procedure, before getting to the actual task at hand, and to save and quit the application when done. On a MID device, where application state management is not on the user's mind, and usage session durations are short, this ritual gets in the way. Dealing with any sort of sequential task becomes more feasible, even attractive, once it is possible to effortlessly "Pick up where you left off".&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;&lt;strong&gt;Progressive Disclosure&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top"&gt;Progressive disclosure, the hiding of secondary information on secondary screens, is a well-known, valuable design principle. Applied to a MID, it can be read slightly differently: high density of information, as encountered in an existing PC application, can be preserved, behind lower-density summary screens, when the application is ported to a MID. Such summary screens, presented as the initial entry points of an application, provide the right small-device scale and satisfy many scenarios. More traditional, higher-density screens underneath, can provide unexpected horsepower for full-featured PC functionality. Handled with care, progressive disclosure is a valuable principle for porting existing applications to MIDs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;&lt;strong&gt;Table1: Design Principals for Mobile Platforms&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Look and Feel&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Expressing features as parts of a software application is not a mechanical procedure. It’s a subjective process, in which the designer makes personal decisions. As a result, the application gains a unique personality. This personality is expressed in the “look and feel,” which has a great impact on shaping the user experience. The user experience — literally the string of moments the user lives through while interacting with the product — determines the user's memory and judgment about the device.&lt;br /&gt;&lt;br /&gt;Look and feel ensures usability through design patterns that string user-facing objects together in ways that make sense. These patterns are reused across the application, providing comfort and predictability.&lt;br /&gt;&lt;br /&gt;Look and feel is concerned with the details of the experience: the central moments when the user pays detailed attention, and those less important moments that lie in between and help string the important ones together. All these moments benefit from the beauty of well-executed emphasis and guidance, through visual means like composition, contrasts and harmonies on a pixel level.&lt;br /&gt;&lt;br /&gt;The user’s experience of an application is shaped over time, as the application changes state during use, bringing up one screen after another, or updating the content that is shown on the screen. This temporal aspect of the experience is part of look and feel too. It can be shaped to provide a good flow, actively help the user with tracking the application’s state, through meaningful transitions.&lt;br /&gt;&lt;br /&gt;Iconic examples of strong, experience-shaping look and feel are the “Fluent” interface of Microsoft* Office 2007, or the category-defining appearance of the Adobe* Lightroom application. Such strong statements can be controversial at first, as they force users to jettison old habits. But they usually establish a following and invite imitations.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Implementation Complexity as a Concern&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;While working on the ‘look and feel’, the designer must be aware of the implementation platform, and its constraints and opportunities as they relate to the user interface. For MIDs, Hildon* is the primary choice platform, and it has some very specific characteristics. It cannot be emphasized enough that the design must be implementable on the given platform, by the developers tasked with the job, in the timeframe available.&lt;br /&gt;&lt;br /&gt;To avoid surprises, it is essential that the actual development team members who are responsible for the UI execution provide their perspective to the designer during the look and feel work. A professional designer is prepared to listen.&lt;br /&gt;With a design team on board, there usually is a temptation to go for a totally custom UI, to maximize usability, beauty, flow, and branding. These are noble intentions, but must be checked against the realities of schedule- and resource constraints. A simpler look and feel that is actually executable might be a better way to go. After all, the measure of success is the real product that makes it to market.&lt;br /&gt;&lt;br /&gt;To ensure that the project is on track, the design must be truly understood by all stakeholders. A particular asset can communicate the design much better then any combination of diagrams, wireframes and specification documents: the prototype.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Expressing Living Features: A Prototype&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As the regular implementation preparation proceeds, a design team can provide a valuable contribution typical project constituents can’t — a prototype. A developer, sometimes called a design technologist, puts the prototype together. This prototype shows core moments and aspects of the application. The ideas shown are those of the project team as a whole, as captured from the stakeholders. The design team shapes these ideas, infusing them with a user-facing structure that eventually evolves into a coherent look and feel. The main value of a prototype is its ability to play out concurrent changes from multiple separate angles of the project. Valuable time can be saved this way, and the project team can cover a lot of ground in the process. &lt;br /&gt;&lt;br /&gt;The prototype is an antidote to analysis paralysis. Application structure, functionality, and look and feel come together as a unit and are refined together. The in-progress result is visible to the entire team, serving as a validation point. The aspect of validation can be taken further, by presenting the prototype to users, who provide both usability feedback and emotional responses, without the need for preparation of additional test assets.&lt;br /&gt;&lt;br /&gt;The prototype neither has to be perfect nor complete, as long as it provides meaningful insights. Bugs and dead ends are allowed and expected, so the developer can focus on relevant details.&lt;br /&gt;&lt;br /&gt;As the prototype is built out, it takes on the role of a living specification, replacing much of the traditional specification documentation that otherwise must be written and maintained. Traditional specifications still play a supporting role, filling in detail for areas that the prototype doesn’t cover. The application developers refer directly to the prototype as a reference for the implementation. The QA team can do the same, informing a traditional QA process by referencing the prototype, bringing efficiencies to the testing process.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;To Do This, Do You Need a Designer?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The answer to the above question is, “it depends.” Do you have enough knowledge of your problem space to perform a well-grounded feature definition? Do you have the time to take care of the details for a good follow-through? Will your stakeholders take care of this for you?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Common Sense…&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It is evident that not every good piece of software is produced with the involvement of a dedicated designer or design team. Much useful work, in terms of crisp feature definition and high execution quality, can be done by “simply” assuming a design perspective.&lt;br /&gt;&lt;br /&gt;This reliance on common sense thrives when a self-motivated developer is driving the work and making her own decisions, within a manageable scope of work. But the efficiency of this approach does drop off, experience suggests, as the complexity of the challenge grows and more stakeholders come to the table. This is not at all a matter of malevolence by any stakeholder: all parties do want the best outcome. It is more a matter of entropy: as more perspectives and opinions come into play, more forces are at work. In such a situation, any perspective that is not formally represented will not be heard. Ask yourself: who is representing the end user?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;…And Addressing Complexity&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;As project size increases, the complexity of the design-addressable challenges also grows, quickly reaching a point where common sense falls short. Here, the benefits of a professional perspective become obvious. Just as the development team should not be handling accounting on the side, it is not in a position to be handling design. The design team’s role is not meant to weaken other project contributors design ideas. On the contrary, the design team synthesizes everyone’s contributions, amplifying the good ones. This synthesis is essential when many different perspectives need to be heard. On large projects without formal design participation, design will go wrong.&lt;br /&gt;&lt;br /&gt;Engaging a design team can bring otherwise unattainable results to a software project: a unique execution, with an outstanding look and feel. This can turn out to be the single, critical differentiator in the marketplace. &lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;Change the Odds&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Full-size desktops and laptops have long given up their position as the only form factors for personal computing. After small form factors had been pioneered by the PDA, the mobile phone matured to provide ad-hoc information access and media consumption. The laptop as sole choice for mobile content creation and productivity has made room for the netbook, its smaller, less powerful sibling. Each of these form factors thrives on useful, attractive software. That’s evident when you consider the variety of software being used on near-identical hardware. &lt;br /&gt;&lt;br /&gt;The MID form factor is in a position to be the next step in this march of personal computing to ubiquity. New form factors start as an underdog. To fuel their possible success, great applications first have to be created, under developmental conditions that are more challenging than those on established platforms. As the software industry comes to terms with the platform, design can make a contribution to the quality of individual software experience offerings, which is what counts most at the current moment in the lifecycle of the platform.&lt;br /&gt;&lt;br /&gt;&lt;span class="sectionHeading"&gt;About the Author&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Knut Graf is a Principal Designer at &lt;a href="http://www.frogdesign.com/" target="_blank"&gt;frog design&lt;/a&gt;, a global innovation firm. Frog Design* works with the world’s leading companies, helping them create and bring to market meaningful products, services, and experiences. Knut joined frog in 1997 and has since served as Developer, as Content Architect and as Senior Design Analyst before assuming the role of Principal Designer. Knut has worked with clients such as SAP*, Microsoft*, and HP*. His recent work includes contributing to the well-received HP Mini 1000 MI edition user interface as a design lead on the project.&lt;br /&gt;&lt;br /&gt;Knut's work focuses on software user interfaces, from idea development to implementation. He guides software designs through the time- and resource constraints that real-world software projects bring, ensuring that the user experience of the end product is of the highest quality possible.&lt;br /&gt;&lt;br /&gt;In his work, Knut brings a programmer’s view of software development to a German design education background, to create innovative solutions that empower both the end user and the development team that has to meet shipping deadlines. In Knut’s opinion, design work must be judged by the quality of the end product. It is the actual result that matters, not the unrealized potential.&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/oSetxQrX3aQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/oSetxQrX3aQ/an-edge-by-design-for-mid-applications</link>
      <pubDate>Thu, 30 Apr 2009 17:16:02 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/an-edge-by-design-for-mid-applications#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/an-edge-by-design-for-mid-applications</guid>
      <category>Mobility</category>
      <category>Intel® Atom™ Software Developer Community</category>
      <category>MID</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/an-edge-by-design-for-mid-applications</feedburner:origLink></item>
    <item>
      <title>Obtaining Display Information on Mobile Internet Devices</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1 class="sectionHeading"&gt;Introduction&lt;/h1&gt;
&lt;br /&gt;With the advent of Mobile Internet Devices (MIDs) based on Intel® Architecture, the porting of desktop and laptop applications to mobile hand-held devices has become significantly easier. However, one area of continued challenge is the adapting of screen layout and user-interface navigation to this small form factor. These devices have a screen size that ranges from 4.5" to 7" and a resolution of at least 800 x 480 pixels. Device characteristics of increased pixel density, combined with the ability to rotate between landscape and portrait orientations, and the strict display brightness constraints necessary to preserve battery power, make it essential for compelling software to be aware of the device's display attributes. Ideally an application will obtain this information at runtime in order to dynamically adapt. &lt;br /&gt;&lt;br /&gt;Since MID devices run Moblin-based, Linux operating system, this paper will describe several mechanisms for obtaining display information in a Linux compliant manner. Unfortunately, all display information isn't available from one easily accessible source, so this document will cover the various sources of screen information. The X Window extension &lt;em&gt;X Resize and Rotation (XRandR)&lt;/em&gt; is a good source for resolution and screen orientation. Physical screen dimensions are also available through the XRandR API but accuracy of this particular information is dependent upon screen drivers providing accurate EDID values. Another source of information is the Hardware Access Layer (HAL). This component exposes a wide range of system information; the properties of interest in this context are screen brightness and the levels of brightness. These pieces of information, as well as other platform and context information, can also be retrieved using the Platform Awareness Service, available from Intel® on Moblin based platforms.&lt;br /&gt;&lt;br /&gt;Getting Display Information from XWindows&lt;br /&gt;&lt;br /&gt;The X11 library is designed to provide a connection to the X Server. It allows access to size and rotation information about the root window of the screen and also provides the ability to set these values.&lt;br /&gt;&lt;br /&gt;In order to get to the resolution information, several preliminary calls need to be made to connect to the X Server and get to the desired data structure. First, a call to &lt;em&gt;XOpenDisplay()&lt;/em&gt; connects to the X Server and returns a Display pointer. The X11 architecture allows for multiple Windows, with the root window being the one that holds the information we want. A call to &lt;em&gt;RootWindow()&lt;/em&gt; will return this window. Once the display is opened and the Root Window is obtained the third call can be made to &lt;em&gt;XRRGetScreenInfo()&lt;/em&gt; which returns an &lt;em&gt;XRRScreenConfiguration&lt;/em&gt; structure.
&lt;pre name="code" class="cpp"&gt;#include &lt;br /&gt; &lt;br /&gt;Display *dpy;&lt;br /&gt;Window root;&lt;br /&gt;XRRScreenConfiguration *sc;&lt;br /&gt; &lt;br /&gt;dpy = XOpenDisplay (NULL); //open the current display&lt;br /&gt;if (dpy) &lt;br /&gt;{&lt;br /&gt;      root = RootWindow (dpy, 0);    &lt;br /&gt;      sc = XRRGetScreenInfo (dpy, root);&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;After the &lt;em&gt;XRRScreenConfiguration&lt;/em&gt; structure is obtained it can be used to make the call that actually returns the resolution information. X11 allows for the possibility of an array of sizes of which the first represents the current display. A call to &lt;em&gt;XRRConfigSizes(),&lt;/em&gt; passing in the &lt;em&gt;XRRScreenConfiguration&lt;/em&gt;, will return this array. Each element of the array contains a &lt;em&gt;width&lt;/em&gt; and &lt;em&gt;height&lt;/em&gt; value.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;XRRScreenSize *sizes;&lt;br /&gt;unsigned int nsize;&lt;br /&gt;unsigned int xres, yres;&lt;br /&gt; &lt;br /&gt;sizes = XRRConfigSizes (sc, &amp;amp;nsize);&lt;br /&gt; &lt;br /&gt;if (0 &amp;gt;= nsize)&lt;br /&gt;{&lt;br /&gt;      xres = sizes[0].width;&lt;br /&gt;      yres = sizes[0].height;&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The physical dimension of the screen can be obtained directly from the &lt;em&gt;XRRScreenConfiguration&lt;/em&gt; structure via the screen member. It should be noted however that the accuracy of this information is dependent on the screen driver providing correct values from the display device's Extended Display Identification Data (EDID) block[1]. At the time or this writing the display devices on a number of publicly available MIDs do not provide correct information.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;// Physical dimensions&lt;br /&gt;         &lt;br /&gt;int mwidth, mheight;&lt;br /&gt; &lt;br /&gt;mwidth = sc-&amp;gt;screen-&amp;gt;mwidth;&lt;br /&gt;mheight = sc-&amp;gt;screen-&amp;gt;mheight;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The other interesting display attribute that can be obtained from X11 is the screen orientation. According X11 there are four settings of rotation; 0%, 90%, 180% and 270%. X will also tell you which of the rotations are supported on the current device. A call to &lt;em&gt;XRRRotations(),&lt;/em&gt; passing in the previously obtained Display pointer will return this info as a bit array. The X11 header file defines values that can be used to mask out the supported rotations.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;// Screen Rotation – What rotations are supported&lt;br /&gt;&lt;br /&gt;Rotation rotations_supported, cur_rotation;&lt;br /&gt;bool bRotate_0, bRotate_90, bRotate_180, bRotate_270;&lt;br /&gt; &lt;br /&gt;rotations_supported = XRRRotations (dpy, 0, &amp;amp;cur_rotation);&lt;br /&gt; &lt;br /&gt;if (1 &amp;gt;= rotations_supported) &lt;br /&gt;      return; // Screen rotation not supported&lt;br /&gt;else &lt;br /&gt;{&lt;br /&gt;      if ( 0 != ( rotations_supported &amp;amp; RR_Rotate_0))&lt;br /&gt;            bRotate_0 = true;&lt;br /&gt;      if ( 0 != (rotations &amp;amp; RR_Rotate_90))&lt;br /&gt;            bRotate_90 = true;&lt;br /&gt;      if ( 0 != (rotations &amp;amp; RR_Rotate_180))&lt;br /&gt;            bRotate_180 = true;&lt;br /&gt;      if ( 0 != (rotations &amp;amp; RR_Rotate_270))&lt;br /&gt;            bRotate_270 = true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The cur_rotation variable that was passed to XRRRotations() specifies the current rotation. Again the X11 header file defines values used to interpret the current rotation value.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;switch (cur_rotation) &lt;br /&gt;{&lt;br /&gt;      case RR_Rotate_0:&lt;br /&gt;            ...&lt;br /&gt;            break;&lt;br /&gt;      case RR_Rotate_90:&lt;br /&gt;            ...&lt;br /&gt;            break;&lt;br /&gt;      case RR_Rotate_180:&lt;br /&gt;            ...&lt;br /&gt;            break;&lt;br /&gt;      case RR_Rotate_270:&lt;br /&gt;            ...&lt;br /&gt;            break;&lt;br /&gt;      default:&lt;br /&gt;            return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Finally, cleanup needs to be done to free the &lt;em&gt;XRRScreenConfiguration&lt;/em&gt; struct and close the display.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;XRRFreeScreenConfigInfo (sc);&lt;br /&gt;XCloseDisplay(dpy);&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Getting Screen Brightness information from the HAL&lt;/h1&gt;
&lt;br /&gt;Screen brightness information is not inherently necessary for MID screen layout and navigation. However, since battery power savings is one of the most critical aspects of MID design, screen brightness management becomes an important factor of overall efficient power usage, and an application may wish to modify its behavior or appearance based on screen brightness settings.&lt;br /&gt;&lt;br /&gt;The HAL is a software layer that provides access to various pieces of hardware on a system. Metadata is available describing the hardware, its state and notifications of change. A Device Object with accompanying properties is used to represent each piece of hardware. Namespaces are also defined to group the properties into logical categories. Finally, D-Bus Interfaces are defined as the access mechanism to the properties and notifications within a namespace. For background information on the D-BUS architecture and usage refer to these locations:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.freedesktop.org/wiki/Software/dbus"&gt;http://www.freedesktop.org/wiki/Software/dbus&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://dbus.freedesktop.org/doc/dbus-tutorial.html"&gt;http://dbus.freedesktop.org/doc/dbus-tutorial.html&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php"&gt;http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;To make a D-BUS connection to the HAL, several steps are necessary. First, a pointer to the System Bus is obtained by calling dbus_g_bus_get()[2]. With the system bus pointer, an interface can be obtained to the HAL Manager by calling dbus_g_proxy_new_for_name(). This manager will allow a search for all objects on the system with the "laptop_panel" capability. The object that provides "laptop_panel" capability is where screen brightness information is found.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;DBusGConnection *systemBus;&lt;br /&gt;GError *error&lt;br /&gt;DBusGProxy *managerProxy;&lt;br /&gt;char **deviceList;&lt;br /&gt;int len;&lt;br /&gt; &lt;br /&gt;// Initialize the System DBus connection&lt;br /&gt;systemBus = dbus_g_bus_get(DBUS_BUS_SYSTEM, error);&lt;br /&gt;      &lt;br /&gt;if (systemBus == NULL) &lt;br /&gt;      return FALSE;&lt;br /&gt; &lt;br /&gt;managerProxy = dbus_g_proxy_new_for_name( systemBus,&lt;br /&gt;                              "org.freedesktop.Hal",&lt;br /&gt;                              "/org/freedesktop/Hal/Manager",&lt;br /&gt;                              "org.freedesktop.Hal.Manager" );&lt;br /&gt; &lt;br /&gt;dbus_g_proxy_call(managerProxy, "FindDeviceByCapability", &amp;amp;error, &lt;br /&gt;                              G_TYPE_STRING, "laptop_panel", G_TYPE_INVALID,&lt;br /&gt;                              G_TYPE_STRV, &amp;amp;deviceList, G_TYPE_INVALID);      &lt;br /&gt;len = g_strv_length(deviceList);&lt;br /&gt; &lt;br /&gt;if (len = 0)&lt;br /&gt;      return false;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Now that we have a pointer to the list of laptop_panel objects we can get the interface that directly provides the screen brightness properties (note the following code assumes there is only one screen attached to the system). This is done with the same call used to obtain the HAL Manager but specifies the Device.LaptopPanel interface as the fourth parameter.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;char **devices_ptr;&lt;br /&gt;DBusGProxy *deviceProxy;&lt;br /&gt; &lt;br /&gt;devices_ptr = deviceList;&lt;br /&gt; &lt;br /&gt;deviceProxy = dbus_g_proxy_new_for_name(  systemBus,&lt;br /&gt;                              "org.freedesktop.Hal",&lt;br /&gt;                              *devices_ptr,&lt;br /&gt;                              "org.freedesktop.Hal.Device.LaptopPanel" );&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;To get the current brightness setting, we need to call a method of the LaptopPanel interface called GetBrightness. This is done again with dbus_g_proxy_call function but takes no parameters and returns the brightness as an integer.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;uint brightness;&lt;br /&gt;&lt;br /&gt;dbus_g_proxy_call(deviceProxy, "GetBrightness", &amp;amp;error,&lt;br /&gt;                              G_TYPE_INVALID,&lt;br /&gt;                              G_TYPE_UINT, &amp;amp;brightness, G_TYPE_INVALID); &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Conclusion&lt;/h1&gt;
&lt;br /&gt;By obtaining a few basic pieces of screen display information (resolution, orientation, physical dimensions and screen brightness) an application is poised to adapt efficiently and dynamically to the various MID form factors and their changing display characteristics. With this information in hand, the real work of creating MID optimized UI designs and navigation can begin!&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;References&lt;/h1&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XrandR Project Documentation -&lt;/strong&gt; &lt;a href="http://www.x.org/wiki/Projects/XRandR"&gt;http://www.x.org/wiki/Projects/XRandR&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAL 0.5.10 Specification -&lt;/strong&gt; &lt;a href="http://people.freedesktop.org/~david/hal-spec/hal-spec.html"&gt;http://people.freedesktop.org/~david/hal-spec/hal-spec.html&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[1] For more information see &lt;a href="http://www.vesa.org/Public/EEDIDguideV1.pdf"&gt;http://www.vesa.org/Public/EEDIDguideV1.pdf&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Extended_display_identification_data"&gt;http://en.wikipedia.org/wiki/Extended_display_identification_data&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;[2] This is actually a glib wrapper to the D-Bus function that retrieves the bus. The glib wrapper is used in this discussion because it is less complex than using D-Bus directly.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/NWIUwMooyps" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/NWIUwMooyps/obtaining-display-information-on-mobile-internet-devices</link>
      <pubDate>Wed, 22 Apr 2009 16:34:23 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices</guid>
      <category>Mobility</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices</feedburner:origLink></item>
    <item>
      <title>Moblin Platform Awareness Service</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;div class="sectionHeading"&gt;Platform Awareness Service – An Introduction&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;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 applications that have been built for the x86 architecture, reducing the cost of porting applications to this platform, while significantly expanding integration potential with existing infrastructures. While the features of the devices that are and will be on the market will vary widely, all MIDs have several features in common (some more obvious than others): a low-power Intel® Atom™ processor, a highly variable set of input mechanisms, a touch screen display, multiple radios and network connectivity options, limited battery and storage capacity, and in many cases an onboard GPS. These hardware devices have been exposed to software developers by way of the Platform Awareness Service, a lightweight, read-only, D-Bus initiated platform information provider. Since the final software stack for each device is determined mainly by Original Equipment Manufacturers (OEMs) and Service Providers (SPs), this service may not be pre-installed on Intel® MIDs. Therefore this series of whitepapers has been written in an effort to simplify access to this information on platforms that do not have this service installed.&lt;br /&gt;&lt;br /&gt;Many of today’s traditional web applications are built with a client server architecture where all the processing is done on the server, and the client is only used to display static content. All interaction with the application must be sent as a request to the server, and then a response is formatted and sent back to the client where is it simply rendered in the browser window. In this interaction, the client is somewhat analogous to a terminal. Very little of its resources are being used to contribute to the experience the user is getting. &lt;br /&gt;&lt;br /&gt;Rich Internet Applications (RIAs) represent the next evolution in the traditional web application model. RIAs employ the power of the client to augment the experience by utilizing the processing power that was previously mostly ignored. RIAs are web applications that have the many of the features of traditional desktop applications, as they introduce another layer of processing on the client that handle richer features such as rendering, state management, and storage.&lt;br /&gt;&lt;br /&gt;The functionality of a RIA is only limited by the capabilities of the client. Instead of designing for the lowest common denominator, RIA’s have the opportunity to scale their features and interfaces to match what the client can handle. Awareness of the client’s capabilities therefore becomes critical when determining how to scale an application’s features, or how to present the user interface. The information exposed by the Platform Awareness Service can be used by RIA designers to effectively scale their applications to the next level.&lt;br /&gt;&lt;br /&gt;Whitepapers have been authored introducing developers to each key area previously mentioned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;Utilizing Processor Performance in Rich Internet Applications&lt;/a&gt; discusses the exposure of processor capabilities to developers.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;Determining Input Devices in Linux&lt;/a&gt; discusses input mechanisms.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/preview/obtaining-display-information-on-mobile-internet-devices"&gt;Obtaining Display Information on Mobile Internet Devices&lt;/a&gt; covers device displays.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;Detecting Network Connectivity Using D-Bus&lt;/a&gt;, network connectivity.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;Developing Power Aware Applications Using D-Bus&lt;/a&gt;, enables application awareness of device power states.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;How to Obtain Storage Information in Linux&lt;/a&gt; addresses storage capacity.&lt;/li&gt;
&lt;li&gt;Last but not least, &lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;How to Obtain Location Information in Linux&lt;/a&gt; covers integration of location-based information into your applications utilizing the GPS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A quick API reference is available in: &lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;Platform Awareness Service: D-Bus Interface Definition&lt;/a&gt;. Finally, the &lt;a href="http://software.intel.com/file/15880"&gt;Platform Monitor&lt;/a&gt; sample application has been included in the package, clearly demonstrating syntax and usage of the Platform Awareness Service API. Full documentation for this tool is available in the: &lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;Platform Monitor User’s Guide&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;As always, feedback is greatly appreciated and will aid development of upcoming releases. Feel free to submit a comment to the Intel® Software Network, or alternatively send an e-mail to either jeremy dot saldate at intel dot com or clayne dot robison at intel dot com. Happy coding!&lt;/p&gt;
&lt;div class="sectionHeading"&gt;&lt;br /&gt;Further Research&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;br /&gt;API Reference &lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Information about how to use the &lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;Platform Awareness Service DBus Interface&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;Sample Applications&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15880"&gt;Platform Monitor&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;Platform Monitor User Guide&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;Source Code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15853"&gt;Platform Awareness Service CVS Tree Snapshot (Inludes Platform Monitor)&lt;/a&gt; (4.5MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15850"&gt;Platform Awareness Service Midinux Source RPM&lt;/a&gt; (1.4MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15851"&gt;Platform Awareness Service Midinux Source RPM (Debug)&lt;/a&gt; (1.4MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15852"&gt;Platform Awareness Service Midinux Source RPM (No GPS)&lt;/a&gt; (1.4MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15854"&gt;Platform Monitor Source RPM&lt;/a&gt; (2MB)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;Downloads&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15874"&gt;Platform Awareness Service RPM Installer&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15875"&gt;Platform Awareness Service RPM Installer (Debug)&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15876"&gt;Platform Awareness Service RPM Installer (No GPS)&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15878"&gt;Platform Awareness Service Debian Installer&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15877"&gt;Platform Awareness Service Debian Installer (Debug)&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15879"&gt;Platform Awareness Service Debian Installer (No GPS)&lt;/a&gt; (1MB)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://software.intel.com/file/15880"&gt;Platform Monitor RPM Installer&lt;/a&gt; (2MB)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;Community&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/zwk_-bL5spY" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/zwk_-bL5spY/moblin-platform-awareness-service</link>
      <pubDate>Wed, 22 Apr 2009 16:18:42 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/moblin-platform-awareness-service#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/moblin-platform-awareness-service</guid>
      <category>Mobility</category>
      <category>MID</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/moblin-platform-awareness-service</feedburner:origLink></item>
    <item>
      <title>Detecting Network Connectivity Using D-Bus</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus/"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 class="sectionHeading"&gt;Preface&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://ossmpsdk.intel.com/"&gt;Intel® Mobile Platform SDK&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Introduction&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;As part of a whole project, MID Platform Awareness, this paper shows how we can call connectivity awareness methods and get event notifications. &lt;br /&gt;&lt;br /&gt;The system was developed on &lt;em&gt;Moblin&lt;/em&gt;[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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Background on D-Bus&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;In order to use D-Bus, we need to understand a few basics. First, an &lt;em&gt;object&lt;/em&gt; 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 &lt;em&gt;object paths&lt;/em&gt;. We can find an object via its path. A &lt;em&gt;proxy&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;An object can also emit an event, or &lt;em&gt;signal&lt;/em&gt;. When a signal is generated by an object, it is broadcasted to any interested observers. Signals can also carry parameters. &lt;em&gt;Methods&lt;/em&gt; and &lt;em&gt;Signals&lt;/em&gt; are embedded members of an object that can be grouped into an &lt;em&gt;interface&lt;/em&gt;. An object can declare one or many interfaces.&lt;br /&gt;&lt;br /&gt;In order to generate dbus-glib binding code, we use a tool called &lt;em&gt;dbus-binding-tool&lt;/em&gt;. We first create an XML file, referred to as an &lt;em&gt;Introspection XML file&lt;/em&gt;, 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:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="xhtml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;
&amp;lt;!DOCTYPE node PUBLIC 
"-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
"http://standards.freedesktop.org/dbus/1.0/introspect.dtd"&amp;gt;
&amp;lt;node name="/org/moblin/Platform"&amp;gt;
  &amp;lt;interface name="org.moblin.Platform.Connection"&amp;gt;
       &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="org_moblin_platform_connection"/&amp;gt;
       &amp;lt;method name="IsConnected"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="isConnected"/&amp;gt;
              &amp;lt;arg type="b" name="isConnected" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
       &amp;lt;method name="IsReachable"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="isReachable"/&amp;gt;
              &amp;lt;arg type="s" name="URI" direction="in" /&amp;gt;
              &amp;lt;arg type="b" name="isReachable" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
       &amp;lt;method name="GetLatency"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getLatency"/&amp;gt;
              &amp;lt;arg type="s" name="URI" direction="in" /&amp;gt;
              &amp;lt;arg type="d" name="seconds" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
       &amp;lt;method name="GetDataRate"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getDataRate"/&amp;gt;
              &amp;lt;arg type="s" name="URI" direction="in" /&amp;gt;
              &amp;lt;arg type="d" name="KiloBytesPerSecond" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
       &amp;lt;method name="GetMediaType"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getMediaType"/&amp;gt;
              &amp;lt;arg type="s" name="mediaType" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
       &amp;lt;method name="GetLinkSpeed"&amp;gt;
              &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getLinkSpeed"/&amp;gt;
              &amp;lt;arg type="d" name="kpbs" direction="out" /&amp;gt;
       &amp;lt;/method&amp;gt;
              
       &amp;lt;signal name="Connected" /&amp;gt;
       &amp;lt;signal name="Disconnected" /&amp;gt;           
   &amp;lt;/interface&amp;gt;
&amp;lt;/node&amp;gt;&lt;/pre&gt;
&lt;br /&gt;In this introspection XML file, an interface called org.moblin.Platform.Connection defines six methods: &lt;br /&gt;&lt;em&gt;IsConnected, IsReachable, GetLatency, GetDatRate, GetMediaType and GetLinkSpeed&lt;/em&gt;. 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 &lt;em&gt;isConnected&lt;/em&gt;. 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.&lt;br /&gt;&lt;br /&gt;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 &lt;em&gt;IsConnected&lt;/em&gt; method return value indicates that the method returns a Boolean. The second method, &lt;em&gt;IsReachable&lt;/em&gt;, 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.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;Below are primary steps to implement a D-Bus service. For more details, look here.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;em&gt;dbus-binding-tool &lt;/em&gt;for an introspection XML file to generate dbus-glib binding code&lt;/li&gt;
&lt;li&gt;Acquire the D-Bus GObject wrapper&lt;/li&gt;
&lt;li&gt;Implement the instance initialization&lt;/li&gt;
&lt;li&gt;Implement the methods&lt;/li&gt;
&lt;li&gt;Register the object on the D-Bus&lt;/li&gt;
&lt;/ul&gt;
To call the methods implemented on a remote object, a client needs to follow the following steps:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Connect to the bus&lt;/li&gt;
&lt;li&gt;Create a proxy object&lt;/li&gt;
&lt;li&gt;Invoke the methods on the proxy object.&lt;/li&gt;
&lt;/ul&gt;
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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Getting Network Connectivity Information&lt;/h1&gt;
&lt;br /&gt;The connectivity awareness service provides the means to query the following connectivity information on the computer where the service is installed. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Detecting the network connection&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;#include &amp;lt;dbus/dbus.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdbool.h&amp;gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;dbus/dbus-glib-bindings.h&amp;gt; &lt;br /&gt; &lt;br /&gt;#define PLATFORM_SERVICE          "org.moblin.Platform"&lt;br /&gt;#define PLATFORM_PATH                    "/org/moblin/Platform"&lt;br /&gt;#define PLATFORM_CONNECTION_IF    "org.moblin.Platform.Connection"&lt;br /&gt; &lt;br /&gt;int main(int argc, char** argv)&lt;br /&gt;{&lt;br /&gt;       DBusGConnection* conn;&lt;br /&gt;       GError *error;&lt;br /&gt;       DBusGProxy *platformProxy;&lt;br /&gt; &lt;br /&gt;       g_type_init();&lt;br /&gt;       error = NULL;&lt;br /&gt;       conn = dbus_g_bus_get(DBUS_BUS_SESSION, &amp;amp;error);&lt;br /&gt; &lt;br /&gt;       // Create the proxy Platform&lt;br /&gt;       platformProxy = dbus_g_proxy_new_for_name(conn,&lt;br /&gt;              PLATFORM_SERVICE,          // target for the method call&lt;br /&gt;               PLATFORM_PATH,                   // object to call on&lt;br /&gt;               PLATFORM_CONNECTION_IF);  // interface to call on&lt;br /&gt; &lt;br /&gt;      gboolean result;&lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "IsConnected", &amp;amp;error, &lt;br /&gt;                            G_TYPE_INVALID,&lt;br /&gt;                            G_TYPE_BOOLEAN, &amp;amp;result,&lt;br /&gt;                            G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                                error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;              printf ("Remote call successes with returned value: %s\n", result? "TRUE" : "FALSE");&lt;br /&gt; &lt;br /&gt;       . . . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;       . . . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;       . . . . . . . . . . . . . . . . . . . . . .&lt;br /&gt; &lt;br /&gt;       return 0;&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;Note that the application invokes the method &lt;em&gt;IsConnected&lt;/em&gt; implemented in the connectivity awareness service: no input is required, and the method returns TRUE if the computer is connected to a network.&lt;br /&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="c-sharp"&gt;netdev_ret netdev_get_running(netdev_dev *dev, // in &lt;br /&gt;                     netdev_running *running)     // out&lt;br /&gt;{&lt;br /&gt;       struct ifreq ifr;&lt;br /&gt;       if(_get_ifreq(dev-&amp;gt;ifname, SIOCGIFFLAGS, &amp;amp;ifr) != NETDEV_SUCCESS)&lt;br /&gt;       {&lt;br /&gt;              running = RUNNING_UNKNOWN;&lt;br /&gt;              return NETDEV_ERROR;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       short flags = ifr.ifr_flags;&lt;br /&gt;       if(flags &amp;amp; IFF_RUNNING)&lt;br /&gt;       {&lt;br /&gt;              *running = RUNNING_RUN;&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;              *running = RUNNING_STOP;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       return NETDEV_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Detecting HTTP reachability&lt;/h1&gt;
&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;"http://www.intel.com/", "http://www.google.com/", "http://www.yahoo.com/", etc ...&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;(length of HTTP GET sent + length of HTTP reply) / latency&lt;br /&gt;&lt;br /&gt;Code referring to these D-Bus methods is shown below.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;              int result1;&lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "IsReachable", &amp;amp;error,&lt;br /&gt;                            G_TYPE_STRING, "http://www.intel.com/",&lt;br /&gt;                            G_TYPE_INVALID,&lt;br /&gt;                            G_TYPE_BOOLEAN, &amp;amp;result1,&lt;br /&gt;                            G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                     error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;       else&lt;br /&gt;                printf ("Remote call successes with returned value: %s\n", result1? "TRUE" : "FALSE");&lt;br /&gt; &lt;br /&gt;      gdouble result2;&lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "GetLatency", &amp;amp;error,&lt;br /&gt;                            G_TYPE_STRING, "http://www.intel.com/",&lt;br /&gt;                            G_TYPE_INVALID,&lt;br /&gt;                            G_TYPE_DOUBLE, &amp;amp;result2,&lt;br /&gt;                            G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                     error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;              printf ("Remote call successes with returned value: %6.3f seconds\n", result2);&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "GetDataRate", &amp;amp;error,&lt;br /&gt;                            G_TYPE_STRING, "http://www.intel.com/",&lt;br /&gt;                            G_TYPE_INVALID,&lt;br /&gt;                            G_TYPE_DOUBLE, &amp;amp;result2,&lt;br /&gt;                            G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                     error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;              else&lt;br /&gt;                     printf ("Remote call successes with returned value: %8.2f KB/sec\n", result2);&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;bool HTTPIsReachable(&lt;br /&gt;              unsigned int *pTime,       // in msec&lt;br /&gt;              double *pRate,             // in KB/sec&lt;br /&gt;              PURI_INFO pUri)&lt;br /&gt;{&lt;br /&gt;              bool bRet = false;&lt;br /&gt;              unsigned long StartTime, StopTime;&lt;br /&gt;              int dwStatusCode;&lt;br /&gt;              int conn;&lt;br /&gt;              int Len = 0;&lt;br /&gt;       &lt;br /&gt;              if (pTime)&lt;br /&gt;                     *pTime = 0;&lt;br /&gt; &lt;br /&gt;              if ( pUri-&amp;gt;Port == 0 )&lt;br /&gt;                     pUri-&amp;gt;Port = HTTPPORT;&lt;br /&gt; &lt;br /&gt;              StartTime = getTime();&lt;br /&gt;              if (pUri-&amp;gt;DestPath)&lt;br /&gt;                        conn = (int)socketClient( pUri-&amp;gt;pHostIP, pUri-&amp;gt;Port, 0);&lt;br /&gt; &lt;br /&gt;                if (conn &amp;lt; 0)&lt;br /&gt;              {&lt;br /&gt;                     printf("conn&amp;lt;0\n");&lt;br /&gt;                       goto GracefulExit;&lt;br /&gt;              }&lt;br /&gt; &lt;br /&gt;              char req[1024];&lt;br /&gt;              sprintf( req, "GET /%s HTTP/1.0\r\nHost: %s\r\n", pUri-&amp;gt;FileName, pUri-&amp;gt;DestPath);&lt;br /&gt;               strcat( req, "User-Agent: hget/"  LIBHTTP_VERSION "\r\n");&lt;br /&gt;                     strcat( req, "Pragma: no-cache\r\n" );&lt;br /&gt;              strcat( req, "Accept: */*\r\n\r\n" );&lt;br /&gt;              dwStatusCode = HttpRequest(conn, &amp;amp;Len, req);    // in Bytes&lt;br /&gt;              close(conn);&lt;br /&gt; &lt;br /&gt;              StopTime = getTime();&lt;br /&gt; &lt;br /&gt;              printf("return code %d\n", dwStatusCode);&lt;br /&gt;              if ( dwStatusCode == 200 || pUri-&amp;gt;FileName == 0 )&lt;br /&gt;              {&lt;br /&gt;                     bRet = true;&lt;br /&gt;                     if (pTime)&lt;br /&gt;                     {&lt;br /&gt;                           unsigned int st;&lt;br /&gt;                           st = StopTime - StartTime;                // in msec&lt;br /&gt;                           *pTime = st;&lt;br /&gt;                           *pRate = (double)Len / (double)st;              // in KB/sec&lt;br /&gt;                     }&lt;br /&gt;              }&lt;br /&gt; &lt;br /&gt;       GracefulExit:&lt;br /&gt;              return bRet;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Detecting the media and speed of the network connection&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The last two methods, &lt;em&gt;GetMediaType&lt;/em&gt; and &lt;em&gt;GetLinkSpeed&lt;/em&gt;, 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 &lt;em&gt;GetMediaType&lt;/em&gt; is a string (i.e., "802.03", "802.11g"… etc) and the output of &lt;em&gt;GetLinkSpeed&lt;/em&gt; is a value of type double, representing the number of kbps (kilobits per second).&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;      char *result3;&lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "GetMediaType", &amp;amp;error,&lt;br /&gt;                            G_TYPE_INVALID,&lt;br /&gt;                            G_TYPE_STRING, &amp;amp;result3,&lt;br /&gt;                            G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                     error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;              printf ("Remote call successes with returned value: %s\n", result3);&lt;br /&gt; &lt;br /&gt;      double result4;&lt;br /&gt; &lt;br /&gt;      if (!dbus_g_proxy_call(platformProxy, "GetLinkSpeed", &amp;amp;error,&lt;br /&gt;                             G_TYPE_INVALID,&lt;br /&gt;                             G_TYPE_DOUBLE, &amp;amp;result4,&lt;br /&gt;                             G_TYPE_INVALID))&lt;br /&gt;      {&lt;br /&gt;              g_printerr("Failed to call remotely: %s\n",&lt;br /&gt;                     error-&amp;gt;message);&lt;br /&gt;              g_error_free(error);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;              printf ("Remote call successes with returned value: %10.1f Kbps (kbit per sec)\n", result4);&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The back-end implementation of the method &lt;em&gt;GetMediaType&lt;/em&gt; is shown below.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;char* RetrieveMediaType(void)&lt;br /&gt;{&lt;br /&gt;   netdev_dev netdev_list[MAX_DEVICE];&lt;br /&gt;   int numInterface = 0;&lt;br /&gt; &lt;br /&gt;   if(netdev_get_devices(netdev_list, &amp;amp;numInterface) == NETDEV_SUCCESS)&lt;br /&gt;   {&lt;br /&gt;       int i;&lt;br /&gt;       netdev_dev *net_devPtr = netdev_list;&lt;br /&gt; &lt;br /&gt;       for (i=0; i= Frequency802_11a1) &amp;amp;&amp;amp; &lt;br /&gt;                                      (freq &amp;lt;= Frequency802_11a2) &amp;amp;&amp;amp; &lt;br /&gt;                                      (rate &amp;lt;= MaxRate802_11a))&lt;br /&gt;                                         return ("802.11a");&lt;br /&gt; &lt;br /&gt;                                  if ((freq &amp;gt;= Frequency802_11b1) &amp;amp;&amp;amp; &lt;br /&gt;                                       (freq &amp;lt;= Frequency802_11b2) &amp;amp;&amp;amp; &lt;br /&gt;                                      (rate &amp;lt;= MaxRate802_11b))&lt;br /&gt;                                         return ("802.11b");&lt;br /&gt;                                                       &lt;br /&gt;                                  if ((freq &amp;gt;= Frequency802_11g1) &amp;amp;&amp;amp; &lt;br /&gt;                                      (freq &amp;lt;= Frequency802_11g2) &amp;amp;&amp;amp; &lt;br /&gt;                                      (rate &amp;lt;= MaxRate802_11g))&lt;br /&gt;                                         return ("802.11g");&lt;br /&gt;&lt;br /&gt;                                  return ("Unknown");&lt;br /&gt;                                  break;&lt;br /&gt;                           }&lt;br /&gt;                                                       &lt;br /&gt;                           default:&lt;br /&gt;                                  return ("Unknown");&lt;br /&gt;                                  break;&lt;br /&gt;                        }&lt;br /&gt; &lt;br /&gt;                     }&lt;br /&gt;&lt;br /&gt;                     else&lt;br /&gt;                        return ("Unknown");&lt;br /&gt; &lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;          net_devPtr++;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   return ("Unknown");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The back-end implementation of the method &lt;em&gt;GetLinkSpeed&lt;/em&gt; is shown below.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt; double RetrieveLinkSpeed(void)   // in bps&lt;br /&gt;{&lt;br /&gt;   netdev_dev netdev_list[MAX_DEVICE];&lt;br /&gt;   int numInterface = 0;&lt;br /&gt; &lt;br /&gt;   if(netdev_get_devices(netdev_list, &amp;amp;numInterface) == NETDEV_SUCCESS)&lt;br /&gt;   {&lt;br /&gt;       int i;&lt;br /&gt;       netdev_dev *net_devPtr = netdev_list;&lt;br /&gt; &lt;br /&gt;       for (i=0; i&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Readers are encouraged to refer to the source code of the MID Platform Awareness project for more details. &lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Monitoring Network Connectivity Change&lt;/h1&gt;
&lt;br /&gt;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 &lt;em&gt;signals&lt;/em&gt;. The application will be notified whenever the network connectivity changes status. Two network events are defined: &lt;em&gt;Connected&lt;/em&gt; and &lt;em&gt;Disconnected&lt;/em&gt;. The &lt;em&gt;Connected&lt;/em&gt; event is emitted by the network connectivity service when the network suddenly becomes available. Similarly, the &lt;em&gt;Disconnected&lt;/em&gt; 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. &lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;       DBusMessage* msg;&lt;br /&gt;       DBusConnection* conn;&lt;br /&gt;       DBusError err;&lt;br /&gt; &lt;br /&gt;       printf("Listening for signals\n");&lt;br /&gt; &lt;br /&gt;       // initialise the errors&lt;br /&gt;       dbus_error_init(&amp;amp;err);&lt;br /&gt;   &lt;br /&gt;       // connect to the bus and check for errors&lt;br /&gt;       conn = dbus_bus_get(DBUS_BUS_SESSION, &amp;amp;err);&lt;br /&gt;       if (dbus_error_is_set(&amp;amp;err)) &lt;br /&gt;       { &lt;br /&gt;              fprintf(stderr, "Connection Error (%s)\n", err.message);&lt;br /&gt;             dbus_error_free(&amp;amp;err); &lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       if (NULL == conn) &lt;br /&gt;              exit(1);&lt;br /&gt; &lt;br /&gt;       dbus_bus_add_match(conn, "type='signal',interface='org.moblin.Platform.Connection'", &amp;amp;err);&lt;br /&gt;       dbus_connection_flush(conn);&lt;br /&gt;       &lt;br /&gt;       if (dbus_error_is_set(&amp;amp;err)) &lt;br /&gt;       { &lt;br /&gt;              fprintf(stderr, "Match Error (%s)\n", err.message);&lt;br /&gt;              exit(1); &lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       printf("Match rule sent\n");&lt;br /&gt; &lt;br /&gt;       // loop listening for signals being emmitted&lt;br /&gt;       while (true) &lt;br /&gt;       {&lt;br /&gt;              // non blocking read of the next available message&lt;br /&gt;             dbus_connection_read_write(conn, 0);&lt;br /&gt;              msg = dbus_connection_pop_message(conn);&lt;br /&gt; &lt;br /&gt;             // loop again if we haven't read a message&lt;br /&gt;              if (NULL == msg) &lt;br /&gt;              { &lt;br /&gt;                     sleep(1);&lt;br /&gt;                     continue;&lt;br /&gt;              }&lt;br /&gt; &lt;br /&gt;              if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_CONNECTED_SIGNAL)) &lt;br /&gt;                     printf("Received signal %s\n", CONN_CONNECTED_SIGNAL);&lt;br /&gt; &lt;br /&gt;              if (dbus_message_is_signal(msg, PLATFORM_CONNECTION_IF, CONN_DISCONNECTED_SIGNAL)) &lt;br /&gt;                     printf("Received signal %s\n", CONN_DISCONNECTED_SIGNAL);&lt;br /&gt; &lt;br /&gt;              // free the message&lt;br /&gt;              dbus_message_unref(msg);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Conclusion&lt;/h1&gt;
&lt;br /&gt;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 &lt;em&gt;MIDPlatformSvc&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Although this implementation has been tested on the &lt;em&gt;Moblin&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;References&lt;/h1&gt;
&lt;br /&gt;[1] D-Bus, &lt;a href="http://www.freedesktop.org/wiki/Software/dbus"&gt;http://www.freedesktop.org/wiki/Software/dbus&lt;/a&gt;&lt;br /&gt;[2] D-Bus Tutorial, &lt;a href="http://dbus.freedesktop.org/doc/dbus-tutorial.html"&gt;http://dbus.freedesktop.org/doc/dbus-tutorial.html&lt;/a&gt;&lt;br /&gt;[3] &lt;a href="http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php"&gt;http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php&lt;/a&gt;&lt;br /&gt;[4] Mobile and Internet Linux Project, &lt;a href="http://moblin.org/"&gt;http://moblin.org/&lt;/a&gt;&lt;br /&gt;[5] RFC 1945 "Hypertext Transfer Protocol – HTTP/1.0"&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/r5OT3ofHooY" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/r5OT3ofHooY/detecting-network-connectivity-using-d-bus</link>
      <pubDate>Wed, 22 Apr 2009 16:14:00 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus</guid>
      <category>Mobility</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus</feedburner:origLink></item>
    <item>
      <title>Determining Input Devices in Linux*</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 class="sectionHeading"&gt;Preface&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 the Moblin-based MIDs. For information on how to retrieve this information from Windows operating systems, please consult that platform’s documentation, or see the &lt;a href="http://ossmpsdk.intel.com/"&gt;Intel Mobile Platform SDK&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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 Moblin 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Introduction&lt;/h1&gt;
&lt;br /&gt;One of the more distinguishing differences between a desktop machine and a mobile device is the way in which data can be input. Most desktop machines are equipped with a keyboard, a mouse, and perhaps other input devices. For a mobile device the choices are not always as obvious, and at times are not even available. The user of these machines, however, expects to be able to input information into the machine, and the software used must be aware of the options for input that are available on the system.&lt;br /&gt;&lt;br /&gt;The purpose of this paper is to demonstrate one way of retrieving input device information from Moblin-based Linux platforms.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;How to get Input Device Information in Linux&lt;/h1&gt;
&lt;br /&gt;While there is a fair amount of information available, we focus on three main pieces of information in order to keep things small and simple:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The existence of a physical keyboard&lt;/li&gt;
&lt;li&gt;The existence of a physical pointing device&lt;/li&gt;
&lt;li&gt;Whether the existence of either device changes&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 class="sectionHeading"&gt;Using HAL&lt;/h1&gt;
&lt;br /&gt;The Linux Hardware Abstraction Layer (&lt;a href="http://freedesktop.org/wiki/Software/hal"&gt;HAL&lt;/a&gt;&amp;gt;) can retrieve information about the hardware that makes up a computer system. HAL can be queried through the command line using commands like &lt;span style="font-family: courier new;"&gt;hal-device, hal-find-by-property, hal-find-by-capability,&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;hal-get-property&lt;/span&gt; . One can get the same information inside of an application by using &lt;a href="http://www.freedesktop.org/wiki/Software/dbus"&gt;D-BUS&lt;/a&gt;. The &lt;a href="http://people.freedesktop.org/~david/hal-spec/hal-spec.html"&gt;HAL 0.5.10 Specification&lt;/a&gt; lists information that is available through HAL. Therefore, for our purposes here, we will illustrate the use of the D-BUS interface to query the HAL and locate the available input devices, and once located determine which input device is relevant to a particular query. This is done by means of the FindDeviceByCapability directive to return a list of devices that have various input capabilities, namely keyboard and mouse. We will also illustrate a method for detecting when input devices are added or removed.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Creating the List of Input Devices&lt;/h1&gt;
&lt;br /&gt;In order to obtain a list of input devices, two functions are used to query the HAL for available devices. isPhysicalKeyboardPresent() collects information about the keyboards that are connected to the system. isPhysicalPointerPresent() collects information about the mouse devices that are connected to the system. Each function has the same parameters:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;MIDPlatformSvc *obj – Contains a pointer to the system bus through which the HAL is queried&lt;/li&gt;
&lt;li&gt;gboolean *Present – Returns TRUE if the device is present, FALSE if no device is present &lt;/li&gt;
&lt;li&gt;GError **error – Used to report the absence of the device being queried &lt;/li&gt;
&lt;/ul&gt;
Each function performs basically the same algorithm: connect to the HAL and request a list of devices using the FindDeviceByCapability directive to look for input.keyboard and input.mouse capability, and then, if appropriate, add the device to the collection of available input devices. The list returned by this query to the HAL is a collection of User Interface Devices (UDI) that each have the capability requested. Each UDI in this list is then examined to ensure that only the appropriate set of capabilities is present in the device, meaning that keyboards do not also have mouse capability, and that mouse devices do not also have keyboard or keys capability. This is done by again calling the HAL to determine if the opposite capability is also present in the UDI. When it is determined that only the desired capability is present in the UDI, a call to adjustinputdevicenames() is then made to track the particular UDI along with its discovered capability. Details of this function are located below. Once the device list has been created, it is used to track devices as they are connected or disconnected from the system.&lt;br /&gt;&lt;br /&gt;A listing of isPhysicalKeyboardPresent() is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean isPhysicalKeyboardPresent(MIDPlatformSvc *obj, gboolean *keyboardPresent, GError **error)&lt;br /&gt;{&lt;br /&gt;       DBusGConnection *sysBus;&lt;br /&gt;       DBusGProxy *proxy;&lt;br /&gt;       char **kbdList = NULL,**mouseList = NULL;&lt;br /&gt;       char **kbd_ptr,**mouse_ptr,**mousename;&lt;br /&gt;       int i = 0,len = 0;&lt;br /&gt;       &lt;br /&gt;       // Initialize the System DBus connection&lt;br /&gt;       sysBus = obj-&amp;gt;systemBus;&lt;br /&gt; &lt;br /&gt;       // Connect a proxy to the Hal Manager interface &lt;br /&gt;       proxy = dbus_g_proxy_new_for_name(sysBus,"org.freedesktop.Hal",&lt;br /&gt;                           "/org/freedesktop/Hal/Manager","org.freedesktop.Hal.Manager" );&lt;br /&gt; &lt;br /&gt;       dbus_g_proxy_call(proxy, "FindDeviceByCapability", error,     //Find Keyboard via HAL&lt;br /&gt;                     G_TYPE_STRING, "input.keyboard", G_TYPE_INVALID,              // param #1&lt;br /&gt;                     G_TYPE_STRV, &amp;amp;kbdList, G_TYPE_INVALID);                // ret val&lt;br /&gt;       &lt;br /&gt;       if (kbdList)&lt;br /&gt;              len = g_strv_length(kbdList);&lt;br /&gt;       if (len == 0) {                   // no keyboard found&lt;br /&gt;              *keyboardPresent = FALSE;         // Function Fail&lt;br /&gt;              g_set_error (error,                             // set an error&lt;br /&gt;                          INPUT_DEVICE_NP,                           // error domain&lt;br /&gt;                          1,                                  // error code&lt;br /&gt;                          "No Keyboard devices were found.\n");      // error message&lt;br /&gt;              return TRUE;&lt;br /&gt;       }&lt;br /&gt;       gboolean haskbd = FALSE,hasmouse;&lt;br /&gt;       for (kbd_ptr = kbdList; *kbd_ptr; kbd_ptr++,i++)       // iterate through the list of&lt;br /&gt;       {                    // keyboard devices, checking each udi to for mouse capability&lt;br /&gt;              hasmouse = FALSE;&lt;br /&gt;              DBusGProxy *kbdProxy = dbus_g_proxy_new_for_name(sysBus,      //Open proxy for&lt;br /&gt;              "org.freedesktop.Hal",*kbd_ptr,"org.freedesktop.Hal.Device" );//Keyboard UDI&lt;br /&gt;              dbus_g_proxy_call(kbdProxy, "GetPropertyStringList", error,   // Checking caps                                &lt;br /&gt;			  G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID,&lt;br /&gt;                                  G_TYPE_STRV, &amp;amp;mouseList, G_TYPE_INVALID);&lt;br /&gt;              len = g_strv_length(mouseList);&lt;br /&gt;              for (mouse_ptr = mouseList;*mouse_ptr &amp;amp;&amp;amp; !hasmouse;mouse_ptr++)&lt;br /&gt;              {&lt;br /&gt;                     if (!strcmp(*mouse_ptr,"input.mouse"))&lt;br /&gt;                           hasmouse = TRUE;&lt;br /&gt;              }&lt;br /&gt;              if (!hasmouse)&lt;br /&gt;              {&lt;br /&gt;                     haskbd = TRUE;&lt;br /&gt;                     adjustinputdevicenames(obj,*kbd_ptr,ADDIT,KEYBOARD);&lt;br /&gt;              }&lt;br /&gt;              if (len)&lt;br /&gt;                     g_strfreev(mouseList);&lt;br /&gt;              g_object_unref (kbdProxy);&lt;br /&gt;      }&lt;br /&gt;       g_strfreev(kbdList);&lt;br /&gt;       g_object_unref (proxy);&lt;br /&gt;       &lt;br /&gt;       *keyboardPresent = haskbd;&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;An additional check is made when working with mouse devices. It has been determined that a mouse emulation UDI is sent by DBUS when a keyboard is connected to or disconnected from the system. It does have input.mouse capabilities only, but, as an emulation, is not connected to a physical device. Thus, when searching mouse devices for keys or keyboard capabilities, an additional call to the HAL is made using the GetPropertyString directive to discover the info.product elements of the UDI. If the property name is not “Macintosh mouse button emulation”, then we proceed with checking to see if keys or keyboard capabilities are also present in the UDI. A listing of isPhysicalPointerPresent() is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean isPhysicalPointerPresent(MIDPlatformSvc *obj, gboolean *pointerPresent, GError **error)&lt;br /&gt;{&lt;br /&gt;       DBusGConnection *sysBus;&lt;br /&gt;       DBusGProxy *proxy;&lt;br /&gt;       char **kbdList = NULL,**mouseList = NULL;&lt;br /&gt;       char **mouse_ptr,**kbd_ptr,*mouseproduct;&lt;br /&gt;       int i = 0,len = 0;&lt;br /&gt;       &lt;br /&gt;       // Initialize the System DBus connection&lt;br /&gt;       sysBus = obj-&amp;gt;systemBus;&lt;br /&gt; &lt;br /&gt;       // Connect a proxy to the Hal Manager interface &lt;br /&gt;       proxy = dbus_g_proxy_new_for_name(sysBus,"org.freedesktop.Hal",&lt;br /&gt;                     "/org/freedesktop/Hal/Manager","org.freedesktop.Hal.Manager" );&lt;br /&gt; &lt;br /&gt;       dbus_g_proxy_call(proxy, "FindDeviceByCapability", error,            //Find Mouse via HAL&lt;br /&gt;                     G_TYPE_STRING, "input.mouse", G_TYPE_INVALID,          // param #1&lt;br /&gt;                     G_TYPE_STRV, &amp;amp;mouseList, G_TYPE_INVALID);                     // ret val&lt;br /&gt; &lt;br /&gt;       if (mouseList)&lt;br /&gt;              len = g_strv_length(mouseList);&lt;br /&gt;       if (len == 0) {                   // no keyboard found&lt;br /&gt;              *pointerPresent = FALSE;          // Function fails&lt;br /&gt;              g_set_error (error,                             // set an error&lt;br /&gt;                          INPUT_DEVICE_NP,                           // error domain&lt;br /&gt;                          1,                                  // error code&lt;br /&gt;                          "No Mouse devices were found.\n");  // error message&lt;br /&gt;              return TRUE;&lt;br /&gt;       }&lt;br /&gt;       gboolean hasmouse = FALSE,haskeyboard;   // No solely mouse capability is assumed&lt;br /&gt; &lt;br /&gt;       for (i=0,mouse_ptr = mouseList; *mouse_ptr &amp;amp;&amp;amp; !hasmouse; mouse_ptr++,i++)&lt;br /&gt;       // iterate through the list of mouse devices, checking each udi for keyboard capability&lt;br /&gt;       {&lt;br /&gt;              haskeyboard = FALSE;&lt;br /&gt;              DBusGProxy *mouseProxy = dbus_g_proxy_new_for_name(sysBus,"org.freedesktop.Hal",&lt;br /&gt;                     *mouse_ptr,"org.freedesktop.Hal.Device" );      //Open Proxy for Mouse UDI&lt;br /&gt;              dbus_g_proxy_call(mouseProxy, "GetPropertyString", error,     // Checking caps. &lt;br /&gt;                                  G_TYPE_STRING, "info.product", G_TYPE_INVALID,                                            &lt;br /&gt;								  G_TYPE_STRING, &amp;amp;mouseproduct, G_TYPE_INVALID);&lt;br /&gt;              if (strcmp(mouseproduct,"Macintosh mouse button emulation"))  // if mouse&lt;br /&gt;              {      // device is not Macintosh mouse button emulation continue&lt;br /&gt;                     dbus_g_proxy_call(mouseProxy, "GetPropertyStringList", error,                                                &lt;br /&gt;					 G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID,                                      &lt;br /&gt;					 G_TYPE_STRV, &amp;amp;kbdList, G_TYPE_INVALID);&lt;br /&gt;                     len = g_strv_length(kbdList);&lt;br /&gt;                     for (kbd_ptr = kbdList; *kbd_ptr &amp;amp;&amp;amp; !haskeyboard; kbd_ptr++) //check to&lt;br /&gt;                     {      // see if device has any "Keyboard" capability as well; if so,&lt;br /&gt;                           // device is not solely a mouse device&lt;br /&gt;                           if (!strncmp(*kbd_ptr,"input.key",9))      //check for input.key*, &lt;br /&gt;                                  // if any exist we have keyboard capability, not just mouse&lt;br /&gt;                                  haskeyboard = TRUE;&lt;br /&gt;                     }&lt;br /&gt;                     if (!haskeyboard)    //set mouse capability with respect to keyboard:&lt;br /&gt;                                         // if no keyboard we have mouse; if keyboard we &lt;br /&gt;                     {                    // don't have mouse only&lt;br /&gt;                           hasmouse = TRUE;&lt;br /&gt;                           adjustinputdevicenames(obj,*mouse_ptr,ADDIT,MOUSE);&lt;br /&gt;                     }&lt;br /&gt;                     if (len)&lt;br /&gt;                           g_strfreev(kbdList);       //free elements as appropriate&lt;br /&gt;              }&lt;br /&gt;              free(mouseproduct);&lt;br /&gt;              g_object_unref (mouseProxy);                                  //free proxy&lt;br /&gt;       }&lt;br /&gt;       g_strfreev (mouseList);&lt;br /&gt;       g_object_unref (proxy);&lt;br /&gt;       *pointerPresent = hasmouse;&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Collecting the Available Input Devices&lt;/h1&gt;
&lt;br /&gt;As information regarding the input devices is discovered, and as it can change any time a device is connected to or disconnected from the system, a method for tracking available devices becomes necessary. Each UDI has a unique name and is generally connected to a unique function, in our case either for mouse support or keyboard support. The function adjustinputdevicesnames() was written to track these changes as they occur. The parameters are as follows:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;MIDPlatformSvc *obj – Contains a pointer to the system bus used when advising users of changes in the availability of devices&lt;/li&gt;
&lt;li&gt;char *name – Contains the name of the UDI being tracked&lt;/li&gt;
&lt;li&gt;int action – Indicates to the function the operation to perform. Options here are ADDIT, REMOVEIT, CLEANUP, INITIALIZE, NOACTION &lt;/li&gt;
&lt;li&gt;int role – Indicates the role of this particular UDI. Options here are KEYBOARD or MOUSE. &lt;/li&gt;
&lt;/ul&gt;
The purpose of this function is to collect and track the information regarding the various UDI’s that are discovered by the system, and to track when changes dictate that an advisory should be sent to interested parties regarding the state of input devices on the system. In tracking the UDI’s, once they are entered in the list of devices, the name remains in the list. This is because each device is assigned the same name, and when disconnected or connected will be the same as the previous use. A listing of adjustinputdevicename() and associated data is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;#define ADDIT              1&lt;br /&gt;#define REMOVEIT           2&lt;br /&gt;#define CLEANUP            3&lt;br /&gt;#define KEYBOARD           4&lt;br /&gt;#define MOUSE              5&lt;br /&gt;#define NOACTION           6&lt;br /&gt;#define INITIALIZE         7&lt;br /&gt; &lt;br /&gt;#define TBLSIZE            20&lt;br /&gt; &lt;br /&gt;typedef struct &lt;br /&gt;{      char *name;&lt;br /&gt;       int active;&lt;br /&gt;       int role;&lt;br /&gt;} DEVICE_INFO;&lt;br /&gt; &lt;br /&gt;static void adjustinputdevicenames(MIDPlatformSvc *obj,char *name,int action,int role)&lt;br /&gt;{&lt;br /&gt;       static DEVICE_INFO inpdevs[TBLSIZE];     // static variables will keep state&lt;br /&gt;       int i;&lt;br /&gt;       static int devcount = 0,mousecount = 0, keyboardcount = 0;&lt;br /&gt;       static gboolean firstpass = TRUE;&lt;br /&gt;       gboolean present = FALSE;&lt;br /&gt; &lt;br /&gt;       if (action == ADDIT) // operation is to add UDI to tracking mechanism&lt;br /&gt;       {&lt;br /&gt;              gboolean adjcount = FALSE;&lt;br /&gt;&lt;br /&gt;             for (i = 0; i &amp;lt; devcount &amp;amp;&amp;amp; !present; i++)&lt;br /&gt;                    if (!strcmp(name,inpdevs[i].name) &amp;amp;&amp;amp; inpdevs[i].role == role)&lt;br /&gt;                     {  // check to see if UDI name and role already exist and is yes&lt;br /&gt;                           adjcount = !inpdevs[i].active; // determine previous state&lt;br /&gt;                           inpdevs[i].active = TRUE;  // set as active&lt;br /&gt;                           present = TRUE;            // set as present&lt;br /&gt;                     }&lt;br /&gt;              if (!present)        // UDI is not present so it is added&lt;br /&gt;              {&lt;br /&gt;                     inpdevs[devcount].name = strdup(name);   // keep UDI name&lt;br /&gt;                     inpdevs[devcount].active = TRUE;         // set as active&lt;br /&gt;                     inpdevs[devcount].role = role;           // store its role&lt;br /&gt;                     devcount++;                       // increase device count&lt;br /&gt;                     adjcount = TRUE;                  // indicate adjustment necessary&lt;br /&gt;              }&lt;br /&gt;              if (adjcount)&lt;br /&gt;              {      //if adjustments are necessary, make them based on role of UDI&lt;br /&gt;                     if (role == KEYBOARD)&lt;br /&gt;                     {      // if keyboard has not been present and now is then&lt;br /&gt;                           if (!firstpass &amp;amp;&amp;amp; !keyboardcount) // alert users of change&lt;br /&gt;                                  keyboardPresentChanged(obj,TRUE,NULL);&lt;br /&gt;                           keyboardcount++;     // adjust keyboard count&lt;br /&gt;                     }&lt;br /&gt;                     else if (role == MOUSE)&lt;br /&gt;                     {      // if mouse has not been present and now is then&lt;br /&gt;                           if (!firstpass &amp;amp;&amp;amp; !mousecount)    // alert users of change&lt;br /&gt;                                  pointerPresentChanged(obj,TRUE,NULL);&lt;br /&gt;                           mousecount++;        // adjust mouse count&lt;br /&gt;                     }&lt;br /&gt;                     firstpass = FALSE;   // set controlling variable to FALSE&lt;br /&gt;              }&lt;br /&gt;       }&lt;br /&gt;       else if (action == REMOVEIT)      // operation is to remove UDI as active&lt;br /&gt;       {&lt;br /&gt;              for (i = 0; i &amp;lt; devcount; i++)    // for each UDI that is tracked&lt;br /&gt;              {      // if UDI is being queried and is active&lt;br /&gt;                     if (!strcmp(name,inpdevs[i].name) &amp;amp;&amp;amp; inpdevs[i].active)&lt;br /&gt;                     {      &lt;br /&gt;                           inpdevs[i].active = FALSE; // set as inactive&lt;br /&gt;                           if (inpdevs[i].role == KEYBOARD)&lt;br /&gt;                           {      // if role is keyboard decrement refence count&lt;br /&gt;                                  keyboardcount--;     // and if now no keyboards are&lt;br /&gt;                                  if (!firstpass &amp;amp;&amp;amp; keyboardcount &amp;lt; 1) // present&lt;br /&gt;                                         keyboardPresentChanged(obj,FALSE,NULL);&lt;br /&gt;                           }             // alert users of change&lt;br /&gt;                           else if (inpdevs[i].role == MOUSE)&lt;br /&gt;                           {      // if role is mouse, decrement reference count&lt;br /&gt;                                  mousecount--;        // and is now no mouse is present&lt;br /&gt;                                  if (!firstpass &amp;amp;&amp;amp; mousecount &amp;lt; 1) // alert users&lt;br /&gt;                                         pointerPresentChanged(obj,FALSE,NULL);&lt;br /&gt;                           }             //of change&lt;br /&gt;                     }&lt;br /&gt;              }&lt;br /&gt;              firstpass = FALSE;&lt;br /&gt;       }&lt;br /&gt;       else if (action == CLEANUP) // operation is to cleanup information&lt;br /&gt;       {&lt;br /&gt;              for (i = 0; i &amp;lt; devcount; i++)&lt;br /&gt;              {&lt;br /&gt;                     free(inpdevs[i].name);     // release memory allocated for name&lt;br /&gt;                     inpdevs[i].name = NULL;&lt;br /&gt;                     inpdevs[i].active = FALSE; // set active and role to zero state&lt;br /&gt;                     inpdevs[i].role = 0;&lt;br /&gt;              }&lt;br /&gt;              devcount = 0;        // set counters all to zero&lt;br /&gt;              keyboardcount = 0;&lt;br /&gt;              mousecount = 0;&lt;br /&gt;&lt;br /&gt;             firstpass = TRUE;    // set to initial state&lt;br /&gt;       }&lt;br /&gt;       else if (action == INITIALIZE &amp;amp;&amp;amp; firstpass)     // operation is to initialize&lt;br /&gt;       {&lt;br /&gt;              for (i = 0; i &amp;lt; TBLSIZE; i++)&lt;br /&gt;              {&lt;br /&gt;                     inpdevs[i].name = NULL;           // set a known state for all&lt;br /&gt;                     inpdevs[i].active = FALSE;        // elements&lt;br /&gt;                     inpdevs[i].role = 0;&lt;br /&gt;              }&lt;br /&gt;       }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Tracking Changes in Available Input Devices&lt;/h1&gt;
&lt;br /&gt;Input devices can change at almost any time. The DBUS provides signaling capabilities are sent when a connection or disconnection of a device occurs on the system. We have taken advantage of this capability to monitor the changes to input devices by subscribing to the DeviceAdded and DeviceRemoved signals. This method provides a mechanism whereby a callback function can be specified to handle these two signals. The function beginInputEventThread(), which is invoked by the Mobile Internet Device platform architecture to initialize the input events, is the function in which we provide hooks into the signaling system to be able to monitor changes to input events. Its parameter is a MIDPlatformSvc object containing system bus information used throughout the input device module. A listing of this function is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;void beginInputEventThread(MIDPlatformSvc *obj)&lt;br /&gt;{&lt;br /&gt;       DBusGConnection *sysBus = obj-&amp;gt;systemBus;       // Initialize the System DBus connection&lt;br /&gt;       DBusGProxy *proxy;&lt;br /&gt;       gboolean kpresent,mpresent;&lt;br /&gt;       GError *error = NULL;&lt;br /&gt; &lt;br /&gt;       adjustinputdevicenames(obj,NULL,INITIALIZE,NOACTION);  //initialize keyboard/mouse data&lt;br /&gt;       isPhysicalPointerPresent(obj,&amp;amp;mpresent,&amp;amp;error); //Make first check of mouse&lt;br /&gt;       isPhysicalKeyboardPresent(obj,&amp;amp;kpresent,&amp;amp;error);       //Make first check of keyboards&lt;br /&gt;       // Connect a proxy to the Hal Manager interface &lt;br /&gt;       proxy =  dbus_g_proxy_new_for_name(sysBus,             // Retrieve proxy to HAL manager&lt;br /&gt;              "org.freedesktop.Hal",&lt;br /&gt;              "/org/freedesktop/Hal/Manager",&lt;br /&gt;              "org.freedesktop.Hal.Manager" );&lt;br /&gt;       dbus_g_proxy_add_signal(proxy,"DeviceAdded",G_TYPE_STRING,G_TYPE_INVALID);&lt;br /&gt;       dbus_g_proxy_connect_signal(proxy,"DeviceAdded",G_CALLBACK(checkAddedDevice),&lt;br /&gt;(void *)obj,NULL);   // add and connect to DeviceAdded signal &lt;br /&gt;                                                // with callbackfunction checkAddedDevice()&lt;br /&gt;       dbus_g_proxy_add_signal(proxy,"DeviceRemoved",G_TYPE_STRING,G_TYPE_INVALID);&lt;br /&gt;       dbus_g_proxy_connect_signal(proxy,"DeviceRemoved",G_CALLBACK(checkRemovedDevice),&lt;br /&gt;                           (void *)obj,NULL);   // add and connect to DeviceRemoved signal      &lt;br /&gt;						   return;	 // with callback function checkRemovedDevice&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;As noted in the function above, two functions, checkAddedDevice() and checkRemoveDevice() are denoted as the callback functions that are called when the aforementioned signals are sent. They will make calls to appropriate functions that will monitor and track the changes to devices as they occur. The callback checkRemovedDevice() function makes use of adjustinputdevicenames() that we have already discussed. Its parameters are:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DBusGProxy *proxy – a DBus proxy pointer stored when the callback function was declared and registered with the connect signal call&lt;/li&gt;
&lt;li&gt;gchar* device_udi – the name of the UDI which has been removed&lt;/li&gt;
&lt;li&gt;gpointer userData – a pointer to user defined data associated with the connect signal call&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;A listing of this function is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;void checkRemovedDevice(DBusGProxy *proxy, gchar *device_udi, gpointer userData)&lt;br /&gt;{&lt;br /&gt;       adjustinputdevicenames((MIDPlatformSvc *)userData,device_udi,REMOVEIT,NOACTION);&lt;br /&gt;       return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;It should be noted that the call to adjustinputdevicenames() in this function denotes that we are removing a device from active service in our data elements.&lt;br /&gt;&lt;br /&gt;The callback checkAddedDevice() function makes use of the function examineUDI(), which is discussed below. Its parameters are:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DBusGProxy *proxy – a DBus proxy pointer stored when the callback function was declared and registered with the connect signal call &lt;/li&gt;
&lt;li&gt;gchar* device_udi – the name of the UDI which has been removed &lt;/li&gt;
&lt;li&gt;gpointer userData – a pointer to user defined data associated with the connect signal call&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;A listing of this function is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;void checkAddedDevice(DBusGProxy *proxy, gchar *device_udi, gpointer userData)&lt;br /&gt;{&lt;br /&gt;       examineUDI(proxy,device_udi,(MIDPlatformSvc *)userData);&lt;br /&gt;       return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Identifying an added input device requires a slightly different approach than removing an input device. Since a device added to the system could belong to a variety of functionality, a means to determine if the device added is an input device had to be created. As we are only interested in input devices, the function examineUDI() is used to make this determination. This function uses the HAL to determine the capability of the device being examined, and only adds a device if it has keyboard or mouse capability. The parameters are:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DBusGProxy *proxy – a DBus proxy pointer stored when the callback function was declared and registered with the connect signal call &lt;/li&gt;
&lt;li&gt;gchar* device_udi – the name of the UDI which has been removed &lt;/li&gt;
&lt;li&gt;MIDPlatformSvc *obj – a pointer to user defined data associated with the connect signal call&lt;/li&gt;
&lt;/ul&gt;
This function, after determining that the added device is an input device, makes use of adjustinputdevicenames() to track the new device. A listing of this function is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;static void examineUDI (DBusGProxy *proxy, gchar *device_udi,MIDPlatformSvc *obj)&lt;br /&gt;{&lt;br /&gt;       char **devicecaps = NULL,**list1 = NULL,**list2 = NULL;&lt;br /&gt;       GError **error = NULL;&lt;br /&gt;       int len = -1;&lt;br /&gt; &lt;br /&gt;       DBusGProxy *capProxy = dbus_g_proxy_new_for_name(obj-&amp;gt;systemBus,&lt;br /&gt;                           "org.freedesktop.Hal",device_udi,&lt;br /&gt;                           "org.freedesktop.Hal.Device");    //Open Proxy for supplied UDI&lt;br /&gt;       dbus_g_proxy_call(capProxy,"GetPropertyStringList",    // Checking for device capability&lt;br /&gt;                           error,G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID,&lt;br /&gt;                           G_TYPE_STRV, &amp;amp;devicecaps, G_TYPE_INVALID);&lt;br /&gt;       if (devicecaps)&lt;br /&gt;       {&lt;br /&gt;              len = g_strv_length(devicecaps);&lt;br /&gt;              for (list1 = devicecaps;*list1;list1++)  &lt;br /&gt;              {&lt;br /&gt;                     if (!strncmp(*list1,"input.key",9))      // Is any key type capability present&lt;br /&gt;                     {&lt;br /&gt;                           gboolean haskbd = FALSE;&lt;br /&gt;                           list2 = list1;       // check remaining through second pointer&lt;br /&gt;                           for (;*list2 &amp;amp;&amp;amp; !haskbd;list2++)  // check for keyboard&lt;br /&gt;                                  if (!strcmp(*list2,"input.keyboard"))&lt;br /&gt;                                         haskbd = TRUE;&lt;br /&gt;                           if (haskbd)   // if there is a keyboard make sure mouse is missing&lt;br /&gt;                           {&lt;br /&gt;                                  gboolean hasmouse = FALSE; &lt;br /&gt;                                  list1++;//begin mouse search one beyond where key was found&lt;br /&gt;                                  if (list1)&lt;br /&gt;                                         for (;*list1 &amp;amp;&amp;amp; !hasmouse;list1++)&lt;br /&gt;                                                if (!strcmp(*list1,"input.mouse"))&lt;br /&gt;                                                       hasmouse = TRUE;&lt;br /&gt;                                  if (!hasmouse)       // if no mouse present add UDI to kbd list&lt;br /&gt;                                         adjustinputdevicenames(obj,device_udi,ADDIT,&lt;br /&gt;                                                               KEYBOARD);&lt;br /&gt;                           }&lt;br /&gt;                           break; //end for loop search&lt;br /&gt;                     }&lt;br /&gt;                     else if (!strcmp(*list1,"input.mouse")) // is mouse the capability&lt;br /&gt;                     {&lt;br /&gt;                           gboolean haskey = FALSE;&lt;br /&gt;                           list1++;&lt;br /&gt;                           if (list1)    // make sure not “key” capability is present&lt;br /&gt;                                  for (;*list1 &amp;amp;&amp;amp; !haskey;list1++)&lt;br /&gt;                                         if (!strncmp(*list1,"input.key",9))&lt;br /&gt;                                                haskey = TRUE;&lt;br /&gt;                           if (!haskey)  // if no key, then add UDI to mouse list&lt;br /&gt;                                  adjustinputdevicenames(obj,device_udi,ADDIT,MOUSE);&lt;br /&gt;                           break;        //end 'for' loop search&lt;br /&gt;                     }&lt;br /&gt;              }&lt;br /&gt;       }&lt;br /&gt;       g_object_unref (capProxy);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Notification of Changes in Available Input Devices&lt;/h1&gt;
&lt;br /&gt;As mentioned above, when changes in input devices occurs the user is notified of these changes through an alert through the DBUS signaling service. These alerts are made via the functions keyboardPresentChanged() and pointerPresentChanged. Both functions have identical parameters:&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;MIDPlatformSvc *obj – Contains a pointer to the system bus to which the alert is issued&lt;/li&gt;
&lt;li&gt;Gboolean isPresent – indicates the current data of the devices&lt;/li&gt;
&lt;li&gt;GError *error = an error reporting element&lt;/li&gt;
&lt;/ul&gt;
Both functions operate the same way by calling g_signal_emit() to pass the specific alert defined for each function. The listing of both functions is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean keyboardPresentChanged(MIDPlatformSvc*obj, gboolean isPresent, GError *error)&lt;br /&gt;{&lt;br /&gt;       if (error == NULL) //GQuark stuff #define SIG_PHYSICAL_KEYBOARD_PRESENT_ID&lt;br /&gt;       {      //"physical_keyboard_present_changed": whether the physical keyboard is present&lt;br /&gt;              g_signal_emit(obj,g_inputSignals[SIG_PHYSICAL_KEYBOARD_PRESENT_ID].signalId,&lt;br /&gt;                           0,isPresent); &lt;br /&gt;       }&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean pointerPresentChanged(MIDPlatformSvc*obj, gboolean isPresent, GError *error)&lt;br /&gt;{&lt;br /&gt;       if (error == NULL)          //GQuark stuff #define SIG_PHYSICAL_POINTER_PRESENT_ID&lt;br /&gt;       {      //"physical_mouse_present_changed": whether the physical mouse is present&lt;br /&gt;              g_signal_emit(obj,g_inputSignals[SIG_PHYSICAL_POINTER_PRESENT_ID].signalId,&lt;br /&gt;                           0,isPresent);&lt;br /&gt;       }&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Cleaning Up Information Regarding Available Input Devices&lt;/h1&gt;
&lt;br /&gt;As must always occur, we must be careful to cleanup the memory and other resources we have used during the process of tracking input devices. The Intel® Mobile Internet Device platform provides a mechanism for all components to release all resources used during the process of managing the device. For input devices, this is done through a call tofinalizeInputObject(). Its one parameter, MIDPlatformSvc *obj, contains the system bus information we have used through out. A list of the function is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;void finalizeInputObject(MIDPlatformSvc *obj)&lt;br /&gt;{&lt;br /&gt;       DBusGConnection *sysBus = obj-&amp;gt;systemBus;       // Initialize the System DBus connection&lt;br /&gt;       DBusGProxy *proxy;&lt;br /&gt;       gboolean present;&lt;br /&gt;       GError *error = NULL;&lt;br /&gt;       &lt;br /&gt;       adjustinputdevicenames(obj,NULL,CLEANUP,NOACTION);     //cleanup the tracking table&lt;br /&gt;       // Connect a proxy to the Hal Manager interface &lt;br /&gt;       proxy = dbus_g_proxy_new_for_name(sysBus,"org.freedesktop.Hal",&lt;br /&gt;                           "/org/freedesktop/Hal/Manager","org.freedesktop.Hal.Manager" );&lt;br /&gt;       dbus_g_proxy_disconnect_signal(proxy,"DeviceAdded",G_CALLBACK(checkAddedDevice),&lt;br /&gt;                                  (void *)obj); // disconnect from DeviceAdded signal&lt;br /&gt;       dbus_g_proxy_disconnect_signal(proxy,"DeviceRemoved",G_CALLBACK(checkRemovedDevice),&lt;br /&gt;                                  (void *)obj); // disconnect from DeviceRemoved signal&lt;br /&gt;       return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Unsupported Input Devices&lt;/h1&gt;
&lt;br /&gt;There are two input devices that are current not supported to the extent of keyboards and the mouse. They are the TouchScreen and the On-Screen keyboard. There are hooks in the input code that returns a fixed state for these devices, but any changes to them is not reported at this time. Future revisions will surely have support for these devices if support in the OS can be found. A listing of the three functions that returned a fixed state is now presented:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean isTouchScreen(MIDPlatformSvc *obj, gboolean *isTouchScreen, GError **error)&lt;br /&gt;{&lt;br /&gt;       *isTouchScreen = TRUE;&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;gboolean isOnScreenKeyboardVisible(MIDPlatformSvc *obj, gboolean *visible, GError **error)&lt;br /&gt;{&lt;br /&gt;       *visible = FALSE;&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;gboolean onScreenKeyboardChanged(MIDPlatformSvc* obj)&lt;br /&gt;{&lt;br /&gt;       gboolean visible;&lt;br /&gt;       GError* error = NULL;&lt;br /&gt;       dbg("Simulating a OnScreenKeyboardChanged Event.");&lt;br /&gt;       isOnScreenKeyboardVisible(obj, &amp;amp;visible, &amp;amp;error);&lt;br /&gt;       if (error == NULL)&lt;br /&gt;       {&lt;br /&gt;              g_signal_emit (      obj, &lt;br /&gt;                                         g_inputSignals[SIG_ON_SCREEN_KEYBOARD_CHANGED_ID].signalId , &lt;br /&gt;                           0, //GQuark stuff&lt;br /&gt;                                  //the parameters; in this case, whether or not the&lt;br /&gt;                                  //keyboard is visible&lt;br /&gt;                                         );&lt;br /&gt;       }//GQuark stuff #define SIG_PHYSICAL_KEYBOARD_PRESENT_ID      "on_screen_keyboard_changed"&lt;br /&gt;       return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Writing Input Device Aware Applications&lt;/h1&gt;
&lt;br /&gt;The ability to determine input devices is very important to an application. When events occur that change that ability, it is important that the application is aware of these changes. Hopefully this paper covered enough detail to get you started on writing your own input device aware applications for Linux.&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/N_NZ9u3FJeQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/N_NZ9u3FJeQ/determining-input-devices-in-linux</link>
      <pubDate>Wed, 22 Apr 2009 16:13:14 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/determining-input-devices-in-linux#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/determining-input-devices-in-linux</guid>
      <category>Mobility</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/determining-input-devices-in-linux</feedburner:origLink></item>
    <item>
      <title>How to Obtain Location Information in Linux</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1 class="sectionHeading"&gt;Preface&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 the Moblin-based MIDs. For information on how to retrieve this information from Windows operating systems, please consult that platform’s documentation, or see the &lt;a href="http://ossmpsdk.intel.com/"&gt;Intel Mobile Platform SDK&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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 Moblin 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. &lt;br /&gt;&lt;br /&gt;For further information on how to use D-Bus to retrieve information from the Platform Awareness Service, please refer to the Platform Awareness Service DBus documentation.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Introduction&lt;/h1&gt;
&lt;br /&gt;One of the features of the Intel® MID platform is its support for GPS-based location awareness. While an OEM of Service Provider makes the decision about whether to include a GPS device in their MID, the ability to provide location-based services (LBS)—including context specific advertising and Point of Interaction sales—is compelling.&lt;br /&gt;&lt;br /&gt;In addition to GPS data, there are several other ways to compute the location of a device, including IP address provider mapping, cell tower triangulation, Wifi access point proximity, etc. This paper focuses exclusively on retrieving data from the GPS device.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;How to get Location Information in Linux&lt;/h1&gt;
&lt;br /&gt;GPS information is not easily accessible in Linux, but it is available. Some GPS devices can connect via Bluetooth, but most will be connected via a USB or serial port. Finding out which port the device is mapped to can be rather difficult. For help on setting up a Bluetooth device, try &lt;a href="http://gpsd.berlios.de/bt.html"&gt;http://gpsd.berlios.de/bt.html&lt;/a&gt;. Linux’s HAL (Hardware Abstraction Layer) might be useful for finding a device connected by USB or serial. You can use HAL to find out which serial devices the system recognizes, and where to access them:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;hal-find-by-capability --capability serial&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;HAL will return a device name for each serial device that if finds (for example: /org/freedesktop/Hal/devices/usb_device_1546_1a4_noserial1_if0_serial_unknown_0). From here you can find the path to access the device:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;hal-get-property &lt;br /&gt;--udi /org/freedesktop/Hal/devices/usb_device_1546_1a4_noserial_if0_serial_unknown_0 &lt;br /&gt;--key serial.device&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;This will generally map to a &lt;span style="font-family: courier new;"&gt;/dev/tty*&lt;/span&gt; location. You can listen to the serial device directly. For example, a GPS device connected to &lt;span style="font-family: courier new;"&gt;/dev/ttyACM0&lt;/span&gt; can be seen by doing the following:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;cat /dev/ttyACM0&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;In most cases, you’ll see rather cryptic NMEA 0183 sentences that are hard to understand. See example NMEA sentances below:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;$GPTPV,2005-02-11T04:40:51.231Z,?,4916.45N,123.12W,2.3,70.1,52.0,01.0,02.1,23.1,0.6,,,8,A&lt;br /&gt;$GPSVU,2005-02-11T04:40:51.231Z,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00,14,25,170,00,16,57,208,39!,18,67,296,40!,19,40,246,00,22,42,067,42,24,14,311,43!,27,05,244,00&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;This data can be parsed and translated into geographic data.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Using gpsd&lt;/h1&gt;
&lt;br /&gt;gpsd is a service daemon that can listen to a USB, serial, or Bluetooth GPS device and provide the user with meaningful location information. For more detailed information, visit &lt;a href="http://gpsd.berlios.de/"&gt;http://gpsd.berlios.de/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;gpsd will connect to the GPS device and parse the device’s data into location coordinates, so you don’t have to do it manually. This takes away all of the hassle of having to translate the NMEA 0183 sentences that were shown above. gpsd also allows multiple GPS clients to have access to the GPS data at the same time. If you design your application to grab the data directly from the serial port, other applications will not be able to access the GPS data.&lt;br /&gt;&lt;br /&gt;For these reasons, the Platform Awareness Service has been implemented to use gpsd for its location-based information.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Install and Launch gpsd&lt;/h1&gt;
&lt;br /&gt;You can download gpsd for Linux directly from the website listed above or install it directly from your favorite package manager repository.&lt;br /&gt;&lt;br /&gt;Once gpsd is installed, it must be run with a parameter indicating the location of the GPS device. In this case the path was &lt;span style="font-family: courier new;"&gt;/dev/ttyUSB0&lt;/span&gt;. For debugging purposes, it may be good to initially include the following optional flags:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gpsd -n -N -D 2 /dev/ttyUSB0&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;-n:&lt;/strong&gt; begin polling the GPS device immediately; otherwise it will wait for a client to connect before it polls the GPS&lt;br /&gt;&lt;strong&gt;-N:&lt;/strong&gt; don’t daemonize; run in foreground; good for debugging&lt;br /&gt;&lt;strong&gt;-D 2:&lt;/strong&gt; set the debug level of information&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt; gpsd can be set to run as a daemon and can also be configured to launch upon startup of the device.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Getting Location data from gpsd&lt;/h1&gt;
&lt;br /&gt;There are a couple of ways to get location data from gpsd.&lt;br /&gt;&lt;br /&gt;1. Libgps&lt;br /&gt;&lt;br /&gt;Libgps is an interface library (in C) that manages communication with the daemon. There’s also libgpsmm, a C++ wrappper for libgps. The libgps documentation is available at http://gpsd.berlios.de/libgps.html.&lt;br /&gt;&lt;br /&gt;Libgps gives you the freedom to poll gpsd as often or as infrequent as you’d like. You can also create a callback method that is called anytime the GPS information is updated (like a signal).&lt;br /&gt;&lt;br /&gt;2. D-Bus&lt;br /&gt;&lt;br /&gt;Listening for a D-Bus signal coming from gpsd can get you this same information. In version 2.37 of gpsd, there are only two implemented D-Bus calls that an application can use. You can call &lt;span style="font-family: courier new;"&gt;initialize_dbus_connection()&lt;/span&gt;, then you can listen for a &lt;span style="font-family: courier new;"&gt;send_dbus_fix()&lt;/span&gt; signal, which includes all of the GPS’s data in a giant struct.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Using Libgps&lt;/h1&gt;
&lt;br /&gt;A client application may choose to listen for D-Bus messages that come from gpsd, or it may use the libgps interface library to communicate with gpsd. The Platform Awareness Service uses libgps’s polling method to get location information. This allows clients to determine how often they want location updates.&lt;br /&gt;&lt;br /&gt;To connect to gpsd, you must use the &lt;span style="font-family: courier new;"&gt;gps_open()&lt;/span&gt; function to connect to port 2947 of the host computer. Then the &lt;span style="font-family: courier new;"&gt;gps_set_raw_hook()&lt;/span&gt; method allows you to define a function to be executed each time a &lt;span style="font-family: courier new;"&gt;gps_query / gps_poll&lt;/span&gt; command is run.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;#include &lt;br /&gt; &lt;br /&gt;gboolean isConn2GPSD = FALSE;&lt;br /&gt;struct gps_data_t *gpsdata = 0;&lt;br /&gt; &lt;br /&gt;void connectToGPSD() {&lt;br /&gt;    if (gpsdata == NULL) {&lt;br /&gt;    // ran for first time: initialization&lt;br /&gt;        char* server = "localhost";&lt;br /&gt;        char* port = "2947";     // default port&lt;br /&gt; &lt;br /&gt;        gpsdata = gps_open(server, port);&lt;br /&gt; &lt;br /&gt;        if (gpsdata != NULL) {&lt;br /&gt;            isConn2GPSD = TRUE;&lt;br /&gt;            gps_set_raw_hook(gpsdata, (void *)updateGPSdata_cb);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;updateGPSdata_cb&lt;/span&gt; is the function that is executed anytime I poll gpsd. &lt;span style="font-family: courier new;"&gt;myGPSdata&lt;/span&gt; stores the location data that I’m interested in.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;struct GPSdata {&lt;br /&gt;    double latitude;&lt;br /&gt;    double longitude;&lt;br /&gt;    double altitude;&lt;br /&gt;} myGPSdata;&lt;br /&gt; &lt;br /&gt;void *updateGPSdata_cb() {&lt;br /&gt;    if (gpsdata-&amp;gt;fix.mode &amp;gt; 1) {&lt;br /&gt;        // if there's a fix&lt;br /&gt;        myGPSdata.latitude = gpsdata-&amp;gt;fix.latitude;&lt;br /&gt;        myGPSdata.longitude = gpsdata-&amp;gt;fix.longitude;&lt;br /&gt;        myGPSdata.altitude = gpsdata-&amp;gt;fix.altitude;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The gpsdata struct that is populated by gpsd carries more than just latitude, longitude, and altitude information. The only place I could find a description of this struct was inside the source code of gpsd.&lt;br /&gt;&lt;br /&gt;With this code in place, an application is free to poll gpsd for location information at its own leisure. It only needs to call the &lt;span style="font-family: courier new;"&gt;gps_query / gps_poll&lt;/span&gt; methods that are available from libgps.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Writing Location-Aware Applications&lt;/h1&gt;
&lt;br /&gt;In a world where more and more computational power is going into handheld devices, location-based software is being developed at a rapid rate. Hopefully this paper covered enough detail to get you started on writing your own location-aware applications for Linux.&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/B_-dyxpdbec" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/B_-dyxpdbec/how-to-obtain-location-information-in-linux</link>
      <pubDate>Wed, 22 Apr 2009 16:12:12 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux</guid>
      <category>Mobility</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux</feedburner:origLink></item>
    <item>
      <title>Developing Power Aware Applications Using D-Bus</title>
      <description>&lt;table id="Table_01" style="height: 101px;" border="0" cellspacing="0" cellpadding="0" width="580"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="13" width="580" height="5"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="580" height="5" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service/"&gt;&lt;img src="http://software.intel.com/file/15855" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-d-bus-interface-documentation"&gt;&lt;img src="http://software.intel.com/file/15856" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-monitor-users-guide"&gt;&lt;img src="http://software.intel.com/file/15857" border="0" alt="" width="95" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-source-code"&gt;&lt;img src="http://software.intel.com/file/15858" border="0" alt="" width="97" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="3"&gt;&lt;a href="http://software.intel.com/en-us/articles/platform-awareness-service-downloads"&gt;&lt;img src="http://software.intel.com/file/15859" border="0" alt="" width="96" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/moblin-platform-awareness-service-community"&gt;&lt;img src="http://software.intel.com/file/15860" border="0" alt="" width="99" height="33" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/utilizing-processor-performance-in-rich-internet-applications"&gt;&lt;img src="http://software.intel.com/file/15861" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/determining-input-devices-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15862" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/obtaining-display-information-on-mobile-internet-devices"&gt;&lt;img src="http://software.intel.com/file/15863" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/detecting-network-connectivity-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15864" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus"&gt;&lt;img src="http://software.intel.com/file/15865" border="0" alt="" width="80" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-storage-information-in-linux"&gt;&lt;img src="http://software.intel.com/file/15866" border="0" alt="" width="79" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;a href="http://software.intel.com/en-us/articles/how-to-obtain-location-information-in-linux/"&gt;&lt;img src="http://software.intel.com/file/15867" border="0" alt="" width="78" height="35" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td rowspan="2" width="27" height="62"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="62" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="12" width="553" height="27"&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="553" height="27" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="80" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="17" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="61" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="35" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="44" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="51" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="28" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="69" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="11" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="79" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="6" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="72" height="1" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://software.intel.com/file/15868" alt="" width="27" height="1" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 class="sectionHeading"&gt;Introduction&lt;/h1&gt;
&lt;br /&gt;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 &lt;em&gt;Mobile Internet Devices (MIDs)&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Background on D-Bus&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;In order to use D-Bus, we need to explore some concepts about D-Bus. First, an &lt;em&gt;object&lt;/em&gt; is an endpoint on the bus, an &lt;em&gt;object&lt;/em&gt; 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 &lt;em&gt;object paths&lt;/em&gt;. 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.&lt;br /&gt;&lt;br /&gt;An object can perform some specific operations. Each operation is referred as &lt;em&gt;method&lt;/em&gt;. 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.&lt;br /&gt;&lt;br /&gt;An object can also emit an event, or &lt;em&gt;signal&lt;/em&gt;. 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. &lt;em&gt;Methods&lt;/em&gt; and &lt;em&gt;Signals&lt;/em&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;In order to generate dbus-glib binding code, we can use a tool called &lt;em&gt;dbus-binding-tool&lt;/em&gt;. We first create an XML file, referred as &lt;em&gt;Introspection XML file&lt;/em&gt;, in which we describe the methods and signals. An example of the introspection XML is shown below:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;
&amp;lt;!DOCTYPE node PUBLIC 
"-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
"http://standards.freedesktop.org/dbus/1.0/introspect.dtd"&amp;gt;
&amp;lt;node name="/org/moblin/Platform"&amp;gt;
  &amp;lt;interface name="org.moblin.Platform.Power"&amp;gt;
       &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="org_moblin_platform_power"/&amp;gt;
    &amp;lt;method name="IsUsingExternalPowerSource"&amp;gt;
       &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="isUsingExternalPowerSource" /&amp;gt;
       &amp;lt;arg type="b" name="usingExternalPowerSource" direction="out" /&amp;gt;
    &amp;lt;/method&amp;gt;
    &amp;lt;method name="GetTimeRemaining"&amp;gt;
       &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getTimeRemaining"/&amp;gt;
       &amp;lt;arg type="i" name="minutesRemaining" direction="out" /&amp;gt;
    &amp;lt;/method&amp;gt;
    &amp;lt;method name="GetPercentRemaining"&amp;gt;
       &amp;lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="getPercentRemaining"/&amp;gt;
       &amp;lt;arg type="u" name="percentRemaining" direction="out" /&amp;gt;
    &amp;lt;/method&amp;gt;
  &amp;lt;/interface&amp;gt;
&amp;lt;/node&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;In this introspection XML file (named &lt;em&gt;MIDPlatformSvcInterfaceDefinition.xml&lt;/em&gt;), an interface called org.moblin.Platform.Power defines three methods: &lt;em&gt;IsUsingExternalPowerSource&lt;/em&gt;, &lt;em&gt;GetTimeRemaining&lt;/em&gt; and &lt;em&gt;GetPerCentRemaining&lt;/em&gt;. 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.&lt;br /&gt;&lt;br /&gt;Below are primary steps to implement a service with methods to be exposed. More details are explained in [3].&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;em&gt;dbus-binding-tool&lt;/em&gt; for an introspection XML file to generate dbus-glib binding code&lt;/li&gt;
&lt;li&gt;Create a simple GObject for D-Bus&lt;/li&gt;
&lt;li&gt;Implement the instance initialization&lt;/li&gt;
&lt;li&gt;Implement the methods&lt;/li&gt;
&lt;li&gt;Register the object to the D-Bus&lt;/li&gt;
&lt;/ul&gt;
To call the methods implemented on a remote object, a client needs to follow the following steps:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Connect to the bus&lt;/li&gt;
&lt;li&gt;Create a proxy object&lt;/li&gt;
&lt;li&gt;Invoke the methods on the proxy object&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 class="sectionHeading"&gt;Using D-Bus as a Communication Channel&lt;/h1&gt;
&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Figure 1. Usage Model: A Client Registers to D-Bus to Get the Information Provided by the MISPlatformSvc&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://software.intel.com/file/15818" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Gathering Battery Information&lt;/h1&gt;
&lt;br /&gt;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 (&lt;em&gt;getPercentRemaining&lt;/em&gt;). This method returns the percent of power currently available in the battery.&lt;br /&gt;&lt;br /&gt;The second method queries the time remaining until the MID runs out of battery power (&lt;em&gt;getTimeRemaining&lt;/em&gt;). This method returns the remaining time in minutes.&lt;br /&gt;&lt;br /&gt;The third method queries whether or not the MID is using an external power source (&lt;em&gt;IsUsingExternalPowerSource&lt;/em&gt;). 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).&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean computePercentPowerRemaining(guint *result)
{
       DIR *d;
       struct dirent *de;
       char *acpi_path  = "/proc/acpi";
       char *device_type  = "battery";
       char *stateFile = "state";
       char *infoFile = "info";
       FILE *file;
       char filename[PATH_LENGTH];
       char line[LINE_LENGTH];
       *result = 0;
       double power_left = 0.0;
       double power_full = 0.0;
       gboolean rc = FALSE;
 
       // First, check if the ACPI path exists
       if (chdir(acpi_path) &amp;lt; 0) 
       {
              dbg("ACPI is not supported (\"%s\").\n", acpi_path);
              return rc;
       }
       else
              dbg("Path %s is found \n", acpi_path);
 
       // Check if battery directory exists
       if (chdir(device_type) &amp;lt; 0) 
       {
              dbg("No support for device type: %s\n", device_type);
              return rc;
       }
       else
              dbg("Device %s is supported \n", device_type);
       
       // /proc/acpi/battery is found. Now search for available batteries
       d = opendir(".");
       if (!d) {
              dbg("Cannot open directory!\n");
              return rc;
       }
 
       while ((de = readdir(d))) {
              // Search for real directory ("BAT0", ...), not ".", ".."
              if (!strcmp(de-&amp;gt;d_name, "."))
                     continue;
 
              if (!strcmp(de-&amp;gt;d_name, ".."))
                     continue;
 
              dbg("device found: %s\n", de-&amp;gt;d_name);
 
              // Open file "state".
              sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de-&amp;gt;d_name, stateFile);
              file = fopen(filename, "r");
              if (!file)
              {
                     closedir(d);
                     return rc;
              }
 
              memset(line, 0, LINE_LENGTH);
              while (fgets(line, LINE_LENGTH, file) != NULL) {
                     if (strstr(line, "remaining capacity:") &amp;amp;&amp;amp; 
                           (strstr(line, "mWh") || strstr(line, "mAh")))
                     {
                           // Search the value
                           char *c;
 
                           c = strchr(line, ':');
                           c++;
 
                           power_left = strtoull(c, NULL, 10);      // in mWh or mAh
 
                           // Cannot perform conversion
                           if ((0 == power_left) &amp;amp;&amp;amp; (EINVAL == errno))
                           {
                                  closedir(d);
                                  return rc;                 
                           }
                           break;
                     }
              }
 
              fclose(file);
 
              // Open file "info".
              sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de-&amp;gt;d_name, infoFile);
              file = fopen(filename, "r");
              if (!file)
              {
                     closedir(d);
                     return rc;
              }
 
              memset(line, 0, LINE_LENGTH);
              while (fgets(line, LINE_LENGTH, file) != NULL) {
                     if (strstr(line, "last full capacity:") &amp;amp;&amp;amp; 
                            (strstr(line, "mWh") || strstr(line, "mAh")))
                     {
                           // Search the value
                           char *c;
 
                           c = strchr(line, ':');
                           c++;
 
                           power_full = strtoull(c, NULL, 10);      // in mWh or mAh
 
                           // Cannot perform conversion
                           if (0 == power_full)
                           {
                                  closedir(d);
                                  return rc;                 
                           }
 
                           *result = (power_left/power_full)*100;  // in %
                           break;
                     }
              }
 
              rc = TRUE;
              fclose(file);
 
              // Exit while loop
              break;
       }
       closedir(d);
 
       return rc;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;The second method queries the time remaining until the MID is out battery power (&lt;em&gt;getTimeRemaining&lt;/em&gt;). 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:&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;int computeTimeRemaining(void)
{
       DIR *d;
       struct dirent *de;
 
       char *acpi_path  = "/proc/acpi";
       char *device_type  = "battery";
       char *stateFile = "state";
 
       FILE *file;
       char filename[PATH_LENGTH];
       char line[LINE_LENGTH];
       int result = -1;
       double power_left = 0.0;
       double power_full = 0.0;
       double dischargeRate = 0.0;
       int find = 0;
 
       // First, check if the ACPI path exists
       if (chdir(acpi_path) &amp;lt; 0) 
       {
              dbg("ACPI is not supported (\"%s\").\n", acpi_path);
              return result;
       }
       else
              dbg("Path %s is found \n", acpi_path);
 
       // Check if battery directory exists
       if (chdir(device_type) &amp;lt; 0) 
       {
              dbg("No support for device type: %s\n", device_type);
              return result;
       }
       else
              dbg("Device %s is supported \n", device_type);
       
       // /proc/acpi/battery is found. Now search for available batteries
       d = opendir(".");
       if (!d) {
              dbg("Cannot open directory!\n");
              return result;
       }
 
       while ((de = readdir(d))) {
              // Search for real directory ("BAT0", ...), not ".", ".."
              if (!strcmp(de-&amp;gt;d_name, "."))
                     continue;
 
              if (!strcmp(de-&amp;gt;d_name, ".."))
                     continue;
 
              dbg("device found: %s\n", de-&amp;gt;d_name);
 
              // Open file "state".
              sprintf(filename, "%s/%s/%s/%s", acpi_path, device_type, de-&amp;gt;d_name, stateFile);
              file = fopen(filename, "r");
              if (!file)
              {
                     closedir(d);
                     return result;
              }
 
              memset(line, 0, LINE_LENGTH);
 
              while (fgets(line, LINE_LENGTH, file) != NULL) {
                     if (strstr(line, "charging state:") &amp;amp;&amp;amp;
                           strstr(line, "discharging"))
                     {
                           find++;
                     }
 
                     if (strstr(line, "present rate:") &amp;amp;&amp;amp;
                           (strstr(line, "mW") || strstr(line, "mA")))
                     {
                           // Search the value
                           char *c;
 
                           c = strchr(line, ':');
                           c++;
 
                           dischargeRate = strtoull(c, NULL, 10);   // in mW or mA
 
                           // Cannot perform conversion
                           if ((0 == dischargeRate) &amp;amp;&amp;amp; (EINVAL == errno))
                           {
                                  closedir(d);
                                  return result;                    
                           }
 
                           find++;
                     }
 
                     if (strstr(line, "remaining capacity:") &amp;amp;&amp;amp; 
                           (strstr(line, "mWh") || strstr(line, "mAh")))
                     {
                           // Search the value
                           char *c;
 
                           c = strchr(line, ':');
                           c++;
 
                           power_left = strtoull(c, NULL, 10);      // in mWh or mAh
 
                           // Cannot perform conversion
                           if ((0 == power_left) &amp;amp;&amp;amp; (EINVAL == errno))
                           {
                                  closedir(d);
                                  return result;                    
                           }
 
                           find++;
                     }
 
 
              }
 
              fclose(file);
 
              // Exit while loop
              break;
       }
       closedir(d);
 
       if (find == 3)
       {
              result = 0;
 
              if (dischargeRate &amp;gt; 0)
                     result = (power_left/dischargeRate)*60;  // convert to minutes
       }
 
       return result;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;int computePowerSource()
{
       DIR *d;
       struct dirent *de;
       char *acadaptor_path  = "/proc/acpi/ac_adapter";
       char *stateFile = "state";
       FILE *file;
       int result = -1;
       char filename[PATH_LENGTH];
 
       // First, check if the ac_adaptor path exists
       if (chdir(acadaptor_path) &amp;lt; 0) 
       {
              return result;
       }
 
       // /proc/acpi/ac_adaptor is found. Now search for available entry
       d = opendir(".");
       if (!d) {
              return result;
       }
 
       while ((de = readdir(d))) {
              char line[LINE_LENGTH];
              // Search for real directory (not ".", ".."
              if (!strcmp(de-&amp;gt;d_name, "."))
                     continue;
 
              if (!strcmp(de-&amp;gt;d_name, ".."))
                     continue;
 
              sprintf(filename, "%s/%s/%s", acadaptor_path, de-&amp;gt;d_name, stateFile);
              file = fopen(filename, "r");
              if (!file)
              {
                     closedir(d);
                     return result;
              }
 
              memset(line, 0, LINE_LENGTH);
              while (fgets(line, LINE_LENGTH, file) != NULL) {
                     if (strstr(line, "state:") &amp;amp;&amp;amp; strstr(line, "off-line"))
                           result = 0;   // AC (battery)
                     else if (strstr(line, "state:") &amp;amp;&amp;amp; strstr(line, "on-line"))
                           result = 1;   // DC
              }
 
              fclose(file);
       }
 
       closedir(d);
 
       return result;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Putting Things Together&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;% dbus-binding-tool --mode=glib-server -–prefix=MIDPlatformSvc --output=MIDPlatformSvc-dbus-glue.h MIDPlatformSvcInterfaceDefinition.xml
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;gboolean getPercentRemaining(MIDPlatformSvc *obj, guint *percentRemaining, GError **error)
{
       gboolean rc = FALSE;
 
       rc = computePercentPowerRemaining(percentRemaining);
 
       if (rc) 
              return TRUE;
       else
       {
              g_set_error(error, 
                         G_FILE_ERROR,
                         G_FILE_ERROR_NOENT,
                         "Failed to open file /proc/acpi/battery");
              return FALSE;
       }
}
 
gboolean getTimeRemaining(MIDPlatformSvc *obj, gint *timeRemaining, GError **error)
{      
       *timeRemaining = computeTimeRemaining();
 
       if (*timeRemaining &amp;gt; 0)
       {
              return TRUE;
       }
       else if (*timeRemaining == 0)
       {
              g_set_error(error, 
                         G_FILE_ERROR,
                         G_FILE_ERROR_NOENT,
                         "Cannot determine since information is missing!");
              return FALSE;        
       }
       else
       {
              g_set_error(error, 
                         G_FILE_ERROR,
                         G_FILE_ERROR_NOENT,
                         "Failed to open file or directory");
              return FALSE;
       }
}
 
gboolean isUsingExternalPowerSource(MIDPlatformSvc *obj, gboolean *onExternalSource, GError **error)
{
       int t = computePowerSource();
 
       if (t == 0)
       {
              *onExternalSource = FALSE;
              return TRUE;
       }
       else if (t == 1)
       {
              *onExternalSource = TRUE;
              return TRUE;
       }
       else
       {
              g_set_error(error, 
                         G_FILE_ERROR,
                         G_FILE_ERROR_NOENT,
                         "Failed to open file or directory");

              return FALSE;
       }
}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;A Test Client&lt;/h1&gt;
&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="cpp"&gt;#define PLATFORM_SERVICE          "org.moblin.Platform"
#define PLATFORM_PATH                    "/org/moblin/Platform"
#define PLATFORM_POWER_IF         "org.moblin.Platform.Power"
#define POWER_SRC_CHANGED_SIGNAL  "PowerSourceChanged"
 
void queryMethod(char* param) 
{
       DBusGConnection* conn;
       GError *error;
       DBusGProxy *platformProxy;
       DBusError err;
 
       printf("Calling remote method: %s\n", param);
 
       g_type_init();
       error = NULL;
       conn = dbus_g_bus_get(DBUS_BUS_SESSION, &amp;amp;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_POWER_IF);      // interface to call on
 
       // Now call the metjod "IsUsingExternalPowerSource"
       if (param == "GetPercentRemaining")
       {
              uint result;
 
              if (!dbus_g_proxy_call(platformProxy, param, &amp;amp;error, 
                                   G_TYPE_INVALID,
                                   G_TYPE_UINT, &amp;amp;result,
                                   G_TYPE_INVALID))
              {
                     g_printerr("Failed to call remotely: %s\n",
                                error-&amp;gt;message);
                     g_error_free(error);
              }
              else
                     printf ("Remote call successes with returned value: %d%\n", result);
       }
       else if (param == "GetTimeRemaining")
       {
              int result;
 
              if (!dbus_g_proxy_call(platformProxy, param, &amp;amp;error, 
                                  G_TYPE_INVALID,
                                 G_TYPE_INT, &amp;amp;result,
                                 G_TYPE_INVALID))
              {
                     g_printerr("Failed to call remotely: %s\n",
                            error-&amp;gt;message);
                     g_error_free(error);
              }
              else
              {
                     printf ("Remote call successes with returned value: %d minutes\n",result);
              }
       }
       else if (param == "IsUsingExternalPowerSource")
       {
              gboolean result;
 
              if (!dbus_g_proxy_call(platformProxy, param, &amp;amp;error, 
                                  G_TYPE_INVALID,
                                 G_TYPE_BOOLEAN, &amp;amp;result,
                                 G_TYPE_INVALID))
              {
                     g_printerr("Failed to call remotely: %s\n",
                            error-&amp;gt;message);
                     g_error_free(error);
              }
              else
                     printf ("Remote call successes with returned value: %s\n", result? "TRUE" : "FALSE");
       }
 
}
 
int main(int argc, char** argv)
{
       char* methodName[3] = {"GetPercentRemaining",
                           "GetTimeRemaining",
                            "IsUsingExternalPowerSource"};
 
       int i;
       
       for (i = 0; i &amp;lt;= 2; i++)
              queryMethod(methodName[i]);
 
       return 0;
}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Below is the result when running the test client.&lt;br /&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;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
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;Conclusion&lt;/h1&gt;
&lt;br /&gt;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...&lt;br /&gt;&lt;br /&gt;
&lt;h1 class="sectionHeading"&gt;References&lt;/h1&gt;
&lt;br /&gt;[1] D-Bus, &lt;a href="http://www.freedesktop.org/wiki/Software/dbus" target="_blank"&gt;http://www.freedesktop.org/wiki/Software/dbus&lt;/a&gt;&lt;br /&gt;[2] D-Bus Tutorial, &lt;a href="http://dbus.freedesktop.org/doc/dbus-tutorial.html" target="_blank"&gt;http://dbus.freedesktop.org/doc/dbus-tutorial.html&lt;/a&gt;&lt;br /&gt;[3] &lt;a href="http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php" target="_blank"&gt;http://www.moblin.org/toolkits/basicDevGuides/mobLinux/toolkits_DevGds_mobLinux_createDBUS.php&lt;/a&gt;&lt;br /&gt;[4] Mobile and Internet Linux Project, &lt;a href="http://moblin.org/" target="_blank"&gt;http://moblin.org/&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/ISNMobility/~4/4wfMqkgBqKE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/ISNMobility/~3/4wfMqkgBqKE/developing-power-aware-applications-using-d-bus</link>
      <pubDate>Wed, 22 Apr 2009 16:11:33 -0700</pubDate>
      <comments>http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus#comments</comments>
      <guid isPermaLink="false">http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus</guid>
      <category>Mobility</category>
    <feedburner:origLink>http://software.intel.com/en-us/articles/developing-power-aware-applications-using-d-bus</feedburner:origLink></item>
  </channel>
</rss>
