zoukankan      html  css  js  c++  java
  • cmpp发送超长短信息

    1、长短信息:是指超过70个汉字,140个字节的信息内容。      

            最近在做一个某地市公司运营商的GPRS导引项目的时候,运营商要求将对用户的提示短信息(超过140个字节)发送到用户手机,在用户的手机上一次全显示。

            上网搜索了一些相关的资料,现在将实现总结如下:

    一、CMPP协议相关字段分析(在此只讲发长短信相关的cmpp_submit消息,cmpp的其他内容的请参考《中国移动互联网短信网关接口协议(V3.0.0).doc》

    1.1.1.1      CMPP_SUBMIT消息定义(SP--->SMG

    字段名
    字节数
    属性
    描述
    Msg_Id
    8
    Unsigned Integer
    信息标识。
    Pk_total
    1
    Unsigned Integer
    相同Msg_Id的信息总条数,从1开始。
    Pk_number
    1
    Unsigned Integer
    相同Msg_Id的信息序号,从1开始。
    Registered_Delivery
    1
    Unsigned Integer
    是否要求返回状态确认报告:
    0:不需要;
    1:需要。
    Msg_level
    1
    Unsigned Integer
    信息级别。
    Service_Id
    10
    Octet String
    业务标识,是数字、字母和符号的组合。
    Fee_UserType
    1
    Unsigned Integer
    计费用户类型字段:
    0:对目的终端MSISDN计费;
    1:对源终端MSISDN计费;
    2:对SP计费;
    3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
    Fee_terminal_Id
    32
    Octet String
    被计费用户的号码,当Fee_UserType为3时该值有效,当Fee_UserType为0、1、2时该值无意义。
    Fee_terminal_type
    1
    Unsigned Integer
    被计费用户的号码类型,0:真实号码;1:伪码。
    TP_pId
    1
    Unsigned Integer
    GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.9。
    TP_udhi
    1
    Unsigned Integer
    GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐。
    Msg_Fmt
    1
    Unsigned Integer
    信息格式:
    0:ASCII串;
    3:短信写卡操作;
    4:二进制信息;
    8:UCS2编码;
    15:含GB汉字。。。。。。
    Msg_src
    6
    Octet String
    信息内容来源(SP_Id)。
    FeeType
    2
    Octet String
    资费类别:
    01:对“计费用户号码”免费;
    02:对“计费用户号码”按条计信息费;
    03:对“计费用户号码”按包月收取信息费。
    FeeCode
    6
    Octet String
    资费代码(以分为单位)。
    ValId_Time
    17
    Octet String
    存活有效期,格式遵循SMPP3.3协议。
    At_Time
    17
    Octet String
    定时发送时间,格式遵循SMPP3.3协议。
    Src_Id
    21
    Octet String
    源号码。SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,该号码最终在用户手机上显示为短消息的主叫号码。
    DestUsr_tl
    1
    Unsigned Integer
    接收信息的用户数量(小于100个用户)。
    Dest_terminal_Id
    32*DestUsr_tl
    Octet String
    接收短信的MSISDN号码。
    Dest_terminal_type
    1
    Unsigned Integer
    接收短信的用户的号码类型,0:真实号码;1:伪码。
    Msg_Length
    1
    Unsigned Integer
    信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节),取值大于或等于0。
    Msg_Content
    Msg_length
    Octet String
    信息内容。
    LinkID
    20
    Octet String
    点播业务使用的LinkID,非点播类业务的MT流程不使用该字段。

    红色部分表示发长短信要更改的字段

    洋红色部分表示发长短信可以更改或者不更改的字段

    (以下资料参考:http://publishblog.blogdriver.com/zeroliu/1234594.html

    在cmpp协议里,CMPP­_SUBMIT消息定义中有相应的参数配置:   
     
    TP_udhi :0代表内容体里不含有协议头信息 1代表内容含有协议头信息(长短信,push短信等都是在内容体上含有头内容的)当设置内容体包含协议头,需要根据协议写入相应的信息,长短信协议头有两种:
                   
    6位协议头格式:05 00 03 XX MM NN
                         byte 1 : 05, 表示剩余协议头的长度
                         byte 2 : 00, 这个值在GSM 03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为1(格式中的XX值)。
                         byte 3 : 03, 这个值表示剩下短信标识的长度
                         byte 4 : XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯
                                     一并不是很 重要。
                         byte 5 : MM, 这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
                         byte 6 : NN, 这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
                         例如:05 00 03 39 02 01 

                   
    7位的协议头格式:06 08 04 XX XX MM NN
                         byte 1 : 06, 表示剩余协议头的长度
                         byte 2 : 08, 这个值在GSM 03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为2(格式中的XX值)。
                         byte 3 : 04, 这个值表示剩下短信标识的长度
                         byte 4-5 : XX XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯一并不是很重要。
                         byte 6 : MM, 这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
                         byte 7 : NN, 这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
                         例如:06 08 04 00 39 02 01    

     二、具体实现例子(JAVA代码)

    package com.mysrc;
    /** */

    /**
     * Copyright 2007 GuangZhou mysrc Co. Ltd.
     * All right reserved.
     * 功能说明:  长短信测试
     * @Author: eric(eric_cheung709@hotmail.com)
     * created in 2007/04/28 16:33:06
     * 
    @version 1.0
     
    */

    public class CmppLongMessage 
    {
        
    public static void main(final String[]args) 
        
    {
            CmppLongMessage.sendLongMessage();
        }

        
    public static int sendLongMessage() 
        
    {
            
    int retStatus = 0;
            String message 
    = "作 者:eric_cheung709@hotmail.com;关于cmpp长短信发送,这是测试文本,将分条下发,在用户手机上一条全显示;如果有问题欢 迎email交流联系;下面的是测试代码,可以做为参考;本实现已经通过实际测试,在NOKIA 6680和LG KG90上正常显示";
            
    try 
            
    {
                
    byte[]messageUCS2;
                messageUCS2 
    = message.getBytes("UnicodeBigUnmarked");
                System.out.println(message 
    + " -(UCS2)编码: " + bytesToHexStr(messageUCS2));
                
    int messageUCS2Len = messageUCS2.length;
                
    //长短信长度
                int maxMessageLen = 140;
                
    if (messageUCS2Len > maxMessageLen) 
                
    {
                    
    //长短信发送
                    int tpUdhi = 1;
                    
    int msgFmt = 0x08;
                    
    int messageUCS2Count = messageUCS2Len / (maxMessageLen - 6+ 1;
                    
    //长短信分为多少条发送
                    byte[]tp_udhiHead = new byte[6];
                    tp_udhiHead[
    0= 0x05;
                    tp_udhiHead[
    1= 0x00;
                    tp_udhiHead[
    2= 0x03;
                    tp_udhiHead[
    3= 0x0A;
                    tp_udhiHead[
    4= (byte)messageUCS2Count;
                    tp_udhiHead[
    5= 0x01;
                    
    //默认为第一条
                    for (int i = 0; i < messageUCS2Count; i ++ ) 
                    
    {
                        tp_udhiHead[
    5= (byte)(i + 1);
                        
    byte[]msgContent;
                        
    if (i != messageUCS2Count - 1
                        
    {
                            
    //不为最后一条
                            msgContent = CmppLongMessage.byteAdd(tp_udhiHead, messageUCS2, i * (maxMessageLen - 6), (i + 1* (maxMessageLen - 6));
                        }

                        
    else 
                        
    {
                            msgContent 
    = CmppLongMessage.byteAdd(tp_udhiHead, messageUCS2, i * (maxMessageLen - 6), messageUCS2Len);
                        }

                        System.out.println(
    "正在发送第" + tp_udhiHead[5+ "条长短信");
                        System.out.println(
    "UCS2:" + CmppLongMessage.bytesToHexStr(msgContent));
                        System.out.println(
    "总长度:" + msgContent.length);
                    }

                    
    //for end
                    return retStatus;
                }

                
    //if end
                
            }

            
    catch(Exception e) 
            
    {
                retStatus 
    =- 1;
                e.printStackTrace();
                
    return retStatus;
            }

            
    return retStatus;
        }

        
    /** */
        
        
    /**
      * 功能:
      *     将字节转换为16进制码(在此只是为了调试输出,此函数没有实际意义)
      * 
    @param b  
      * 
    @return 转化后的16进制码
      * @Author: eric(eric_cheung709@hotmail.com)
         * created in 2007/04/28 16:33:06
      
    */

        
    private static String bytesToHexStr(byte[]b) 
        
    {
            
    if (b == null)return "";
            StringBuffer strBuffer 
    = new StringBuffer(b.length * 3);
            
    for (int i = 0; i < b.length; i ++ ) 
            
    {
                strBuffer.append(Integer.toHexString(b[i] 
    & 0xff));
                strBuffer.append(
    " ");
            }

            
    return strBuffer.toString();
        }

        
    /** */
        
        
    /***
      * * 功能:
      *     将src里的字节与add里的从start开始到end(不包括第end个位置)的字节串连在一起返回
      * 
    @param src
      * 
    @param add
      * 
    @param start    add 开始位置
      * 
    @param end      add 的结束位置(不包括end位置)
      * 
    @return 也即实现类似String类型的src+add.subString(start,end)功能
      
    */

        
    public static byte[]byteAdd(byte[]src, byte[]add, int start, int end) 
        
    {
            
    byte[]dst = new byte[src.length + end - start];
            
    for (int i = 0; i < src.length; i ++ ) 
            
    {
                dst[i] 
    = src[i];
            }

            
    for (int i = 0; i < end - start; i ++ ) 
            
    {
                dst[src.length 
    + i] = add[start + i];
            }

            
    return dst;
        }



    }

    2、这是例子输出
     

    作者:eric_cheung709@hotmail.com; 关于cmpp长短信发送,这是测试文本,将分条下发,在用户手机上一条全显示;如果有问题欢迎email交流联系;下面的是测试代码,可以做为参考;本实 现已经通过实际测试,在NOKIA 6680和LG KG90上正常显示 -(UCS2)编码: 4f 5c 80 5 ff 1a 0 65 0 72 0 69 0 63 0 5f 0 63 0 68 0 65 0 75 0 6e 0 67 0 37 0 30 0 39 0 40 0 68 0 6f 0 74 0 6d 0 61 0 69 0 6c 0 2e 0 63 0 6f 0 6d 0 3b 51 73 4e 8e 0 63 0 6d 0 70 0 70 95 7f 77 ed 4f e1 53 d1 90 1 ff c 8f d9 66 2f 6d 4b 8b d5 65 87 67 2c ff c 5c 6 52 6 67 61 4e b 53 d1 ff c 57 28 75 28 62 37 62 4b 67 3a 4e a 4e 0 67 61 51 68 66 3e 79 3a ff 1b 59 82 67 9c 67 9 95 ee 98 98 6b 22 8f ce 0 65 0 6d 0 61 0 69 0 6c 4e a4 6d 41 80 54 7c fb ff 1b 4e b 97 62 76 84 66 2f 6d 4b 8b d5 4e e3 78 1 ff c 53 ef 4e e5 50 5a 4e 3a 53 c2 80 3 ff 1b 67 2c 5b 9e 73 b0 5d f2 7e cf 90 1a 8f c7 5b 9e 96 45 6d 4b 8b d5 ff c 57 28 0 4e 0 4f 0 4b 0 49 0 41 0 20 0 36 0 36 0 38 0 30 54 8c 0 4c 0 47 0 20 0 4b 0 47 0 39 0 30 4e a 6b 63 5e 38 66 3e 79 3a
    正在发送第1条长短信
    UCS2:5 0 3 a 3 1 4f 5c 80 5 ff 1a 0 65 0 72 0 69 0 63 0 5f 0 63 0 68 0 65 0 75 0 6e 0 67 0 37 0 30 0 39 0 40 0 68 0 6f 0 74 0 6d 0 61 0 69 0 6c 0 2e 0 63 0 6f 0 6d 0 3b 51 73 4e 8e 0 63 0 6d 0 70 0 70 95 7f 77 ed 4f e1 53 d1 90 1 ff c 8f d9 66 2f 6d 4b 8b d5 65 87 67 2c ff c 5c 6 52 6 67 61 4e b 53 d1 ff c 57 28 75 28 62 37 62 4b 67 3a 4e a 4e 0 67 61 51 68 66 3e 79 3a ff 1b
    总长度:140
    正在发送第2条长短信
    UCS2:5 0 3 a 3 2 59 82 67 9c 67 9 95 ee 98 98 6b 22 8f ce 0 65 0 6d 0 61 0 69 0 6c 4e a4 6d 41 80 54 7c fb ff 1b 4e b 97 62 76 84 66 2f 6d 4b 8b d5 4e e3 78 1 ff c 53 ef 4e e5 50 5a 4e 3a 53 c2 80 3 ff 1b 67 2c 5b 9e 73 b0 5d f2 7e cf 90 1a 8f c7 5b 9e 96 45 6d 4b 8b d5 ff c 57 28 0 4e 0 4f 0 4b 0 49 0 41 0 20 0 36 0 36 0 38 0 30 54 8c 0 4c 0 47 0 20 0 4b 0 47 0 39 0 30 4e a 6b 63 5e 38
    总长度:140
    正在发送第3条长短信
    UCS2:5 0 3 a 3 3 66 3e 79 3a
    总长度:10

    三、总结。

    cmpp发长短信

    1、TP_udhi设置为  0x01

    2、Msg_Content    按TP_udhi协议填写6字节或者7字节的TP_udhi协议头然后加上经过USC2编码的消息内容。由TP_udhi协议头和消息内容体组成的Msg_Content总长度不能超过140个字节

    3、Msg_Fmt   设置为    0x08    UCS2编码;

    4、Pk_total和Pk_number 可以不设置,如果要设置,就要分别跟TP_udhi的MM和NN字段一致

  • 相关阅读:
    HTML5 的成长之路
    黑马程序员——JAVA基础之数组
    黑马程序员——JAVA基础之函数,重载,内存结构
    黑马程序员——JAVA基础之程序控制流结构之循环结构,循环嵌套
    黑马程序员——JAVA基础之程序控制流结构之判断结构,选择结构
    黑马程序员——JAVA基础之语法、命名规则
    黑马程序员——JAVA基础之常用DOS命令和环境变量的配置
    Android应用开发高效工具集1---ant构建简单Android项目
    10个你能参与并学习的Java开源项目
    Anroid 异常:is not valid; is your activity running?
  • 原文地址:https://www.cnblogs.com/jintan/p/1234233.html
Copyright © 2011-2022 走看看