/// <summary> /// 发送短信 /// 发送失败将引发异常 /// </summary> /// <param name="phone">手机号码</param> /// <param name="msg">短信内容</param> public void SendMsg(string phone, string msg) { PDUEncoding pe = new PDUEncoding(); pe.ServiceCenterAddress = msgCenter; //短信中心号码 服务中心地址 string tmp = string.Empty; foreach (CodedMessage cm in pe.PDUEncoder(phone, msg)) { try { //注销事件关联,为发送做准备,本命令直接发送不写Sim卡,CMSS从Sim卡发送,CMGW写Sim卡 _com.DataReceived -= sp_DataReceived; _com.Write("AT+CMGS=" + cm.Length.ToString() + "\r"); _com.ReadTo(">"); _com.DiscardInBuffer(); //事件重新绑定 正常监视串口数据 _com.DataReceived += sp_DataReceived; tmp = SendAT(cm.PduCode + (char)(26)); //26 Ctrl+Z ascii码 } catch (Exception ex) { //打印日志 string errTxt = string.Format(" 短信发送失败:{0}\r\n{1}\r\n{2}", "SendMsg", ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); throw new Exception("短信发送失败:" + ex.ToString()); } //打印日志 LogHelpers.Write(string.Format(" 短信已发送:{0}\r\n{1}:{2}", tmp, phone, msg)); if (tmp.Contains("OK")) { continue; } //打印日志 LogHelpers.Error(string.Format(" 短信发送失败:{0}", tmp)); throw new Exception("短信发送失败:" + tmp); } }
/// <summary> /// 开启服务 /// </summary> public void StartService() { try { // 启动服务... string sResult = ""; IsOpen = srv.Open(out sResult); if (!IsOpen) { LogHelpers.Error("GMS开启服务失败:" + sResult); return; } _quSendMsgThread.Start(); LogHelpers.Write("GMS开启服务成功:" + sResult); } catch (Exception e) { LogHelpers.Error("GMS开启服务失败:" + e.StackTrace); } }
/// <summary> /// 返回连接信息的Open方法 /// </summary> public bool Open(out string sResult) { //如果串口已打开 则先关闭 sResult = ""; if (_com.IsOpen) { _com.Close(); } _com.Open(); //初始化设备 if (_com.IsOpen) { try { _com.DataReceived -= sp_DataReceived; _com.Write("ATE0\r"); Thread.Sleep(200); sResult += " ATE0:" + _com.ReadExisting(); _com.Write("AT+CMGF=0\r"); Thread.Sleep(200); sResult += " AT+CMGF=0:" + _com.ReadExisting(); _com.Write("AT+CNMI=2," + recvMsgLoc + "\r"); Thread.Sleep(200); sResult += " AT+CNMI=2," + recvMsgLoc + ":" + _com.ReadExisting(); //绑定事件 _com.DataReceived += sp_DataReceived; return(true); } catch (Exception ex) { //打印日志 string errTxt = string.Format(" Connect Send AT Exception Result:{0}\r\n{1}\r\n{2}", sResult, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); throw new Exception(" Connect Send AT Exception:" + ex.ToString() + " Result:" + sResult); } } return(false); }
//发送消息 private void OKSend(TMsg sendMsg) { int i = 0; while (true) { i++; try { srv.SendMsg(sendMsg.TelNum, sendMsg.Msg); string logTxt = string.Format("消息发送成功:{0}---{1}", sendMsg.TelNum, sendMsg.Msg); LogHelpers.Error(logTxt); break; } catch (Exception ex) { string logExTxt = string.Format("短信发送失败:第{0}次--{1}:{2}\n{3}\n{4}\n", i, sendMsg.TelNum, sendMsg.Msg, ex.Message, ex.StackTrace); LogHelpers.Error(logExTxt); Thread.Sleep(2 * 1000); if (i > ReSendTimes) { ReStartService(); try { srv.SendMsg(sendMsg.TelNum, sendMsg.Msg); string logTxt = string.Format("消息发送成功:{0}---{1}", sendMsg.TelNum, sendMsg.Msg); LogHelpers.Error(logTxt); break; } catch (Exception rEx) { string logTxt = string.Format("短信重启后发送失败:---{0}:{1}\n{2}\n{3}", sendMsg.TelNum, sendMsg.Msg, rEx.Message, rEx.StackTrace); LogHelpers.Error(logTxt); break; } } } } }
/// <summary> /// 设置Sim卡槽号,仅适用于MTK手机 /// </summary> public bool SetMTKSim(int SimCardNo, out string sATResult) { SimCardNo = SimCardNo + 3; sATResult = "";// "AT+ESUO=" + SimCardNo + " Result:"; try { sATResult += SendAT("AT+ESUO=" + SimCardNo); if (sATResult.Contains("OK")) { return(true); } } catch (Exception ex) { //打印日志 string errTxt = string.Format(" AT+ESUO=:{0}\r\n{1}\r\n{2}", SimCardNo, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); throw new Exception("AT+ESUO=" + SimCardNo + " Fail:" + ex.ToString()); } return(false); //throw new Exception("设置失败:" + sATResult); }
//重启短信猫 private void ReStartService() { LogHelpers.Error("GMS服务开始重启"); try { srv.Close(); IsOpen = false; } catch (Exception e) { string exMsg = string.Format("GMS服务重启时关闭失败:{0}\n{1}", e.Message, e.StackTrace); LogHelpers.Error(exMsg); } try { // 初始化. GsmModem newSrv = new GsmModem(); newSrv.AutoDelMsg = srv.AutoDelMsg; newSrv.ComPort = srv.ComPort; newSrv.BaudRate = srv.BaudRate; // 启动服务... string sResult = ""; IsOpen = newSrv.Open(out sResult); if (!IsOpen) { LogHelpers.Error("GMS开启服务失败:" + sResult); return; } srv = newSrv; LogHelpers.Error("GMS服务重启成功"); } catch (Exception e) { string exMsg = string.Format("GMS服务重启失败:{0}\n{1}", e.Message, e.StackTrace); LogHelpers.Error(exMsg); } }
/// <summary> /// 获取短信中心号码 /// </summary> /// <returns></returns> public string GetMsgCenterNo() { string tmp = string.Empty; if (msgCenter != null && msgCenter.Length != 0) { return(msgCenter); } else { tmp = SendAT("AT+CSCA?"); if (tmp.Substring(tmp.Length - 4, 3).Trim() == "OK") { return(tmp.Split('\"')[1].Trim()); } else { //打印日志 string errTxt = string.Format(" 获取短信中心失败:{0}", tmp); LogHelpers.Error(errTxt); throw new Exception("获取短信中心失败:" + tmp); } } }
/// <summary> /// 获取已读或未读信息列表 /// </summary> /// <returns>未读信息列表(中心号码,手机号码,发送时间,短信内容)</returns> public List <DecodedMessage> GetReceiveMsg(int iMsgType, out string sInfo) { List <DecodedMessage> result = new List <DecodedMessage>(); string[] temp = null; string tmp = string.Empty; string sRead = string.Empty; int iCurIndex = 0; sInfo = ""; if (iMsgType != 1) { iMsgType = 0; } tmp = SendAT("AT+CMGL=" + iMsgType); if (tmp.Contains("OK")) { temp = tmp.Split('\r'); PDUEncoding pe = new PDUEncoding(); foreach (string str in temp) { if (str != null && str.Length > 6) //短信PDU长度仅仅短信中心就18个字符 { sRead = str.Replace((char)(13), ' ').Trim(); if (sRead.Substring(0, 6) == "+CMGL:") { iCurIndex = Convert.ToInt32(sRead.Split(',')[0].Substring(6)); //存储新信息序号 } if (sRead.Length > 30) { try { //sInfo += " ReadPDUindex: " + iCurIndex + " sReadPDU:" + sRead; result.Add(pe.PDUDecoder(iCurIndex, sRead)); } catch (Exception ex) { sInfo += " DECODER:" + ex.ToString() + " ReadPDUindex: " + iCurIndex + " sReadPDU:" + sRead; //打印日志 string errTxt = string.Format(" sInfo:{0}\r\n{1}\r\n{2}", sInfo, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //return result; //throw ex; } if (AutoDelMsg) { try { DeleteMsgByIndex(iCurIndex); } catch (Exception ex) { sInfo += " DEL:" + ex.ToString(); //打印日志 string errTxt = string.Format(" sInfo:{0}\r\n{1}\r\n{2}", sInfo, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //throw ex; } } } } } } return(result); }
public DecodedMessage PDUDecoder(int SmsIndex, string strPDU) { int lenSCA = 0; //错误PDU时可能抛出异常 int lenOA; int lenPDU = strPDU.Length; try { lenSCA = Convert.ToInt32(strPDU.Substring(0, 2), 16) * 2 + 2; //短消息中心占长度 //int lenSCA = Convert.ToInt32(strPDU.Substring(0, 2), 16) * 2 + 2; //短消息中心占长度 serviceCenterAddress = strPDU.Substring(0, lenSCA); //PDU-type位组 protocolDataUnitType = strPDU.Substring(lenSCA, 2); lenOA = Convert.ToInt32(strPDU.Substring(lenSCA + 2, 2), 16); //OA占用长度 if (lenOA % 2 == 1) //奇数则加1 F位 { lenOA++; } lenOA += 4; //加号码编码的头部长度 originatorAddress = strPDU.Substring(lenSCA + 2, lenOA); dataCodingScheme = strPDU.Substring(lenSCA + lenOA + 4, 2); //DCS赋值,区分解码7bit serviceCenterTimeStamp = strPDU.Substring(lenSCA + lenOA + 6, 14); userDataLength = strPDU.Substring(lenSCA + lenOA + 20, 2); int lenUD = Convert.ToInt32(userDataLength, 16) * 2; } catch (Exception ex) { //打印日志 string errTxt = string.Format(" PDU:{0}\r\n{1}\r\n{2}", strPDU, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //由于解码出来SubString中引用的长度与字StrPdu实际长度不一致,因而加大异常捕获范围 throw new Exception(ex.Message + " PDU:" + strPDU); } if ((Convert.ToInt32(protocolDataUnitType, 16) & 0x40) != 0) //长短信 { if (dataCodingScheme.Substring(1, 1) == "8") //USC2 长短信 去掉消息头 { try { userDataLength = (Convert.ToInt16(strPDU.Substring(lenSCA + lenOA + 20, 2), 16) - 6).ToString("X2"); userData = strPDU.Substring(lenSCA + lenOA + 22 + 6 * 2); } catch (Exception ex) { //打印日志 string errTxt = string.Format(" LongMSG1-PDU:{0}\r\n{1}\r\n{2}", strPDU, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //由于解码出来SubString中引用的长度与字StrPdu实际长度不一致,因而加大异常捕获范围 throw new Exception(ex.Message + " LongMSG1-PDU:" + strPDU); } return(new DecodedMessage(SmsIndex, strPDU.Substring(lenSCA + lenOA + 22 + 4 * 2, 2 * 2) + strPDU.Substring(lenSCA + lenOA + 22 + 3 * 2, 2) , ServiceCenterAddress , ServiceCenterTimeStamp.Substring(0, 4) + "-" + ServiceCenterTimeStamp.Substring(4, 2) + "-" + ServiceCenterTimeStamp.Substring(6, 2) + " " + ServiceCenterTimeStamp.Substring(8, 2) + ":" + ServiceCenterTimeStamp.Substring(10, 2) + ":" + ServiceCenterTimeStamp.Substring(12, 2) , OriginatorAddress, UserData)); } else { try { userData = strPDU.Substring(lenSCA + lenOA + 22 + 6 * 2 + 1 * 2); //消息头六字节,第一字节特殊译码 >>7 } catch (Exception ex) { //打印日志 string errTxt = string.Format(" LongMSG2-PDU:{0}\r\n{1}\r\n{2}", strPDU, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //由于解码出来SubString中引用的长度与字StrPdu实际长度不一致,因而加大异常捕获范围 throw new Exception(ex.Message + " LongMSG2-PDU:" + strPDU); } //首字节译码 byte byt = Convert.ToByte(strPDU.Substring(lenSCA + lenOA + 22 + 6 * 2, 2), 16); char first = (char)(byt >> 1); return(new DecodedMessage(SmsIndex, strPDU.Substring(lenSCA + lenOA + 22 + 4 * 2, 2 * 2) + strPDU.Substring(lenSCA + lenOA + 22 + 3 * 2, 2) , ServiceCenterAddress , ServiceCenterTimeStamp.Substring(0, 4) + "-" + ServiceCenterTimeStamp.Substring(4, 2) + "-" + ServiceCenterTimeStamp.Substring(6, 2) + " " + ServiceCenterTimeStamp.Substring(8, 2) + ":" + ServiceCenterTimeStamp.Substring(10, 2) + ":" + ServiceCenterTimeStamp.Substring(12, 2) , OriginatorAddress , first + UserData)); } } try { userData = strPDU.Substring(lenSCA + lenOA + 22); } catch (Exception ex) { //打印日志 string errTxt = string.Format(" SMSUserData-PDU:{0}\r\n{1}\r\n{2}", strPDU, ex.Message, ex.StackTrace); LogHelpers.Error(errTxt); //由于解码出来SubString中引用的长度与字StrPdu实际长度不一致,因而加大异常捕获范围 throw new Exception(ex.Message + " SMSUserData-PDU:" + strPDU); } return(new DecodedMessage(SmsIndex, "010100" , ServiceCenterAddress , ServiceCenterTimeStamp.Substring(0, 4) + "-" + ServiceCenterTimeStamp.Substring(4, 2) + "-" + ServiceCenterTimeStamp.Substring(6, 2) + " " + ServiceCenterTimeStamp.Substring(8, 2) + ":" + ServiceCenterTimeStamp.Substring(10, 2) + ":" + ServiceCenterTimeStamp.Substring(12, 2) , OriginatorAddress , UserData)); }