Class 0 SMS (flash SMS) On Android


Answer :

For rooted Android it is possible to bypass an API and send Class 0 SMS. There is a project on Git Hub called ZeroSMS:

ZeroSMS is a proof-of-concept demonstrating a way to send Class 0 SMS on android >=2.3.

Note: this only works on versions 2.2 -> 4.1.2, the sendRawPdu method was removed, so you will need to find a new way to do this.


It was possible to send Flash SMS (that's the term for class 0 SMS) before Android 2.2. Google removed the sendRawPdu API, so even if you used reflection, you wouldn't be able to do it.

Here's how I did it previously (this was tested on Android 1.6 and worked)

private void sendSms(String phone, String sms) {     if ((phone == null) || (sms == null) || (phone.length() == 0)             || (sms.length() == 0)) {         String message = "Phone or message empty!!!";         Toast notification = Toast.makeText(getBaseContext(), message,                 Toast.LENGTH_SHORT);         notification.show();         return;     }      // SecurityManager oldSM = System.getSecurityManager();     // MySecurityManager newSM = new MySecurityManager();     // System.setSecurityManager(newSM);      // ServiceManager.getService("isms")     // ServiceManager.getService("isms");      SmsManager m = SmsManager.getDefault();     PendingIntent sentIntent = PendingIntent             .getBroadcast(this, 0, new Intent(                     MessageStatusReceiver_MESSAGE_STATUS_RECEIVED_ACTION),                     0);      PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,             new Intent(SmsReceiverService_MESSAGE_SENT_ACTION), 0);      // String sms = "Message self-destroyed!!!";     // String phone = "93634096";      long NOW = System.currentTimeMillis();     String time = String.valueOf(NOW);      // // m.sendTextMessage(phone, null, sms, sentIntent, deliveryIntent);     // working // m.sendTextMessage(phone, null, sms, null, null);     byte[] bb = new byte[1];     Method m2 = null;     try {         m2 = SmsManager.class.getDeclaredMethod("sendRawPdu",                 bb.getClass(), bb.getClass(), PendingIntent.class,                 PendingIntent.class);     } catch (SecurityException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (NoSuchMethodException e) {         // TODO Auto-generated catch block         e.printStackTrace();     }      // send message      SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(null, phone, sms,             false);      // http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=telephony/java/android/telephony/gsm/SmsMessage.java;h=9ccfa90d2e24e5caea26c1deac641b3c31ae56d4;hb=c883b143ba2b8bfe2f2033d00dee9ff733f1b59c      boolean submitted = false;     try {         byte[] encodedMessage = pdus.encodedMessage;         // byte[0] = mtiByte         // byte[1] = TP Message Reference         // byte[2] = length of source phone         // byte[3..length] = phone         // protocol identifier         int msgLen = encodedMessage[2] / 2;         // +2 -> length of source phone         // +2 -> for 91 after the length         // +1 -> TP PID         int indexTPDCS = msgLen + 5;         byte TPDCS = encodedMessage[indexTPDCS];         // System.out.println(TPDCS);         System.out.println(getHexString(encodedMessage));         byte[] changedMessage = encodedMessage.clone();         // Set bit 4 to 1 using OR (|), indicating there is a message class         // Set bit 0 and 1 to 0 using AND (&), indicating class 0         byte newTPDCS = (byte) ((TPDCS | 0x10) & 0xFC); // Flash SMS         changedMessage[indexTPDCS] = newTPDCS; // Class 0         System.out.println(getHexString(changedMessage));         // Log.d(SmsScheduler_TAG, getHexString(changedMessage));         boolean send = true;         if (send) {             m2.invoke(m, pdus.encodedScAddress, changedMessage, null, null);              // sendSMS(HexDump.bytesToHexString(pdus.encodedScAddress),             // HexDump.bytesToHexString(changedMessage), null);              String message = "Flash SMS sent to " + phone                     + " successfully!";             Toast notification = Toast.makeText(getBaseContext(), message,                     Toast.LENGTH_SHORT);             notification.show();             Log.d(SmsScheduler_TAG, message);             submitted = true;         }     } catch (IllegalArgumentException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (UnsupportedEncodingException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (IllegalAccessException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (InvocationTargetException e) {         // TODO Auto-generated catch block         e.printStackTrace();     }              // not essential, saves the SMS sent.      if (submitted) {         ContentValues values = new ContentValues();         values.put(ADDRESS, phone);         values.put(DATE, time);         values.put(READ, 0);         values.put(STATUS, -1);         values.put(TYPE, MESSAGE_TYPE_SENT);         values.put(BODY, sms);          Uri inserted = getContentResolver().insert(                 Uri.parse("content://sms"), values);     }      // System.setSecurityManager(oldSM);  } 

Scrool's answer is indeed correct, https://stackoverflow.com/a/12873325/3082310 , as ZeroSMS does send flash SMS's; however, it is a Proof-of-Concept and only supports SMS's with 7-bit encoding.

For proper encoding it seems there is a need to modify the code and add if-then or switch-case statements: For 7-bit coding, as in english

use (byte)0xF0

For 16-bit encoding, UCS-2 encoding

use (byte) 0x18

Otherwise, junk characters appear if you enter unsupported language.


Comments

Popular posts from this blog

Are Regular VACUUM ANALYZE Still Recommended Under 9.1?

Can Feynman Diagrams Be Used To Represent Any Perturbation Theory?