📄 fsmsthread.pas
字号:
4 Length: 0003, Data: AT
5 Length: 0003, Data: AT
6 Length: 0007, Data: AT+CSQ
信号强度
This command is used to know the received signal strength indication (<rssi>) and the
channel bit error rate (<ber>) with or without any SIM card inserted.
7 Length: 0012, Data: AT+CNMI=1,1
wavecom只支持2,1
8 0010, Data: AT+CMGF=0
}
//初始化短信中心号码at+csca?取短信中心号码
if FSMSCenterNO<>'' then
begin
AT:='AT+CSCA="'+FSMSCenterNO+'"'+#13;
FCommandResult:=ExcuteCommand(AT,Str);
end
else
begin
AT:='AT+CSCA?'+#13;
FCommandResult:=ExcuteCommand(AT,Str);
end;
//设置短信格式为PDU
AT:='AT+CMGF=0'+#13;
FCommandResult:=ExcuteCommand(AT,Str);
//设置短信通知
AT:='AT+CNMI=2,1,0,0,0'+#13;
FCommandResult:=ExcuteCommand(AT,Str);
//读取现有短信
if FReadExistMSG then
begin
AT:='AT+CMGL=4'+#13;
FCommandResult:=ExcuteCommand(AT,Str);
end;
//如果设置为自动删除短信,则发送删除短信指令
//AT+CMGD=1,1
if FAutoDeleteMsg then
begin
AT:='AT+CMGD=1,1'+#13;
FCommandResult:=ExcuteCommand(AT,Str);//删除所有短信
end;
end;
function TSMSThread.IsOpen: Boolean;
begin
Result:=ApdCom.Open;
end;
function TSMSThread.ManageCall(CallHandle:Boolean): Boolean;
var
s: string;
begin
//接听或挂断电话
//接听
if CallHandle then
s:='ATA'+#13
else
s:='ATH'+#13;
//WriteCommDataAT(s);
PushCommand(s);
Result:=True;
//Result:=ExcuteCommand(s,r);
end;
procedure TSMSThread.ManageQueue;
var
TryCount: Integer;
CommandReturn: string;
CommandResult: Boolean;
begin
//**************************************************************************
//如果命令队列中有待发命令
//**************************************************************************
TryCount:=0;
while FSMSCommandQueue.Count>0 do
begin
PostSMSMsg('端口'+IntToStr(FCommNumber)+'队列中有命令数:'+IntToStr(FSMSCommandQueue.Count));
//取末端,即先进入队列的短信
with TSMSCommandQueue(FSMSCommandQueue.Peek) do
begin
if TryCount>=FTryNumber then //超过了重试次数
begin
TSMSCommandQueue(FSMSCommandQueue.Pop).Free; //释放对象
TryCount:=0;
end
else
begin
//命令执行成功或错误
FCommandResult:=ExcuteCommand(ATCommand,CommandReturn);
if FCommandResult>0 then
begin
TSMSCommandQueue(FSMSCommandQueue.Pop).Free; //释放对象
TryCount:=0;//计数复位
end
else
Inc(TryCount); //计数加1
end;
end;
end;
//**************************************************************************
//**************************************************************************
//如果发送短信队列中有待发短信
//**************************************************************************
TryCount:=0;
while FSMSQueue.Count>0 do
begin
PostSMSMsg('端口'+IntToStr(FCommNumber)+'队列中有短信数:'+IntToStr(FSMSQueue.Count));
//取末端,即先进入队列的短信
with TSMSQueue(FSMSQueue.Peek) do
begin
if TryCount>=FTryNumber then //超过了重试次数
begin
//执行失败,引发发送短信事件
if Assigned(FOnSMSSend) then
FOnSMSSend(ID,PhoneNO,Content,formatdatetime('yyyy-mm-dd hh:mm:ss',Date),IntToStr(FCommNumber),False);
TSMSQueue(FSMSQueue.pop).Free; //释放对象
TryCount:=0;
end
else
begin
if SendSMS(PhoneNO,Content) then
begin
with TSMSQueue(FSMSQueue.pop) do
begin
//触发发送短信成功事件
if Assigned(FOnSMSSend) then
FOnSMSSend(ID,PhoneNO,Content,formatdatetime('yyyy-mm-dd hh:mm:ss',Date),IntToStr(FCommNumber),True);
Free; //释放对象
end;
TryCount:=0; //计数复位
//延时
Sleep(FSMSDelay*1000);
end
else
Inc(TryCount);//计数加1
end;
end;
end;
//**************************************************************************
end;
procedure TSMSThread.ManagerListMsg(Str:String);
var
P, P2: PChar;
Msg, TempStr, PhoneNO, MsgContent, MSGDateTime: string;
Len: Integer;
begin
//没有返回短信
if Pos('+CMGL:',Str)<=0 then exit;
p:=PChar(Str);
p:=StrScan(p,#10)+1; //去掉AT+CMGL=4一行
while p<>Nil do
begin
p:=StrScan(p,#10)+1; //第一个换行
TempStr:=p; //转换为String
Len:=StrScan(p,#10)-p; //第二个换行
TempStr:=p;
//结束退出
if Len<10 then break; //????
Msg:=Copy(TempStr,1,Len);
if MyDisposeReadPDU(TempStr,PhoneNO,MsgContent,MSGDateTime)=0 then
if Assigned(FOnSMSNewMsgEvent) then
FOnSMSNewMsgEvent(PhoneNO,MsgContent,IntToStr(FCommNumber),StrToDateTime(MSGDateTime));
p:=StrScan(p,#10)+1; //下一个换行,移到以+CMGL:开头
end;
//如果设置为自动删除短信,则发送删除短信指令
//AT+CMGD=1,1
if FAutoDeleteMsg then PushCommand('AT+CMGD=1,1'+#13); //删除所有短信
end;
procedure TSMSThread.OpenComm;
begin
ApdCom.Open:=True;
Sleep(500);
end;
procedure TSMSThread.PostSMSMsg(Msg: shortstring);
var
Msg1Str: PShortString;
begin
New(Msg1Str);
Msg1Str^ := Msg;
PostMessage(MsgHandle, MsgSMS, Integer(Msg1Str), 0);
end;
procedure TSMSThread.PushCommand(AT:String);
var
NewCommand: TSMSCommandQueue;
begin
//建立新的短信,并将其压入短信队列
NewCommand:=TSMSCommandQueue.create;
with NewCommand do
begin
ATCommand:=AT;
end;
//入队
FSMSCommandQueue.push(NewCommand);
end;
procedure TSMSThread.PushSMS(SMSID:Integer;SMSPhoneNO,SMSMsg:String;
SMSSendTime:TDatetime);
var
NewSMS: TSMSQueue;
begin
//建立新的短信,并将其压入短信队列
NewSMS:=TSMSQueue.create;
with NewSMS do
begin
ID:=SMSID;
PhoneNO:=SMSPhoneNO;
Content:=SMSMsg;
SendTime:=SMSSendTime;
InTime:=Time;
end;
//入队
FSMSQueue.push(NewSMS);
end;
procedure TSMSThread.PutString(AT:String);
begin
CurrentCommand:=AT;
ApdCom.PutString(AT);
end;
procedure TSMSThread.ReadSMS(ID:Integer);
var
s: string;
begin
//读短信
s:='AT+CMGR='+inttostr(ID)+#13;
PushCommand(s);
end;
function TSMSThread.SendSMS(PhoneNO:String;Msg:String): Boolean;
var
I: Integer;
SendStr, MixMsg, Len, ReturnMsg: string;
R: Boolean;
begin
//********************************************
//发送成功返回True,失败返回False
//使用PDU单元
//*********************************************
//取编码
MixMsg:=GetPDUData(FSMSCenterNO,PhoneNO,Msg,Len);
//*********************************************
//**************************************************************************
//先发送发送短信指令,收到">"后再发送短信内容
//**************************************************************************
//发送发短信指令
SendStr:='AT+CMGS='+Len+#13;
if ExcuteCommand(SendStr,ReturnMsg)=2 then
begin
SendStr:=MixMsg+#26;
//判断是否发送成功
if ExcuteCommand(SendStr,ReturnMsg)=1 then
Result:=True
else
Result:=False;
end
else
Result:=False;
//**************************************************************************
end;
procedure TSMSThread.SetAutoOpen(AutoOpen:Boolean);
begin
ApdCom.AutoOpen:=AutoOpen;
end;
procedure TSMSThread.SetBaud(Baud:Integer);
begin
ApdCom.Baud:=Baud;
end;
procedure TSMSThread.SetComNum(Comm:Integer);
begin
FCommNumber:=Comm;
ApdCom.ComNumber:=Comm;
end;
procedure TSMSThread.TriggerAvail(CP : TObject; Count : Word);
var
I: Word;
vReceive: string;
begin
vReceive:='';
for I := 1 to Count do
vReceive:=vReceive + ApdCom.GetChar;
CurrentAnswer := CurrentAnswer + vReceive;
if Assigned(FOnReceiveData) then
FOnReceiveData(vReceive,IntToStr(FCommNumber));
end;
procedure TSMSThread.TriggerData(CP : TObject; TriggerHandle : Word);
var
SMSIndex: string;
begin
//收到回车
if TriggerHandle=FTriggerReturn then
begin
if Pos('+CMTI',CurrentAnswer)>0 then
begin
SMSIndex:=GetString(CurrentAnswer,'"SM",',' ');
CurrentAnswer:='';
//发送读取短信指令,触发收到短信事件
ReadSMS(strtoint(trim(SMSIndex)));
//如果设置为自动删除短信,则发送删除短信指令
if FAutoDeleteMsg then DeleteSMS(strtoint(trim(SMSIndex)));
end;
//*************************************************************************
//收到电话
//*************************************************************************
//TODO:增加电话控制,有重复信息
//在未处理时,反复送RING信息
if POS('RING',UpperCase(CurrentAnswer))>0 then
begin
//如果队列中有挂断电话指令,则不再处理
if not FCallState then
begin
//列出电话号码
GetCall;
//挂断电话或接听电话
//挂断电话
ManageCall(False);
FCallState:=True;
end;
end;
end;
//收到新短信
{
if TriggerHandle = FTriggerNewMsg then
begin
SMSIndex:=GetString(CurrentAnswer,'"SM",',' ');
//发送读取短信指令,触发收到短信事件
ReadSMS(strtoint(trim(SMSIndex)));
//如果设置为自动删除短信,则发送删除短信指令
if FAutoDeleteMsg then DeleteSMS(strtoint(trim(SMSIndex)));
end;
}
//发送短信命令就续
if TriggerHandle = FTriggerSendReadyMsg then
begin
FCommandResult:=2;
end;
//命令执行成功
if TriggerHandle = FTriggerOK then
begin
AnalyseReceiveData;
FCommandResult:=1;
end;
//命令执行失败
if TriggerHandle = FTriggerERROR then
begin
FCommandResult:=0;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -