Android S短消息接收流程

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 版权协议,转载请附上原文出处链接和本声明。
本文链接://www.greatytc.com/p/793cb58876ee

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容