Front Page

InfoInfo TalkTalk

**.01 mini-update 2011-02-27 - see below

Virgin 2.2 MMC findings

The MMS data arrives on the radio the same way, regardless of baseband.
The garbling *likely* takes place within the framework.jar.  I have been trying to track down exactly where the
stream of bytes gets changed inside froyo's framework.jar but haven't been successful.

This is what I do know:
  From both froyo and eclair, the data that arrives on the radio is the same -
    the user is 999999999; this is likely a trigger (virgin mobile only?) that indicates a MMS message
    has arrived that needs to be downloaded.

After changing my usb port to a modem, I hooked up QXDM and limited the logging to Message Unknown and to display all raw data.
Then, I sent an MMS message from my gmail account to my phone and dumped the log to a file.

From this log file, I grepped all lines that contain USER[##] and pulled out the byte noted after the equal sign.

USER[0] = 0x0
USER[1] = 0x3
USER[2] = 0x10
USER[3] = 0xa

To use the above, push all these values in to an array of bytes,
 i.e. syntax in perl: @b=("\x00","\x03","\x10","\x0a",...)

The test message I sent arrived in three segments (3 groupings of USER[##] arrays)
  the first, a byte array of 8 elements (USER[0] -> USER[8] in log)
  the second, a byte array of 119 elements (later inside the log, USER[0] -> USER[119])
  the third, a byte array of 38 elements (later inside the log, USER[0] -> USER[38])

The 2nd and 3rd byte arrays are what I care about for this example.
Compiling all the USER[##] bytes in to an string rep, the 2nd array equates to (view as a continuous string):

The third array:

Inside eclair's framework.jar is a class - something like com/android/internal/telephony/cdma/CdmaSMSMessage.
This class contains the method:
  processCdmaWapPdu(byte[] paramArrayOfByte, int paramInt, String paramString)

  This method performs a little math on the byte array passed it. (see perl snippet below)

   The message PDU is passed to this function (a segment of the byte array).
   A little math is performed and the result is:

   - for the second byte array (skipping the first 18 bytes*):
      application/vnd.wap.mms-message���ڴ����CMC1DX����        :�����w��http://mmsc
   - for the third (skipping the first 11 bytes*):

   * I only stripped off these bytes to reduce the amount of unreadble chars displayed for this example.

The above combined is the address of our downloadable MMS web file: .
The file is downloadable using the hData settings (BetterCut shortcut) and the Basic Authentication mechanism.
Attached is a java method to do this.

Pass this function a byte array; it will print the string representation that we want.

sub process_array {
  my @x=@_;
  my $p=27;
  my $txt="";
  while( $p<($#x+1) ) {
    my $a=$x[$p];
    my $b=$x[$p];
    my $v1=(ord($a) & hex("07")) << 5;
    my $v2=(ord($b) & hex("F8")) >> 3;
    my $v3=($v1 | $v2);
  print $txt,"\n";

# Java SNIPPET of downloading the raw file from the web
# (this is really sloppy - I lost my source and Dj-Decompiled it)

public String executeHttpGet(String msgID)
        BufferedReader in=null;
        String fname = "/sdcard/raw_"+msgID+".txt";
        String meid = "";

       // may as well make it static - Base64 encode <meid>:pcs (go to
        String auth = "Basic ################";

        fname = (new StringBuilder("/sdcard/raw_")).append(msgID).append(".txt").toString();
        DefaultHttpClient client = new DefaultHttpClient();
        String PROXY_IP = "";
        int PROXY_PORT = 81;
        client.getCredentialsProvider().setCredentials(new AuthScope("", 81), new UsernamePasswordCredentials(meid, "pcs"));
        HttpHost proxy = new HttpHost("", 81);
        client.getParams().setParameter("http.route.default-proxy", proxy);
        URI uri = new URI((new StringBuilder("")).append(msgID).toString());
        HttpGet method = new HttpGet(uri);
        method.addHeader("x-wap-profile", "");
        method.addHeader("Proxy-Authorization", auth);
        method.addHeader("User-Agent", "SPH-M910/Android-mms");
        HttpResponse response = client.execute(method);
        in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");
        while((line = in.readLine()) != null)
            sb.append((new StringBuilder(String.valueOf(line))).append(NL).toString());
        String page = sb.toString();
            File f = new File(fname);
            FileOutputStream fOut = new FileOutputStream(f);
        catch(IOException ioe)
            fname = null;

**.01 - I switched out to a Virgin Optimus V and swapped stock for the excellent aospCMod rom
  - MMS incoming issue is the same
  - I was leaning to the culprit being the proprietary radio lib, but aospCMod uses the same rild library as stock
  - this seems to indicate to me that somewhere in the android framework the modification of the radio stream is
    occurring - which if true, is great news, since injecting/modd'ing java code is much easier (to me) than trying to reverse-
    engineer the linux lib

  - I have injected a trace in framework.jar's's method readRILMessage - the data that arrives here has already been modified
  - next step is to find some online doco on the path of the radio data

This is a Wiki Spot wiki. Wiki Spot is a 501(c)3 non-profit organization that helps communities collaborate via wikis.