Create WAP Push SMS Messages

来源:互联网 发布:做网络推广压力大吗 编辑:程序博客网 时间:2024/04/30 23:35

转自:http://blog.163.com/htlxyz@126/blog/static/1685940292009620111811387/


改过后的代码在下面,程序好像可以输出了WAPPUSH的结构化的东西,但是,没有在CMPP协议上测试通过。

共7个文件:

package com.wap.wbxml;

public class Runner {

/**
* @param args
*/
public static void main(String[] args) {
   try
   {
    String recipient = "";   // mobile number to send the message to
    String href = "http://wap.monternet.com"; // url of the content to be pushed
    String text = "A WAP Push to 梦网 site"; // description of the content displayed to the user

    PushMessage message = new PushMessage(href, text);
    HexDecoder decoder = new HexDecoder();


//    Console.WriteLine("SMS body");
    System.out.println("SMS body");
//    Console.WriteLine(body);

    String body = new String(decoder.GetChars(message.GetSMSBytes()));
    System.out.println(body);
    body =byteToHexStr(message.GetSMSBytes());
    System.out.println(body);
    // this body is now ready to be sent, either via
    // an SMS Web Service as shown below or 
    // via a mobile phone on a serial port.
    // Making sure the message is flagged as containing
    // a User Data Header

    // A free evaluation account for this service can
    // be set up at https://www.esendex.com/secure/registration/evaluation.aspx

//    messenger.MessengerHeader header = new messenger.MessengerHeader();
//    header.Username = "";   // username for the SMS account
//    header.Password = "";   // password for the SMS account
//    header.Account = "";   // account reference
//
//    messenger.SendService service = new messenger.SendService();
//    service.MessengerHeaderValue = header;
//
//    service.SendMessage(recipient, body, messenger.MessageType.SmartMessage);
//    Console.WriteLine("Message sent");
   }
   catch (Exception ex)
   {
//    Console.WriteLine(ex);
    ex.printStackTrace();
   }
//   Console.ReadLine();

}
private static String byteToHexStr(byte buf[]) {
   StringBuffer sb = new StringBuffer(2 * buf.length);
   for(int i = 0; i < buf.length; i++) {
    int h = (buf[ i ] & 0xf0) >> 4;
   int l = (buf[ i ] & 0x0f);
   sb.append(new Character((char)((h > 9) ? 'a' + h - 10 : '0' + h)));
   sb.append(new Character((char)((l > 9) ? 'a' + l - 10 : '0' + l)));
   }
   return sb.toString().toUpperCase();
}
}

package com.wap.wbxml;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;

public class PushMessage {

// Ports for the WDP information element, instructing the handset which 
// application to load on receving the message
protected static byte[] WDP_DESTINATIONPORT = new byte[] {0x0b, (byte) 0x84};
protected static byte[] WDP_SOURCEPORT = new byte[] {0x23, (byte) 0xf0};

ServiceIndication serviceIndication;

public PushMessage(String href, String text)
{
   this.serviceIndication = new ServiceIndication(href, text, ServiceIndication.ServiceIndicationAction.signal_high);
}

/// <summary>
/// Generates the body of the SMS message
/// </summary>
/// <returns>byte array</returns>
public byte[] GetSMSBytes()
{
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
//   MemoryStream stream = new MemoryStream();
//   stream.Write(wdpHeader, 0, wdpHeader.length);
//   stream.Write(pdu, 0, pdu.length);
  
   byte[] wdpHeader = GetWDPHeaderBytes();

   stream.write(wdpHeader, 0, wdpHeader.length);

   byte[] pdu = GetPDUBytes();

   stream.write(pdu, 0, pdu.length);
   return stream.toByteArray();
}

/// <summary>
/// Generates the PDU (Protocol Data Unit) comprising the encoded Service Indication
/// and the WSP (Wireless Session Protocol) headers
/// </summary>
/// <returns>byte array comprising the PDU</returns>
public byte[] GetPDUBytes()
{
   byte[] body = serviceIndication.GetWBXMLBytes();
  
   byte[] headerBuffer = GetWSPHeaderBytes((byte)body.length);
  
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
  
//   MemoryStream stream = new MemoryStream();
//   stream.Write(headerBuffer, 0, headerBuffer.length);
//   stream.Write(body, 0, body.length);
   stream.write(headerBuffer, 0, headerBuffer.length);
   stream.write(body, 0, body.length);
   return stream.toByteArray();
}

/// <summary>
/// Generates the WSP (Wireless Session Protocol) headers with the well known
/// byte values specfic to a Service Indication
/// </summary>
/// <param name="contentLength">the length of the encoded Service Indication</param>
/// <returns>byte array comprising the headers</returns>
public byte[] GetWSPHeaderBytes(byte contentLength)
{
//   MemoryStream stream = new MemoryStream();
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
  
//   stream.WriteByte(WSP.TRANSACTIONID_CONNECTIONLESSWSP);
//   stream.WriteByte(WSP.PDUTYPE_PUSH);
   stream.write(WSP.TRANSACTIONID_CONNECTIONLESSWSP);
   stream.write(WSP.PDUTYPE_PUSH);
  
//   MemoryStream headersStream = new MemoryStream();
   ByteArrayOutputStream headersStream = new ByteArrayOutputStream();
  
   headersStream.write(WSP.HEADER_CONTENTTYPE_application_vnd_wap_sic_utf_8, 0, WSP.HEADER_CONTENTTYPE_application_vnd_wap_sic_utf_8.length);
  
   headersStream.write(WSP.HEADER_APPLICATIONTYPE);
   headersStream.write(WSP.HEADER_APPLICATIONTYPE_x_wap_application_id_w2);

//   headersStream.WriteByte(WSP.HEADER_CONTENTLENGTH);
//   headersStream.WriteByte((byte)(contentLength + 128));
//
   headersStream.write(WSP.HEADER_PUSHFLAG, 0, WSP.HEADER_PUSHFLAG.length);

//   stream.write((byte)headersStream.length);
//
//   headersStream.WriteTo(stream);
//  
   stream.write((byte)headersStream.toByteArray().length);

   stream.write(headersStream.toByteArray(),0,headersStream.toByteArray().length);
//   headersStream.WriteTo(stream);
  

   return stream.toByteArray();
}

/// <summary>
/// Generates the WDP (Wireless Datagram Protocol) or UDH (User Data Header) for the 
/// SMS message. In the case comprising the Application Port information element
/// indicating to the handset which application to start on receipt of the message
/// </summary>
/// <returns>byte array comprising the header</returns>
public byte[] GetWDPHeaderBytes()
{
//   MemoryStream stream = new MemoryStream();
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
//   stream.WriteByte(WDP.INFORMATIONELEMENT_IDENTIFIER_APPLICATIONPORT);
//   stream.WriteByte((byte)(WDP_DESTINATIONPORT.length + WDP_SOURCEPORT.length));
   stream.write(WDP.INFORMATIONELEMENT_IDENTIFIER_APPLICATIONPORT);
   stream.write((byte)(WDP_DESTINATIONPORT.length + WDP_SOURCEPORT.length));
   stream.write(WDP_DESTINATIONPORT, 0, WDP_DESTINATIONPORT.length);
   stream.write(WDP_SOURCEPORT, 0, WDP_SOURCEPORT.length);

//   MemoryStream headerStream = new MemoryStream();
   ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
   // write length of header
   headerStream.write((byte)stream.toByteArray().length);
   headerStream.write(stream.toByteArray(),0,stream.toByteArray().length);
//   stream.WriteTo(headerStream);
   return headerStream.toByteArray();
}

/**
* @param args
*/
public static void main(String[] args) {

}

}

package com.wap.wbxml;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import com.tools.Utf8Util;

/**
* @author

* @date 2007-2-24 22:16:15
* @
*/

public class ServiceIndication {

public static enum ServiceIndicationAction {NotSet, signal_none, signal_low, signal_medium, signal_high, delete};

// Well known DTD token
public static byte DOCUMENT_DTD_ServiceIndication = 0x05;    // ServiceIndication 1.0 Public Identifier

// Tag Tokens
public static byte TAGTOKEN_si = 0x5;
public static byte TAGTOKEN_indication = 0x6;
public static byte TAGTOKEN_info = 0x7;
public static byte TAGTOKEN_item = 0x8;

// Attribute Tokens
public static byte ATTRIBUTESTARTTOKEN_action_signal_none = 0x5;
public static byte ATTRIBUTESTARTTOKEN_action_signal_low = 0x6;
public static byte ATTRIBUTESTARTTOKEN_action_signal_medium = 0x7;
public static byte ATTRIBUTESTARTTOKEN_action_signal_high = 0x8;
public static byte ATTRIBUTESTARTTOKEN_action_signal_delete = 0x9;
public static byte ATTRIBUTESTARTTOKEN_created = 0xA;
public static byte ATTRIBUTESTARTTOKEN_href = 0xB;
public static byte ATTRIBUTESTARTTOKEN_href_http = 0xC;    // http://
public static byte ATTRIBUTESTARTTOKEN_href_http_www = 0xD; // http://www.
public static byte ATTRIBUTESTARTTOKEN_href_https = 0xE;    // https://
public static byte ATTRIBUTESTARTTOKEN_href_https_www = 0xF; // https://www.
public static byte ATTRIBUTESTARTTOKEN_si_expires = 0x10;
public static byte ATTRIBUTESTARTTOKEN_si_id = 0x11;
public static byte ATTRIBUTESTARTTOKEN_ // Attribute Value Tokens
public static byte ATTRIBUTEVALUETOKEN_com = (byte) 0x85;       // .com/
public static byte ATTRIBUTEVALUETOKEN_edu = (byte) 0x86;       // .edu/
public static byte ATTRIBUTEVALUETOKEN_net = (byte) 0x87;       // .net/
public static byte ATTRIBUTEVALUETOKEN_org = (byte) 0x88;       // .org/

private static HashMap<String,Byte> hrefStartTokens;
// private static HashTable attributeValueTokens;
private static HashMap<String,Byte> attributeValueTokens;

public String Href;
public String Text;

// public DateTime CreatedAt;
// public DateTime ExpiresAt;

public Calendar CreatedAt;
public Calendar ExpiresAt;

public ServiceIndicationAction Action;

static 
{
   hrefStartTokens = new HashMap<String,Byte>();


//   hrefStartTokens.Add("https://www.", ATTRIBUTESTARTTOKEN_href_https_www);
//   hrefStartTokens.Add("http://www.", ATTRIBUTESTARTTOKEN_href_http_www);
//   hrefStartTokens.Add("https://", ATTRIBUTESTARTTOKEN_href_https);
//   hrefStartTokens.Add("http://", ATTRIBUTESTARTTOKEN_href_http);

   hrefStartTokens.put("https://www.", ATTRIBUTESTARTTOKEN_href_https_www);
   hrefStartTokens.put("http://www.", ATTRIBUTESTARTTOKEN_href_http_www);
   hrefStartTokens.put("https://", ATTRIBUTESTARTTOKEN_href_https);
   hrefStartTokens.put("http://", ATTRIBUTESTARTTOKEN_href_http);
  
   attributeValueTokens =new HashMap<String,Byte>();

   attributeValueTokens.put(".com/", ATTRIBUTEVALUETOKEN_com);
   attributeValueTokens.put(".edu/", ATTRIBUTEVALUETOKEN_edu);
   attributeValueTokens.put(".net/", ATTRIBUTEVALUETOKEN_net);
   attributeValueTokens.put(".org/", ATTRIBUTEVALUETOKEN_org);
  
//   attributeValueTokens.Add(".com/", ATTRIBUTEVALUETOKEN_com);
//   attributeValueTokens.Add(".edu/", ATTRIBUTEVALUETOKEN_edu);
//   attributeValueTokens.Add(".net/", ATTRIBUTEVALUETOKEN_net);
//   attributeValueTokens.Add(".org/", ATTRIBUTEVALUETOKEN_org);
}

public ServiceIndication(String href, String text, ServiceIndicationAction action)
{
   this.Href = href;
   this.Text = text;
   this.Action = action;
}

public ServiceIndication(String href, String text, Calendar createdAt, Calendar expiresAt)
  
{
   this(href, text, ServiceIndicationAction.NotSet);
   this.CreatedAt = createdAt;
   this.ExpiresAt = expiresAt;
}

public ServiceIndication(String href, String text, Calendar createdAt, Calendar expiresAt, ServiceIndicationAction action)
{
   this (href, text, action);
   this.CreatedAt = createdAt;
   this.ExpiresAt = expiresAt;
}

/// <summary>
/// Generates a byte array comprising the encoded Service Indication
/// </summary>
/// <returns>The encoded body</returns>
public byte[] GetWBXMLBytes()
{
//   MemoryStream stream = new MemoryStream();
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
   // wbxml headers
   stream.write(WBXML.VERSION_1_1);
   stream.write(DOCUMENT_DTD_ServiceIndication);
   stream.write(WBXML.CHARSET_UTF_8);
   stream.write(WBXML.NULL);

   // start xml doc
   stream.write(WBXML.SetTagTokenIndications(TAGTOKEN_si, false, true));
   stream.write(WBXML.SetTagTokenIndications(TAGTOKEN_indication, true , true));

   // href attribute
   // this attribute has some well known start tokens that 
   // are contained within a static hashtable. Iterate through
   // the table and chose the token.
   int i = 0;
   byte hrefTagToken = ATTRIBUTESTARTTOKEN_href;
//   foreach (String startString : hrefStartTokens.Keys)
   for (String startString : hrefStartTokens.keySet())
   {
    if (this.Href.startsWith(startString))
    {
//     hrefTagToken = (byte)hrefStartTokens[startString];
     hrefTagToken = (byte)hrefStartTokens.get(startString);
     i = startString.length();
     break;
    }
   }
   stream.write(hrefTagToken);

   WriteInlineString(stream, this.Href.substring(i));
/* 
* Date elements removed as does not seem to be supported
* by all handsets, or I'm doing it incorrectly, or it's a version 1.2
* thing.

   // created attrbute
   stream.WriteByte(ATTRIBUTESTARTTOKEN_created);
   WriteDate(stream, this.CreatedAt);

   // si-expires attrbute
   stream.WriteByte(ATTRIBUTESTARTTOKEN_si_expires);
   WriteDate(stream, this.ExpiresAt);
*/
   // action attibute
   if (this.Action != ServiceIndicationAction.NotSet)
    stream.write(GetActionToken(this.Action));

   // close indication element attributes
   stream.write(WBXML.TAGTOKEN_END);
  
   // text of indication element
   WriteInlineString(stream, this.Text);

   // close indication element
   stream.write(WBXML.TAGTOKEN_END);
   // close si element
   stream.write(WBXML.TAGTOKEN_END);
  
   return stream.toByteArray();
}

/// <summary>
/// Gets the token for the action attribute
/// </summary>
/// <param name="action">Interruption level instruction to the handset</param>
/// <returns>well known byte value for the action attribute</returns>
protected byte GetActionToken(ServiceIndicationAction action)
{
   switch (action)
   {
//    case ServiceIndicationAction.delete :
    case delete :   
     return ATTRIBUTESTARTTOKEN_action_signal_delete;
//    case ServiceIndicationAction.signal_high :
    case signal_high :
     return ATTRIBUTESTARTTOKEN_action_signal_high;
    case signal_low :
     return ATTRIBUTESTARTTOKEN_action_signal_low;
    case signal_medium : 
     return ATTRIBUTESTARTTOKEN_action_signal_medium;
    default :
     return ATTRIBUTESTARTTOKEN_action_signal_none;
   }
}

/// <summary>
/// Encodes an inline String into the stream using UTF8 encoding
/// </summary>
/// <param name="stream">The target stream</param>
/// <param name="text">The text to write</param>
protected void WriteInlineString(ByteArrayOutputStream stream, String text)
{
   // indicate that the follow bytes comprise a String
   stream.write(WBXML.TOKEN_INLINE_STRING_FOLLOWS);

   // write character bytes
//   byte[] buffer = Encoding.UTF8.GetBytes(text);
   byte[] buffer=null;
   try {
    buffer = text.getBytes("UTF-8");
    stream.write(buffer, 0, buffer.length);
   } catch (UnsupportedEncodingException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
   }
  

   // end is indicated by a null byte
   stream.write(WBXML.NULL);
}
/// <summary>
/// Encodes the DateTime to the stream.
/// DateTimes are encoded as Opaque Data with each number in the String represented
/// by its 4-bit binary value
/// eg: 1999-04-30 06:40:00
/// is encoded as 199904300640.
/// Trailing zero values are not included.
/// </summary>
/// <param name="stream">Target stream</param>
/// <param name="date">DateTime to encode</param>
protected void WriteDate(ByteArrayOutputStream stream, Calendar date)
{
   byte[] buffer = new byte[7];
  
   int year=date.get(Calendar.YEAR);
   int month=date.get(Calendar.MONTH)+1;
   int day=date.get(Calendar.DATE);
   int hour=date.get(Calendar.HOUR_OF_DAY);
   int minute=date.get(Calendar.MINUTE);
   int second=date.get(Calendar.SECOND);
  
   buffer[0] = (byte)(year / 100);
   buffer[1] = (byte)(year % 100);
   buffer[2] = (byte)month;
   buffer[3] = (byte)day;

   int dateLength = 4;

   if (hour > 0)
   {
    buffer[4] = (byte)hour;
    dateLength = 5;
   }

   if (minute> 0)
   {
    buffer[5] = (byte)minute;
    dateLength = 6;
   }

   if (second > 0)
   {
    buffer[6] = (byte)second;
    dateLength = 7;
   }
  
   // write to stream
   stream.write(WBXML.TOKEN_OPAQUEDATA_FOLLOWS);
   stream.write((byte)dateLength);
   stream.write(buffer, 0, dateLength);
}


/**
* @param args
*/
public static void main(String[] args) {
   // TODO 自动生成方法存根

}

}

package com.wap.wbxml;

public class WBXML {

public static byte NULL = 0x00;

public static byte VERSION_1_1 = 0x01;
public static byte VERSION_1_2 = 0x02;

public static byte CHARSET_UTF_8 = 0x6A;

public static byte TAGTOKEN_END = 0x01;
public static byte TOKEN_INLINE_STRING_FOLLOWS = 0x03;
public static byte TOKEN_OPAQUEDATA_FOLLOWS = (byte) 0xC3;

public static byte SetTagTokenIndications(byte token, Boolean hasAttributes, Boolean hasContent)
{
   if (hasAttributes)
    token |= 0xC0;
   if (hasContent)
    token |= 0x40;

   return token;
}

/**
* @param args
*/
public static void main(String[] args) {
   // TODO 自动生成方法存根

}

}

package com.wap.wbxml;

import java.io.ByteArrayOutputStream;

public class WDP {

public static byte INFORMATIONELEMENT_IDENTIFIER_APPLICATIONPORT = 0x05;

/**
* @param args
*/
public static void main(String[] args) {
   ByteArrayOutputStream stream = new ByteArrayOutputStream();
//   MemoryStream stream = new MemoryStream();
//   stream.Write(wdpHeader, 0, wdpHeader.length);
//   stream.Write(pdu, 0, pdu.length);
  
   byte[] wdpHeader = {0x01};

   stream.write(wdpHeader, 0, wdpHeader.length);

   byte[] pdu ={0x03,0x04,0x05};
   stream.write(12);
   stream.write(pdu, 0, pdu.length);

   byte[] b=stream.toByteArray();
   for(int i=0;i<b.length;i++){
    System.out.println(b[i]);
   }
   System.out.println(stream.toByteArray().length);


}

}

package com.wap.wbxml;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class WSP {

public static byte TRANSACTIONID_CONNECTIONLESSWSP = 0x25;

public static byte PDUTYPE_PUSH = 0x06;

public static byte HEADER_CONTENTLENGTH = (byte) 0x8D;

public static byte[] HEADER_CONTENTTYPE_application_vnd_wap_sic_utf_8 = new byte[] {0x03,(byte) 0xAE,(byte) 0x81,(byte) 0xEA};

public static byte HEADER_APPLICATIONTYPE = (byte) 0xaf;
public static byte HEADER_APPLICATIONTYPE_x_wap_application_id_w2 = (byte) 0x82;

public static byte[] HEADER_PUSHFLAG = new byte[] {(byte) 0xB4, (byte) 0x84};

/**
* @param args
*/
public static void main(String[] args) {

  
   java.text.DateFormat df = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
   String Time = df.format(new java.util.Date());
   java.util.Date dt=new java.util.Date();
   System.out.println(dt.getYear());
  
   System.out.println(Time);
//   int timeint=Integer.parseInt(Time);
  
   Calendar calendar = new GregorianCalendar();
   int year=calendar.get(Calendar.YEAR);
   int month=calendar.get(Calendar.MONTH)+1;
   int date=calendar.get(Calendar.DATE);
   int hour=calendar.get(Calendar.HOUR_OF_DAY);
   int minute=calendar.get(Calendar.MINUTE);
   int second=calendar.get(Calendar.SECOND);
   String Time2 = Integer.toString(year)+Integer.toString(month)+Integer.toString(date)+" "+Integer.toString(hour)+Integer.toString(minute)+Integer.toString(second);
   System.out.println(Time2);
}

}

package com.wap.wbxml;

/**
* @author xujianqiang
* @date 2007-2-24 22:16:15
* @project yxhservice11
*/
public class HexDecoder {

// internal HexDecoder()
// {
// }

/// <summary>
/// Returns the length of the Hex represenation of a byte array
/// </summary>
/// <param name="bytes">array of bytes to represent</param>
/// <param name="index">start index in buffer</param>
/// <param name="maxBytes">number of bytes from start to represent</param>
/// <returns></returns>
public int GetCharCount(byte[] bytes, int index, int maxBytes)
{
   return Math.min(bytes.length-index, maxBytes)*2;
  
}

/// <summary>
/// Returns the char for a given byte value
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
private static char GetChar(byte b)
{
   if (b<=9)
    return (char)('0'+b);
   else
    return (char)('A'+(b-10));
}

/// <summary>
/// Write the Hex representation of a byte array to the char array passed in
/// </summary>
/// <param name="bytes">array to represent</param>
/// <param name="byteIndex">start index</param>
/// <param name="maxBytes">number of bytes to represent</param>
/// <param name="chars">target array</param>
/// <param name="charIndex">start index in target array</param>
/// <returns>number of characters written</returns>
public int GetChars(byte[] bytes, int byteIndex, int maxBytes, char[] chars, int charIndex)
{
   //Work out how many chars to return.
   int charCount = GetCharCount(bytes, byteIndex, maxBytes);

   //Check the buffer size.
   if (chars.length-charIndex<charCount)
    try {
     throw new Exception("The character array is not large enough to contain the characters that will be generated from the byte buffer.");
    } catch (Exception e) {
     // TODO 自动生成 catch 块
     e.printStackTrace();
    }
   for (int i=byteIndex; i<maxBytes; i++, charIndex+=2)
   {
    byte upperValue = (byte)Math.floor(bytes[i]/16);
    byte lowerValue = (byte)(bytes[i]%16);
    chars[charIndex] = GetChar(upperValue);
    chars[charIndex+1] = GetChar(lowerValue);
   }

   return charCount;
}
/// <summary>
/// Returns the Hex representation of a byte array
/// </summary>
/// <param name="bytes">The byte array to represent</param>
/// <returns>char array representing the byte array</returns>
public char[] GetChars(byte[] bytes)
{
   int charCount = GetCharCount(bytes, 0, bytes.length);
   char[] chars = new char[charCount];
   GetChars(bytes, 0, bytes.length, chars, 0);
   return chars;
}

/**
* @param args
*/
public static void main(String[] args) {


}

}
0 0
原创粉丝点击