⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms_pudunit.pas

📁 AT Command 短信收發功能,需搭配 GSM Module 使用
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{ 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;

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -