2015-05-28 208 views
2

我一直在研究了超過兩天,試圖讓一個應用程序無法正常工作使用AT命令發送短信,我實現了在網上提供一些教程和項目。不幸的是,他們都沒有工作。AT命令發送短信在Windows 8.1

[https://docs.google.com/document/d/1VfBbMcKZsutP8Cwg2iu7Rqiyccks1J6N2ZEbkbxnCTU/preview]這段代碼給了我執行命令,但不發送消息。

然後我嘗試了另一個項目(我使用的是C#和Visual Studio 2013),它具有以下文件,執行後狀態更改爲消息已發送,但我沒有收到消息。我使用華爲移動連接 - 3G的應用程序接口 GSM調制解調器

Program.cs的

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace CSharp_SMS 
{ 
static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form_SMS_Sender()); 
    } 
} 
} 

Form1.cs的

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO.Ports; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace CSharp_SMS 
{ 
public partial class Form_SMS_Sender : Form 
{ 
    private SerialPort _serialPort; 
    public Form_SMS_Sender() 
    { 
     InitializeComponent(); 
    } 

    private void buttonSend_Click(object sender, EventArgs e) 
    { 
     string number = textBoxNumber.Text; 
     string message = textBoxMessage.Text; 

     _serialPort = new SerialPort("COM17", 19200); //Replace "COM7" with corresponding port name 

     Thread.Sleep(1000); 

     _serialPort.Open(); 

     Thread.Sleep(1000); 

     _serialPort.Write("AT+CMGF=1\r"); 

     Thread.Sleep(1000); 

     _serialPort.Write("AT+CMGS=\"" + number + "\"\r\n"); 

     Thread.Sleep(1000); 

     _serialPort.Write(message + "\x1A"); 

     Thread.Sleep(1000); 

     labelStatus.Text = "Status: Message sent"; 

     _serialPort.Close(); 
    } 
} 
} 

有問題的程序?我錯過了什麼?或者,在Windows 8.1中運行這個問題有問題,因爲我還發現有一個名爲MS HyperTerminal的程序,這部分對我來說不是很清楚。

+1

即_tutorial_應刪除(相關帖子:[1](http://stackoverflow.com/q/283​​15943/1207195)和[2](http://stackoverflow.com/a/15591673/ 1207195))。什麼不工作?有什麼異常?根本沒有結果?你必須改變一些串口屬性,不要等待使用Thred.Sleep(),**檢查調制解調器響應**(順便說一下,第一次睡眠是無用的)。我還建議將該代碼移到背景工作者(或者您將掛起UI)。狀態變爲「發送消息」,因爲這是你寫的,調制解調器實際告訴你的是未知的(因爲你沒有閱讀它的答案)。 –

+0

您沒有進行身份驗證。你確定你的SIM卡沒有PIN嗎? 超級終端直接發送AT命令(不管你輸入被立即發送。) –

+0

運行此的東西,如SysIntertnals Portmon運行,所以你可以看到從設備是您目前完全忽視了響應(看發出ATV1/AT + CMEE命令以啓用更詳細的響應) –

回答

0

我在下面的格式使用AT Commands和它的作品。

public bool sendMsg(string smsid, string PhoneNo, string Message, string from, string to) 
{ 
    string recievedData; 
    bool isSend = false; 
    string text = "Hello " + to + ",\n" + Message + "\n\n" + from; 
    if (!port.IsOpen)     
     port = OpenPort(); 
    recievedData = ExecCommand(port, "AT+CMGF=1", 400, "Failed to set message format."); 

    try 
    { 
     //string recievedData; // = ExecCommand(port, "AT", 3000, "No phone connected"); 
     String command = "AT+CMGS=\"" + PhoneNo + "\""; 
     recievedData = ExecCommand(port, command, 1000, "Failed to accept phoneNo"); 
     command = text + char.ConvertFromUtf32(26) + "\r"; 
     recievedData = ExecCommand(port, command, 1000, "Failed to send message"); 
     if (recievedData.Contains("OK")) 
     { 
      isSend = true;     
     } 
     else if (recievedData.Contains("ERROR")) 
     { 
      isSend = false;     
     } 
    } 
    catch (Exception ex) 
    { 
     MyLog.Write(new LogPacket(ex, DateTime.Now)); 
    } 
    return isSend; 
} 
2

我用SMSPDUlib

和代碼

private const string LT = "\r\n"; 

    public void Auth(string pin) 
    { 
     lock (smsSendSync) 
     { 
      //Check if gateway is alive 
      lastSplit = SplitResponse(SendCommand("AT")); 
      if (!(lastSplit[lastSplit.Length - 1] == "OK")) 
       throw new OperationCanceledException("AT connection failed"); 

      //Echo ON 
      lastSplit = SplitResponse(SendCommand("ATE1")); 
      if (!(lastSplit[lastSplit.Length - 1] == "OK")) 
       throw new OperationCanceledException("ATE command failed"); 

      //Check echo 
      lastSplit = SplitResponse(SendCommand("AT")); 
      if (!(lastSplit.Length == 2 && lastSplit[1] == "OK")) 
       throw new OperationCanceledException("AT command failed"); 

      //Verbose error reporting 
      lastSplit = SplitResponse(SendCommand("AT+CMEE=2")); 
      if (!(lastSplit.Length == 2 && lastSplit[1] == "OK")) 
       throw new OperationCanceledException("AT+CMEE command failed"); 

      //Enter a PIN 
      lastSplit = SplitResponse(SendCommand("AT+CPIN?")); 
      if (!(lastSplit.Length == 3 && lastSplit[2] == "OK")) 
       throw new OperationCanceledException("AT+CPIN? command failed"); 
      switch (lastSplit[1]) 
      { 
       case "+CPIN: READY": //no need to enter PIN 
        break; 
       case "+CPIN: SIM PIN": //PIN requested 
        lastSplit = SplitResponse(SendCommand("AT+CPIN=" + pin)); 
        string m_receiveData = String.Empty; 
        WaitForResponse(out m_receiveData); 
        if (m_receiveData == String.Empty) 
         throw new OperationCanceledException("PIN authentification timed out"); 
        break; 
       default: 
        throw new OperationCanceledException("Unknown PIN request"); 
      } 
      //Check if registered to a GSM network 
      lastSplit = SplitResponse(SendCommand("AT+CREG?")); 
      if (!(lastSplit.Length == 3 && lastSplit[2] == "OK")) 
       throw new OperationCanceledException("AT+CREG? command failed"); 
      lastSplit = lastSplit[1].Split(new string[] {" ", ","}, StringSplitOptions.RemoveEmptyEntries); 
      if (!(lastSplit[2] == "1" || lastSplit[2] == "5")) 
       throw new OperationCanceledException("Not registered to a GSM network"); 
      Debug.WriteLine("Authentification successfull"); 
     } 
    } 

    private string[] SplitResponse(string response) 
    { 
     string[] split = response.Split(new string[] { LT }, StringSplitOptions.RemoveEmptyEntries); 
     for (int i = 0; i < split.Length; i++) 
      split[i] = split[i].Trim(); 
     return split; 
    } 

    public string SendCommand(string command) 
    { 
     string m_receiveData = string.Empty; 
     smsPort.ReadExisting();  //throw away any garbage 
     smsPort.WriteLine(command + LT); 
     WaitForResponse(out m_receiveData); 
     //Debug.WriteLine(m_receiveData); 
     return m_receiveData; 
    } 

    public string SendSms2(string phoneNumber, string message, bool flashMsg, SMS.SMSEncoding encoding) 
    { 
     if (phoneNumber.StartsWith("00")) 
      phoneNumber = "+" + phoneNumber.Substring(2); 
     if (phoneNumber.StartsWith("0")) 
      //replace with your national code 
      phoneNumber = "+386" + phoneNumber.Substring(1); 
     string StatusMessage = string.Empty; 
     SMS sms = new SMS();       //Compose PDU SMS 
     sms.Direction = SMSDirection.Submited;   //Setting direction of sms 
     sms.Flash = flashMsg;       //Sets the flash property of SMS 
     sms.PhoneNumber = phoneNumber.Replace(" ",""); //Set the recipient number 
     sms.MessageEncoding = encoding;     //Sets the Message encoding for this SMS 
     sms.ValidityPeriod = new TimeSpan(4, 0, 0, 0); //Set validity period 
     sms.Message = message;       //Set the SMS Message text 
     string sequence = sms.Compose() + CtrlZ;  //Compile PDU unit 
     string sequenceLength = ((sequence.Length - 3)/2).ToString(); 
     lock (smsSendSync) 
     { 
      StatusMessage = SendCommand("AT+CMGS=" + sequenceLength) + " "; 
      Thread.Sleep(500); 
      StatusMessage += SendCommand(sequence); 
     } 
     Debug.WriteLine(StatusMessage); 
     if (StatusMessage.Contains("ERROR")) 
      throw new OperationCanceledException("Error sending SMS"); 
     return StatusMessage; 
    } 

使用Auth()初始化調制解調器和SendSms2()發送短信。

+0

你可以給參數的彙總方式通'flashMsg'和'encoding'此功能'公共字符串SendSms2(字符串phoneNumber,字符串消息,布爾flashMsg,SMS.SMSEncoding編碼)' –

+0

FlashSMS: https://en.wikipedia.org/wiki/Short_Message_Service#Flash_SMS 通常它應該是錯誤的。 編碼: 用於發送短信的編碼。它可以是_7bit,_8bit或UCS2(類似於Unicode) –

+0

請不要使用'Thread.Sleep'來等待來自調制解調器的''n \ r>「'響應。有關詳細信息,請參閱[此答案]的第一部分(http://stackoverflow.com/a/15591673/23118)。 – hlovdal