编码采用PDU unit imSMS; {******************************************************* masterjames *******************************************************} interface uses Classes,imSMSUtils,SysUtils,StrUtils,Dialogs,AdPort,OoMisc; const SMS_SEND_OK = 0 ; SMS_SEND_ERR = 1; SMS_CENTER_CODE ='00'; SMS_MOBILE_HEAD = '0D9168'; SMS_SINGLE_LEN = 140 ; SMS_UNICODE_LEN = 70; SMS_UNICODE_HEADLEN = 3 ; SMS_USER_BODYLEN = 67; SMS_AUTO_BODYLEN = 70; SMS_MAX_COUNT = 3; SMS_ERR_OVERCOUNT = 0; SMS_TYPE_USER = 1 ; SMS_TYPE_AUTO = 2; SMS_TIME_DELAY = 3000; SMS_SORT_ASC = 1 ; SMS_SORT_DESC = 2; SMS_SET_PDU_ERR = 8001; SMS_SEND_READY_ERR = 8002; SMS_SEND_ERR_ERR = 8003 ; SMS_SINGLE_THREAD = 1 ; SMS_MUTIL_THREAD = 2; SMS_CMD_CGMI = 0 ; SMS_CMD_CMGF = 1; SMS_DEL_ALL = 999999; type TimSMS = class private TSMS_PDU_HEAD : record SMSCenter : string; FirstOcter : string; // TP_MR : string; //消息参考 SMSRMobile : string; // TP_PID : string; //协议标识 TP_DCS : string; // PUD TP_SCTS : string; //有效期间 TP_DHL : string; //数据长度 end; FPDUStr : string; FSMSCenter : string; FMobile : string; FMsgStr : string; FSMSUtils : TimSMSUtils; FApdComPort : TApdComport; FPDUHeadLists : TStrings; FPDUBodyLists : TStrings; FCount : integer ; FSendType : integer; FSort : integer; FComResult : string; FInfo : string; public constructor Create; destructor Destory; procedure SetSend(vCenter,vMobile,vMsg : string; vType:integer); procedure SetPDUHead ; procedure SetPDUBody ; procedure EncodePDU; procedure OnRecCom(CP: TObject; Count: Word); procedure SetPDULists(vHeadList,vBodyList,vTotalList:TStrings);overload; procedure SetPDULists(vTotalList:TStrings);overload; function GetInfo : string; function SendSMS(vThread:integer) : integer;overload; function SendSMS(vPDUStr:string):integer;overload; procedure DelSMS(vIndex:integer); function ReadSMS(vNum:integer): string; function TestComm : boolean; procedure InitComm(vPort, vRate: integer); published end; type TimSMSInf = class private FTotal : TStrings; FSMS : TimSMS; public constructor Create; destructor Destory; procedure SendSMS(vCenter,vMobile,vMsg : string; vType:integer); function ReadSMS(vIndex:integer) : string; procedure DelSms(vIndex:integer); function TestComm : boolean; procedure InitComm(vPort, vRate: integer); end; implementation { TimSMS } constructor TimSMS.Create; begin FSMSUtils := TimSMSUtils.Create; FPDUBodyLists := TStringList.Create; FPDUHeadLists := TStringList.Create; FApdComPort := TApdComport.Create(nil); FApdComPort.AutoOpen := False; FApdComport.ComNumber := 1; FApdComport.Baud := 9600; FApdComport.OnTriggerAvail := OnRecCom; end; destructor TimSMS.Destory; begin FSMSUtils.Free; FPDUBodyLists.Free; FPDUHeadLists.Free; FApdComport.Free; end; procedure TimSMS.SetPDUHead ; var SMS_PDU_HEAD : string; vLen : integer; vWideStr : WideString; i : integer; begin FPDUHeadLists.Clear; TSMS_PDU_HEAD.SMSCenter := SMS_CENTER_CODE; case FSendType of SMS_TYPE_USER : begin if FSendType = SMS_TYPE_USER then begin if FCount > 1 then TSMS_PDU_HEAD.FirstOcter := '51' else TSMS_PDU_HEAD.FirstOcter := '11'; end; end; SMS_TYPE_AUTO : begin TSMS_PDU_HEAD.FirstOcter := '11'; end; end; TSMS_PDU_HEAD.TP_MR := '00'; TSMS_PDU_HEAD.SMSRMobile := SMS_MOBILE_HEAD + FSMSUtils.GetMobilePDU(FMobile); TSMS_PDU_HEAD.TP_PID := '00'; TSMS_PDU_HEAD.TP_DCS := '08'; TSMS_PDU_HEAD.TP_SCTS := 'A7'; vLen := 0; vWideStr := FMsgStr; for i := 1 to FCount do begin if (i<>FCount) then begin vLen := SMS_UNICODE_LEN; end else begin case FSendType of SMS_TYPE_USER : begin vLen := (Length(vWideStr) - (i-1)*SMS_USER_BODYLEN) + 3; end; SMS_TYPE_AUTO : begin vLen := (Length(vWideStr) - (i-1)*SMS_AUTO_BODYLEN); end; end; end; TSMS_PDU_HEAD.TP_DHL := FSMSUtils.GetMsgLenPDU(vLen); SMS_PDU_HEAD := TSMS_PDU_HEAD.SMSCenter + TSMS_PDU_HEAD.FirstOcter + TSMS_PDU_HEAD.TP_MR + TSMS_PDU_HEAD.SMSRMobile + TSMS_PDU_HEAD.TP_PID + TSMS_PDU_HEAD.TP_DCS + TSMS_PDU_HEAD.TP_SCTS + TSMS_PDU_HEAD.TP_DHL ; FPDUHeadLists.Add(SMS_PDU_HEAD); end; end; procedure TimSMS.SetPDUBody ; var Str : string; i: integer; vList : TStrings; vWideStr : WideString; vWideLen : integer; begin FPDUBodyLists.Clear; vList := TStringList.Create; vWideStr := FMsgStr ; if FCount > SMS_MAX_COUNT then Exit; vWideLen := Length(vWideStr); case FSendType of SMS_TYPE_USER : begin for i := 0 to FCount - 1 do begin if(i<>FCount - 1) then begin Str := Copy(vWideStr,i*(SMS_USER_BODYLEN)+1,SMS_USER_BODYLEN); end else begin Str := Copy(vWideStr,i*(SMS_USER_BODYLEN)+1,vWideLen-i*(SMS_USER_BODYLEN)); end; vList.Add(Str); end; for i :=0 to vList.Count -1 do begin if FCount = 1 then begin FPDUBodyLists.Add(FSMSUtils.StrToUCS2(vList[i])); end else begin FPDUBodyLists.Add(FSMSUtils.GetSMSHeadPDU(FCount,i)+ FSMSUtils.StrToUCS2(vList[i])); end; end; end; SMS_TYPE_AUTO : begin for i := 0 to FCount - 1 do begin if(i<>FCount - 1) then begin Str := Copy(vWideStr,i*(SMS_AUTO_BODYLEN)+1,SMS_AUTO_BODYLEN); end else begin Str := Copy(vWideStr,i*(SMS_AUTO_BODYLEN)+1,vWideLen-i*(SMS_AUTO_BODYLEN)); end; vList.Add(Str); end; for i :=0 to vList.Count -1 do FPDUBodyLists.Add(FSMSUtils.StrToUCS2(vList[i])); end;// end;//END CASE vList.Free; end; procedure TimSMS.SetSend(vCenter, vMobile, vMsg: string; vType: integer); begin FSMSCenter := vCenter ; FMobile := vMobile; FMsgStr := Trim(vMsg); FSendType := vType; if FSendType = SMS_TYPE_AUTO then begin FCount := Length(FMsgStr) div SMS_SINGLE_LEN; Inc(FCount); end else begin FCount := Length(FMsgStr) div SMS_USER_BODYLEN; if FCount = 0 then FCount := 1; FSort := SMS_SORT_ASC; end; if FCount = 1 then FSendType := 2; EncodePDU; end; function TimSMS.SendSMS(vThread:integer): integer; var i : integer; vPDUStr,vStrLen : string ; begin if vThread = SMS_SINGLE_THREAD then begin for i :=0 to FPDUHeadLists.Count - 1 do begin vPDUStr := FPDUHeadLists[i] + FPDUBodyLists[i] ; try FApdComPort.Open := True; FApdComPort.Output := 'AT+CMGF=0'#13; DelayTicks(7,True); vStrLen := IntToStr(FSMSUtils.GetATCMGSLen(vPDUStr)); FApdComPort.Output := 'AT+CMGS='+vStrLen+#13; DelayTicks(7,True); FApdComPort.Output := vPDUStr+^Z; DelayTicks(9,True); FApdComPort.Open := False; Sleep(SMS_TIME_DELAY); finally FApdComPort.Open := False; end; end; end; if vThread = SMS_MUTIL_THREAD then begin end; Result := SMS_SEND_OK; end; function TimSMS.SendSMS(vPDUStr: string): integer; var vStrLen : string ; begin FPDUStr := vPDUStr; try FApdComPort.Open := True; FApdComPort.Output := 'AT+CMGF=0'#13; DelayTicks(7,True); vStrLen := IntToStr(FSMSUtils.GetATCMGSLen(vPDUStr)); FApdComPort.Output := 'AT+CMGS='+vStrLen+#13; DelayTicks(7,True); FApdComPort.Output := vPDUStr+^Z; DelayTicks(9,True); FApdComPort.Open := False; Sleep(SMS_TIME_DELAY); finally FApdComPort.Open := False; end; Result := SMS_SEND_OK; end; procedure TimSMS.SetPDULists(vHeadList, vBodyList, vTotalList: TStrings); var vList : TStrings; i : integer; begin vList := TStringList.Create; if vHeadList<>nil then vHeadList.AddStrings(FPDUHeadLists); if vBodyList<>nil then vBodyList.AddStrings(FPDUBodyLists); for i := 0 to FPDUHeadLists.Count - 1 do vList.Add(FPDUHeadLists[i]+FPDUBodyLists[i]); vTotalList.AddStrings(vList); vList.Free; end; procedure TimSMS.SetPDULists(vTotalList: TStrings); var vList : TStrings; i : integer; begin vList := TStringList.Create; for i := 0 to FPDUHeadLists.Count - 1 do vList.Add(FPDUHeadLists[i]+FPDUBodyLists[i]); vTotalList.AddStrings(vList); vList.Free; end; procedure TimSMS.EncodePDU; begin SetPDUHead; SetPDUBody; end; function TimSMS.GetInfo: string; begin Result := FInfo; end; function TimSMS.ReadSMS(vNum: integer): string; begin try FApdComPort.Open := True; FApdComPort.Output := 'AT+CMGR=1'#13; DelayTicks(7,True); finally FApdComPort.Open := False; end; end; procedure TimSMS.DelSMS(vIndex: integer); begin if vIndex = SMS_DEL_ALL then begin try FApdComPort.Open := True; FApdComPort.Output := 'AT+CMGD=1,3'+#13; DelayTicks(7,True); finally FApdComPort.Open := False; end; end else begin try FApdComPort.Open := True; FApdComPort.Output := 'AT+CMGD='+IntToStr(vIndex)+#13; DelayTicks(7,True); finally FApdComPort.Open := False; end; end; end; procedure TimSMS.OnRecCom(CP: TObject; Count: Word); var i : Word; Str: string; begin for i := 1 to Count do Str := Str + FApdComPort.GetChar; FComResult := UpperCase(Str); end; function TimSMS.TestComm: boolean; var vResult : boolean; begin try try FApdComPort.Open := True; //FApdComPort.Output := 'AT'#13; vResult := True; except vResult := False; end; finally FApdComPort.Open := False; end; Result := vResult ; end; procedure TimSMS.InitComm(vPort,vRate:integer); begin FApdComPort.ComNumber := vPort ; FApdComPort.Baud := vRate; end; { TimSMSInf } constructor TimSMSInf.Create; begin FSMS := TimSMS.Create; FTotal := TStringList.Create; end; procedure TimSMSInf.DelSms(vIndex: integer); begin FSMS.DelSMS(vIndex); end; destructor TimSMSInf.Destory; begin FTotal.Free; FSMS.Free; end; procedure TimSMSInf.InitComm(vPort, vRate: integer); begin FSms.InitComm(vPort,vRate); end; function TimSMSInf.ReadSMS(vIndex: integer): string; begin FSMS.ReadSMS(vIndex); end; procedure TimSMSInf.SendSMS(vCenter, vMobile, vMsg: string; vType: integer); var i : integer; begin FSMS.SetSend(vCenter, vMobile, vMsg, vType); FSMS.SetPDULists(FTotal); for i := 0 to FTotal.Count - 1 do FSMS.SendSMS(FTotal[i]); end; function TimSMSInf.TestComm: boolean; begin Result := FSMS.TestComm; end; end.