移动CMPP2.0封装

// 移动短信接口(cmpp 2.0)
//

unit untYiDongInterface;

interface

uses
SysUtils, untSocket, IdGlobal, MessageDigest_5, Types;

const
{$REGION 'Command_Id定义'}
CMPP_CONNECT = $00000001; // 请求连接
CMPP_CONNECT_RESP = $80000001; // 请求连接应答
CMPP_TERMINATE = $00000002; // 终止连接
CMPP_TERMINATE_RESP = $80000002; // 终止连接应答
CMPP_SUBMIT = $00000004; // 提交短信
CMPP_SUBMIT_RESP = $80000004; // 提交短信应答
CMPP_DELIVER = $00000005; // 短信下发
CMPP_DELIVER_RESP = $80000005; // 下发短信应答
CMPP_QUERY = $00000006; // 发送短信状态查询
CMPP_QUERY_RESP = $80000006; // 发送短信状态查询应答
CMPP_CANCEL = $00000007; // 删除短信
CMPP_CANCEL_RESP = $80000007; // 删除短信应答
CMPP_ACTIVE_TEST = $00000008; // 激活测试
CMPP_ACTIVE_TEST_RESP = $80000008; // 激活测试应答
CMPP_FWD = $00000009; // 消息前转
CMPP_FWD_RESP = $80000009; // 消息前转应答
CMPP_MT_ROUTE = $00000010; // MT路由请求
CMPP_MT_ROUTE_RESP = $80000010; // MT路由请求应答
CMPP_MO_ROUTE = $00000011; // MO路由请求
CMPP_MO_ROUTE_RESP = $80000011; // MO路由请求应答
CMPP_GET_ROUTE = $00000012; // 获取路由请求
CMPP_GET_ROUTE_RESP = $80000012; // 获取路由请求应答
CMPP_MT_ROUTE_UPDATE = $00000013; // MT路由更新
CMPP_MT_ROUTE_UPDATE_RESP = $80000013; // MT路由更新应答
CMPP_MO_ROUTE_UPDATE = $00000014; // MO路由更新
CMPP_MO_ROUTE_UPDATE_RESP = $80000014; // MO路由更新应答
CMPP_PUSH_MT_ROUTE_UPDATE = $00000015; // MT路由更新
CMPP_PUSH_MT_ROUTE_UPDATE_RESP = $80000015; // MT路由更新应答
CMPP_PUSH_MO_ROUTE_UPDATE = $00000016; // MO路由更新
CMPP_PUSH_MO_ROUTE_UPDATE_RESP = $80000016; // MO路由更新应答
{$ENDREGION}
const_SP_Id = 'HHJC'; // SP的企业代码
const_shared_secret = ''; // 由中国移动与源地址实体事先商定
const_Version = 11; // 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号

type
{$REGION '缓存定义'}
TByte21 = array [0 .. 20] of Byte;
TByte8 = array [0 .. 7] of Byte;
TChar21 = array [0 .. 20] of AnsiChar;
TChar10 = array [0 .. 9] of AnsiChar;
TChar140 = array [0 .. 139] of AnsiChar;
TChar8 = array [0 .. 7] of AnsiChar;
TChar6 = array [0 .. 5] of AnsiChar;
TChar16 = array [0 .. 15] of AnsiChar;
TChar2 = array [0 .. 1] of AnsiChar;
TChar17 = array [0 .. 16] of AnsiChar;
{$ENDREGION}
{$REGION '公用消息头定义'}
{
Total_Length 4 Unsigned Integer 消息总长度(含消息头及消息体)
Command_Id 4 Unsigned Integer 命令或响应类型
Sequence_Id 4 Unsigned Integer 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)
}
TMsgHeader = packed record
Total_Length: Cardinal;
Command_Id: Cardinal;
Sequence_Id: Cardinal;
end;
{$ENDREGION}
{$REGION 'SP请求连接到ISMG(CMPP_CONNECT)操作'}
{
Source_Addr 6 Octet String 源地址,此处为SP_Id,即SP的企业代码。
AuthenticatorSource 16 Octet String 用于鉴别源地址。其值通过单向MD5 hash计算得出,表示如下:
AuthenticatorSource =
MD5(Source_Addr+9 字节的0 +shared secret+timestamp)
Shared secret 由中国移动与源地址实体事先商定,timestamp格式为:MMDDHHMMSS,即月日时分秒,10位。
Version 1 Unsigned Integer 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号)
Timestamp 4 Unsigned Integer 时间戳的明文,由客户端产生,格式为MMDDHHMMSS,即月日时分秒,10位数字的整型,右对齐 。
}
TConnect = packed record
Source_Addr: TChar6;
AuthenticatorSource: TChar16;
Version: Byte;
Timestamp: Cardinal;
end;

TConnectMsg = packed record
Head: TMsgHeader;
Body: TConnect;
end;
{$ENDREGION}
{$REGION 'SP向ISMG提交短信(CMPP_SUBMIT)操作'}
{
Msg_Id 8 Unsigned Integer 信息标识,由SP侧短信网关本身产生,本处填空。
Pk_total 1 Unsigned Integer 相同Msg_Id的信息总条数,从1开始
Pk_number 1 Unsigned Integer 相同Msg_Id的信息序号,从1开始
Registered_Delivery 1 Unsigned Integer 是否要求返回状态确认报告:
0:不需要
1:需要
2:产生SMC话单
(该类型短信仅供网关计费使用,不发送给目的终端)
Msg_level 1 Unsigned Integer 信息级别
Service_Id 10 Octet String 业务类型,是数字、字母和符号的组合。
Fee_UserType 1 Unsigned Integer 计费用户类型字段
0:对目的终端MSISDN计费;
1:对源终端MSISDN计费;
2:对SP计费;
3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
Fee_terminal_Id 21 Unsigned Integer 被计费用户的号码(如本字节填空,则表示本字段无效,对谁计费参见Fee_UserType字段,
本字段与Fee_UserType字段互斥)
TP_pId 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.9
TP_udhi 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
Msg_Fmt 1 Unsigned Integer 信息格式
0:ASCII串
3:短信写卡操作
4:二进制信息
8:UCS2编码
 15:含GB汉字 。。。。。。
Msg_src 6 Octet String 信息内容来源(SP_Id)
FeeType 2 Octet String 资费类别
01:对“计费用户号码”免费
02:对“计费用户号码”按条计信息费
03:对“计费用户号码”按包月收取信息费
04:对“计费用户号码”的信息费封顶
05:对“计费用户号码”的收费是由SP实现
FeeCode 6 Octet String 资费代码(以分为单位)
ValId_Time 17 Octet String 存活有效期,格式遵循SMPP3.3协议
At_Time 17 Octet String 定时发送时间,格式遵循SMPP3.3协议
Src_Id 21 Octet String 源号码
SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,
该号码最终在用户手机上显示为短消息的主叫号码
DestUsr_tl 1 Unsigned Integer 接收信息的用户数量(小于100个用户)
Dest_terminal_Id 21*DestUsr_tl Octet String 接收短信的MSISDN号码
Msg_Length 1 Unsigned Integer 信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节)
Msg_Content Msg_length Octet String 信息内容
Reserve 8 Octet String 保留
}
TSubmit = packed record
Msg_Id: TByte8;
Pk_total: Byte;
Pk_number: Byte;
Registered_Delivery: Byte;
Msg_level: Byte;
Service_Id: TChar10;
Fee_UserType: Byte;
Fee_terminal_Id: TByte21;
TP_pId: Byte;
TP_udhi: Byte;
Msg_Fmt: Byte;
Msg_src: TChar6;
FeeType: TChar2;
FeeCode: TChar6;
ValId_Time: TChar17;
At_Time: TChar17;
Src_Id: TChar21;
DestUsr_tl: Byte;
Dest_terminal_Id: TByte21;
Msg_Length: Byte;
Msg_Content: TChar140;
Reserve: TChar8;
end;

TSubmitMsg = packed record
Head: TMsgHeader;
Body: TSubmit;
end;
{$ENDREGION}
{$REGION 'ISMG向SP送交短信(CMPP_DELIVER)操作'}
{
Msg_Id 8 Unsigned Integer 信息标识
生成算法如下:
采用64位(8字节)的整数:
时间(格式为MMDDHHMMSS,即月日时分秒):bit64~bit39,其中
bit64~bit61:月份的二进制表示;
bit60~bit56:日的二进制表示;
bit55~bit51:小时的二进制表示;
bit50~bit45:分的二进制表示;
bit44~bit39:秒的二进制表示;
短信网关代码:bit38~bit17,把短信网关的代码转换为整数填写到该字段中。
序列号:bit16~bit1,顺序增加,步长为1,循环使用。
各部分如不能填满,左补零,右对齐。
Dest_Id 21 Octet String 目的号码
SP的服务代码,一般4--6位,或者是前缀为服务代码的长号码;该号码是手机用户短消息的被叫号码。
Service_Id 10 Octet String 业务类型,是数字、字母和符号的组合。
TP_pid 1 Unsigned Integer GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9
TP_udhi 1 Unsigned Integer GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
Msg_Fmt 1 Unsigned Integer 信息格式
0:ASCII串
3:短信写卡操作
4:二进制信息
8:UCS2编码
 15:含GB汉字
Src_terminal_Id 21 Octet String 源终端MSISDN号码(状态报告时填为CMPP_SUBMIT消息的目的终端号码)
Registered_Delivery 1 Unsigned Integer 是否为状态报告
0:非状态报告
1:状态报告
Msg_Length 1 Unsigned Integer 消息长度
Msg_Content Msg_length Octet String 消息内容
Reserved 8 Octet String 保留项
}
TDeliver = packed record
Msg_Id: TByte8;
Dest_Id: TChar21;
Service_Id: TChar10;
TP_pId: Byte;
TP_udhi: Byte;
Msg_Fmt: Byte;
Src_terminal_Id: TChar21;
Registered_Delivery: Byte;
Msg_Length: Byte;
Msg_Content: TChar140;
Reserved: TChar8;
end;

TDeliverMsg = packed record
Head: TMsgHeader;
Body: TDeliver;
end;
{$ENDREGION}
{$REGION '连接方法'}

function Connect(Sequence_Id, Timestamp: Cardinal;
SP_Id, AuthenticatorSource: AnsiString; Version: Byte): Boolean; // 连接
{
Source_Addr 6 Octet String 源地址,此处为SP_Id,即SP的企业代码。
AuthenticatorSource 16 Octet String 用于鉴别源地址。其值通过单向MD5 hash计算得出,表示如下:
AuthenticatorSource =
MD5(Source_Addr+9 字节的0 +shared secret+timestamp)
Shared secret 由中国移动与源地址实体事先商定,timestamp格式为:MMDDHHMMSS,即月日时分秒,10位。
Version 1 Unsigned Integer 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号)
Timestamp 4 Unsigned Integer 时间戳的明文,由客户端产生,格式为MMDDHHMMSS,即月日时分秒,10位数字的整型,右对齐 。
}
{$ENDREGION}
{$REGION '发送方法'}
procedure Send(Sequence_Id: Cardinal; Pk_total, Pk_number, Registered_Delivery,
Msg_level, Fee_UserType, TP_pId, TP_udhi, Msg_Fmt, DestUsr_tl,
Msg_Length: Byte; Service_Id, Msg_src, FeeType, FeeCode, ValId_Time, At_Time,
Src_Id, Msg_Content: AnsiString; Dest_terminal_Id: AnsiString);
{
Msg_Id 8 Unsigned Integer 信息标识,由SP侧短信网关本身产生,本处填空。
Pk_total 1 Unsigned Integer 相同Msg_Id的信息总条数,从1开始
Pk_number 1 Unsigned Integer 相同Msg_Id的信息序号,从1开始
Registered_Delivery 1 Unsigned Integer 是否要求返回状态确认报告:
0:不需要
1:需要
2:产生SMC话单
(该类型短信仅供网关计费使用,不发送给目的终端)
Msg_level 1 Unsigned Integer 信息级别
Service_Id 10 Octet String 业务类型,是数字、字母和符号的组合。
Fee_UserType 1 Unsigned Integer 计费用户类型字段
0:对目的终端MSISDN计费;
1:对源终端MSISDN计费;
2:对SP计费;
3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
Fee_terminal_Id 21 Unsigned Integer 被计费用户的号码(如本字节填空,则表示本字段无效,对谁计费参见Fee_UserType字段,本字段与Fee_UserType字段互斥)
TP_pId 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.9
TP_udhi 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
Msg_Fmt 1 Unsigned Integer 信息格式
0:ASCII串
3:短信写卡操作
4:二进制信息
8:UCS2编码
 15:含GB汉字 。。。。。。
Msg_src 6 Octet String 信息内容来源(SP_Id)
FeeType 2 Octet String 资费类别
01:对“计费用户号码”免费
02:对“计费用户号码”按条计信息费
03:对“计费用户号码”按包月收取信息费
04:对“计费用户号码”的信息费封顶
05:对“计费用户号码”的收费是由SP实现
FeeCode 6 Octet String 资费代码(以分为单位)
ValId_Time 17 Octet String 存活有效期,格式遵循SMPP3.3协议
At_Time 17 Octet String 定时发送时间,格式遵循SMPP3.3协议
Src_Id 21 Octet String 源号码
SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,该号码最终在用户手机上显示为短消息的主叫号码
DestUsr_tl 1 Unsigned Integer 接收信息的用户数量(小于100个用户)
Dest_terminal_Id 21*DestUsr_tl Octet String 接收短信的MSISDN号码
Msg_Length 1 Unsigned Integer 信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节)
Msg_Content Msg_length Octet String 信息内容
Reserve 8 Octet String 保留

}
{$ENDREGION}
{$REGION '接收方法'}
procedure Accept(var Msg_Id: AnsiString; var Dest_Id, Service_Id, Src_terminal_Id,
Msg_Content: AnsiString; var TP_pId, TP_udhi, Msg_Fmt, Registered_Delivery,
Msg_Length: Byte);
{
Msg_Id 8 Unsigned Integer 信息标识
生成算法如下:
采用64位(8字节)的整数:
时间(格式为MMDDHHMMSS,即月日时分秒):bit64~bit39,其中
bit64~bit61:月份的二进制表示;
bit60~bit56:日的二进制表示;
bit55~bit51:小时的二进制表示;
bit50~bit45:分的二进制表示;
bit44~bit39:秒的二进制表示;
短信网关代码:bit38~bit17,把短信网关的代码转换为整数填写到该字段中。
序列号:bit16~bit1,顺序增加,步长为1,循环使用。
各部分如不能填满,左补零,右对齐。
Dest_Id 21 Octet String 目的号码
SP的服务代码,一般4--6位,或者是前缀为服务代码的长号码;该号码是手机用户短消息的被叫号码。
Service_Id 10 Octet String 业务类型,是数字、字母和符号的组合。
TP_pid 1 Unsigned Integer GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9
TP_udhi 1 Unsigned Integer GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
Msg_Fmt 1 Unsigned Integer 信息格式
0:ASCII串
3:短信写卡操作
4:二进制信息
8:UCS2编码
 15:含GB汉字
Src_terminal_Id 21 Octet String 源终端MSISDN号码(状态报告时填为CMPP_SUBMIT消息的目的终端号码)
Registered_Delivery 1 Unsigned Integer 是否为状态报告
0:非状态报告
1:状态报告
Msg_Length 1 Unsigned Integer 消息长度
Msg_Content Msg_length Octet String 消息内容
Reserved 8 Octet String 保留项
}
{$ENDREGION}

{$REGION '消息流水号'}
var
g_Sequence_Id: Cardinal = 0;
function GetSequence_Id: Integer; // 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)
{$ENDREGION}

function MD5(value: AnsiString): string; // MD5加密

implementation

function MD5(value: AnsiString): string;
var
m: IMD5;
begin
m := GetMD5;
m.Init;
m.Update(TByteDynArray(RawByteString(value)), Length(value));
Result := LowerCase(m.AsString);
end;

function GetSequence_Id: Integer;
begin
if g_Sequence_Id = 4294967295 then
g_Sequence_Id := 0;
g_Sequence_Id := g_Sequence_Id + 1;
Result := g_Sequence_Id;
end;

procedure Accept(var Msg_Id: AnsiString; var Dest_Id, Service_Id, Src_terminal_Id,
Msg_Content: AnsiString; var TP_pId, TP_udhi, Msg_Fmt, Registered_Delivery,
Msg_Length: Byte);
var
Head: TMsgHeader;
Body: TDeliver;
Msg: TDeliverMsg;
buf: TIdBytes;
begin
// 初始化
buf := nil;
FillChar(Head, SizeOf(Head), '');
FillChar(Body, SizeOf(Body), '');
FillChar(Msg, SizeOf(Msg), '');
// 接收
if frmSocket.Connect then
begin
frmSocket.tcp.IOHandler.ReadBytes(buf, SizeOf(Msg), false);
BytesToRaw(buf, Msg, SizeOf(Msg));
Head := Msg.Head;
Body := Msg.Body;
// 解析
if Head.Command_Id = CMPP_DELIVER then
begin
SetLength(Msg_Id, SizeOf(Body.Msg_Id) + 1);
Move(Body.Msg_Id, Msg_Id[1], SizeOf(Body.Msg_Id));
SetLength(Dest_Id, SizeOf(Body.Dest_Id) + 1);
Move(Body.Dest_Id, Dest_Id[1], SizeOf(Body.Dest_Id));
SetLength(Service_Id, SizeOf(Body.Service_Id) + 1);
Move(Body.Service_Id, Service_Id[1], SizeOf(Body.Service_Id));
TP_pId := Body.TP_pId;
TP_udhi := Body.TP_udhi;
Msg_Fmt := Body.Msg_Fmt;
SetLength(Src_terminal_Id, SizeOf(Body.Src_terminal_Id) + 1);
Move(Body.Src_terminal_Id, Src_terminal_Id[1], SizeOf(Body.Src_terminal_Id));
Registered_Delivery := Body.Registered_Delivery;
Msg_Length := Body.Msg_Length;
SetLength(Msg_Content, SizeOf(Body.Msg_Content) + 1);
Move(Body.Msg_Content, Msg_Content[1], SizeOf(Body.Msg_Content));
end;
end;
end;

procedure Send(Sequence_Id: Cardinal; Pk_total, Pk_number, Registered_Delivery,
Msg_level, Fee_UserType, TP_pId, TP_udhi, Msg_Fmt, DestUsr_tl,
Msg_Length: Byte; Service_Id, Msg_src, FeeType, FeeCode, ValId_Time, At_Time,
Src_Id, Msg_Content: AnsiString; Dest_terminal_Id: AnsiString);
var
Head: TMsgHeader;
Body: TSubmit;
Msg: TSubmitMsg;
buf: TIdBytes;
begin
// 初始化
buf := nil;
FillChar(Head, SizeOf(Head), '');
FillChar(Body, SizeOf(Body), '');
FillChar(Msg, SizeOf(Msg), '');
if frmSocket.Connect then
begin
// 消息头
Head.Total_Length := SizeOf(Head) + SizeOf(Body);
Head.Command_Id := CMPP_SUBMIT;
Head.Sequence_Id := Sequence_Id;
// 消息体
Body.Pk_total := Pk_total;
Body.Pk_number := Pk_number;
Body.Registered_Delivery := Registered_Delivery;
Body.Msg_level := Msg_level;
StrPCopy(Body.Service_Id, Service_Id);
Body.Fee_UserType := Fee_UserType;
Body.TP_pId := TP_pId;
Body.TP_udhi := TP_udhi;
Body.Msg_Fmt := Msg_Fmt;
StrPCopy(Body.Msg_src, Msg_src);
StrPCopy(Body.FeeType, FeeType);
StrPCopy(Body.FeeCode, FeeCode);
StrPCopy(Body.ValId_Time, ValId_Time);
StrPCopy(Body.At_Time, At_Time);
StrPCopy(Body.Src_Id, Src_Id);
Body.DestUsr_tl := DestUsr_tl;
Move(Dest_terminal_Id[1], Body.Dest_terminal_Id, Length(Dest_terminal_Id));
Body.Msg_Length := Msg_Length;
StrPCopy(Body.Msg_Content, Msg_Content);
// 消息
Msg.Head := Head;
Msg.Body := Body;
// 发送
buf := RawToBytes(Msg, SizeOf(Msg));
frmSocket.tcp.IOHandler.Write(buf);
end;
end;

function Connect(Sequence_Id, Timestamp: Cardinal;
SP_Id, AuthenticatorSource: AnsiString; Version: Byte): Boolean;
var
Head: TMsgHeader;
Body: TConnect;
Msg: TConnectMsg;
buf: TIdBytes;
begin
// 初始化
buf := nil;
FillChar(Head, SizeOf(Head), '');
FillChar(Body, SizeOf(Body), '');
FillChar(Msg, SizeOf(Msg), '');
Result := frmSocket.Connect;
if Result then
begin
// 消息头
Head.Total_Length := SizeOf(TConnectMsg);
Head.Command_Id := CMPP_CONNECT;
Head.Sequence_Id := Sequence_Id;
// 消息体
StrPCopy(Body.Source_Addr, SP_Id);
StrPCopy(Body.AuthenticatorSource, AuthenticatorSource);
Body.Version := Version;
Body.Timestamp := Timestamp;
// 消息
Msg.Head := Head;
Msg.Body := Body;
// 发送
buf := RawToBytes(Msg, SizeOf(Msg));
frmSocket.tcp.IOHandler.Write(buf);
end;
end;

end.

 

客户端调用示例:

function TSMSService.ConnectYDApp: Boolean; // 连接移动 应用层验证
var
  AuthenticatorISMG: AnsiString;
  SP_Id, SharedSecret, timestr: AnsiString;
  LengthI, i, Md5UpLen: Integer;
  str1: array [0 .. 30] of ansiChar;
  md5str: md5digest;
  md5_con: MD5Context;
  Version: Byte;
  Sequence_Id: Cardinal;
  bBool: Boolean;
  Status: Byte;
  AuthenticatorSource: TByte16;
  s:AnsiString;
  iTime: Cardinal;
  Msg: TConnectRespMsg;
  buf: TIdBytes;
begin
  try
    timestr := FormatDateTime('MMDDHHMMSS', now);
    SP_Id := '731145';
    SharedSecret :='888888';
   // Source_Addr+9 字节的0 +shared secret+timestamp
   // 6+9+9+10=34
    StrPCopy(str1, SP_Id + '000000000' + SharedSecret + timestr);
    for i := 6 to 14 do
      str1[i] := #0;
    MD5Init(md5_con);
    MD5Update(md5_con, str1, 31);
    MD5Final(md5_con, md5str);
    move(md5str, AuthenticatorSource, 16);

    Sequence_Id := untYiDongInterface.GetSequence_Id;
    Version := $20;     // CMPP2.0
    untYiDongInterface.connect(Sequence_Id, StrToInt(timestr), SP_Id,AuthenticatorSource, Version);
    SMSService.CMPPTcp.IOHandler.ReadBytes(buf, SizeOf(Msg), False);
    BytesToRaw(buf, Msg, SizeOf(Msg));
    case Msg.Body.Status of
      0:
      begin
        OutputDebugView('CMPP 验证成功:SPID:'+SP_ID);
      end;
      1:
      begin
        OutputDebugView('CMPP 消息结构错误');
      end;
      2:
      begin
        OutputDebugView('CMPP 非法源地址');
      end;
      3:
      begin
        OutputDebugView('CMPP:认证错');
      end;
      4:
      begin
        OutputDebugView('CMPP:太高的版本');
      end;
    else
      OutputDebugView('CMPP 其他错误');
    end;
  except
    on e: Exception do
      OutputDebugView('ConnectYDApp 异常' + e.Message);
  end;
end;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值