猪年无聊,改了一个代码,有点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]); 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) {
}
}