猪年无聊,改了一个代码,有点D版那个意思,把WAP PUSH的C#代码改到了JAVA
原来出处:
http://www.codeproject.com/cs/internet/wappush/wappush_src.zip
http://www.codeproject.com/cs/internet/wappush.asp
改过后的代码在下面,程序好像可以输出了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_class = 0x12;
// 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) {
}
}