📄 cmpp.java~1~
字号:
package com.zhanghao.cmpp;
/**
* <p>Title: CMPP Interface</p>
* <p>Description: 湖南移动短信网关通讯程序</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: sunun tech ltd.</p>
* <p>Reference Cmpp 2.0 protocol</p>
* @author zhanghao
* @version 1.0
*/
import java.io.*;
import com.zhanghao.common.util.*;
public class CMPP {
/**4 Unsigned Integer 消息总长度(含消息头及消息体)**/
private int Total_Length;
/**4 Unsigned Integer 命令或响应类型**/
public int Command_Id;
/**4 Unsigned Integer
* 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)**/
private int Sequence_Id;
/************************CMPP_CONNECT*********************/
/**6 Octet String 源地址,此处为SP_Id,即SP的企业代码。 **/
public String Source_Addr = "";
/**16 Octet String 用于鉴别源地址。其值通过单向MD5 hash计算得出,表示如下:
* AuthenticatorSource =MD5(Source_Addr+9 字节的0 +shared secret+timestamp)
* Shared secret 由中国移动与源地址实体事先商定,
* timestamp格式为:MMDDHHMMSS,即月日时分秒,10位。 **/
public String AuthenticatorSource = "";
/** 4 Unsigned Integer
* 时间戳的明文,由客户端产生,格式为MMDDHHMMSS,即月日时分秒,10位数字的整型,右对齐 。**/
private int Timestamp ;
/************************CMPP_CONNECT_RESP*********************/
/**1 Unsigned Integer
* 状态0:正确1:消息结构错 2:非法源地址 3:认证错 4:版本太高 5~ :其他错误**/
public int Status = 0;
/**16 Octet String ISMG认证码,用于鉴别ISMG。
* 其值通过单向MD5 hash计算得出,表示如下:AuthenticatorISMG =MD5(Status+AuthenticatorSource+shared secret),Shared secret 由中国移动与源地址实体事先商定,AuthenticatorSource为源地址实体发送给ISMG的对应消息CMPP_Connect中的值。 认证出错时,此项为空。**/
public String AuthenticatorISMG;
/** 信息标识生成算法如下:采用64位(8字节)的整数:
* (1)时间(格式为MMDDHHMMSS,即月日时分秒):bit64~bit39,其中
* bit64~bit61:月份的二进制表示;bit60~bit56:日的二进制表示;
* bit55~bit51:小时的二进制表示;bit50~bit45:分的二进制表示;
* bit44~bit39:秒的二进制表示;
* (2)短信网关代码:
* bit38~bit17,把短信网关的代码转换为整数填写到该字段中。
* (3)序列号:bit16~bit1,顺序增加,步长为1,循环使用。各部分如不能填满,左补零,右对齐。 **/
public long Msg_Id = 0;
/** GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9 **/
public byte TP_pid = 0;
/** GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐 **/
public byte TP_udhi = 0;
/**信息格式 0:ASCII串 3:短信写卡操作 4:二进制信息 8:UCS2编码15:含GB汉字 **/
public byte Msg_Fmt = 15;
/**CMPP_DELIVER: 是否为状态报告0:非状态报告1:状态报告 1 Unsigned Integer
* CMPP_SUBMIT : 是否要求返回状态确认报告:0:不需要;1:需要。**/
public byte Registered_Delivery = 0;
/**消息长度 1 Unsigned Integer**/
public byte Msg_Length = 4;
/**消息内容 Msg_length Octet String**/
public String Msg_Content = "测试数据";
/**保留项 8 Octet String**/
public String Reserved = "";
/************************CMPP_DELIVER******************
* CMPP_DELIVER操作的目的是ISMG把从短信中心或其它ISMG转发来的
* 短信送交SP,SP以CMPP_DELIVER_RESP消息回应。***/
public String Service_Id = "";
/** 源终端号码类型,0:真实号码;1:伪码。 **/
public byte Src_terminal_type = 0;
/**源终端MSISDN号码(状态报告时填为CMPP_SUBMIT消息的目的终端号码)**/
public String Src_terminal_Id = "";
/***************************CMPP_SUBMIT********************
* CMPP_SUBMIT操作的目的是SP在与ISMG建立应用层连接后向ISMG提交短信。
* ISMG以CMPP_SUBMIT_RESP消息响应。**/
/** 相同Msg_Id的信息总条数,从1开始。 **/
public byte Pk_total = 1;
/** 相同Msg_Id的信息序号,从1开始。 **/
public byte Pk_number = 1;
/** 信息级别。 **/
public byte Msg_level = 9;
/** 计费用户类型字段:0:对目的终端MSISDN计费;1:对源终端MSISDN计费;
* 2:对SP计费;3:表示本字段无效,
* 对谁计费参见Fee_terminal_Id字段。**/
public byte Fee_UserType = 0;
/** 被计费用户的号码,当Fee_UserType为3时该值有效,当Fee_UserType为0、1、2时该值无意义。**/
public String Fee_terminal_Id = "13900001234";
/** 被计费用户的号码类型,0:真实号码;1:伪码。**/
public byte Fee_terminal_type = 0;
/** 信息内容来源(SP_Id)。 **/
public String Msg_src = CMPPParameter.SP_Id;
/** 资费类别:01:对“计费用户号码”免费;
* 02:对“计费用户号码”按条计信息费;
* 03:对“计费用户号码”按包月收取信息费。 **/
public String FeeType ="02";
/** 资费代码(以分为单位)。 **/
public String FeeCode = "";
/** 存活有效期,格式遵循SMPP3.3协议。 **/
public String ValId_Time = "";
/** 定时发送时间,格式遵循SMPP3.3协议。 **/
public String At_Time = "";
/** 接收信息的用户数量(小于100个用户)。 **/
public byte DestUsr_tl = 1;
/** 接收短信的MSISDN号码。 **/
public String Dest_terminal_Id = "13900001234";
/** 接收短信的用户的号码类型,0:真实号码;1:伪码。 **/
public byte Dest_terminal_type = 0;
/** 结果0:正确1:消息结构错 2:命令字错
* 3:消息序号重复4:消息长度错5:资费代码错
* 6:超过最大信息长7:业务代码错
* 8: 流量控制错9~ :其他错误 ***/
public byte Result = 0;
/** 消息包 **/
public byte[] dataPack = null;
/**Reserved 1**/
private byte ActiveReserved = 0x00;
/**点播业务使用的LinkID,非点播类业务的MT流程不使用该字段。**/
public String LinkID = "";
/************************CMPP_QUERY***********************************/
/** 时间YYYYMMDD(精确至日)。 **/
public String Time = "";
/** 查询类别:0:总数查询;1:按业务类型查询。 **/
public byte Query_Type = 0;
/** 查询码。当Query_Type为0时,此项无效;当Query_Type为1时,此项填写业务类型Service_Id. **/
public String Query_Code = "";
/************************CMPP_QUERY_RESP*****************************/
/** 从SP接收信息总数。 **/
public int MT_TLMsg = 0;
/** 从SP接收用户总数。 **/
public int MT_Tlusr = 0;
/** 成功转发数量。 **/
public int MT_Scs = 0;
/** 待转发数量。 **/
public int MT_WT = 0;
/** 转发失败数量。 **/
public int MT_FL = 0;
/** 向SP成功送达数量。 **/
public int MO_Scs = 0;
/** 向SP待送达数量。 **/
public int MO_WT = 0;
/** 向SP送达失败数量。 **/
public int MO_FL = 0;
/**********************CMPP CANSTANTS****************************/
public final static int CMPP_CONNECT = 0x00000001 ; //请求连接
public final static int CMPP_CONNECT_RESP = 0x80000001 ; //请求连接应答
public final static int CMPP_TERMINATE = 0x00000002 ; //终止连接
public final static int CMPP_TERMINATE_RESP = 0x80000002 ; //终止连接应答
public final static int CMPP_SUBMIT = 0x00000004 ; //提交短信
public final static int CMPP_SUBMIT_RESP = 0x80000004 ; //提交短信应答
public final static int CMPP_DELIVER = 0x00000005 ; //短信下发
public final static int CMPP_DELIVER_RESP = 0x80000005 ; //下发短信应答
public final static int CMPP_QUERY = 0x00000006 ; //发送短信状态查询
public final static int CMPP_QUERY_RESP = 0x80000006 ; //发送短信状态查询应答
public final static int CMPP_CANCEL = 0x00000007 ; //删除短信
public final static int CMPP_CANCEL_RESP = 0x80000007 ; //请求连接应答
public final static int CMPP_ACTIVE_TEST = 0x00000008 ; //激活测试
public final static int CMPP_ACTIVE_TEST_RESP= 0x80000008 ; //激活测试应答
/**1 Unsigned Integer
* 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号)**/
private byte Version = (byte)CMPPParameter.Version;
/**空构造器,用于parse**/
public CMPP() {
}
/** 用于pack的构造器**/
public CMPP(int CMPPMsgType) {
this.Command_Id = CMPPMsgType;
this.Sequence_Id = getSeqNo();
}
/**
* 打包函数,返回打包后数据字节数组
* @return 打包后数据字节数组
*/
public byte[] pack(){
byte[] retBB = null;
switch(Command_Id){
case CMPP.CMPP_CONNECT:
retBB = this.makeConnectMsgPack();
break;
case CMPP.CMPP_CONNECT_RESP:
retBB = this.makeConnectRespMsgPack();
break;
case CMPP.CMPP_DELIVER:
break;
case CMPP.CMPP_DELIVER_RESP:
retBB = this.makeDeliverRespMsgPack();
break;
case CMPP.CMPP_SUBMIT:
retBB = this.makeSubmitMsgPack();
break;
case CMPP.CMPP_SUBMIT_RESP:
break;
case CMPP.CMPP_ACTIVE_TEST:
retBB = this.makeActiveMsgPack();
break;
case CMPP.CMPP_ACTIVE_TEST_RESP:
retBB = makeActiveRespMsgPack();
break;
case CMPP.CMPP_TERMINATE:
break;
case CMPP.CMPP_TERMINATE_RESP:
break;
}
return retBB;
}
/** 生成序列号 **/
public static int fmo_number = 0;
private synchronized static int getSeqNo(){
int temp_SeqNo = fmo_number++;
if (fmo_number >= 100000000)
fmo_number = 1;
return temp_SeqNo;
}
/**取得CMPP CMPP_ACTIVE_TEST的消息包
* 7.4.7 链路检测(CMPP_ACTIVE_TEST)操作
**/
private byte[] makeActiveMsgPack(){
ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
DataOutputStream dataOutStream = new DataOutputStream(byteArrayOutStream);
try{
//MT消息长度
this.Total_Length = 12;
//打包MT消息报头
packHead(dataOutStream);
//返回消息的字节流
dataPack = byteArrayOutStream.toByteArray();
return this.dataPack;
}catch(Exception e){
e.printStackTrace();
System.out.println("[CMPP] makeActiveMsgPack.pack() error : "+e.getMessage());
return null;
}
}
/**取得CMPP CMPP_ACTIVE_TEST_RESP的消息包
* 7.4.7.1 CMPP_ACTIVE_TEST_RESP定义(SP -> ISMG或ISMG->SP)
**/
private byte[] makeActiveRespMsgPack(){
ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
DataOutputStream dataOutStream = new DataOutputStream(byteArrayOutStream);
try{
//MT消息长度
this.Total_Length = 12 + 1;
//打包MT消息报头
packHead(dataOutStream);
//打包消息体
dataOutStream.writeByte(ActiveReserved);
//返回消息的字节流
dataPack = byteArrayOutStream.toByteArray();
return this.dataPack;
}catch(Exception e){
e.printStackTrace();
System.out.println("[CMPP] makeActiveRespMsgPack.pack() error : "+e.getMessage());
return null;
}
}
/**取得CMPP CMPP_CONNECT的消息包
* 7.4.1.1 CMPP_CONNECT消息定义(SP->ISMG)
**/
private byte[] makeConnectMsgPack(){
ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
DataOutputStream dataOutStream = new DataOutputStream(byteArrayOutStream);
try{
//MT消息长度
this.Total_Length = 12 + 27;
this.Source_Addr = CMPPParameter.SP_Id;
this.Timestamp = Integer.parseInt(PublicFunction.getTimeStamp());
this.AuthenticatorSource = Source_Addr +"\0\0\0\0\0\0\0\0\0"+CMPPParameter.SP_Pwd+this.Timestamp;
Debug.outDebug(this.AuthenticatorSource);
MD5 md5 = new MD5();
this.AuthenticatorSource = md5.encrypt(this.AuthenticatorSource);
//打包MT消息报头
packHead(dataOutStream);
//打包消息体
writeString(dataOutStream,Source_Addr,6); //写入源地址
writeString(dataOutStream,AuthenticatorSource,16); //写入用于鉴别源地址的数据
dataOutStream.writeByte(Version); //写入双方协商的版本号
dataOutStream.writeInt(Timestamp); //写入时间戳的明文
//返回消息的字节流
dataPack = byteArrayOutStream.toByteArray();
return this.dataPack;
}catch(Exception e){
e.printStackTrace();
System.out.println("[CMPP] makeConnectMsgPack.pack() error : "+e.getMessage());
return null;
}
}
/**取得CMPP CMPP_CONNECT_RESP的消息包
* 7.4.1.2 CMPP_CONNECT_RESP消息定义(ISMG -> SP)
**/
private byte[] makeConnectRespMsgPack(){
ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
DataOutputStream dataOutStream = new DataOutputStream(byteArrayOutStream);
try{
//MT消息长度
this.Total_Length = 12 + 27;
//打包MT消息报头
packHead(dataOutStream);
//打包消息体
dataOutStream.writeByte(Status); //写入连接状态
writeString(dataOutStream,AuthenticatorISMG,16); //写入用于鉴别源地址的数据
dataOutStream.writeByte(Version); //写入双方协商的版本号
//返回消息的字节流
dataPack = byteArrayOutStream.toByteArray();
return this.dataPack;
}catch(Exception e){
e.printStackTrace();
System.out.println("[CMPP] makeConnectRespMsgPack.pack() error : "+e.getMessage());
return null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -