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

📄 adgsm.pas

📁 很好的手机发短信的例子。含GSM群发机设计原理和使用说明。还有详细代码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                                      // or = 2,,2,,0
                //'+CSCB?',           // Types of CBMs to be received by the ME
                //'+CSMP=,167,0,0',   // variable 17 for status 32 for no status
                '',
                '+CSCA=',             // Service Center if FSMSCenter not empty
                '+CMGS=',             // Send Destination address
                '');                  // Sending message text

  GSMSendMessageResponse : array[0..3] of string =
               (//'+CNMI: ',          // Response StartString expected
                //'OK',               // No Response Expected, just OK
                //'+CSCB: ',          // Response StartString expected
                //'OK',               // No Response Expected, just OK
                'OK',                 // No Response Expected, just OK
                'OK',                 // No Response Expected, just OK
                #13#10,               // Response from phone to Send Message
                '+CMGS: ');           // Response StartString expected

  GSMListAllMessagesCommands : array[0..0] of string =
               ('+CMGL');           // List Messages on Phone
  GSMListAllMessagesResponse : array[0..0] of string =
               ('+CMGL: ');         // Response StartString expected

  GSMSendMessFromStorage : array[0..0] of string =
               ('+CMSS=');          // Send Message from Storage
  GSMSendMessFromStorageResp : array[0..0] of string =
               (#13#10'OK');        // Response StartString expected

  GSMWriteToMemoryCommands : array[0..1] of string =
               ('+CMGW=',           // Write Message to Memory
                '');                // Writing message text
  GSMWriteToMemoryResponse : array[0..1] of string =
               (#13#10,             // Response StartString expected
                '+CMGW: ');
  GSMDeleteAMessageCommand : array[0..0] of string =
               ('+CMGD=');          // Delete Message from Memory
  GSMDeleteAMessageResponse : array[0..0] of string =
               (#13#10'OK');        // No Response Expected, just OK

  GSMDialCommand : array[0..0] of string =
               ('ATD');
  GSMDialResponse : array[0..0] of string =
               (#13#10'OK');        // No Response Expected, just OK

  GSMHangUpCommand : array[0..0] of string =
               ('ATH');
  GSMHangUpResponse :  array[0..0] of string =
               (#13#10'OK');        // No Response Expected, just OK
{ TApdSMSMessage }

function TApdSMSMessage.GetMessageAsPDU : string;
begin
  Result := StringToPDUCN (FMessage);
end;

function PDUToString (v : string) : string;
var
  I, InLen, OutLen, OutPos : Integer;
  TempByte, PrevByte : Byte;
begin
  { Check for empty input }
  if v = '' then Exit;

  { Init variables }
  PrevByte := 0;
  OutPos := 1;

  { Set length of output string }
  InLen := Length(v);
  Assert(InLen <= 140, 'Input string greater than 140 characters');
  OutLen := (InLen * 8) div 7;
  SetLength(Result, OutLen);

  { Encode output string }
  for I := 1 to InLen do begin
    TempByte := Byte(v[I]);
    TempByte := TempByte and not ($FF shl (7-((I-1) mod 7)));
    TempByte := TempByte shl ((I-1) mod 7);
    TempByte := TempByte or PrevByte;
    Result[OutPos] := AnsiChar(TempByte);
    Inc(OutPos);

    { Set PrevByte for next round (or directly put it to Result) }
    PrevByte := Byte(v[I]);
    PrevByte := PrevByte shr (7-((I-1) mod 7));
    if (I mod 7) = 0 then begin
      Result[OutPos] := AnsiChar(PrevByte);
      Inc(OutPos);
      PrevByte := 0;
    end;
  end;
  if Result[Length(Result)] = #0 then
    Result := Copy(Result, 1, pred(Length(Result)));
end;

procedure TApdSMSMessage.SetMessageAsPDU (v : string);
begin
  FMessage := PDUToStringCN (v);
end;


function StringToPDUCN (v : string) : string;
var
  i,j,len:Integer;
  cur:Integer;
  t:String;
  ws:WideString;
begin
  Result := '';
  if V='' then
    exit;
  ws := TrimRight(V);

  len := Length(ws);
  i := 1;
  j := 0;
  while i <= len do
  begin
      cur := ord(ws[i]);
      FmtStr(t,'%4.4X',[cur]);  //BCD转换
    Result := Result+t;
    inc(i);
    //移位计数达到7位的特别处理
    j := (j+1) mod 7;
  end;
end;

function PDUToStringCN(V: String): String;
var
  Buf:array[0..70] of widechar;
  len,i:integer;
begin
  len := round(Length(V)/4)-1;
  for i:=0 to Len do
    buf[i] := widechar(StrToint('$'+copy(V,4*i+1,4)));
  buf[i] := #0;
  result := WideCharToString(Buf)
end;


function StringToPDU (v : string) : string;
var
  I, InLen, OutLen, OutPos : Integer;
  RoundUp : Boolean;
  TempByte, NextByte : Byte;
begin
  { Check for empty input }
  if v = '' then Exit;

  { Init OutPos }
  OutPos := 1;

  { Set length of output string }
  InLen := Length(v);
  Assert(InLen <= 160, 'Input string greater than 160 characters');
  RoundUp := (InLen * 7 mod 8) <> 0;
  OutLen := InLen * 7 div 8;
  if RoundUp then Inc(OutLen);
  SetLength(Result, OutLen);

  { Encode output string }
  for I := 1 to InLen do
  begin
    TempByte := Byte(v[I]);
    Assert((TempByte and $80) = 0, 'Input string contains 8-bit data');
    if (I < InLen) then
      NextByte := Byte(v[I+1])
    else
      NextByte := 0;
    TempByte := TempByte shr ((I-1) mod 8);
    NextByte := NextByte shl (8 - ((I) mod 8));
    TempByte := TempByte or NextByte;
    Result[OutPos] := AnsiChar(TempByte);
    if I mod 8 <> 0 then
      Inc(OutPos);
  end;
end;

{ TApdCustomGSMPhone }

procedure TApdCustomGSMPhone.TestConnect;
var
  Res : Integer;
  ET : EventTimer;
begin
  if FGSMState > gsNone then
  begin
    DoFail(secSMSBusy,-8100);
    Exit;
  end;
  if not FConnected then
  begin
    { Do connection/configuration stuff }
    CheckPort;
  end;
  if FQueryModemOnly then                                                {!!.06}
    exit;                                                                {!!.06}
  if FNotifyOnNewMessage and not Assigned(NotifyPacket) then
  begin                                                           {!!.02}{!!.05}
    NotifyPacket := TApdDataPacket.Create(Self);                         {!!.05}
    NotifyPacket.OnStringPacket := NotifyStringPacket;                   {!!.05}
    NotifyPacket.StartCond := scString;                                  {!!.05}
    NotifyPacket.StartString := '+CMTI:';                                {!!.05}
    NotifyPacket.EndCond := [ecString];                                  {!!.05}
    NotifyPacket.EndString := #13;                                       {!!.05}
    NotifyPacket.IncludeStrings := False;                                {!!.05}
    NotifyPacket.ComPort := FComPort;                                    {!!.05}
    NotifyPacket.Enabled := True;                                        {!!.02}
    NotifyPacket.AutoEnable := True;                                     {!!.02}
  end;                                                                   {!!.02}
  FConfigList := True;                                                   {!!.02}
  CmdIndex := 0;
  ResponsePacket.StartString := GSMConfigResponse[CmdIndex];
  ResponsePacket.EndString := #13;
  ResponsePacket.ComPort := FComPort;                                    {!!.05}
  ResponsePacket.Enabled := True;
  //DelayTicks(4, True);                                                 {!!.04}
  SetState(gsConfig);
  FComPort.Output := 'AT' + GSMConfigAvail[CmdIndex] + #13;
  NewTimer(ET, ExpiredTime); // 60 second timer
  repeat
    Sleep(SLEEPTIME);
    Res := SafeYield;
  until (FGSMState = gsNone) or (FGSMState = gsListAll) or (Res = wm_Quit)
        or TimerExpired(ET);
  if TimerExpired(ET) then
  begin
    DoFail(secSMSTimedOut,-8101);
    Exit;
  end;
end;

{ opens the port, issues configuration commands }
{Generates the OnMessageList (+CMGL) event when complete if not QuickConnect}
procedure TApdCustomGSMPhone.Connect;
var
  Res : Integer;
  ET : EventTimer;
begin
  if FGSMState > gsNone then
  begin
    DoFail(secSMSBusy,-8100);
    Exit;
  end;
  if not FConnected then
  begin
    { Do connection/configuration stuff }
    CheckPort;
  end;
  if FQueryModemOnly then                                                {!!.06}
    exit;                                                                {!!.06}
  if FNotifyOnNewMessage and not Assigned(NotifyPacket) then
  begin                                                           {!!.02}{!!.05}
    NotifyPacket := TApdDataPacket.Create(Self);                         {!!.05}
    NotifyPacket.OnStringPacket := NotifyStringPacket;                   {!!.05}
    NotifyPacket.StartCond := scString;                                  {!!.05}
    NotifyPacket.StartString := '+CMTI:';                                {!!.05}
    NotifyPacket.EndCond := [ecString];                                  {!!.05}
    NotifyPacket.EndString := #13;                                       {!!.05}
    NotifyPacket.IncludeStrings := False;                                {!!.05}
    NotifyPacket.ComPort := FComPort;                                    {!!.05}
    NotifyPacket.Enabled := True;                                        {!!.02}
    NotifyPacket.AutoEnable := True;                                     {!!.02}
  end;                                                                   {!!.02}
  FConfigList := True;                                                   {!!.02}
  CmdIndex := 0;
  ResponsePacket.StartString := GSMConfigResponse[CmdIndex];
  ResponsePacket.EndString := #13;
  ResponsePacket.ComPort := FComPort;                                    {!!.05}
  ResponsePacket.Enabled := True;
  //DelayTicks(4, True);                                                 {!!.04}
  SetState(gsConfig);
  FComPort.Output := 'AT' + GSMConfigAvail[CmdIndex] + #13;
  NewTimer(ET, ExpiredTime); // 60 second timer
  repeat
    Sleep(SLEEPTIME);
    Res := SafeYield;
  until (FGSMState = gsNone) or (FGSMState = gsListAll) or (Res = wm_Quit)
        or TimerExpired(ET);
  if TimerExpired(ET) then
  begin
    DoFail(secSMSTimedOut,-8101);
    Exit;
  end;
end;

constructor TApdCustomGSMPhone.Create(AOwner: TComponent);
begin
  inherited;
  { Some of the initialization for the packets were moved to Checkport to make
    sure there was a comport - Marked there with "!!.05" }

  FConnected := False;
  FNeedNewMessage := 0;                                                  {!!.04}
  FRecNewMess := '';                                                     {!!.06}
  FQueryModemOnly := False;                                              {!!.06}
  FHandle := AllocateHWnd(WndProc);
  FMessageStore := TApdMessageStore.Create(Self);
  FComPort := SearchComPort(Owner);
end;

destructor TApdCustomGSMPhone.Destroy;
begin
  FConnected := False;
  ResponsePacket.Free;
  ErrorPacket.Free;
  DialErrorPacket.Free;
  NotifyPacket.Free;                                                     {!!.02}
  FMessageStore.Clear;
  FMessageStore.Free;
  DeallocateHwnd(FHandle);
  inherited;
end;

{!!.PDU}
procedure TApdCustomGSMPhone.SetPDUMode (v : Boolean);
begin
  if v <> FPDUMode then
    FPDUMode := v;
end;

{ +CMS ERROR: message Service Failure Result Code }
procedure TApdCustomGSMPhone.ErrorStringPacket(Sender: TObject;
  Data: string);
var
  ErrorCode : Integer;
  ErrorMessage : string;
  Temp : string;
begin
  //Display Message Service Failure Result Code
  Temp := Data;
  if Temp <> '' then                                                     {!!.06}
  begin
    Temp := Copy(Data, Pos(' ', Data), Length(Data));
    ErrorCode := -8000 - StrToInt(Temp);
    ErrorMessage := 'Phone error <refer to AdExcept.inc>';               {!!.06}
  end else
  begin                                                                  {!!.06}
    ErrorCode := -8500;                                                  {!!.06}
    ErrorMessage := 'Unknown Error';                                     {!!.06}
  end;                                                                   {!!.06}

⌨️ 快捷键说明

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