Welcome to MSDN Blogs Sign in | Join | Help

Managing APN Settings on Google Android

An APN (Access Point Name) is the information needed to establish a GPRS/EDGE/UMTS cellular packet data connection on a mobile device. Usually the device can be configured by the operator, the OEM, and users with an APN address such as wap.cingular or epc.tmobile.com that will be eventually resolved to the IP address of the GGSN in the operator's network.

Users can go to Settings-->Wireless control-->Mobile networks-->Access point names to view and edit existing APNs.

Google Android uses a SQLite data table to store all APNs configured on the device, as shown below:

Database: /data/data/com.android.providers.telephony/databases/telephony.db
Table: carriers
URI: content://telephony/carriers

_id

 name

numeric

mcc

mnc

apn

user

server

 password

1

 T-Mobile US

310260

310

260

epc.tmobile.com

none

   *

 none

 

proxy

port

mmsproxy

mmsport

mmsc

type

current

  

      

      

      

http://mms.msg.eng.t-mobile.com/mms/wapenc

default

1

This is a data record in the carriers table. the "_id" is the primary key auto-generated when you add new APN records using APIs or the UI manually. The "name" filed will appear on the setting UI. The 'numeric' field identifies the network that the APN associates with, which is a combination of mcc (mobile country code) and mnc (mobile network code). An operator may have a number of 'numeric' values to cover all this network. The "mmsproxy", "mmsport", and "mmsc" fields are for MMS configurations. The "type" field for an APN can be either 'default' for general data traffic, or 'mms' for MMS.

Note: Android does not support multiple actively APNs (simultaneous PDP contexts), as of 1.6 SDK. In other words, if MMS APN is activated, then the default web APN will be disconnected. 

The Android SDK (1.5 and 1.6) does not provide APIs to manage APN (Access Point Name)s directly. So you have to use the Telephony content provider to do that. Take a look at the TelephonyProvider.java source code will definitely help.I wrote some quick test code to enumerate and add APNs to the system, as well as set an APN to be the default one such that the device will use it for subsequent connections (this is indicated by the radio button in the APN list UI).

  •  Enumerate all APNs in the system:
    /*
     * Information of all APNs
     * Details can be found in com.android.providers.telephony.TelephonyProvider
     */
    public static final Uri APN_TABLE_URI =
        Uri.parse("content://telephony/carriers");
    /*
     * Information of the preferred APN
     *
     */
    public static final Uri PREFERRED_APN_URI =
        Uri.parse("content://telephony/carriers/preferapn"); 

    /*
     * Enumerate all APN data
     */
    private void EnumerateAPNs()
    {
        Cursor   c = context.getContentResolver().query(
                APN_TABLE_URI, null, null, null, null);
        if (c != null)
        {
            /*
             *  Fields you can retrieve can be found in
                com.android.providers.telephony.TelephonyProvider :
                
                db.execSQL("CREATE TABLE " + CARRIERS_TABLE +
                "(_id INTEGER PRIMARY KEY," +
                "name TEXT," +
                "numeric TEXT," +
                "mcc TEXT," +
                "mnc TEXT," +
                "apn TEXT," +
                "user TEXT," +
                "server TEXT," +
                "password TEXT," +
                "proxy TEXT," +
                "port TEXT," +
                "mmsproxy TEXT," +
                "mmsport TEXT," +
                "mmsc TEXT," +
                "type TEXT," +
                "current INTEGER);");
             */
            
            String s = "All APNs:\n";
            Log.d(TAG, s);
              try
            {
                s += printAllData(c); //Print the entire result set
            }
              catch(SQLException e)
              {
                  Log.d(TAG, e.getMessage());
              }
 
              //Log.d(TAG, s + "\n\n");
            c.close();
        }

    }

  • Add a new APN record:
   /*
     * Insert a new APN entry into the system APN table
     * Require an apn name, and the apn address. More can be added.
     * Return an id (_id) that is automatically generated for the new apn entry.
     */
    public int InsertAPN(String name, String apn_addr)
    {
        int id = -1;
        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues();
        values.put("name", name);
        values.put("apn", apn_addr);
       
        /*
         * The following three field values are for testing in Android emulator only
         * The APN setting page UI will ONLY display APNs whose 'numeric' filed is
         * TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC.
         * On Android emulator, this value is 310260, where 310 is mcc, and 260 mnc.
         * With these field values, the newly added apn will appear in system UI.
         */
        values.put("mcc", "310");
        values.put("mnc", "260");
        values.put("numeric", "310260");
       
        Cursor c = null;
        try
        {
            Uri newRow = resolver.insert(APN_TABLE_URI, values);
            if(newRow != null)
            {
                c = resolver.query(newRow, null, null, null, null);
                Log.d(TAG, "Newly added APN:");
                printAllData(c); //Print the entire result set
               
                // Obtain the apn id
                int idindex = c.getColumnIndex("_id");
                c.moveToFirst();
                id = c.getShort(idindex);
                Log.d(TAG, "New ID: " + id + ": Inserting new APN succeeded!");
            }
        }
        catch(SQLException e)
        {
            Log.d(TAG, e.getMessage());
        }

        if(c !=null )
            c.close();
        return id;
    }
  •  Set an APN to be the default
   /*
     * Set an apn to be the default apn for web traffic
     * Require an input of the apn id to be set
     */
    public boolean SetDefaultAPN(int id)
    {
        boolean res = false;
        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues();
       
        //See /etc/apns-conf.xml. The TelephonyProvider uses this file to provide
        //content://telephony/carriers/preferapn URI mapping
        values.put("apn_id", id);
        try
        {
            resolver.update(PREFERRED_APN_URI, values, null, null);
            Cursor c = resolver.query(
                    PREFERRED_APN_URI,
                    new String[]{"name","apn"},
                    "_id="+id,
                    null,
                    null);
            if(c != null)
            {
                res = true;
                c.close();
            }
        }
        catch (SQLException e)
        {
            Log.d(TAG, e.getMessage());
        }
         return res;
    }
Two helper functions are created to print data using a cursor:
    /*
     * Return all column names stored in the string array
     */
    private String getAllColumnNames(String[] columnNames)
    {
        String s = "Column Names:\n";
        for(String t:columnNames)
        {
            s += t + ":\t";
        }
        return s+"\n";
    }
   
    /*
     *  Print all data records associated with Cursor c.
     *  Return a string that contains all record data.
     *  For some weird reason, Android SDK Log class cannot print very long string message.
     *  Thus we have to log record-by-record.
     */
    private String printAllData(Cursor c)
    {
        if(c == null) return null;
        String s = "";
        int record_cnt = c.getColumnCount();
        Log.d(TAG, "Total # of records: " + record_cnt);
       
        if(c.moveToFirst())
        {
            String[] columnNames = c.getColumnNames();
            Log.d(TAG,getAllColumnNames(columnNames));
            s += getAllColumnNames(columnNames);
            do{
                String row = "";
                for(String columnIndex:columnNames)
                {
                    int i = c.getColumnIndex(columnIndex);
                    row += c.getString(i)+":\t";
                }
                row += "\n";
                Log.d(TAG, row);
                s += row;
            }while(c.moveToNext());
            Log.d(TAG,"End Of Records");
        }
        return s;
    }
The Android emulator's default APN is a T-Mobile APN as shown in the picture below:

 Then, let's add a new APN and set it to default:

       //Let's try insert a new APN, whose name is 'google2' and apn address is google.com, just for fun.
        int id = InsertAPN("google2","google.com");
       
        //Set the newly added APN to be the default one for web traffic.
        //The new one will show up in settings->Wireless controls->Mobile networks->Access Point Names),
        //and has been set as default (indicated by the green check button)
        SetDefaultAPN(id);

Then the newly added APN will appear in the UI and shown as 'default'.

Posted by zhengpei | 0 Comments
Filed under:

Mobile Service Innovations In Developing Countries

Check out the latest special report on mobile marvels by Economist. For many of the people in Kenya who don't have a bank card and a named address, mobile phones are increasingly becoming an indispensable part of day-to-day life.  Farmers in Uganda are using SMS based query services o know the weather forecast for the coming season so they can decide when to plant. The trends of mobile services in developing countries are summarized as follows:

The third trend is the development of new phone-based services, beyond voice calls and basic text messages, which are now becoming feasible because mobile phones are relatively widely available. In rich countries most such services have revolved around trivial things like music downloads and mobile gaming. In poor countries data services such as mobile-phone-based agricultural advice, health care and money transfer could provide enormous economic and developmental benefits. Beyond that, mobile networks and low-cost computing devices are poised to offer the benefits of full internet access to people in the developing world in the coming years.

And where are the new mobile subscribers?

 

 What does this mean to mobile OEMs and software vendors? I think there are at least two aspects to look into:

  1. From business development perspective: Do we have acknowledged this trend in the global mobile ecosystem and have developed strategy to build products optimized for those booming emerging markets?
  2. Form R&D perspective: What technologies can be applied to these new services to provide better user experience, productivity, security, interoperability, and reliability?  Beyond mobile money, text query service, social finance, and village computing, what else can be developed to address big problems that people in developing countries are facing everyday?
Sounds like unlimted potential if you look at the wide range of devices/services that can be developed for emerging markets, and keep in mind that their buying power will increase significantly as these become an essential part of their lives.
Posted by zhengpei | 0 Comments

ConnectivityManager in Android SDK: Compared with Connection Manager in Windows Mobile

Anyone who has ever used Windows Mobile (actually WinCE) Connection Manager will probably share mix feelings: on one side, the ConnMgr APIs provide a nice abstraction for applications to request and use a connection without knowing and controlling the physical connectivity; on the other side, it has been a pain in the neck to override or bypass Connection Manager's connection selection logic if the application should use a specific physical connection (for example, GPRS rather than WiFi). And the concept of metanetworks, Internet, Work, WAP network, Secured WAP, is indeed very confusing and difficult to manipulate.

So how does Android manage connections?

In Android SDK 1.5 (code named cupcake),  the android.net.ConnectivityManager class (this is Java, not C++) provides connection state management and notification functionality. Specifically, it can be used to:

  1. Obtain broadcast intents when network connectivity changes by checking ConnectivityManager.CONNECTIVITY_ACTION and ConnectivityManager.EXTRA_NETWORK_INFO in a class extended from BroadcastReceiver. (For a brief introduction to Android application fundamentals, read this document. An example of network connectivity listener can be found here.
  2. Query the coarse-grained or fine-grained state of the available networks using ConnectivityManager.GetActiveNetworkInfo() or ConnectivityManager.GetNetworkInfo(int networkType).

This is same-old same-old as in Windows Mobile, which provides similar APIs like ConnMgrRegisterStatusNotification(), ConnMgrConnectionStatus, and ConnMgrQueryDetailedStatus() (examples of these APIs can be found in WM SDK cmhelper).

However, the ConnectivityManager class does offer an interesting method called requestRouteToHost():

public boolean requestRouteToHost (int networkType, int hostAddress)

Since: API Level 1

Ensure that a network route exists to deliver traffic to the specified host via the specified network interface. An attempt to add a route that already exists is ignored, but treated as successful.

Parameters
networkType the type of the network over which traffic to the specified host is to be routed
hostAddress the IP address of the host to which the route is desired
Returns
  • true on success, false on failure

 This method is very useful--it allows your application to ensure that a desired physical connectivity (represented by the networkType) is available to reach a specific destination. If a route to the destination IP address from the desired network type is in place (in the routing table), then it simply returns success. Otherwise, it will try to make that happen--this is not mentioned in the above description but can be traced to ConnectivityService class:

In ConnectivityManager class where mService is a ConnectivityService object:

/**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the specified network interface.
     * @param networkType the type of the network over which traffic to the specified
     * host is to be routed
     * @param hostAddress the IP address of the host to which the route is desired
     * @return {@code true} on success, {@code false} on failure
     */
    public boolean requestRouteToHost(int networkType, int hostAddress) {
        enforceChangePermission();
        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
            return false;
        }
        NetworkStateTracker tracker = mNetTrackers[networkType];
        /*
         * If there's only one connected network, and it's the one requested,
         * then we don't have to do anything - the requested route already
         * exists. If it's not the requested network, then it's not possible
         * to establish the requested route. Finally, if there is more than
         * one connected network, then we must insert an entry in the routing
         * table.
         */
        if (getNumConnectedNetworks() > 1) {
            return tracker.requestRouteToHost(hostAddress);
        } else {
            return tracker.getNetworkInfo().getType() == networkType;
        }
    }

The mNetTrackers array contains NetworkStateTracker objects for different network types (mobile data and WiFi).

In MobileDataStateTracker class, which extends from NetworkStateTracker:

/**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the mobile data network.
     * @param hostAddress the IP address of the host to which the route is desired,
     * in network byte order.
     * @return {@code true} on success, {@code false} on failure
     */
    @Override
    public boolean requestRouteToHost(int hostAddress) {
        if (mInterfaceName != null && hostAddress != -1) {
            if (DBG) {
                Log.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress));
            }
            return NetworkUtils.addHostRoute(mInterfaceName, hostAddress) == 0;
        } else {
            return false;
        }
    }

Notice the NetworkUtils.addHostRoute() call. This will add a host route into the system's routing table for the specified destination address via the mobile WWAN interface. This enables the scenario where you want your MMS go through a specific APN for MMS while other traffic on another APN. As of Android SDK 1.5, only MobileDataStateTracker class will actually does this--the WiFiStateTracker class does not do anything yet at this point.

"Wireless Networking Complete" Book Published!

I was told by my dear friends at Elsevier (formerly Morgan Kaufmann publishers) that the book "Wireless Networking Complete" has been published!

This book is a desktop reference covering everything about wireless networking, mainly from R&D perspective. Below is the TOC. Chapter 1: Supporting Wireless Technologies was excerpted from my book "Smart Phone and Next Generation Mobile Computing" published by Elsevier in 2005.

Contents


Chapter 1 Supporting Wireless Technologies

Chapter 2 Wireless Networks

Chapter 3 An Overview of Wireless Systems

Chapter 4 Wireless Application Protocol

Chapter 5 Wireless Local Area Networks

Chapter 6 Fourth Generation Systems and New Wireless Technologies

Chapter 7 Mesh Networks: Optimal Routing and Scheduling

Chapter 8 Ad Hoc Wireless Sensor Networks (WSNs)

Chapter 9 Sensor Network Platforms and Tools

Chapter 10 Mobile IP

Chapter 11 Mobile IPv6

Chapter 12 Security and Survivability of Wireless Systems

Posted by zhengpei | 0 Comments

Microsoft OneApp: A Could-Enabled App Framework for J2ME

The latest announcement of Microsoft OneApp does create some buzz in the mobile device community. Just to be clear, based on limited information Microsoft made available to the public, OneApp is a Java application for feature phones that provides a framework for developers to write apps using XML or JavaScript to leverage underlying device capability and, more importantly, cloud service (server side computing power and storage). Some sample apps running within OneApp are Windows Live Messager, Facebook, and Twitter. According to the OneApp site, OneApp has a very small footprint (less than 150KB), and has been highly optimized to reduce data traffic cost.

OneApp is reportedly to be able to run on any feature phones with Java (most likely J2ME CLDC+MIDP). So here come the questions:

1. Why bother with OneApp? Just go ahead downloading those Java apps from the Internet...

Today, even complex software like Opera Mini provides Java client for many feature phones, as long as the phone has J2ME. However, keep in mind that OneApp introduces a middle-man between your device and the software service provider (Twitter, Facebook) that, very likely, acts as a proxy or an agent to process transmitted and received data. This is the same idea as UCWeb Java version. It seems optimization enabled by the cloud is the key benefit of OneApp.

2. How difficult is it to develop an app (or widget?) for OneApp such that it runs on most cell phones in the world? 

We know that Palm WebOS, Google Android, and Windows Mobile 6.5 both allow developers to write widgets using just JavaScript and some flash. Opera Mobile browser also provides such a framework. And then here is another framework. We've yet to see a tutorial with some sort of OneApp emulator such that we can try develop a Digg for OneApp widget.

3. Is it only available from the operators? No free download?

It seems to me that OneApp folks are seeking collaboration with phone OEMs and operators to ship the product. No indication of free download yet at this moment. Well, to make this massively popular, it has to be made available for download from a Java midlet manager or some sort. To feature phone end-users, this should be like an one-stop shopping for several cool Java apps in a single JAR/JAD. If this is true, naturally the next question is, without charging license fee from OEMs and operator, how can Microsoft make money from this product? The underlying platform is NOT Windows Mobile, so boosting WM market share is not the goal here.

 

Posted by zhengpei | 0 Comments
Filed under:

Building a WAP Push Test Environment

For smart phone OEMs, it is generally difficult to test WAP Push and OMA OTA provisioning without having access to operator's testing facility. When operators or customers report issues related to SI (Service Indication) or SL (Service Loading) message handling, a local test environment to reproduce those issues will be a great help. For example, if an operator requires a specific handling of SL messages that the operating system does not support by default, we have to develop a customized SMS provider to enable it, and an environment for SL testing is needed for this task.

To build a small WAP Push test environment, we need to have SMS gateway software on the PC side that can send WAP Push as well as other SMS/MMS messages. For example, NowSMS is a pretty good SMS gateway tool that can allow you to send SMS text message, binary message, WAP Push, MMS, and OMA OTA settings to a phone, as long as you have either a GSM modem or a phone that can act as a GSM modem supporting SMS. Microsoft SMS Sender is another PC-side tool but it does not provide MMS and flash SMS capability. Hush SMS can be used to send SMS, Flash SMS, and SI/SL messages directly from the device.

My recommendation for building a WAP Push test environment is:

1. Purchase NowSMS and install on a desktop computer

2. Purchase  a GSM Modem, either a Sierra Wireless PC card or an external GSM model (Wavecom Fasttrack modem, for example).

3. Setup NowSMS with the GSM modem, and then use the web interface NowSMS provides to send WAP Push messages. 

Note: before setting up NowSMS with the GSM modem, make sure you first use HyperTerminal to verify the modem (with your SIM card) can actually send SMS messages. The following AT sequence is usually used to send a text SMS from the modem: 

ATE1V1
OK
AT+CSMS=0
+CSMS: 1,1,1
OK
AT+CSMS? (check if modem supports SMS)
+CSMS: 0,1,1,1
OK
AT+CSMS=?
+CSMS: (0-1)

OK
AT+CMGF=1 (to send text SMS)
OK
AT+CMGS="##########"
> hello (when modem returns ">", type your message and press Ctrl+Z)
+CMGS: 48
OK

 


Posted by zhengpei | 0 Comments

3rd Party Software Integration: What Quality Gates are Needed?

One of the key phases for a mobile device project is 3rd party software integration, which is usually done after initial software baseline has been established (BSP migration complete, driver stabilized, hopper & battery life pass). According to device software product definition, a number of 3rd party applications and modules (for example, some DShow filters) have been identified and made available for integration at this phase. Some of these software may not be the final release as the vendors may also need to conduct technical evaluation and testing with a sample device on their side before releasing a final release. Vendors will provide in-ROM integration instructions, and the ROM build team just needs to follow the instructions to generate test images.

Nonetheless, a well-defined strategy and process for 3rd party software quality gating turn out to be highly critical for device software stability. At minimum, for each 3rd party application, the following quality gates must be used:

  • Detecting leaks using Application Verifier: Make sure the application does no have significant memory leaks, handle leaks, GDI leaks. For modules/drivers, develop test tools to run within Application Verifier. This can be done within 3 days for a single application or module.
  • MTTF using hopper: Any application should not take down hopper number by more than 10%. Some applications were not designed with hopper testing in mind (for example, an application runs full-screen but does not enable "Start" button). These will bring down hopper numbers so they must be fixed. Having a focused hopper tool handy such that you can stress a specific application. Also useful is to enable debug messages in those 3rd party applications such that you can always check CElogs for a failed hopper run. This will usually take 3-6 days depending on the degradation of hopper numbers caused by the application. 
  • Battery life/DoU: Windows Mobile application design guideline suggests that an application should follow device power management (by registering for power notification events) and react to system power state changes accordingly. No polling or animations when the application is in background. Use power monitor to check power consumption when the application is running and the device is in various power states. DoU test can be performed to ensure an application does not bring down more than 10% of the DoU number. This will take one or two weeks if the application needs to be modified and re-tested.
  • No device crashes/hang: this is quite obvious. A 3rd party application often comes with an acceptance test plan, which identifies test cases in different priorities. Perform all the tests and make sure there is no crash (we're sorry messages) or device hang. If there are crashes, the root cause must be found and fixed (if it is in the application) by looking into the dump files (kdmp) with symbols. A consistent repro of a crash is ship-blocking and must be fixed. Depending on the complexity of the test plan, this step may take 2-3 weeks and even longer if the 3rd party software does not come with good quality.

In summary, for a single 3rd party application, it may take several weeks to perform the integration and quality gating, during which effective communication with the vendors is important and both sides understand the device will not ship unless these quality gates are passed (according to the license agreement with the vendors). Issues uncovered should be properly prioritized such that key blocking/critical issues are resolved in the new builds from the vendor, whereas low-user-impact issues can be punted to maintenance releases later.

To ensure high quality of the 3rd party software and overall device stability, and importantly device software will be delivered as planned, an earlier planning of integration and quality gating for each 3rd party software is a must-do for overall device software engineering management, along with required QA/Dev resources pre-allocated.

Windows CE Storage Manager Breakdown

The best architectural pictures for Windows CE / Windows Mobile Storage Manager are the followings (from msdn site):

 

Now, if you look at the following call stack on a WM6.5 device emulator (CE5), the above picture is much easier to understand:

Call Stack: filesys.exe: 0x1FFE9356

0x0406eb18 AMDNORD!CNorFmd::ReadSector(unsigned long) fmd.cpp line 256
0x0406eb18 AMDNORD!FMD_ReadSector() fmd.cpp line 1168
0x0406eb24 AMDNORD!Fal::ReadFromMedia() fal.cpp line 160 + 36 bytes
0x0406eb50 AMDNORD!ReadFromMedia() falmain.cpp line 1064 + 20 bytes
0x0406eb7c AMDNORD!DSK_IOControl(unsigned char *, unsigned long, unsigned long *) falmain.cpp line 695 + 8 bytes
0x0406ebb4 FSDMGR!CBlockDevice::Control(void *, unsigned long, unsigned long *, _OVERLAPPED *) blockdev.h line 90 + 40 bytes
0x0406ebe0 FSDMGR!FS_DevDeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) blockdev.cpp line 24
0x0406ec00 NK!SC_DeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) kmisc.c line 2871 + 52 bytes
0x0406ec74 COREDLL!xxx_DeviceIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) twinbase.cpp line 49 + 52 bytes
0x0406ecac FSDMGR!CStore::InternalStoreIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) store.cpp line 887
0x0406eccc FSDMGR!FSDMGR_DiskIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) fsdserv.cpp line 567 + 60 bytes
0x0406ed10 MSPART!ReadPartition(unsigned long, unsigned long *) part.cpp line 600 + 60 bytes
0x0406ed40 MSPART!PD_DeviceIoControl(unsigned char *, unsigned long, unsigned long *) part.cpp line 754 + 36 bytes
0x0406ed74 FSDMGR!CPartDriver::DeviceIoControl(unsigned long, void *, unsigned long, unsigned long *) partition.h line 273 + 52 bytes
0x0406edac FSDMGR!PartitionIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) partition.cpp line 57 + 40 bytes
0x0406edd8 FSDMGR!FSDMGR_DiskIoControl(void *, unsigned long, unsigned long *, _OVERLAPPED *) fsdserv.cpp line 567 + 60 bytes
0x0406ee1c FSDMGR!ReadWriteDiskEx() fsdserv.cpp line 215 + 48 bytes
0x0406ee4c FSDMGR!FSDMGR_ReadDiskEx() fsdserv.cpp line 317
0x0406ee50 IMGFS!CVolume::ReadDisk() imgfsvol.cpp line 1715 + 32 bytes
0x0406eeac IMGFS!CStream::LoadBlockAllocationTable() imgfsfile.cpp line 326 + 16 bytes
0x0406eedc IMGFS!CStream::CStream(unsigned long) imgfsfile.cpp line 215
0x0406eee4 IMGFS!CFile::GetStream() imgfsfile.cpp line 172 + 36 bytes
0x0406ef00 IMGFS!CVolume::FS_CreateFileW_read(unsigned long, unsigned long, unsigned long) imgfsvol.cpp line 944 + 12 bytes
0x0406f138 IMGFS!FSD_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) imgfsapi.cpp line 95
0x0406f150 FSDMGR!FSDMGR_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) fsdapis.cpp line 1020 + 76 bytes
0x0406f1b0 COREDLL!xxx_AFS_CreateFileW(unsigned long, _SECURITY_ATTRIBUTES *, unsigned long, unsigned long, void *) textfile.c line 95
0x0406f1dc FILESYS!FS_CreateFileW(unsigned long, unsigned long, void *) fsmain.c line 2246 + 60 bytes
0x0406f6fc NK!SC_CreateFileW(unsigned long, unsigned long, void *) kmisc.c line 2600 + 56 bytes

From the top to the bottom of the stack:

AMDNORD.DLL: flash driver, which is a block driver FMD (Flash Media Driver) linked with FAL (Flash Abstraction Layer) lib.  Source code for this FMD used in the device emulator is in \PLATFORM\DeviceEmulator\SRC\COMMON\AMD\FMD\. Real world examples of MSFLASHFMD are avaliable here PUBLIC\COMMON\OAK\DRIVERS\BLOCK\MSFLASHFMD.

FMD exposes standard stream interface to device manager. The associated storage file is specified in the Drivers registry key.

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\AmdNorFMD]
   "Dll"="amdnord.dll"
   "Order"=dword:2
   "Prefix"="DSK"
   "Ioctl"=dword:4
   "Profile"="MSFlash"
   "IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
   "MemBase"=dword:A8020000
   "MemLen"=dword:05FE0000
   "Flags"=dword:00010000

FSDMGR.DLL: file system driver manager, which looks into the storage profile in the registry to find partition driver (if any) and file system drivers (FSDs) for those partitions (and possiblely file system filter drivers as well). If no partition driver is specified, then entire device is exposed as a single partition. In this example, the file systems to be loaded are Imgfs and FATFS (FMD for RAM file system (root) plus hive storage is ramfmd.dll in PUBLIC\COMMON\OAK\DRIVERS\BLOCK\MSFLASHFMD\RAM). Note that the MSFLASH flash block driver has been specified as auto-load block driver, meaning that it will be loaded by storage manager instead of device manager, and it cannot be unloaded.

 [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
    "PartitionDriver"="mspart.dll"
    "MountAsROM"=dword:1
    "MountHidden"=dword:1
    "Folder"="Flash Disk"
    "Name"="FLASH Disk Block Device"

; Keep FATFS from trying to shadow \Windows
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS]
    "MountAsROM"=dword:0
    "MountHidden"=dword:0

; Support XIP in IMGFS
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\IMGFS]
    "XIP"=dword:1

; Default settings for ImgFS. These can be overriden per profile.
[HKEY_LOCAL_MACHINE\System\StorageManager\IMGFS]
    "FriendlyName"="Image-Update Filesystem"
    "Dll"="imgfs.dll"
    "Paging"=dword:1
; @CESYSGEN IF IMGFS_IMGFS_NOWRITE
    ; By default, a read-only imgfs partition will shadow ROM.
    "ShadowROM"=dword:1
; @CESYSGEN ENDIF


; Override names in default profile
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
    "Name"="MSFLASH for AMD Nor"
    "Folder"="NOR Flash"

[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\MSFlash]
    "DriverPath"="Drivers\\BuiltIn\\AmdNorFMD"
    ; LoadFlags 0x01 == load synchronously
    "LoadFlags"=dword:1
    "Order"=dword:0
    "BootPhase"=dword:0

MSPART.DLL: partition driver to be used for the MSFLASH profile bound with the flash block driver.

IMGFS.DLL: file system driver for Imgfs which is mounted at \Windows. 

So from the bottom to the top, when the file system (filesys.exe) is about to create a file, file system manager (fsdmgr.dll) finds the file system driver (imgfs.dll) which in turn asks for ReadDisk from file system manager. Then the file system driver issues FSDMGR_DiskIoControl to partition driver (mspart.dll), which eventually goes to the flash block driver (amdnord.dll). If there is a file system filter driver in place, then it will reside as an extra lightweight file system driver on top of the standard one. I hope this helps clarify the architecture of CE/Mobile storage management.

 

Posted by zhengpei | 0 Comments
Filed under:

Using Power Monitor to Tackle Battery Life Problems: Examples

Power monitor (made by Monsoon solutions) is a very useful to improve device battery life. I think every OEM/ODM engineering team should have on handy to watch and troubleshoot battery life issues. Even better, bring the power monitor with your devices into the field, and perform filed tests or comparison tests. For example, how's power consumption of the GPS chip on your device? Just take a drive with your device and connected power monitor with GPS on and capture the logs. Then power monitor will parse the logs and give you a power consumption graph for the test.

The following are some examples of using power monitor to uncover mysterious battery life issues.

1. Standby Current - 30mA !

This graph shows power consumption data of several scenarios on a device: 2G MT call, 2G MO call, Switching to 3G (by changing phone settings), 3G MT call, 3G MO call, and then device gets back to standby with screen off. Device backlight, which burns about 50mA of current, will be turned off after 30 seconds of idle time. When that happens the standby current is around 2-8mA, as can seen after the 2G MT, 2G MO, and 3G MT calls. 

The problem is that after the 3G MO call, and device backlight off and suspends, the standby current stays at around 30mA forever. Back-of-the-envelop calculation shows for a whole day 30mA * 24h = 720mAH, about half of the battery capacity on the device.

As this can be reproduced pretty easily, modem log and CE log can be collected and investigated. Eventually this turned out to be the audio path not being properly closed when the 3G MO out ended. After fixing it in RIL driver, the problem was solved.

2. Mysterious thread

This is a classic example of power-unaware programming. At some point the device starts to run a mysterious thread exactly every minute (see the 120mA spikes, even if in suspend mode. Essentially this leads to an average current of about 20-30mA, which is definitely unacceptable. More specifically, when the thread runs, it drains an average of 50mA for 16 seconds, and that will be 13.3mAh for an hour, or 320mAh a day!

How to find the culprit thread? Use Kernel Tracker. Try to look for WaitForSingleObject() calls that has a timeout of 1 minute. If the kernel tracker GUI does not work for you, get the CE log and look for mysterious threads that run every 60 seconds:

0:10:35.890.640 , Switch Thread , hThread=0x07A9FFAE
0:10:35.890.645 , Migrate Thread , hProcess=0x07AB230E
0:10:35.890.741 , Wait for Multiple Objects , Timeout=60000ms , WaitAll=0 , NumObjects=8 , Object 0: 0x07AA8C2A , Object 1: 0x07A9A2C6 , Object 2: 0xC7A9A5D2 , Object 3: 0x07A9A392 , Object 4: 0xC7A9A506 , Object 5: 0x07A9FAAA , Object 6: 0x47A9A986 , Object 7: 0x07AC15E2


0:11:15.961.408 , Switch Thread , hThread=0x07A9FFAE
0:11:15.961.412 , Migrate Thread , hProcess=0x07AB230E
0:11:15.961.508 , Wait for Multiple Objects , Timeout=60000ms , WaitAll=0 , NumObjects=8 , Object 0: 0x07AA8C2A , Object 1: 0x07A9A2C6 , Object 2: 0xC7A9A5D2 , Object 3: 0x07A9A392 , Object 4: 0xC7A9A506 , Object 5: 0x07A9FAAA , Object 6: 0x47A9A986 , Object 7: 0x07AC15E2

This can be further mapped to a thread name as long as you have flat release directory. For the issue, it turned out a battery monitor thread in devices.exe that has a bug which will keep the thread running forever even if the device has been suspended.

Summary:

Power monitor is a great weapon to attach battery life problems for mobile devices. Use it along with other tools such as kernel tracker, CE Log, and KITL to pinpoint what has been wrong in your system. Always has a reference device handy so you know what are normal and what are not. When you perform a scenario test, have CE Log running will be a good idea, but you have to be aware that CE Log flush will drain some battery and create some spikes in your power graph.

Posted by zhengpei | 0 Comments
Filed under:

Windows Mobile Device DRM Integration

Many devices today provide an OMA DRM 1.x/2.0 solution from a 3rd party (for example, from irdeto). So how to verify if the integration has been properly done? Well, aside from the tests that your vendor performed, you can also use the following site to verify:

http://www.drmtest.com

Common use of this site is to test those Forward Lock and Combined Delivery content such as images (JPG, GIF) and media formats (WAV, mp3, etc). 

To make a Windows Mobile phone DRM-ready, i.e., be able to recognize DRM content received via MMS, email, or from the web, a specific file system filter driver has to be loaded into the system. This is often done by adding the the filter into the MODULES section of the memory bib file such that it will be loaded into Slot 1 (unless Slot 1 is so crowded that the module overflows into Slot 0), and put required registry values (for registering the filter driver with file system) to BOOT HIVE.

; HIVE BOOT SECTION 

[HKEY_LOCAL_MACHINE\System\StorageManager\Filters] 

[HKEY_LOCAL_MACHINE\System\StorageManager\Filters\DrmFSFilter] 

"Order"=dword:00000001 

"Dll"="DrmFSFilter.dll"

; END HIVE BOOT SECTION

MA DRM specifications can be downloaded from http://www.openmobilealliance.org/technical/release_program/drm_archive.aspx

 

 

Posted by zhengpei | 0 Comments
Filed under:

DirectShow Tool GraphEdt on Windows Mobile

On Windows and Windows CE, the GraphEdt tool can be used to investigate (visually) what DShow filters are used for a given media file, and it is also very useful to verify if your filters work as expected. For desktop Windows, this tool is included in the platform SDK or so called Windows SDK. On Windows CE, the following steps have been suggested to do this:

 To use graphedt on CE 5.0, you need to do the following:

1. set WINCEREL=1

2. graphedt uses MFC, so set SYSGEN_MFC=1. Then do "sysgen -p dcom mfc"

3. sysgen -p directx graphedt

Then you should see graphedt.exe in your _flatreleasedir.

On a Windows Mobile AKU build environment, if you follow the steps above, you will hit errors like there at Step 3:

\public\common\sdk\lib\ARMV4I\retail\corelibc.lib
graphedt.lib(filtervw.obj) : error LNK2001: unresolved external symbol IID_IDirectDrawSurfaceKernel
graphedt.lib(filtervw.obj) : error LNK2001: unresolved external symbol IID_IDirectDrawKernel
graphedt.lib(filtervw.obj) : error LNK2001: unresolved external symbol IID_IDDVideoPortContainer

Meantime I am looking into this and see if this can be fixed. Or it can't be fixed because it is by-design because officially Microsoft does not support GraphEdt on Windows Mobile?  

Posted by zhengpei | 1 Comments
Filed under:

Recommended China IT Web Links

Like anyone who is looking to ride the wave of China's booming economy, I always want to know what are the hot topics and technological trends in its mobile wireless industry and IT industry. Below is a list of links I use to keep me updated.

http://www.cctime.com 飞象网 3G, cell phone, mobile operators, created by Xiang Ligang (blog).

http://blog.sina.com.cn/lm/tech/ 新浪IT博客 tech blogs at sina.com

http://cn.engadget.com engadget中文版 engadget Chinese site

Please feel free to share links you want to recommend.

Posted by zhengpei | 0 Comments
Filed under:

Mobile 2.0 - Critical Issues and Why Japan and Korea are the Mobile Time Machines

I came across a great presentation deck on "Mobile 2.0" written by  Gerhard Fasol, CEO of Eurotechnology Japan K. K. In the presentation, Gerhard shared his insight into next generation mobile services and four critical issues, Platforms, Business Models, Globalization, and Standardization vs Risk Taking & Early Adoption. Definitely worth a read.

The presentation also has some interesting data showing Japan and Korea being the "Mobile Time Machines" - they are way ahead of EU (and US) in adopting new technologies and business models. Speaking of my personal experience, in Tokyo I saw people use cell phone at the gate to enter train stations. I don't know if people can do the same anywhere in the US.

Source: Eurotechnology.com 

 Update: Watch for the latest development of China's recent 3G launch. All the players are trying to ride this wave with app stores, oPhone/hiPhone, reduced data fee, and the upcoming iPhone launch.

Posted by zhengpei | 0 Comments
Filed under:

Best Client Apps of Twitter, Facebook, LinkedIn, Youtube, Picassa for Windows Mobile

Here is the outcome of my little research... 

Best Twitter Client for Windows Mobile

PocketTwit

---------------------------------------------------------------------------------------------------------------------------------------

Best Facebook Client for Windows Mobile

Offical Facebook Client by Microsoft

---------------------------------------------------------------------------------------------------------------------------------------

Best LinkedIn Client for Windows Mobile

There is no LinkedIn client for Windows Mobile yet at this moment.

---------------------------------------------------------------------------------------------------------------------------------------

Best Youtube Client for Windows Mobile

The official Youtube client

---------------------------------------------------------------------------------------------------------------------------------------

Best Picasa Client for Windows Mobile

No standalone app available yet. From a web browser you can visit m.google.com/photos to acccess the mobile picasa site.

Twitter-Fanfou, Omegle-LuGuoDe, and ppstream ...

Twitter: Fanfou (饭否)

Omegle: Luguode (路过的)

LinkedIn: Wealink

Facebook: KaiXin (开心)

For every popular social networking site in the US, several Chinese copycats have been created--the idea was adopted, but the business model and user experience are often totally different.

Keep in mind that Chinese people are quite open and willing to chat/comment in online forums or using SMS. According to data published by China Mobile and China Unicom, every Chinese cell phone user sent more than 850 text messages on average in 2008. The need for communication with close friends, with people in the same industry, and with whoever wants to chat is evident. Those copycats (山寨) above were created by those entrepreneurs who see the huge opportunity of capitalizing on the localized Chinese social networking service market. Will they succeed? Hard to say, depending on how good the localization is done, how to build a hype(?) for the site, and perhaps how to convince a Internet giant to acquire it......


On the other hand, there are very cool home-grown Chinese online services and also financially successful. Some examples are ppstream, xunlei, and of course, QQ. Their US competitors (if any) are nowhere close to them by all means. 

With 3G services launched in China, and upcoming iPhone and oPhone launches, a new battlefield is emerging.

Posted by zhengpei | 1 Comments
Filed under:
More Posts Next page »
 
Page view tracker