随笔篇1--短信模块
很久没有写点技术笔记了,今天随笔记录和回忆一下之前短信模块,以防被如今重复无积累的事情所遗忘。
正题 关于 GSM SMS && MMS 封装篇
首先要理解一些基本的常见缩写名词
GSM Global System for MobileCommunication 全球移动通信系统,一种2G网络标准
SMS Short Message Service 短消息服务
EMS Enhanced Message Service 增强型短消息服务
CBS Cell Broadcast Service 小区广播服务
MMS Multimedia Message Service 多媒体消息服务
PDU Protocol Data Unit 协议数据单元,由Header和Data部分组成
TPDU Transfer Protocol Data Unit 传输协议数据单元,是传输层的PDU
MO Mobile Originated 消息的发送方
MT Mobile Terminal 消息的接收方
MS Mobile Station 移动台,在业务流程中可能是MO或者MT
SMSC Short Message Service Centre 短消息服务中心
MMSC Multimedia Message Service Centre 多媒体消息服务中心
3GPP 3rd GenerationPartnership Project 第三代合作伙伴计划,GSM核心的技术规范
OMA Open Mobile Alliance 开放移动联盟,一个标准化组织
RIL Radio Interface Layer 无线接口层,可以看做是modem的HAL层
SM-TL ShortMessage Transfer Layer 短消息传输过程中的传输层
OTA OverThe Air 空中接口
WAP Wireless Application Protocol 无线应用协议,将HTML转成WML以便传输
WSP Wireless Session Protocol 无线会话协议
SI Service Indication 服务通知,让用户主动打开的PUSH消息
SL Service Load 服务加载,PUSH消息到来会自动打开链接
2.短信发送接口
短彩信的接口文件:frameworks\opt\telephony\src\java\android\telephony\SmsManager.java
• void sendTextMessage(
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent);
• void sendTextMessage(String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent, int priority,
boolean isExpectMore, int validityPeriod);
• void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
Bundle configOverrides, PendingIntent sentIntent);
.....还有很多不一一粘贴,可具体到类中查看
2 短消息类型
短消息服务分为:
普通短信:
单条短信最多160个7-BIT字符/140个8-BIT字符/70个16-BIT字符,多条普通短信将组成串接短信(SMS Concatenation)EMS:
Enhanced Message Service,历史的产物,现在已经见不到了,增强型短信,可以发送少量的音频,是多媒体彩信的前身,大小不能超过1KBCBS:
Cell Broadcast Service,小区广播,国内没有这玩意
3 普通短信四种类型PDU
根据MTI(Message Type Indicator)类型可以将普通短信分成四种类型:SMS-SUBMIT,SMS-DELIVERY,SMS-STATUS-REPORT,SMS-COMMAND,其中SMS-COMMAND目前不支持。
3.1 First Byte
每个PDU的第一个字节包含了丰富的意义,
bit7: TP-Reply-Path
1 有
0 无
bit6: 指示是否有userdata header (UDH)
1 有
0 无
bit4.bit3: TP-Validity-Period (submit类型的PDU才有意义)
00: len=0
10: len=1
01/11: len=7
bit1.bit0: MTI – Message Type Indicator
00 Delevery (MT 短信:SC 》 MS)
01 Submit (MO短信:MS 》 SC)
10 Status Report (短信发送之后由SC反馈给发送方的状态报告:SC 》 MS)
3.2 SMS-SUBMIT
MO类型短信,从MS 》 SMSC
解析方法在:
frameworks\opt\telephony\src\java\com\android\internal\telephony\gsm\ SmsMessage.java
void parseSmsSubmit(PduParser p, int firstByte);
4 短信发送流程
短信发送需要destinationAddress(收件人号码)、scAddress(短信中心,可为null)、messages(消息内容,是一个ArrayList,每条消息不能超出单条短信的长度)、sentIntents(PendingIntent,短信发送到SMSC之后通知发送方)、deliveryIntents(PendingIntent,短信中心返回状态报告之后通知发送方这条短信的状态)。
发送前需要构造SMS-SUBMIT类型的PDU。
4.2 GSM SmsMessage的解码接口
frameworks\opt\telephony\src\java\com\android\internal\telephony\gsm\ SmsMessage.java提供了对短信内容进行编码以及对短信PDU进行解码的操作,这是GSM短信的最核心的内容。
TextEncodingDetails calculateLength(CharSequence msgBody,
boolean use7bitOnly);
2) SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message,
boolean statusReportRequested, byte[] header, int encoding,
int languageTable, int languageShiftTable, int validityPeriod)
3) SmsMessage newFromCMT(String[] lines);
4.3 计算长度以确定编码方式
最开始需要计算短信长度,用以确定短信内容的编码方式,调用的就是上面的接口calculateLength
-
7-BIT编码规则在3GPP 23.038 clause 6.2中有详细规定,下面的这张表是GSM标准编码表
默认的短信长度是140个8-BIT字符,经过7-BIT转换之后得到 140 * 8 / 7 = 160个7-BIT字符
强制7bit 重要::这种需要在海外的项目中是有要求的。因为有些国外的运营商并没有提供网络侧的转换,比如德语ä通常来说会要求转成英文字母a,而这些一般是由运营商来做的。
8-BIT,这种编码方式很少使用
16-BIT,当无法使用7-BIT进行编码时,就会使用UCS2进行编码,这种编码方式基本可以满足我们的要求
4.4 构造串接短信头部
从应用层传过来的消息内容条数可以知道这条短信是否是串接短信,如果是串接短信,需要构造短信头(SmsHeader,即PDU中的UDH)来进行组织。如下图。
concatRef.refNumber标识当前的短信片段ID,这是从第一条短信片段开始逐一递增的;
concatRef.seqNumber标识这条短信片段在整条串接短信中的位置,这是用来标识拼接顺序的
concatRef.msgCount标识这条串接短信的片段数
4.5 构造PDU
有了足够的元素,开始构造SMS-SUBMIT PDU,还是调用SmsMessage中的getSubmitPdu方法。
1)构造FisrtByte,
2)填充UserData和UserDataLength
4.6 发送过程
SMS-SUBMIT 类型的PDU构造完成,准备调用RIL接口发送。
1)发送之前检查当时是否允许发送。
SmsUsageMonitor这个类是用来检查某个APK短时间内发送短信数量是否超标。
有时候我们测试群发短信会弹出“在发送大量短信。是否允许该应用继续发送短信?”就是这个限制在起作用
2)RIL的处理方式是异步的,因此调用RIL接口发送之前,需要有Message来接收RIL的结果。
。。。。。。。。。。。。。。。。。。。未完待续