C# 利用AT指令开发短信功能

论坛中看到的AT发送短信的代码,可以学习用


  1. namespace ModemImpl {  
  2.     public class Modem {  
  3.         public bool IsOpen { get { return isOpen; } }  
  4.    
  5.         public Modem(string portName) {  
  6.             this.portName = portName;  
  7.    
  8.             Regex r1 = new Regex(@"^\+CMTI\:");  
  9.             Regex r2 = new Regex(@"^\+CMGR\:");  
  10.             Regex r3 = new Regex(@"^\+RING\:");  
  11.    
  12.             ATBeginHandlerMap.Add(r1, OnBeginCMTI);  
  13.             ATBeginHandlerMap.Add(r2, OnBeginCMGR);  
  14.             ATBeginHandlerMap.Add(r3, OnBeginRING);  
  15.    
  16.             ATHandlerMap.Add(r1, OnCMTI);  
  17.             ATHandlerMap.Add(r2, OnCMGR);  
  18.             ATHandlerMap.Add(r3, OnRING);  
  19.    
  20.             responseMap.Add(typeof(SendMessageRequest), OnCMGSResponse);  
  21.         }  
  22.    
  23.         public void Open() {  
  24.             port = new SerialPort(portName);  
  25.             port.Encoding = Encoding.Default;  
  26.             port.ReadTimeout = 30000;  
  27.             port.WriteTimeout = 30000;  
  28.             port.BaudRate = 9600;  
  29.             port.RtsEnable = true;  
  30.    
  31.             port.Open();  
  32.             port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);  
  33.    
  34.             AddRequestToQueue(new SettingReuqest("AT").Execute(port));  
  35.             Thread.Sleep(50);  
  36.             AddRequestToQueue(new SettingReuqest("ATE0").Execute(port));  
  37.             AddRequestToQueue(new SettingReuqest("AT+CMGF=1").Execute(port));  
  38.             AddRequestToQueue(new SettingReuqest("AT+CNMI=2,1").Execute(port));  
  39.             AddRequestToQueue(new SettingReuqest("AT+CSMP=49,167,0,8").Execute(port));  
  40.    
  41.             isOpen = true;  
  42.         }  
  43.    
  44.         public void Close() {  
  45.             port.DataReceived -= port_DataReceived;  
  46.             port.Close();  
  47.             isOpen = false;  
  48.         }  
  49.    
  50.         public void Send(Message arg) {  
  51.             if (arg.Text.Length > 70) {  
  52.                 throw new ArgumentOutOfRangeException("短信不能超过70个字符");  
  53.             }  
  54.    
  55.             AddRequestToQueue(new SendMessageRequest(arg).Execute(port));  
  56.         }  
  57.    
  58.         // ----------------------------------------------------------------------  
  59.         private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {  
  60.             string line = string.Empty;  
  61.    
  62.             try {  
  63.                 while (port.BytesToRead > 0) {  
  64.                     line = port.ReadLine();  
  65.                     if (!string.IsNullOrEmpty(line) && "\r" != line) {  
  66.                         Console.WriteLine(line);  
  67.                         receiveBuffer.Add(line);  
  68.    
  69.                         if (!isInterrupt) {  
  70.                             if (IsBeginInterrupt(line)) {  
  71.                                 if (IsEndInterrupt()) {  
  72.                                     EndInterrupt();  
  73.                                 }  
  74.                             } else {  
  75.                                 string c = line.TrimEnd('\r');  
  76.                                 if ("OK" == c || "ERROR" == c) {  
  77.                                     var response = new ModemResponse(receiveBuffer);  
  78.                                     response.Request = requestQueue.Dequeue();  
  79.                                     Type t = response.Request.GetType();  
  80.                                     if (responseMap.ContainsKey(t)) {  
  81.                                         responseMap[t](response);  
  82.                                     }  
  83.                                     receiveBuffer.Clear();  
  84.                                 }  
  85.                             }  
  86.                         } else {  
  87.                             if (IsEndInterrupt()) {  
  88.                                 EndInterrupt();  
  89.                             }  
  90.                         }  
  91.                     }  
  92.                 }  
  93.             } catch (Exception ex) {  
  94.                 Trace.WriteLine(ex);  
  95.             }  
  96.         }  
  97.    
  98.         private void EndInterrupt() {  
  99.             interruptHandler(receiveBuffer);  
  100.    
  101.             beginInterruptHandler = null;  
  102.             interruptHandler = null;  
  103.             receiveBuffer.Clear();  
  104.         }  
  105.    
  106.         private bool IsEndInterrupt() {  
  107.             Trace.Assert(beginInterruptHandler != null);  
  108.             bool result = false;  
  109.             if (beginInterruptHandler(receiveBuffer)) {  
  110.                 result = true;  
  111.             }  
  112.             return result;  
  113.         }  
  114.    
  115.         private bool IsBeginInterrupt(string arg) {  
  116.             bool result = false;  
  117.    
  118.             foreach (var each in ATBeginHandlerMap.Keys) {  
  119.                 if (each.IsMatch(arg)) {  
  120.                     beginInterruptHandler = ATBeginHandlerMap[each];  
  121.                     interruptHandler = ATHandlerMap[each];  
  122.                     result = true;  
  123.                     break;  
  124.                 }  
  125.             }  
  126.    
  127.             return result;  
  128.         }  
  129.    
  130.         private bool OnBeginCMTI(List<string> content) {  
  131.             return true;  
  132.         }  
  133.    
  134.         private void OnCMTI(List<string> content) {  
  135.             // +CMTI:"SM",1  
  136.             Regex pattern = new Regex(@"^\+CMTI:.+,(\d+)");  
  137.             Match m = pattern.Match(content[0]);  
  138.             index = Convert.ToInt32(m.Groups[1].Value);  
  139.    
  140.             AddRequestToQueue(new RetrieveMessageReuqest(index).Execute(port));  
  141.         }  
  142.    
  143.         private bool OnBeginCMGR(List<string> content) {  
  144.             return (content.Count == 3);  
  145.         }  
  146.    
  147.         private void OnCMGR(List<string> content) {  
  148.             Regex pattern = new Regex("^\\+CMGR:.+,\"(\\S+)\",");  
  149.    
  150.             Match m = pattern.Match(content[0]);  
  151.             string address = m.Groups[1].Value;  
  152.             if (address.StartsWith("+86")) {  
  153.                 address = address.Substring(3);  
  154.             }  
  155.             string content1 = content[1].TrimEnd('\r');  
  156.             if (content1.StartsWith("050003")) {  
  157.                 content1 = content1.Substring(12);  
  158.             }  
  159.    
  160.             Message message = new Message(address, MessageHelper.MessageDecode(content1));  
  161.             message.Raw = content[1].TrimEnd('\r');  
  162.             message.Flags = MessageFlags.UNREAD;  
  163.             message.CreatedAt = DateTime.Now;  
  164.    
  165.             DeleteByIndex(index);  
  166.             Receive(message);  
  167.         }  
  168.    
  169.         private bool OnBeginRING(List<string> content) {  
  170.             return true;  
  171.         }  
  172.    
  173.         private void OnRING(List<string> content) {  
  174.    
  175.         }  
  176.    
  177.         private void OnCMGSResponse(ModemResponse response) {  
  178.             SendResult(response);  
  179.         }  
  180.    
  181.         private void DeleteByIndex(int index) {  
  182.             port.Write(string.Format("AT+CMGD={0}\r", index));  
  183.         }  
  184.    
  185.         private void AddRequestToQueue(ModemMessage arg) {  
  186.             if (arg is ModemRequest) {  
  187.                 requestQueue.Enqueue(arg as ModemRequest);  
  188.             }  
  189.         }  
  190.    
  191.         private List<string> receiveBuffer = new List<string>();  
  192.         private ATReceivedEventHandler interruptHandler;  
  193.         private ATBeginReceivedEventHandler beginInterruptHandler;  
  194.         private bool isInterrupt { get { return beginInterruptHandler != null; } }  
  195.    
  196.         private Queue<ModemRequest> requestQueue = new Queue<ModemRequest>();  
  197.         private Dictionary<Type, ModemResponseHandler> responseMap = new Dictionary<Type, ModemResponseHandler>();  
  198.         private Dictionary<Regex, ATBeginReceivedEventHandler> ATBeginHandlerMap = new Dictionary<Regex, ATBeginReceivedEventHandler>();  
  199.         private Dictionary<Regex, ATReceivedEventHandler> ATHandlerMap = new Dictionary<Regex, ATReceivedEventHandler>();  
  200.         private string portName;  
  201.         private SerialPort port;  
  202.         private int index;  
  203.         private bool isOpen = false;  
  204.    
  205.         public event MessageReceivedEventHandler Receive;  
  206.         public event MessageSendEventHandler SendResult;  
  207.     }  
  208.    
  209.     public abstract class ModemMessage {  
  210.         public List<string> Content { getset; }  
  211.         public virtual ModemMessage Execute(SerialPort port) { return this; }  
  212.     }  
  213.    
  214.     public class ModemRequest : ModemMessage {  
  215.    
  216.     }  
  217.    
  218.     public class ModemResponse : ModemMessage {  
  219.         public ModemRequest Request { getset; }  
  220.    
  221.         public ModemResponse(List<string> content) {  
  222.             Content = content;  
  223.         }  
  224.     }  
  225.    
  226.     public class ModemNotify : ModemMessage { }  
  227.     public class SettingReuqest : ModemRequest {  
  228.         public SettingReuqest(string command) {  
  229.             this.command = command;  
  230.         }  
  231.    
  232.         public override ModemMessage Execute(SerialPort port) {  
  233.             base.Execute(port);  
  234.    
  235.             port.Write(command + "\r");  
  236.    
  237.             return this;  
  238.         }  
  239.    
  240.         private string command;  
  241.     }  
  242.     public class SendMessageRequest : ModemRequest {  
  243.         public Message Message { getset; }  
  244.    
  245.         public SendMessageRequest(Message message) {  
  246.             Message = message;  
  247.         }  
  248.    
  249.         public override ModemMessage Execute(SerialPort port) {  
  250.             base.Execute(port);  
  251.    
  252.             try {  
  253.                 port.DiscardInBuffer();  
  254.                 port.Write(string.Format("AT+CMGS={0}\r", Message.Address));  
  255.                 port.DiscardInBuffer();  
  256.                 port.Write(MessageHelper.MessageEncode(Message.Text) + ControlZ + "\r");  
  257.                 Message.Flags = MessageFlags.SENDED;  
  258.                 Message.CreatedAt = DateTime.Now;  
  259.             } catch (Exception) {  
  260.                 Message.Flags = MessageFlags.SENDFAILED;  
  261.                 Message.CreatedAt = DateTime.Now;  
  262.                 throw;  
  263.             }  
  264.    
  265.             return this;  
  266.         }  
  267.    
  268.         private const char ControlZ = (char)0x1A;  
  269.     }  
  270.    
  271.     public class RetrieveMessageReuqest : ModemRequest {  
  272.         public RetrieveMessageReuqest(int index) {  
  273.             this.index = index;  
  274.         }  
  275.    
  276.         public override ModemMessage Execute(SerialPort port) {  
  277.             base.Execute(port);  
  278.             port.Write(string.Format("AT+CMGR={0}\r", index));  
  279.             return this;  
  280.         }  
  281.    
  282.         private int index;  
  283.     }  
  284.        
  285.     public delegate bool ATBeginReceivedEventHandler(List<string> content);  
  286.     public delegate void ATReceivedEventHandler(List<string> content);  
  287.     public delegate void ModemResponseHandler(ModemResponse response);  
  288.     public delegate void MessageReceivedEventHandler(Message arg);  
  289.     public delegate void MessageSendEventHandler(ModemResponse response);  
  290. }  
namespace ModemImpl {
    public class Modem {
        public bool IsOpen { get { return isOpen; } }
 
        public Modem(string portName) {
            this.portName = portName;
 
            Regex r1 = new Regex(@"^\+CMTI\:");
            Regex r2 = new Regex(@"^\+CMGR\:");
            Regex r3 = new Regex(@"^\+RING\:");
 
            ATBeginHandlerMap.Add(r1, OnBeginCMTI);
            ATBeginHandlerMap.Add(r2, OnBeginCMGR);
            ATBeginHandlerMap.Add(r3, OnBeginRING);
 
            ATHandlerMap.Add(r1, OnCMTI);
            ATHandlerMap.Add(r2, OnCMGR);
            ATHandlerMap.Add(r3, OnRING);
 
            responseMap.Add(typeof(SendMessageRequest), OnCMGSResponse);
        }
 
        public void Open() {
            port = new SerialPort(portName);
            port.Encoding = Encoding.Default;
            port.ReadTimeout = 30000;
            port.WriteTimeout = 30000;
            port.BaudRate = 9600;
            port.RtsEnable = true;
 
            port.Open();
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
 
            AddRequestToQueue(new SettingReuqest("AT").Execute(port));
            Thread.Sleep(50);
            AddRequestToQueue(new SettingReuqest("ATE0").Execute(port));
            AddRequestToQueue(new SettingReuqest("AT+CMGF=1").Execute(port));
            AddRequestToQueue(new SettingReuqest("AT+CNMI=2,1").Execute(port));
            AddRequestToQueue(new SettingReuqest("AT+CSMP=49,167,0,8").Execute(port));
 
            isOpen = true;
        }
 
        public void Close() {
            port.DataReceived -= port_DataReceived;
            port.Close();
            isOpen = false;
        }
 
        public void Send(Message arg) {
            if (arg.Text.Length > 70) {
                throw new ArgumentOutOfRangeException("短信不能超过70个字符");
            }
 
            AddRequestToQueue(new SendMessageRequest(arg).Execute(port));
        }
 
        // ----------------------------------------------------------------------
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
            string line = string.Empty;
 
            try {
                while (port.BytesToRead > 0) {
                    line = port.ReadLine();
                    if (!string.IsNullOrEmpty(line) && "\r" != line) {
                        Console.WriteLine(line);
                        receiveBuffer.Add(line);
 
                        if (!isInterrupt) {
                            if (IsBeginInterrupt(line)) {
                                if (IsEndInterrupt()) {
                                    EndInterrupt();
                                }
                            } else {
                                string c = line.TrimEnd('\r');
                                if ("OK" == c || "ERROR" == c) {
                                    var response = new ModemResponse(receiveBuffer);
                                    response.Request = requestQueue.Dequeue();
                                    Type t = response.Request.GetType();
                                    if (responseMap.ContainsKey(t)) {
                                        responseMap[t](response);
                                    }
                                    receiveBuffer.Clear();
                                }
                            }
                        } else {
                            if (IsEndInterrupt()) {
                                EndInterrupt();
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                Trace.WriteLine(ex);
            }
        }
 
        private void EndInterrupt() {
            interruptHandler(receiveBuffer);
 
            beginInterruptHandler = null;
            interruptHandler = null;
            receiveBuffer.Clear();
        }
 
        private bool IsEndInterrupt() {
            Trace.Assert(beginInterruptHandler != null);
            bool result = false;
            if (beginInterruptHandler(receiveBuffer)) {
                result = true;
            }
            return result;
        }
 
        private bool IsBeginInterrupt(string arg) {
            bool result = false;
 
            foreach (var each in ATBeginHandlerMap.Keys) {
                if (each.IsMatch(arg)) {
                    beginInterruptHandler = ATBeginHandlerMap[each];
                    interruptHandler = ATHandlerMap[each];
                    result = true;
                    break;
                }
            }
 
            return result;
        }
 
        private bool OnBeginCMTI(List<string> content) {
            return true;
        }
 
        private void OnCMTI(List<string> content) {
            // +CMTI:"SM",1
            Regex pattern = new Regex(@"^\+CMTI:.+,(\d+)");
            Match m = pattern.Match(content[0]);
            index = Convert.ToInt32(m.Groups[1].Value);
 
            AddRequestToQueue(new RetrieveMessageReuqest(index).Execute(port));
        }
 
        private bool OnBeginCMGR(List<string> content) {
            return (content.Count == 3);
        }
 
        private void OnCMGR(List<string> content) {
            Regex pattern = new Regex("^\\+CMGR:.+,\"(\\S+)\",");
 
            Match m = pattern.Match(content[0]);
            string address = m.Groups[1].Value;
            if (address.StartsWith("+86")) {
                address = address.Substring(3);
            }
            string content1 = content[1].TrimEnd('\r');
            if (content1.StartsWith("050003")) {
                content1 = content1.Substring(12);
            }
 
            Message message = new Message(address, MessageHelper.MessageDecode(content1));
            message.Raw = content[1].TrimEnd('\r');
            message.Flags = MessageFlags.UNREAD;
            message.CreatedAt = DateTime.Now;
 
            DeleteByIndex(index);
            Receive(message);
        }
 
        private bool OnBeginRING(List<string> content) {
            return true;
        }
 
        private void OnRING(List<string> content) {
 
        }
 
        private void OnCMGSResponse(ModemResponse response) {
            SendResult(response);
        }
 
        private void DeleteByIndex(int index) {
            port.Write(string.Format("AT+CMGD={0}\r", index));
        }
 
        private void AddRequestToQueue(ModemMessage arg) {
            if (arg is ModemRequest) {
                requestQueue.Enqueue(arg as ModemRequest);
            }
        }
 
        private List<string> receiveBuffer = new List<string>();
        private ATReceivedEventHandler interruptHandler;
        private ATBeginReceivedEventHandler beginInterruptHandler;
        private bool isInterrupt { get { return beginInterruptHandler != null; } }
 
        private Queue<ModemRequest> requestQueue = new Queue<ModemRequest>();
        private Dictionary<Type, ModemResponseHandler> responseMap = new Dictionary<Type, ModemResponseHandler>();
        private Dictionary<Regex, ATBeginReceivedEventHandler> ATBeginHandlerMap = new Dictionary<Regex, ATBeginReceivedEventHandler>();
        private Dictionary<Regex, ATReceivedEventHandler> ATHandlerMap = new Dictionary<Regex, ATReceivedEventHandler>();
        private string portName;
        private SerialPort port;
        private int index;
        private bool isOpen = false;
 
        public event MessageReceivedEventHandler Receive;
        public event MessageSendEventHandler SendResult;
    }
 
    public abstract class ModemMessage {
        public List<string> Content { get; set; }
        public virtual ModemMessage Execute(SerialPort port) { return this; }
    }
 
    public class ModemRequest : ModemMessage {
 
    }
 
    public class ModemResponse : ModemMessage {
        public ModemRequest Request { get; set; }
 
        public ModemResponse(List<string> content) {
            Content = content;
        }
    }
 
    public class ModemNotify : ModemMessage { }
    public class SettingReuqest : ModemRequest {
        public SettingReuqest(string command) {
            this.command = command;
        }
 
        public override ModemMessage Execute(SerialPort port) {
            base.Execute(port);
 
            port.Write(command + "\r");
 
            return this;
        }
 
        private string command;
    }
    public class SendMessageRequest : ModemRequest {
        public Message Message { get; set; }
 
        public SendMessageRequest(Message message) {
            Message = message;
        }
 
        public override ModemMessage Execute(SerialPort port) {
            base.Execute(port);
 
            try {
                port.DiscardInBuffer();
                port.Write(string.Format("AT+CMGS={0}\r", Message.Address));
                port.DiscardInBuffer();
                port.Write(MessageHelper.MessageEncode(Message.Text) + ControlZ + "\r");
                Message.Flags = MessageFlags.SENDED;
                Message.CreatedAt = DateTime.Now;
            } catch (Exception) {
                Message.Flags = MessageFlags.SENDFAILED;
                Message.CreatedAt = DateTime.Now;
                throw;
            }
 
            return this;
        }
 
        private const char ControlZ = (char)0x1A;
    }
 
    public class RetrieveMessageReuqest : ModemRequest {
        public RetrieveMessageReuqest(int index) {
            this.index = index;
        }
 
        public override ModemMessage Execute(SerialPort port) {
            base.Execute(port);
            port.Write(string.Format("AT+CMGR={0}\r", index));
            return this;
        }
 
        private int index;
    }
     
    public delegate bool ATBeginReceivedEventHandler(List<string> content);
    public delegate void ATReceivedEventHandler(List<string> content);
    public delegate void ModemResponseHandler(ModemResponse response);
    public delegate void MessageReceivedEventHandler(Message arg);
    public delegate void MessageSendEventHandler(ModemResponse response);
}


from:http://blog.csdn.net/trassion/article/details/8287809


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值