wavecom CDMA MODEM发送短信,仅支持Q2358C型号电信卡短信设备,Q2438F型号需要去掉AT+CMGF=1指令,因为这个型号不支持这cmgf指令。
发送短信
发送前要先设置 :
- private System.IO.Ports.SerialPort _com= new System.IO.Ports.SerialPort();
- _com.Write("AT+WSCL=6,4\r");
- _com.Write("AT+CMGF=1\r");
- void SendMsgByCDMA(string phone, string msg)
- {
- string tmp = string.Empty;
- //发送的内容转为byte
- byte[] b = Encoding.BigEndianUnicode.GetBytes(msg);
- //cdma使用文本方式发送短信,因此每次只能发70个字符
- int j = b.Length / 140;
- System.Collections.Generic.List<byte[]> c = new System.Collections.Generic.List<byte[]>();
- //短信进行拆分
- for (int i = 0; i <= j; i++)
- {
- int index = 0;
- int length = 140;
- if (b.Length < 140)
- length = b.Length;
- if (i == j)
- length = b.Length - length * i;
- if (length == 0)
- continue;
- if (i != 0)
- index = i * 140;
- byte[] temp = new byte[length];
- Array.Copy(b, index, temp, 0, length);
- c.Add(temp);
- }
- //CDMA的AT命令手机号码前面不能加86,否则虽然显示成功发送,但短信中心回应错误代码5
- if (phone.IndexOf("86") == 0)
- {
- phone = phone.Substring(2);
- }
- try
- {
- foreach (byte[] item in c)
- {
- //设置发送的号码和发送内容字节长度
- _com.Write("AT+CMGS=\"" + phone + "\"," + item.Length + "\r");
- Thread.Sleep(50);
-
- //写入
- _com.Write(item, 0, item.Length);
- //写入CTRL+Z结束短信内容,注意在UNICODE模式下需要两个字节,这个也是不能在超级终端下操作的原因,如果write中指明length的话可以不用发送
- //byte[] b2 = new byte[] { 0x00, 0x1a };
- //_com.Write(b2, 0, b2.Length);
- ///等到运营商反馈收到命令
- _com.ReadTo("+CDS:");
- _com.DiscardInBuffer();
- }
- }
- catch (Exception)
- {
- throw new Exception("短信发送失败");
- }
-
- }
复制代码
收短信:
SerialPort类默认的是ascii编码。
使用readerLine方法只要是中文的读出来就是乱码,使用ascii反成字节数组,再转成Unicode都无法解决。
所以就以字节的方式读取缓冲区的内容,分组后字节数组直接转Unicode才正确解码。
- public string ReadNewMsgByCdma(int index)
- {
- string result = string.Empty;
- //读消息前先要注销端口消息事件
- _com.DataReceived -= sp_DataReceived;
- try
- {
- _com.DiscardInBuffer();
- _com.Write("AT+CMGR=" + index.ToString() + "\r");
- byte[] buffer = new byte[_com.ReadBufferSize + 1]; //建立缓冲区大小的byte[]
- //读取缓冲区所有的byte
- int count = _com.Read(buffer, 0, _com.ReadBufferSize);
- //去掉空字节
- Array.Resize<byte>(ref buffer, count);
- //缓冲区读出来的内容比较多包涵了:\r \n \0 | OK 等字符,使用readerLine()读数据 都是\r结尾,所以根据它再分组
- List<byte[]> tempList = Split(buffer, System.Text.Encoding.ASCII.GetBytes("\r")[0]);
- ///转码
- //读出来的短信分组后一般count为4,第3条为短信正文,
- //非短信正文使用ascii进行读取,System.Text.Encoding.ASCII.GetString(tempList[0]);
- //短信正文使用Unicode读取 System.Text.Encoding.BigEndianUnicode.GetString(tempList[2]);
- }
- catch (Exception)
- {
- _com.DataReceived += sp_DataReceived;
- throw;
- }
- return result;
- }
- /// <summary>
- /// 根据\r对byte进行分组
- /// </summary>
- /// <param name="array"></param>
- /// <param name="splitVale"></param>
- /// <returns></returns>
- List<byte[]> Split(byte[] array, byte splitVale)
- {
- List<byte[]> objList = new List<byte[]>();
- int i = Array.IndexOf(array, splitVale);
- while (i >= 0)
- {
- byte[] temp = new byte[i + 1];
- Array.ConstrainedCopy(array, 0, temp, 0, i + 1);
- byte[] bt = new byte[array.Length - temp.Length - 1];
- Array.Copy(array, temp.Length + 1, bt, 0, bt.Length);
- array = bt;
- objList.Add(temp);
- i = Array.IndexOf(array, splitVale);
- }
- return objList;
- }
复制代码
|