⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wappushsmsconstructor.java

📁 短信系统SMS:支持普通短信、长短信和wap push短信的发送。
💻 JAVA
字号:
package com.ekun.common.sms;

import java.util.*;
import com.ekun.common.log.*;

public class WAPPushSmsConstructor
{
  String msisdn;
  String title;
  String url;
  Date createdTime;
  Date expiresTime;
  protected static final int SMSMAXLENGTH = 140;

  protected static final int UDH_LENGTH = 7;

  protected static final int UDH_EXT_LENGTH = 12;

  private static Logger logger = LoggerFactory.getLogger(WAPPushSmsConstructor.class);

  /**
   * PAP协议短信格式构造器构造函数
   * @param MSISDN
   * @param Title
   * @param URL
   */
  public WAPPushSmsConstructor(String MSISDN, String Title, String URL)
  {
    this.msisdn = MSISDN;
    this.title = Title;
    this.url = URL;
    this.createdTime = null;
    this.expiresTime = null;
    url = url == null ? "" : url.trim();
    int pos = url.toLowerCase().indexOf("http://");
    if (pos == 0)
    {
      url = url.substring(7);
    }
  }

  /**
   * 获取短信格式二进制内容
   *
   * @return 二进制内容
   */
  public byte[] GetSMSBinaryData()
  {
    byte[] Title = null;
    try
    {
      Title = this.title.getBytes("UTF-8");
    }
    catch (java.io.UnsupportedEncodingException e)
    {
      Title = this.title.getBytes();
    }

    byte[] Url = null;
    Url = this.url.getBytes();

    byte[] result = new byte[35 + Title.length + Url.length];
    int i = 0;

    //0x06, 0x05, 0x04, 0x0B, 0x84, 0x23, 0xF0, ' Wap Push Header
    result[i++] = 0x06;  //User Data Header Length (6 bytes)
    result[i++] = 0x05;  //UDH Item Element id (Port Numbers)
    result[i++] = 0x04;  //UDH IE length (4 bytes)
    //0B 84:destination port number
    result[i++] = 0x0b;
    result[i++] = (byte) 0x84;
    //23 F0:origin port number
    result[i++] = 0x23;
    result[i++] = (byte) 0xf0;

    //PDU
    result[i++] = 0x01; // push-id
    result[i++] = 0x06; // 'pdu type (06=push)
    result[i++] = 0x0a; // Headers len
    //03 AE 81 EA  'content type: application/vnd.wap.sic; charset=utf-8
    result[i++] = 0x03; // cert ??
    result[i++] = (byte) 0xae; // application/vnd.wap.sic
    result[i++] = (byte) 0x81; // charset
    result[i++] = (byte) 0xea; // utf-8

    result[i++] = (byte) 0xaf;
    result[i++] = (byte) 0x82;
    result[i++] = (byte) 0x8d; //
    result[i++] = (byte) 0xae;

    result[i++] = (byte) (Url.length + 159);
    result[i++] = (byte) 0x87;

    //SI part
    result[i++] = 0x02;
    result[i++] = 0x05; //-//WAPFORUM//DTD SI 1.0//EN
    result[i++] = 0x6A; //UTF-8
    result[i++] = 0x00; //字符串结束
    result[i++] = 0x45; //<si>
    result[i++] = (byte) 0xC6; //<indication
    result[i++] = 0x08; //<action=signal-high>
    result[i++] = 0x0C; //href="http://
    result[i++] = 0x03; //字符串开始

    for (int j = 0; j < Url.length; )
    {
      result[i++] = Url[j++];
    } //实际地址
    result[i++] = 0x00; //字符串结束
    result[i++] = 0x01; //>

    result[i++] = 0x03; //字符串开始
    for (int j = 0; j < Title.length; )
    {
      result[i++] = Title[j++];

    }

    result[i++] = 0x00; //字符串结束
    result[i++] = 0x01; //</indication>"
    result[i++] = 0x01; //'</si>

    return result;
  }

  /**
   * 获取二进制的短信内容
   *
   * @return 短信内容
   */
  public byte[][] getMultiSMSBinaryData()
  {
    logger.debug("***************getMultiSMSBinaryData begin*************");
    byte[] oneBigSMS = GetSMSBinaryData();
    logger.debug("oneBigSMS.length  = " + oneBigSMS.length);
    final int MaxExtBodyLen = SMSMAXLENGTH - UDH_EXT_LENGTH;
    byte[][] results;
    // 需要对刚好整除情况处理,所以用ceil()表示上约,注意ceil()需要传入double参数才能得到正确结果
    int totalSMSAmount = (oneBigSMS.length <= SMSMAXLENGTH) ? 1
        : ( (int) Math.ceil( (double) (oneBigSMS.length - UDH_LENGTH)
                            / MaxExtBodyLen));
    // ((oneBigSMS.length-UDH_LENGTH) / (SMSMAXLENGTH-UDH_EXT_LENGTH) + 1);
    logger.debug("totalSMSAmount  = " + totalSMSAmount);
    results = new byte[totalSMSAmount][]; //a SMS per row
    //单包
    if (totalSMSAmount == 1)
    {
      logger.debug("Single SMS Packet, packet length is : "
                   + oneBigSMS.length);
      results[0] = new byte[oneBigSMS.length];
      //fillUDH(results[0], 1, 1);
      fillBody(oneBigSMS, 0, results[0], 0, oneBigSMS.length);
      logger
          .debug("*************Single SMS Packet finished ************");
      return results;
    }
    //多包
    for (int j = 0; j < totalSMSAmount; j++)
    {
      //根据是否最后一个包判定包长度
      int length = (j != (totalSMSAmount - 1)) ? SMSMAXLENGTH
          : (oneBigSMS.length - UDH_LENGTH - MaxExtBodyLen * j + UDH_EXT_LENGTH);
      logger.debug("length of SMS packet [ " + j + " ] is " + length);
      results[j] = new byte[length];

      fillUDH(results[j], totalSMSAmount, j + 1);
      fillBody(oneBigSMS, UDH_LENGTH + MaxExtBodyLen * j, results[j],
               UDH_EXT_LENGTH, length - UDH_EXT_LENGTH);
    }
    logger
        .debug("*******************getMultiSMSBinaryData finished.(Multiple SMS packet) ****************");
    return results;
  }

  /**
   * fillBody
   * 填充SMS 包体内容,方法是从原来的一个大包中复制到目标包中
   *
   */
  private void fillBody(byte[] src, int srcOffset, byte[] dest,
                        int destOffset, int nCount)
  {
    logger.debug("*******************fillBody begin*******************");
    logger.debug("source start from " + srcOffset);
    logger.debug("dest start from " + destOffset);
    logger.debug("length of this packet body is " + nCount);
    for (int i = 0; i < nCount; i++)
    {
      dest[i + destOffset] = src[i + srcOffset];
    }
    logger.debug("*******************fillBody finished*******************");
  }

  /**
   * 一个扩展包wappush包是这么构成的
   * WDP + WSP + SI/SL

   * 如果长度超常(短信一个包的Content不要超过140)
   * 就要分解成

   * WDP1 + (WSP+SI/SL)的part 1
   * WDP2 + (WSP+SI/SL)的part 2
   * ...
   * WDPN + (WSP+SI/SL)的part N

   * 如单包
   * WDP: 06 05 04 0B 84 23 F0
   * WSP: ...
   * SI/SL:...

   * 双包是
   * 第1包
   * WDP: 0B 05 04 0B 84 23 F0 00 03 01 02 01
   * Part1: ...

   * // 00 - UDH IE Tag
   * // 03 - UDH SAR IE Length
   * // 01 - Reference
   * // 02 - Total Packet
   * // 01 - Current Packet

   * 第2包
   * WDP: 0B 05 04 0B 84 23 F0 00 03 01 02 02
   * Part2:...
   *
   *
   * @param totalSMSAmount 总包数
   * @param number 第几包 (0<number<=总包数)
   */
  private void fillUDH(byte[] result, int totalSMSAmount, int number)
  {
    logger.debug("*******************fillUDH begin*******************");
    if ( (number > totalSMSAmount) || (number <= 0))
    {
      logger.error("can't generate UDH correctly.");
    }
    // WDP header(单包前7 bytes,多包12bytes)
    if (totalSMSAmount > 1)
    {
      result[0] = 0x0b;
    }
    else
    {
      result[0] = 0x06;
    }

    result[1] = 0x05;
    result[2] = 0x04;
    result[3] = 0x0b;
    result[4] = (byte) 0x84;
    result[5] = 0x23;
    result[6] = (byte) 0xf0;
    //多包
    if (totalSMSAmount > 1)
    {
      logger.debug("multiple packet: No. " + number + "of total "
                   + totalSMSAmount);
      result[7] = 0x00;
      result[8] = 0x03;
      result[9] = 0x01;

      result[10] = (byte) totalSMSAmount;
      result[11] = (byte) number;
    }
    logger.debug("*******************fillUDH finished*******************");
  }

  /**test case**/
  public static void main(String[] args)
  {
    WAPPushSmsConstructor psc = new WAPPushSmsConstructor("13510328056", "test", "http://ddd.com");
    byte[][] b = psc.getMultiSMSBinaryData();
    System.out.println("b.len = " + b.length);
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -