美文网首页
Android S短消息接收流程

Android S短消息接收流程

作者: 无痕1024 | 来源:发表于2022-03-17 19:09 被阅读0次

    1 入口

    该BroadcastReceiver配置了对intent: SMS_DELIVER_ACTION的接收:
    /packages/apps/Messaging/AndroidManifest.xml

            <receiver android:name=".receiver.SmsDeliverReceiver"
                      android:exported="true"
                      android:permission="android.permission.BROADCAST_SMS">
                <intent-filter>
                    <action android:name="android.provider.Telephony.SMS_DELIVER" />
                </intent-filter>
            </receiver>
    

    Telephony对该intent的定义:
    /frameworks/base/core/java/android/provider/Telephony.java

                public static final String SMS_DELIVER_ACTION =
                        "android.provider.Telephony.SMS_DELIVER";
    

    2 Framework流程

    2.1 流程图

    这里以普通接收到的GSM SMS(其他CDMA和IMS SMS可查看代码)为例:


    mtSmsFramework.png

    2.2 源码

    2.2.1 注册New SMS

    在GsmInboundSmsHandler这个Handler中注册EVENT_NEW_SMS事件,设置RIL_UNSOL_RESPONSE_NEW_SMS的监听者为mGsmSmsRegistrant:
    /frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java

        /**
         * Create a new GSM inbound SMS handler.
         */
        private GsmInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
                Phone phone) {
            super("GsmInboundSmsHandler", context, storageMonitor, phone);
            phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null);
            mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi, phone.getPhoneId());
            mCellBroadcastServiceManager.enable();
    
            if (TEST_MODE) {
                if (sTestBroadcastReceiver == null) {
                    sTestBroadcastReceiver = new GsmCbTestBroadcastReceiver();
                    IntentFilter filter = new IntentFilter();
                    filter.addAction(TEST_ACTION);
                    context.registerReceiver(sTestBroadcastReceiver, filter);
                }
            }
        }
    

    RILJ方法:

        public void setOnNewGsmSms(Handler h, int what, Object obj) {
            mGsmSmsRegistrant = new Registrant (h, what, obj);
        }
    

    2.2.2 接收New SMS

    RadioIndication通过newSms()上报新短信,最终通过mRil.mGsmSmsRegistrant.notifyRegistrant()发送消息EVENT_NEW_SMS事件给GsmInboundSmsHandler:
    /frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioIndication.java

        public void newSms(int indicationType, ArrayList<Byte> pdu) {
            mRil.processIndication(indicationType);
    
            byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
            if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
    
            SmsMessageBase smsb = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pduArray);
            if (mRil.mGsmSmsRegistrant != null) {
                mRil.mGsmSmsRegistrant.notifyRegistrant(
                        new AsyncResult(null, smsb == null ? null : new SmsMessage(smsb), null));
            }
        }
    

    GsmInboundSmsHandler最终会发送intent: SMS_DELIVER_ACTION给相关app。

    2.2.3 发送Delivery Report

    对于普通短消息,会在GsmInboundSmsHandler中发送Delivery Report给网络。

    3 RILD流程

    3.1 接收New SMS流程

    3.1.1 流程图

    mtSmsRild.png

    3.1.2 源码

    vendor_ril收到RIL_onUnsolicitedResponse(),会调用radio::newSmsInd()方法:
    /hardware/ril/libril/ril_unsol_commands.h

        {RIL_UNSOL_RESPONSE_NEW_SMS, radio::newSmsInd, WAKE_PARTIAL},
    

    该方法直接调用RadioIndication的newSms()方法通知Framework:
    /hardware/ril/libril/ril_service.cpp

    int radio::newSmsInd(int slotId, int indicationType,
                         int token, RIL_Errno e, void *response, size_t responseLen) {
        if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
            if (response == NULL || responseLen == 0) {
                RLOGE("newSmsInd: invalid response");
                return 0;
            }
    
            uint8_t *bytes = convertHexStringToBytes(response, responseLen);
            if (bytes == NULL) {
                RLOGE("newSmsInd: convertHexStringToBytes failed");
                return 0;
            }
    
            hidl_vec<uint8_t> pdu;
            pdu.setToExternal(bytes, responseLen/2);
    #if VDBG
            RLOGD("newSmsInd");
    #endif
            Return<void> retStatus = radioService[slotId]->mRadioIndication->newSms(
                    convertIntToRadioIndicationType(indicationType), pdu);
            radioService[slotId]->checkReturnStatus(retStatus);
            free(bytes);
        } else {
            RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
        }
    
        return 0;
    }
    

    3.2 发送Delivery Report流程

    3.2.1 流程图

    mtSmsDeliveryReportRild.png

    3.2.2 源码

    RILJ直接调用radioProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause),最终该消息会通过RILC发送给Modem:
    /frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java : RIL_REQUEST_SMS_ACKNOWLEDGE
    当收到网络侧的回复后,RILC通过ril.cpp调用ril_service的radio::acknowledgeLastIncomingGsmSmsResponse():
    /hardware/ril/reference-ril/reference-ril.c
    /hardware/ril/libril/ril.cpp
    ril_service直接调用RadioResponse的acknowledgeLastIncomingGsmSmsResponse()去通知Framework:
    /hardware/ril/libril/ril_service.cpp
    /hardware/ril/libril/ril_service.cpp:RadioImpl
    /frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioResponse.java

    4 命令+CMT和AT+CNMA

    3GPP 27.005介绍了这两个AT命令:
    3 Text Mode
    3.4 Message Receiving and Reading Commands
    3.4.1 New Message Indications to TE +CNMI
    +CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled); or
    +CMT: <oa>,[<alpha>],<scts>[,<tooa>,<fo>,<pid>,<dcs>,<sca>,<tosca>,<length>]<CR><LF><data> (text mode enabled; about parameters in italics, refer command Show Text Mode Parameters +CSDH)
    4 PDU Mode
    4.6 New Message Acknowledgement to ME/TA +CNMA

    < +CMT: ,30
    0891683110808805F0040BA13142166977F10000223061713590230CC9531B642FCBF3A0F7DA05
    > AT+CNMA=1, 2, "0000"
    < OK
    

    5 Modem流程

    3GPP 24.011,以LTE S1 mode下接收SMS为例:

    协议分层 Step1(NW->MS) Step2(MS->NW) Step3(MS->NW) Step4(NW->MS)
    SM_AL SMS-DELIVER SMS-DELIVER REPORT
    SM_TL
    SM_RL RP-DATA RP-ACK
    CM_sublayer CP-DATA CP-ACK CP-DATA CP-ACK
    EMM_sublayer Downlink NAS transport Uplink NAS Transport Uplink NAS Transport Downlink NAS Transport
    ERRC dlInformationTransfer ulInformationTransfer ulInformationTransfer dlInformationTransfer

    PDU消息:

    Step1: SMS DELIVER
    Downlink NAS transport: 07 62 2e 09 01 2b 01 00 08 91 68 31 10 80 88 05 f0 00 1e 04 0b a1 31 42 16 69 77 f1 00 00 22 30 61 71 35 90 23 0c c9 53 1b 64 2f cb f3 a0 f7 da 05
    Step2: CP-ACK
    Uplink NAS Transport:   07 63 02 89 04
    Step3: SMS DELIVER REPORT
    Uplink NAS Transport:   07 63 09 89 01 06 02 00 41 02 00 00
    Step4: CP-ACK
    Downlink NAS transport: 07 62 02 09 04
    

    6 参考文档

    Android6.0的SMS(短信)源码分析--短信发送
    https://blog.csdn.net/a34140974/article/details/50964080
    Android6.0的SMS(短信)源码分析--短信接收
    https://blog.csdn.net/a34140974/article/details/50963617
    Android源码
    http://aospxref.com/android-12.0.0_r3/
    http://aosp.opersys.com/xref/android-12.0.0_r2/

    版权声明:本文为 无痕1024 原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://www.jianshu.com/p/793cb58876ee

    相关文章

      网友评论

          本文标题:Android S短消息接收流程

          本文链接:https://www.haomeiwen.com/subject/cofbdrtx.html