?? unitmodem.pas
字號:
{*******************************************************}
{ }
{ 名稱:TModem類 }
{ 功能: }
{ 1.繼承TSerial類 }
{ 2.定義不同設備間短信收發接口 }
{ 調用: }
{ 1.TModem子類實例化抽象方法 }
{ 2.TModemPool類創建TModem子類實例 }
{ 3.TModemPool類調用TModem類的虛方法 }
{ }
{*******************************************************}
{*************************************************************************}
{ AT 指令認證 }
{ ATI 認證信息 }
{ AT+CGMI 廠家認證 }
{ AT+CGMM 模塊認證 }
{ AT+CGMR 版本認證 }
{ AT&V 顯示設置 }
{ AT+CSQ 網絡信號 }
{ AT+CGSN 查詢設備序列號(IMEI) }
{ AT+CIMI 查詢SIM卡序列號(IMSI國際移動簽署者標識) }
{ AT+COPS? 查詢當前網絡 }
{ AT+CMGC Send an SMS command(發出一條短消息命令) }
{ AT+CMGD Delete SMS message(刪除SIM卡內存的短消息) }
{ AT+CMGF Select SMS message formate(選擇短消息信息格式:0-PDU;1-文本) }
{ AT+CMGL List SMS message from preferred store }
{ (列出SIM卡中的短消息PDU/text: 0/"REC UNREAD"-未讀,1/"REC READ"-已讀 }
{ 2/"STO UNSENT"-待發,3/"STO SENT"-已發,4/"ALL"-全部的 }
{ AT+CMGR Read SMS message(讀短消息) }
{ AT+CMGS Send SMS message(發送短消息) }
{ AT+CMGW Write SMS message to memory(向SIM內存中寫入待發的短消息) }
{ AT+CMSS Send SMS message from storage(從SIN|M內存中發送短消息) }
{ AT+CNMI New SMS message indications(顯示新收到的短消息) }
{ AT+CPMS Preferred SMS message storage(選擇短消息內存) }
{ AT+CSCA SMS service center address(短消息中心地址) }
{ AT+CSCB Select cell broadcast messages(選擇蜂窩廣播消息) }
{ AT+CSMP Set SMS text mode parameters(設置短消息文本模式參數) }
{ AT+CSMS Select Message Service(選擇短消息服務) }
{*************************************************************************}
unit UnitModem;
interface
uses
Windows, Messages, SysUtils, Forms, Classes, Dialogs, SyncObjs, UnitPublicFun, UnitSerial;
type
TModem = class(TSerial)
private
FNetDefine: integer; //網絡標識:0-中國聯通,1-中國移動
protected
FSMSCenter: string; //短信中心號碼
function IntToHexStr(i: integer): string; //十進制整數轉換成十六進制
function HexStrToInt(s: string): integer; //十六進制字符串轉換成十進制數
function HexCharToInt(HexToken: char): integer;
function HexCharToBin(HexToken: char): string;
function HexToBin(HexNr: string): string;
function pow(base, power: integer): integer;
function BinStrToInt(BinStr: string): integer;
function ExchangeCode(s: string): string; //字符PDU轉換
function gsmEncodeUcs2(ws: widestring): string; //按Ucs2格式編碼
function gsmDecodeUcs2(s: string): string; //按Ucs2格式解碼
function gsmEncode7bit(s: string): string; //按7bit格式編碼
function gsmDecode7bit(s: string): string; //按7bit格式解碼
public
function ATCommandTest: boolean; virtual; //可被override的虛方法:AT指令測試
function GetModemStatus: string; virtual; //可被override的虛方法:獲取MODEM狀態
published
property ModemOpen: boolean read ATCommandTest;
property NetDefine: integer read FNetDefine write FNetDefine;
public
function GetModemInfo: string; virtual; abstract; //抽象方法:獲取MODEM信息
function GetNetSignal: string; virtual; abstract; //抽象方法:獲取信號強度
function GetSIMID: string; virtual; abstract; //抽象方法:獲取SIM卡序列號
function GetSIMServerNo: string; virtual; abstract; //抽象方法:獲取短信中心服務號碼
function SetZero: boolean; virtual; abstract; //抽象方法:恢復到廠商默認設置
function SetSIMServerNo(strSIMServerNo: string): boolean; virtual; abstract;//抽象方法:設置短信中心服務號碼
function SetPduMode: boolean; virtual; abstract; //抽象方法:設置成PDU模式
function SetTECharacterSet: boolean; virtual; abstract; //抽象方法:設置字符集
function SetReportErrorOff: boolean; virtual; abstract; //抽象方法:設置錯誤碼回顯關閉
function SetEchoOff: boolean; virtual; abstract; //抽象方法:設置回顯關閉
function SendPduSMS(data: string;
mobile: string): boolean; virtual; abstract; //抽象方法:發送PDU格式短信
function RecievePduSMS(bAutoDel: boolean;
var MsgNum: integer;
var MsgArray: array of TRecieveSMS): boolean; virtual; abstract; //抽象方法:接收PDU格式短信
end;
implementation
{ TModem }
function TModem.HexCharToInt(HexToken: char): integer;
begin
{if HexToken>#97 then HexToken:=Chr(Ord(HexToken)-32);
{ use lowercase aswell }
Result := 0;
if (HexToken>#47) and (HexToken<#58) then { chars 0....9 }
Result := Ord(HexToken) - 48
else if (HexToken>#64) and (HexToken<#71) then { chars A....F }
Result := Ord(HexToken) - 65 + 10;
end;
function TModem.HexCharToBin(HexToken: char): string;
var
DivLeft: integer;
begin
DivLeft := HexCharToInt(HexToken); { first HEX->BIN }
Result := '';
{ Use reverse dividing }
repeat { Trick; divide by 2 }
if odd(DivLeft) then { result = odd ? then bit = 1 }
Result := '1' + Result { result = even ? then bit = 0 }
else
Result := '0' + Result;
DivLeft := DivLeft div 2; { keep dividing till 0 left and length = 4 }
until (DivLeft=0) and (length(Result)=4); { 1 token = nibble = 4 bits }
end;
function TModem.HexToBin(HexNr: string): string; { only stringsize is limit of binnr }
var
Counter: integer;
begin
Result := '';
for Counter := 1 to length(HexNr) do
Result := Result + HexCharToBin(HexNr[Counter]);
end;
function TModem.pow(base, power: integer): integer;
var
counter: integer;
begin
Result := 1;
for counter:=1 to power do
Result := Result * base;
end;
function TModem.BinStrToInt(BinStr: string): integer;
var
counter: integer;
begin
if length(BinStr)>16 then
raise ERangeError.Create(#13+BinStr+#13+
'is not within the valid range of a 16 bit binary.'+#13);
Result := 0;
for counter:=1 to length(BinStr) do
if BinStr[Counter]='1' then
Result := Result + pow(2, length(BinStr)-counter);
end;
function TModem.HexStrToInt(s: string): integer;
var
H, L: integer;
begin
H := Ord(s[1]);
if H >= 65 then H := H-55 else H := H-48;
L := Ord(s[2]);
if L >= 65 then L := L-55 else L := L-48;
Result := H * 16 + L;
end;
function TModem.IntToHexStr(i: integer): string;
var
H,L: integer;
begin
H := i div 16;
if H < 10 then H:=H+48 else H:=H+55;
L := i mod 16;
if L < 10 then L:=L+48 else L:=L+55;
Result := Chr(H) + Chr(L);
end;
function TModem.ExchangeCode(s: string): string;
var
i, iLen: integer;
strSrc, strResult: string;
begin
strResult := '';
iLen := Length(s);
strSrc := s;
//如果長度不為偶數則后補F
if iLen mod 2 <> 0 then
strSrc := s + 'F';
i := 1;
while i<=iLen do
begin
strResult := strResult + strSrc[i+1] + strSrc[i];
Inc(i, 2);
end;
Result := strResult;
end;
function TModem.gsmEncodeUcs2(ws: widestring): string;
var
i, len : integer;
cur : integer;
t : string;
begin
Result := '';
len := Length(ws);
i := 1;
while i<=len do
begin
cur := Ord(ws[i]);
FmtStr(t, '%4.4X', [cur]);
Result := Result + t;
Inc(i);
end;
end;
function TModem.gsmDecodeUcs2(s: string): string;
var
i, iLen: integer;
Buf: array[0..1000] of WideChar;
begin
iLen := Round(Length(s) / 4) - 1;
for i:=0 to iLen do
begin
Buf[i] := widechar(StrToint('$' + copy(s, 4*i+1, 4)));
end;
Buf[iLen+1] := #0;
Result := WideCharToString(Buf);
end;
function TModem.gsmEncode7bit(s: string): string;
var
i, j, len: Integer;
cur: Integer;
t: string;
begin
Result := '';
len := Length(s);
i := 1;
j := 0; //j 用于移位計數
while i<=len do
begin
if i<len then
cur := (ord(s[i]) shr j) or ((ord(s[i+1]) shl (7-j)) and $ff) //數據變換
else
cur := (ord(s[i]) shr j) and $7f;
FmtStr(t,'%2.2X',[cur]);
Result := Result + t;
Inc(i);
j := (j+1) mod 7; //移位計數達到7位的特別處理
if j=0 then Inc(i);
end;
end;
function TModem.gsmDecode7bit(s: string): string;
var
OctetStr: string;
OctetBin: string;
Charbin: string;
PrevOctet: string;
Counter: integer;
Counter2: integer;
begin
PrevOctet := '';
Result := '';
for Counter:=1 to length(s) do
begin
if length(PrevOctet)>=7 then { if 7 Bit overflow on previous }
begin
if BinStrToInt(PrevOctet)<>0 then
Result := Result + Chr(BinStrToInt(PrevOctet))
else
Result := Result + ' ';
PrevOctet := '';
end;
if Odd(Counter) then { only take two nibbles at a time }
begin
OctetStr := Copy(s, Counter, 2);
OctetBin := HexToBin(OctetStr);
Charbin := '';
for Counter2:=1 to length(PrevOctet) do
Charbin := Charbin + PrevOctet[Counter2];
for Counter2:=1 to 7-length(PrevOctet) do
Charbin := OctetBin[8-Counter2+1] + Charbin;
if BinStrToInt(Charbin)<>0 then
Result := Result + Chr(BinStrToInt(CharBin))
else
Result := Result + ' ';
PrevOctet := Copy(OctetBin, 1, length(PrevOctet)+1);
end;
end;
end;
function TModem.ATCommandTest: boolean;
var
ATCommand, ReadData: string;
begin
Result := False;
if not IsOpen then Exit;
//AT指令
ATCommand := 'AT' + ENTER_KEY_FLAG;
try
if not PublicFun.FSemaphoreManager.Lock then Exit;
if not WriteAndWaitRead(ATCommand, ReadData) then Exit;
finally
PublicFun.FSemaphoreManager.Unlock;
end;
if pos('OK', UpperCase(Trim(ReadData)))<=0 then Exit;
Result := True;
end;
function TModem.GetModemStatus: string;
begin
if ATCommandTest then
Result := COMM_OPEN_STATUS
else
Result := COMM_STOP_STATUS;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -