📄 sms_pudunit.pas
字号:
{ SMSPDUproc }
/// <summary>
/// 短信收发控件
/// </summary>
/// <author> agamem </author>
/// <date> 2005-7-12 </date>
unit SMS_PUDUnit;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,SPComm,ExtCtrls,StrUtils;//,csintf;
type
/// <summary>
/// 用户信息编码方式
/// td7_Bit : 7-bit编码,只能用于发送英文字符,160个字符
/// td8_Bit : 8-bit编码,可用于发送透明数据
/// tdUCS2 : Unicode编码,可发送中英文,限制在70个字符
/// </summary>
TTP_DCS = (td7_Bit, td8_Bit, tdUCS2);
/// <summary>
/// 短信模块控制状态
/// </summary>
TSMSState = (NORMAL, ATE, ATCMGF, ATCNMI, ATCMGS_1, ATCMGS_2,ATCMGR,ATCMGD);
/// <summary>
/// 数据监视事件
/// </summary>
TSMSMonitor=procedure(Sender:TObject;RevString:string) of object;
/// <summary>
/// 接收短信通知事件
/// </summary>
TSMSRev=procedure(Sender:TObject;mSMSC,mPhoneID,mInfo:string;mGTime:TDateTime) of object;
/// <summary>
/// 短信控件
/// </summary>
TSMSPDUproc = class(TComponent)
private
/// <summary>
/// 串口控件
/// </summary>
SMScomm:TComm;
/// <summary>
/// 超时判断计时器
/// </summary>
OTTimer:TTimer;
/// <summary>
/// PDU包信息长度
/// </summary>
FCMGSLen:string;
/// <summary>
/// 用户信息编码模式(短消息编码模式)
/// </summary>
FTP_DCS:TTP_DCS;
/// <summary>
/// 目标号码
/// </summary>
FTP_DA:string;
/// <summary>
/// 短消息中心号码
/// </summary>
FSMSC:string;
/// <summary>
/// 透明数据短消息
/// </summary>
FTP_UDByte:array of Byte;
/// <summary>
/// 字符数据短消息
/// </summary>
FTP_UDStr:string;
/// <summary>
/// PUD包
/// </summary>
FPUDStr:string;
/// <summary>
/// 波特率
/// </summary>
FBaudRate:DWORD;
/// <summary>
/// 串口号
/// </summary>
FCommName:string;
/// <summary>
/// 数据位
/// </summary>
FByteSize:TByteSize;
/// <summary>
/// 校验位
/// </summary>
FParity:TParity;
/// <summary>
/// 停止位
/// </summary>
FStopBits:TStopBits;
/// <summary>
/// 激活控件
/// </summary>
FActive:Boolean;
/// <summary>
/// 当前收到短消息的编号
/// </summary>
FCurrSMSIndex:Integer;
/// <summary>
/// 当前短消息机的状态
/// </summary>
CurrState:TSMSState;
/// <summary>
/// 超时/错误 重发计数
/// </summary>
ReSendCount:Integer;
/// <summary>
/// 超时判断计数
/// </summary>
tver:Integer;
/// <summary>
/// 串口接收监视
/// </summary>
FOnRevMonitor: TSMSMonitor;
/// <summary>
/// 串口发送监视
/// </summary>
FOnSndMonitor: TSMSMonitor;
/// <summary>
/// 接收短消息后是否删除短消息
/// </summary>
FDelAfterRev: Boolean;
/// <summary>
/// 收到短消息事件
/// </summary>
FOnReceiveSMS: TSMSRev;
procedure setTP_DCS(const Value:TTP_DCS);
procedure setSMSC(const Value:string);
procedure setTP_DA(const Value:string);
/// <summary>
/// 获取PUD包
/// </summary>
function getPUDStr:string;
procedure SetBaudRate(const Value:DWORD);
procedure SetByteSize(const Value:TByteSize);
procedure SetStopBits(const Value:TStopBits);
procedure SetCommName(const Value:string);
procedure SetParity(const Value:TParity);
procedure setActive(const Value:Boolean);
/// <summary>
/// 串口接收事件
/// </summary>
procedure SMSReceiveData(Sender:TObject; Buffer:Pointer;
BufferLength:Word);
/// <summary>
/// 初始化短信机
/// </summary>
procedure resetSMS();
/// <summary>
/// 数据写入串口
/// </summary>
procedure sendStrToComm(str:string);
/// <summary>
/// 超时计数器事件
/// </summary>
procedure OTTimerTimer(Sender:TObject);
/// <summary>
/// PDU包解码
/// </summary>
procedure DecodePUD(s:string);
protected
public
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
/// <summary>
/// 设置发送的内容 透明数据
/// </summary>
procedure setTP_UD(value:array of Byte); overload;
/// <summary>
/// 设置发送的内容 字符数据
/// </summary>
procedure setTP_UD(value:string); overload;
/// <summary>
/// 发送消息
/// </summary>
procedure SendSM; overload;
/// <summary>
/// 发送消息
/// </summary>
procedure SendSM(mTP_DA,Info:string);overload;
published
/// <summary>
///用户信息编码方式(TP-DCS)
/// </summary>
property TP_DCS:TTP_DCS read FTP_DCS write setTP_DCS;
/// <summary>
/// SMSC地址,短消息中心号码
/// </summary>
property SMSC:string read FSMSC write setSMSC;
/// <summary>
/// 目标地址(TP-DA),目标号码
/// </summary>
property TP_DA:string read FTP_DA write setTP_DA;
/// <summary>
/// 取得PUD包
/// </summary>
property PUDStr:string read getPUDStr;
/// <summary>
/// PUD包长度
/// </summary>
property CMGSLen:string read FCMGSLen;
/// <summary>
/// 串口
/// </summary>
property CommName:string read FCommName write SetCommName;
/// <summary>
/// 波特率
/// </summary>
property BaudRate:DWORD read FBaudRate write SetBaudRate;
/// <summary>
/// 数据位
/// </summary>
property ByteSize:TByteSize read FByteSize write SetByteSize;
/// <summary>
/// 校验
/// </summary>
property Parity:TParity read FParity write SetParity;
/// <summary>
/// 停止位
/// </summary>
property StopBits:TStopBits read FStopBits write SetStopBits;
/// <summary>
/// 激活短消息控件
/// </summary>
property Active:Boolean read FActive write setActive;
/// <summary>
/// 回收数据监视
/// </summary>
property OnRevMonitor:TSMSMonitor read FOnRevMonitor write FOnRevMonitor;
/// <summary>
/// 发送数据监视
/// </summary>
property OnSndMonitor:TSMSMonitor read FOnSndMonitor write FOnSndMonitor;
/// <summary>
/// 错误信息
/// </summary>
property OnError:TSMSMonitor read FOnSndMonitor write FOnSndMonitor;
/// <summary>
/// 读出短消息后删除
/// </summary>
property DelAfterRev:Boolean read FDelAfterRev write FDelAfterRev;
/// <summary>
/// 收到短消息后触发事件
/// </summary>
property OnReceiveSMS:TSMSRev read FOnReceiveSMS write FOnReceiveSMS;
end;
procedure Register;
implementation
{ SMSPDUproc }
/// <summary>
/// 延时
/// </summary>
/// <param name="MSecs">需要延时的毫秒</param>
procedure Delay(MSecs: Longint);
//延时函数,MSecs单位为毫秒(千分之1秒)
var
FirstTickCount, Now: Longint;
begin
FirstTickCount := GetTickCount();
repeat
Application.ProcessMessages;
Now := GetTickCount();
until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;
function GB5ToUniCode(Value:WideString):string;
var
I, Len:Integer;
S:string;
begin
Result := '';
Len := Length(Value);
I := 1;
while I <= Len do
begin
FmtStr(S, '%4.4X', [ord(Value[I])]); //BCD转换
Result := Result + S;
Inc(I);
end;
end;
//******************************************************************************
// Function/Procedure : HexToInt
// Purpose : 把十六进制转换成十进制
// Inputs : 十六进制字符
// Return : 十进制数
//******************************************************************************
function HexToInt(HexStr:String):Integer;
begin
Result:=StrToInt('$'+HexStr);
end;
//******************************************************************************
// Function/Procedure : UniCodeToGB5
// Purpose : 把十六进制的字符数组转换成UNICODE字符
// Inputs : 十六进制的字符数组
// Return : UNICODE字符
//******************************************************************************
function UniCodeToGB5(s:String):WideString;
var
P:PWord;
I,RealLen:Integer;
sStr:WideChar;
begin
New(p);
RealLen:=Length(s) div 4; //计算UNICODE真实长度
for I:=0 to RealLen - 1 do begin
P^:=HexToInt(Copy(s,4*I+1,4));
Move(P^,sStr,2);
Result:=Result+sStr;
end;
Dispose(P);
end;
//******************************************************************************
// Function/Procedure : ChangeLeftAndRight
// Purpose : 将一个字符串在位置上进行奇数位与偶数
// 位的交换,字符串长度为奇数位时自动补F
// Inputs : 字符串
// Return : 字符串
//******************************************************************************
function ChangeLeftAndRight(Value:string):string;
var
I:Integer;
S:Char;
begin
Result := Trim(Value);
if Length(Result) = 0 then Exit;
if Length(Result) mod 2 = 1 then Result := Result + 'F';
I := 1;
while I < Length(Result) do begin
S := Result[I];
Result[I] := Result[I + 1];
Result[I + 1] := S;
I := I + 2;
end;
end;
//******************************************************************************
// Function/Procedure : ResumeOrder
// Purpose : ChangeOrder反向操作
// Inputs : 字符串
// Return : 字符串
//******************************************************************************
function ResumeOrder(OriStr:String):String;
var
I:Integer;
sStr:String;
begin
sStr:='';
for i:=1 to (Length(OriStr) Div 2) do
sStr:=sStr+OriStr[I*2]+OriStr[I*2-1];
Result:=StringReplace(sStr,'F','',[rfReplaceAll]);
end;
function gsmEncode7bit(pSrc:string; nSrcLength:Integer):string;
var
nSrc:Integer; // 源字符串的计数值
nChar:Integer; // 当前正在处理的组内字符字节的序号,范围是0-7
nLeft:byte; // 上一字节残余的数据
tmpChar:Byte;
procChar:byte;
s, pDst:string;
i:Integer;
begin
// 计数值初始化
nSrc := 0;
nLeft := 0;
// 将源串每8个字节分为一组,压缩成7个字节
// 循环该处理过程,直至源串被处理完
// 如果分组不到8字节,也能正确处理
i := 1;
pDst := '';
while (nSrc <= nSrcLength) do
begin
// 取源字符串的计数值的最低3位
nChar := nSrc and 7;
// 处理源串的每个字节
if (nChar = 0) then
begin
// 组内第一个字节,只是保存起来,待处理下一个字节时使用
nLeft := Byte(pSrc[i]);
end
else
begin
// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
procChar := Byte(pSrc[i]);
tmpChar := (procChar shl (8 - nChar)) or nLeft;
fmtstr(s, '%2.2X', [tmpChar]);
pDst := pDst + s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -