modem层不懂,所以直接从RIL.java开始。以电信卡接收短信为例
modem通知RIL.java中的 RILReceiver处理接收信息
class RILReceiver implements Runnable { byte[] buffer; RILReceiver() { buffer = new byte[RIL_MAX_COMMAND_BYTES]; } @Override public void run() { ...... //建立socked连接,读取数据 processResponse(p); ...... } }
private void processResponse (Parcel p) { int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED) { processUnsolicited (p); //接收短息会进入这里 } else if (type == RESPONSE_SOLICITED) { RILRequest rr = processSolicited (p); if (rr != null) { rr.release(); decrementWakeLock(); } } }
processUnsolicited(Parcel p)方法中,罗列了各种类型的信息,
processUnsolicited (Parcel p) { int response; Object ret; response = p.readInt(); try {switch(response) { /* cat libs/telephony/ril_unsol_commands.h | egrep "^ *{RIL_" | sed -re 's/{([^,]+),[^,]+,([^}]+).+/case 1: 2(rr, p); break;/' */ case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break; case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break; case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break; case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break; case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break; case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break; case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break; case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break; case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break; case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break; case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break; case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; case RIL_UNSOL_SIM_REFRESH: ret = responseSimRefresh(p); break; case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break; case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break; case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break; case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break; case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break; case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break; case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break; case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break; case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break; case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break; case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_CELL_INFO_LIST: ret = responseCellInfoList(p); break; case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: ret = responseInts(p); break; case RIL_UNSOL_SRVCC_STATE_NOTIFY: ret = responseInts(p); break; case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: ret = responseHardwareConfig(p); break; case RIL_UNSOL_RADIO_CAPABILITY: ret = responseRadioCapability(p); break; case RIL_UNSOL_ON_SS: ret = responseSsData(p); break; case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: ret = responseString(p); break; case RIL_UNSOL_LCEDATA_RECV: ret = responseLceData(p); break;
电信卡接收信息,是 RIL_UNSOL_RESPONSE_CDMA_NEW_SMS
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: if (RILJ_LOGD) unsljLog(response); SmsMessage sms = (SmsMessage) ret; if (mCdmaSmsRegistrant != null) { mCdmaSmsRegistrant .notifyRegistrant(new AsyncResult(null, sms, null)); //mCdmaSmsRegistrant 在 CdmaInboundSmsHandler 初始化时创建 } break;
public void notifyRegistrant(AsyncResult ar) { internalNotifyRegistrant (ar.result, ar.exception); } /*package*/ void internalNotifyRegistrant (Object result, Throwable exception) { Handler h = getHandler(); if (h == null) { clear(); } else { Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); //handler来处理接收信息事件 } }
mCdmaSmsRegistrant.notifyRegistrant(..)就进入状态机(StateMachine)处理了。处理的信息接收的状态机是 InboundSmsHandler extends StateMachine
InboundSmsHandler是抽象类,对于CDMA信息是 CdmaInboundSmsHandler extends InboundSmsHandler, 对于GSM信息是 GsmInboundSmsHandler extends InboundSmsHandler
关于CdmaInboundSmsHandler 状态机是何时启动并初始化的,细节没研究。应该是在手机启动后,一系列系统服务启动时完成的。
看看CdmaInboundSmsHandler 的构造函数
/** * Create a new inbound SMS handler for CDMA. */ private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor, PhoneBase phone, CdmaSMSDispatcher smsDispatcher) { super("CdmaInboundSmsHandler", context, storageMonitor, phone, CellBroadcastHandler.makeCellBroadcastHandler(context, phone)); mSmsDispatcher = smsDispatcher; mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context, phone.mCi); phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null); //这里构造了RIL中需要的 mCdmaSmsRegistrant
}
public void setOnNewCdmaSms(Handler h, int what, Object obj) { mCdmaSmsRegistrant = new Registrant (h, what, obj); }
/** * Wait for state machine to enter startup state. We can't send any messages until then. */ public static CdmaInboundSmsHandler makeInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor, PhoneBase phone, CdmaSMSDispatcher smsDispatcher) { CdmaInboundSmsHandler handler = new CdmaInboundSmsHandler(context, storageMonitor, phone, smsDispatcher); //构造CdmaInboudSmsHandler状态机 handler.start(); //启动 state machine return handler; }
在CdmaInboudSmsHandler初始化会调用父类InboundSmsHandler的构造函数,会增加各种状态。
protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor, PhoneBase phone, CellBroadcastHandler cellBroadcastHandler) { super(name); ...... addState(mDefaultState); addState(mStartupState, mDefaultState); addState(mIdleState, mDefaultState); addState(mDeliveringState, mDefaultState); addState(mWaitingState, mDeliveringState); setInitialState(mStartupState); if (DBG) log("created InboundSmsHandler"); }
综上,RILReceiver接收信息,进入状态机CdmaInboundSmsHandler处理,具体是父类StateMachine中的Hanler传递消息,并切换各状态(state)处理。
状态: mDefaultState,mStartupState,mIdleState,mDeliveringState,mWaitingState以及默认的QuitSatte, HaltState。
各状态是如何切换处理的? 没搞明白。有待研究。
接收信息最终传递处理在 mDeliveringState中 (代码实现在InboundsSmsHandler.java中)
class DeliveringState extends State { @Override public void enter() { if (DBG) log("entering Delivering state"); } @Override public void exit() { if (DBG) log("leaving Delivering state"); } @Override public boolean processMessage(Message msg) { log("DeliveringState.processMessage:" + msg.what); switch (msg.what) { case EVENT_NEW_SMS: // handle new SMS from RIL handleNewSms((AsyncResult) msg.obj); //继续处理新接收的信息 sendMessage(EVENT_RETURN_TO_IDLE); return HANDLED;
void handleNewSms(AsyncResult ar) { if (ar.exception != null) { loge("Exception processing incoming SMS: " + ar.exception); return; } int result; try { SmsMessage sms = (SmsMessage) ar.result; result = dispatchMessage(sms.mWrappedSmsMessage); //信息传递处理完成,并返回结果 } catch (RuntimeException ex) { loge("Exception dispatching message", ex); result = Intents.RESULT_SMS_GENERIC_ERROR; } // RESULT_OK means that the SMS will be acknowledged by special handling, // e.g. for SMS-PP data download. Any other result, we should ack here. if (result != Activity.RESULT_OK) { //注意这里的返回结果,一般是 Intents.RESULT_SMS_HANDLED,才可以继续反馈 ack 到 smsc boolean handled = (result == Intents.RESULT_SMS_HANDLED); notifyAndAcknowledgeLastIncomingSms(handled, result, null); //这里返回ACK给短信中心(smsc),表示信息已接收。 } }
void notifyAndAcknowledgeLastIncomingSms(boolean success, int result, Message response) { if (!success) { // broadcast SMS_REJECTED_ACTION intent Intent intent = new Intent(Intents.SMS_REJECTED_ACTION); intent.putExtra("result", result); mContext.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS); } acknowledgeLastIncomingSms(success, result, response); }
protected abstract void acknowledgeLastIncomingSms(boolean success,
int result, Message response); //具体实现在 CdmaInboundsSmsHandler 或 GsmInboundSmsHandler中
CdmaInboundsSmsHandler中处理acknowledgeLastIncomingSms
@Override protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { if (isInEmergencyCallMode()) { return; } int causeCode = resultToCause(result); mPhone.mCi.acknowledgeLastIncomingCdmaSms(success, causeCode, response); //这里又回到RIL中处理 if (causeCode == 0) { mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; } mLastDispatchedSmsFingerprint = null; }
RIL中用 RILSender 处理返回ACK,
public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result); rr.mParcel.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass // cause code according to X.S004-550E rr.mParcel.writeInt(cause); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + success + " " + cause); send(rr); }
再看看信息传递处理dispatchMessage()
public int dispatchMessage(SmsMessageBase smsb) { // If sms is null, there was a parsing error. if (smsb == null) { loge("dispatchSmsMessage: message is null"); return Intents.RESULT_SMS_GENERIC_ERROR; } if (mSmsReceiveDisabled) { // Device doesn't support receiving SMS, log("Received short message on device which doesn't support " + "receiving SMS. Ignored."); return Intents.RESULT_SMS_HANDLED; } return dispatchMessageRadioSpecific(smsb); }
protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb);
InboundsSmsHandler中的dispatchMessageRadioSpecific(..)是抽象的,具体处理在CdmaInboundSmsHandler 或 GsmInboundSmsHandler中
然后会将新信息,用广播传递给MMS应用处理。