When parsing WAPPUSH over SMS, I checked the SMS receiving process in Android and recorded the process as needed. The detailed processing of other branches is not described. The encode/decode of the pdu data is not parsed in this article. If you are interested, you can read the relevant code.
In Android, RIL uses RILReciever to receive SMS pdu and uses corresponding functions to process the pdu based on different information types. Due to differences in mobile phone systems, gsmsdispatcher or CdmaSmsDispatcher is used for message processing and distribution. The final distribution is through sending the corresponding Broadcast. Therefore, for message processing that you are interested in, you can register a Receiver to listen to the corresponding Broadcast and implement your own SMS/MMS/Wap push, and other types of messages.
In the RIL constructor, Handler initialization [in the file RIL. java]
[Java]
Mcycler = newRILReceiver ();
MReceiverThread = new Thread (mReceiver, "RILReceiver ");
MReceiverThread. start ();
Type
MReceiver: RILReceiver
MReceiverThread: Thread
RILReceiver implements Runnable
Focus on The Implementation of The RILReceiver thread [IN RILReceiver: run ()]
[Java] public void run (){
Int retryCount = 0;
Try {(;;){
LocalSockets = null;
LocalSocketAddress l;
Try {
S = newLocalSocket ();
L = newLocalSocketAddress (SOCKET_NAME_RIL,
LocalSocketAddress. Namespace. RESERVED );
S. connect (l );
} Catch (IOException ex ){
//...
}
RetryCount = 0;
MSocket = s;
Int length = 0;
Try {
InputStreamis = mSocket. getInputStream ();
For (;;){
Parcel p;
Length = readRilMessage (is, buffer );
If (length <0 ){
// End-of-stream reached
Break;
}
P = Parcel. obtain ();
P. unmarshall (buffer, 0, length );
P. setDataPosition (0 );
ProcessResponse (p );
P. recycle ();
}
} Catch (java. io. IOException ex ){
//...
} Catch (Throwable tr ){
//...
}
//...
} Catch (Throwable tr ){
Log. e (LOG_TAG, "Uncaught exception", tr );
}
}
Public void run (){
Int retryCount = 0;
Try {(;;){
LocalSockets = null;
LocalSocketAddress l;
Try {
S = newLocalSocket ();
L = newLocalSocketAddress (SOCKET_NAME_RIL,
LocalSocketAddress. Namespace. RESERVED );
S. connect (l );
} Catch (IOException ex ){
//...
}
RetryCount = 0;
MSocket = s;
Int length = 0;
Try {
InputStreamis = mSocket. getInputStream ();
For (;;){
Parcel p;
Length = readRilMessage (is, buffer );
If (length <0 ){
// End-of-stream reached
Break;
}
P = Parcel. obtain ();
P. unmarshall (buffer, 0, length );
P. setDataPosition (0 );
ProcessResponse (p );
P. recycle ();
}
} Catch (java. io. IOException ex ){
//...
} Catch (Throwable tr ){
//...
}
//...
} Catch (Throwable tr ){
Log. e (LOG_TAG, "Uncaught exception", tr );
}
}
The RILReceiver thread keeps listening to local sockets and processes the data in processResponse () [Line #37] after reading the data.
[Java] private void processResponse (Parcel p ){
Int type;
Type = p. readInt ();
If (type = RESPONSE_UNSOLICITED ){
ProcessUnsolicited (p );
} Else if (type = RESPONSE_SOLICITED ){
ProcessSolicited (p );
}
ReleaseWakeLockIfDone ();
}
Private void processResponse (Parcel p ){
Int type;
Type = p. readInt ();
If (type = RESPONSE_UNSOLICITED ){
ProcessUnsolicited (p );
} Else if (type = RESPONSE_SOLICITED ){
ProcessSolicited (p );
}
ReleaseWakeLockIfDone ();
}
If the message type is Unsolicited, it is processed in processUnsolicited. The received text message is Unsolicited information. Check its implementation.
A long switch in processUnsolicited... In case RIL_UNSOL_RESPONSE_NEW_SMS:
[Java] SmsMessage sms;
Sms = SmsMessage. newFromCMT ();
If (mSMSRegistrant! = Null ){
MSMSRegistrant. policyregistrant (new AsyncResult (null, sms, null ));
}
SmsMessage sms;
Sms = SmsMessage. newFromCMT ();
If (mSMSRegistrant! = Null ){
MSMSRegistrant. policyregistrant (new AsyncResult (null, sms, null ));
}
The SmsMessage here is android. telephony. SmsMessage. NewFromCMT () will select a specific SmsMessage for encapsulation Based on the phone type (GSM/CDMA) (because in Rational Rose, classes in different packages in the same project cannot have the same name, com. android. internal. telephony. gsm. smsMessage uses gsm. replace smessage; com. android. internal. telephony. cdma. smsMessage uses cdma. replace smessage. SmsMessage ).
MSMSRegistrant is a member of the RIL parent class. Use setOnNewSMS ()/unSetOnNewSMS () to set and cancel the settings. The SMSDispatcher constrfunction registers the Registrant of SMS.
MCm. setOnNewSMS (this, EVENT_NEW_SMS, null );
Therefore, after calling mSMSRegistrant. notifyRegistrant (newAsyncResult (null, sms, null), the Handler in SMSDispatcher processes EVENT_NEW_SMS in handleMessage:
[Java] SmsMessage sms;
Ar = (AsyncResult) msg. obj;
If (ar. exception! = Null ){
Log. e (TAG, "Exception processing incoming SMS. Exception:" + ar. exception );
Return;
}
Sms = (SmsMessage) ar. result;
Try {
Int result = dispatchMessage (sms. mwrappedsmessage );
If (result! = Activity. RESULT_ OK ){
// RESULT_ OK means thatmessage was broadcast for app (s) to handle.
// Any other result, weshoshould ack here.
Boolean handled = (result = Intents. RESULT_SMS_HANDLED );
NotifyAndAcknowledgeLastIncomingSms (handled, result, null );
}
} Catch (RuntimeException ex ){
Log. e (TAG, "Exception dispatching message", ex );
NotifyAndAcknowledgeLastIncomingSms (false, Intents. RESULT_SMS_GENERIC_ERROR, null );
}
SmsMessage sms;
Ar = (AsyncResult) msg. obj;
If (ar. exception! = Null ){
Log. e (TAG, "Exception processing incoming SMS. Exception:" + ar. exception );
Return;
}
Sms = (SmsMessage) ar. result;
Try {
Int result = dispatchMessage (sms. mwrappedsmessage );
If (result! = Activity. RESULT_ OK ){
// RESULT_ OK means thatmessage was broadcast for app (s) to handle.
// Any other result, weshoshould ack here.
Boolean handled = (result = Intents. RESULT_SMS_HANDLED );
NotifyAndAcknowledgeLastIncomingSms (handled, result, null );
}
} Catch (RuntimeException ex ){
Log. e (TAG, "Exception dispatching message", ex );
NotifyAndAcknowledgeLastIncomingSms (false, Intents. RESULT_SMS_GENERIC_ERROR, null );
}
SMSDispatcher is an abstract class. The implementation of dispatchMessage () is in GsmSMSDispatcher or CdmaSMSDispatcher.
In GsmSMSDispatcher: dispatchMessage (), messages of the Class 0 type, messages with the target port, and long messages are processed.
If the target port is WAPPUSH, mWapPush is called. dispatchWapPdu (sms. getUserData (), pdus) allows WAPPUSH for processing. For other unknown ports, use "sms: // localhost: <port>" to specify the port.
For long messages, you can call processMessagePart () for combined processing.
1) information about the target port and the target port is wap push (SmsHeader. PORT_WAP_PUSH), which is handled by WapPushOverSms: dispatchWapPdu:
Depending on the contentType:
-> DispatchWapPdu_PushCO ();
-> DispatchWapPdu_MMS ();
-> DispatchWapPdu_default ()
2) there is a target address and the target port is not wap push information, which can be processed in SMSDispatcher: dispatchPortAddressedPdus:
Uri uri = Uri. parse ("sms: // localhost:" + port );
Intent intent = new Intent (Intents. DATA_SMS_RECEIVED_ACTION, uri );
Intent. putExtra ("pdus", pdus );
Dispatch (intent, "android. permission. RECEIVE_SMS ");
3) common information with no target address (common text message) is processed in SMSDispatcher: dispatchPdus:
Intent intent = new Intent (Intents. SMS_RECEIVED_ACTION );
Intent. putExtra ("pdus", pdus );
Dispatch (intent, "android. permission. RECEIVE_SMS ");
From Tian haili @ CSDN