中国电信的短信接入提供了两种方式,一种是ISAG方式接入,一种是SMGP协议接入。ISAG本身自行有长短信的封装,由于厂家不同,支持的长度也存在差异。SMGP协议接入SP端需要自行封装长短信协议。如何在SMGP的协议中发送长短信。我们需要做三件事情,分别为:
一、设置tlv字段TP_udhi为0x01,表示消息内容里面包含消息头(也就是说含长短信头)
TLV字段说明
TLV是可选参数 Tag,Length,Value的缩写
其中
Tag是2个字节,表示字段的标签,说明是啥值
Length是2个字节,表示后面具体值的长度
Value可变长度,长度为Length,字段的内容
TP_udhi的 Tag为:0x0002,Length为:0x0001 Value:为0x01,具体TLV参数设置参考SMGP3.1协议
二、内容前面需要增加6个字段
1、 字节一:包头长度,固定填写0x05;
2、 字节二:包头类型标识,固定填写0x00,表示长短信;
3、 字节三:子包长度,固定填写0x03,表示后面三个字节的长度;
4、 字节四到字节六:包内容:
a) 字节四:长消息参考号,每个SP给每个用户发送的每条参考号都应该不同,可以从0开始,每次加1,最大255,便于同一个终端对同一个SP的消息的不同的长短信进行识别;
b) 字节五:本条长消息的的总消息数,从1到255,一般取值应该大于2;
c) 字节六:本条消息在长消息中的位置或序号,从1到255,第一条为1,第二条为2,最后一条等于第四字节的值。
例子:
05 00 03 00 02 01
05 00 03 00 02 02
参考代码如下:
- private static byte[] addContentHeader(byte[] content, int total, int num) { // 为了加消息头参数为(原数据,总条数,当前条数)
- // int curlong = content.length;
- byte[] newcontent = new byte[content.length + 6];
- newcontent[0] = 0x05;
- newcontent[1] = 0x00;
- newcontent[2] = 0x03;
- newcontent[4] = (byte) total;
- newcontent[5] = (byte) num;
- System.arraycopy(content, 0, newcontent, 6, content.length);
- return newcontent;
- }
三、你还需要设置TVL字段:PkTotal和PkNumber(非必选)
这个字段如果不设置并不影响用户手机对短信的拼装,但是会影响ismp的健权和计费,一组pktotal pknumber里面的数据ismp是当一条短信健权和计费。
需要说明的是:
一、如果网关方式长短信建议用ucs-2编码。
因为在gbk编码的过程中,英文当1个字节;usc-2 中英文都2字节,对于即将分割的长短信你很难确保中间不会混排中英文,所以拆分的时候不会出现汉字被截半个的问题。出现的现象为第一条短信正常,第二条短信开始存在乱码。
二、长短信成功率的问题也是不得不考虑的
对于一组长短信,如果中间有一条短信丢了就无法拼回来长短信了,也就是说这组短信要全部都发送到用户手机这里才能正常拼装和显示,如果丢1条,其他的短信就等于白发。假设短信发送成功率是95%,那2条拼接的长短信成功率是0.95*0.95=90.25%,如果10条短信拼接的长短信的成功率是0.95^10=59.87%。可以看出越长的长短信下行以后的成功率越低,可能会抵到超过你的想象。
三、SMGP2.0协议无法发送长短信
虽然部分CDMA的短信网关支持2.0协议,但是由于2.0协议未定义有TLV字段,所以无法设置长短信必要的参数:TP_udhi
四、长短信最大长度
长短信目前根据网关的实际测试,最长可以由10条短信拼接,所以理论上发送最大的汉字为:(140-6(6个字节的udh)) *10/2 = 670个汉字,不过需要说明的是,如此长的长短信正如第二点所说的成功率是低的惊人的。
更多的帮助可以参考我在Google上的项目:http://smgp.googlecode.com 该API已经对长短信进行了封装,可以直接使用。