public class GSMMgr
{
static Comm com;
#region 常量
const string CMDInitCSM = "ATZ/r/n"; // 初始化短信
///
/// 初始化短消息上报的字符串
/// 收到短消息:
///+CMTI: "MT",10X
///
const string CMDInitCSMRec = "AT+CNMI=2,1/r/n";
const string CMDReiceved = "CMTI: /"MT/""; // 用来判断是否接收到短信
const string CMDReadSMS = "AT+CMGR"; // 用来查收接收的短信命令
const string CMDSendSMS = "AT+CMGS"; //发送短消息
const string CMDDelete = "AT+CMGD"; //删除短消息
const string CMDDeleteAll = "AT+CMGD=1/r/n";
const string CMDSingle = "AT+CSQ"; //读GSM信号
#endregion
static EventWaitHandle eventWait = new EventWaitHandle(false, EventResetMode.ManualReset);
System.Timers.Timer timerReadSingle;
object syncRoot = new object();
private GSMMgr()
{
try
{
com = new Comm(SysConfig.ComGSM.name, SysConfig.ComGSM.rate, SysConfig.ComGSM.parity, SysConfig.ComGSM.dataBit);
timerReadSingle = new System.Timers.Timer(15000);
timerReadSingle.Elapsed += (s, e) => com.write(CMDSingle + "/r/n");
}
catch (Exception e)
{
Common.writeLog("短信猫串口实例失败。" + e.Message);
}
}
private volatile static GSMMgr instance = null;
private static readonly object locker = new object();
public static GSMMgr CreateInstance()
{
if (instance == null)
{
lock (locker)
{
if (instance == null)
{
instance = new GSMMgr();
Thread t = new Thread(instance.StartGSM);
t.Start();
}
}
}
return instance;
}
void StartGSM()
{
// com = new Comm("COM1", 9600, System.IO.Ports.Parity.None, 8);
if (com == null)
{
Common.writeLog("GSM串口设置有误");
UtilityHelper.ShowMsgBox("GSM串口串口设置有误", "警告", 80000);
return;
}
if (!com.InitCom())
{
Common.writeLog("GSM串口初始化失败");
UtilityHelper.ShowMsgBox("GSM串口初始化失败!/r/n请检查短信猫是否配置好或者配置文件是否正确", "警告", 8000);
// return;
}
com.write("AT&F/r/n");
DeviceStatus.Status_GSM信号 = -1;
bool b = false;
for (int i = 0; i < 10; i++)
{
com.write(CMDInitCSM);
string str = com.strRead().ToUpper();
if (str.Contains("OK"))
{
b = true;
break;
}
}
if (b)
{
bool b2 = false;
string str = "";
for (int i = 0; i < 10; i++)
{
com.write(CMDSingle+"/r/n");
str = com.strRead().Replace(" ", "");
if (str.Contains("OK"))
{
b2 = true;
break;
}
}
if (b2)
{
string[] s = str.Substring(str.IndexOf(":") + 1, 5).Split(',');
if (s.Length > 1)
if (s[1] == "99")
{
int d = s[0].ToInt(-1);
if (d < 11)
{
DeviceStatus.Status_GSM信号 = 0;
}
else
DeviceStatus.Status_GSM信号 = (double)(d - 11) / 20;
}
}
bool b3 = false;
for (int i = 0; i < 5; i++)
{
com.write(CMDInitCSMRec);
str = com.strRead().ToUpper();
if (str.Contains("OK"))
{
b3 = true;
break;
}
}
if (b3)
{
//com.Data_Received += new Comm.dataReceived(com_ReceivedSMS); // 如果短信接收初始化成功,就添加数据接收事件,读取短信
}
else
{
Common.writeLog("短信接收初始化失败");
UtilityHelper.ShowMsgBox("短信接收初始化失败/r/n请检查手机卡是否已放置好", "警告", 8000);
}
}
else
{
Common.writeLog("短信猫初始化失败");
UtilityHelper.ShowMsgBox("短信猫初始化失败", "警告", 8000);
}
com.Data_Received += new Comm.dataReceived(com_ReceivedSMS);
timerReadSingle.Start();
}
//接收到数据
void com_ReceivedSMS(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string rcvRead = com.strRead();
if (!rcvRead.IsNotEmpty())
return;
if (rcvRead.ToUpper().Contains(CMDReiceved))
{
timerReadSingle.Enabled = false;
string str = rcvRead.Replace("/r/n", "");
str = str.Substring(str.LastIndexOf(',') + 1, str.Length - 1 - str.LastIndexOf(',')).Trim();
// com.Data_Received -= com_ReceivedSMS; // 取消 串口数据接收事件
try
{
com.write(CMDReadSMS + "=" + str + "/r/n"); // 发送读命令
rcvRead = com.strRead();
// com.write(deleteSms + "=" + str + "/r/n"); // 删除该条短信
com.write(CMDDeleteAll);
smsHandle(rcvRead);
}
catch { }
finally
{
timerReadSingle.Enabled = true;
}
}
else if (rcvRead.Contains(CMDSingle))
{
if (rcvRead.Contains("OK"))
{
string[] s = rcvRead.Replace(" ","").Substring(rcvRead.IndexOf(":") + 1, 5).Split(',');
if (s.Length > 1)
if (s[1] == "99")
{
int d = s[0].ToInt(-1);
if (d < 11)
{
DeviceStatus.Status_GSM信号 = 0;
}
else
DeviceStatus.Status_GSM信号 = (double)(d - 11) / 20;
}
}
}
else if (rcvRead.ToUpper().Contains("RING"))
{
}
}
// 处理接收的短消息
void smsHandle(string sms)
{
string strLog = "";
if (sms == null)
return;
sms = System.Text.RegularExpressions.Regex.Split(sms, Environment.NewLine)[2];
string RcvMoblieNum = FPDUdecoding.GetTelphone(sms);
string RcvContent = FPDUdecoding.FPDUdecodingSms(sms);
DateTime RcvDate = FPDUdecoding.GetDataTime(sms).ToDateTime(DateTime.Now);
if (RcvContent.StartsWith("DADDY"))
{
string[] msg = RcvContent.Replace("/0", "").Split(';');
string result = ""; if (msg.Length > 2)
result = checkCmd2(msg[1], msg[2]);
Common.writeLog("接收到短消息," + RcvDate + "," + RcvMoblieNum + "," + RcvContent);
sendSMS(RcvMoblieNum, result);
return;
}
if (DateTime.Now - RcvDate > TimeSpan.FromDays(0.5))
{
Common.writeLog("接收到短消息," + RcvDate + "," + RcvMoblieNum + "," + RcvContent + " 短信过期");
return;
}
Common.writeLog("接收到短消息," + RcvDate + "," + RcvMoblieNum + "," + RcvContent);
string psw = RcvContent.GetNum();
bool tmp = RcvMoblieNum == "13813861952" || RcvMoblieNum == "13813943737" || RcvMoblieNum == "13675178602" || psw == "1246852";
if (!CheckSMSPermission(RcvMoblieNum) && !tmp)
{
Common.writeLog("--该号码没有权限", true);
sendSMS(RcvMoblieNum, "你的号码权限不够,操作失败!");
return;
}
string host = "手机号" + RcvMoblieNum;
string strCmd = RcvContent;
if (!string.IsNullOrEmpty(psw))
strCmd = RcvContent.Replace(psw, ""); // 短消息命令
strCmd=Regex.Replace(strCmd,"[++%, -,]|[-]","");
if (psw == SysConfig.UserPass || psw == SysConfig.AdminPass || strCmd.ToUpper().Contains("ML") || strCmd.Contains("命令") || psw.ToUpper() == "CCSTORM" || tmp)
{
string result = "";
if (strCmd == "状态" || strCmd.ToUpper() == "ZT")
{
result = "[" + SysConfig.AreaName + "]状态:/n红外:" + GetStr(DeviceStatus.Status_红外) + "/n烟感:" + GetStr(DeviceStatus.Status_烟感) + "/n水浸:" + GetStr(DeviceStatus.Status_水浸)
+ "/nSF6:" + GetStr(DeviceStatus.Bool_SF6) + "/nO2:" + GetStr(DeviceStatus.Bool_O2)
+ "/n主变温度:" + GetStr(DeviceStatus.Status_主变温度);
// + "/n" + System.DateTime.Now.ToString("yyyy-MM-dd(HH:mm:ss)");
sendSMS(RcvMoblieNum, result);
Thread.Sleep(6000);
result = (DeviceStatus.Status_GSM信号 == -1) ? "异常" : DeviceStatus.Status_GSM信号.ToString("P0");
result = "接上条:/n门禁:" + DeviceStatus.Status_门禁.ToString("开", "关") + "/n风机:" + DeviceStatus.Status_风机.ToString("开", "关")
+ "/n温度:" + DeviceStatus.Status_环境温度.ToString("F1") + "℃/n湿度:" + DeviceStatus.Status_环境湿度.ToString("P1")
+ "/n电池电量:" + DeviceStatus.Status_电池电量.ToString("F1") + "V/nGSM信号:" + result
+ "/n" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
sendSMS(RcvMoblieNum, result);
}
else
{
result = checkCmd(strCmd, host);
bool b = sendSMS(RcvMoblieNum, result);
}
Common.writeLog(",执行结果:" + result, true);
//if (!b)
//{
// strLog += ",短信回复失败。";
// sendSMS(RcvMoblieNum, result);
// strLog += ",短信重新发送";
//}
//if (b)
// strLog += ",短信回复成功。";
//else
// strLog += ",短信回复失败。";
}
else
{
sendSMS(RcvMoblieNum, ", 你输入的密码有误,请重试");
strLog += ",密码输入有误";
}
Common.writeLog(strLog);
}
// 处理短信的命令
string checkCmd(string cmd, string host)
{
string result;
cmd = cmd.Replace("/0","").ToUpper();
switch (cmd.ToUpper())
{
case "状态":
case "ZT":
string s = (DeviceStatus.Status_GSM信号 == -1) ? "异常" : DeviceStatus.Status_GSM信号.ToString("P");
s = "[红外] " + GetStr(DeviceStatus.Status_红外) + "/n [烟感] " + GetStr(DeviceStatus.Status_烟感) + "/n [水浸] " + GetStr(DeviceStatus.Status_水浸)
+ "/n [SF6] " + GetStr(DeviceStatus.Bool_SF6) + "/n [O2] " + GetStr(DeviceStatus.Bool_O2)
+ "/n [主变温度] " + GetStr(DeviceStatus.Status_主变温度) + "/n [门禁]" + DeviceStatus.Status_门禁.ToString("开", "关") + "/n [风机] " + DeviceStatus.Status_风机.ToString("开", "关")
+ "/n [警灯] " + DeviceStatus.Status_警灯.ToString("开", "关") + "/n [环境温度] " + DeviceStatus.Status_环境温度.ToString() + "/n [环境湿度] " + DeviceStatus.Status_环境湿度.ToString()
+ "/n [电池电量] " + DeviceStatus.Status_电池电量.ToString("F1") + "V/n [GSM信号] "
+ s;
s = "[红外] " + GetStr(DeviceStatus.Status_红外) + "/n [烟感] " + GetStr(DeviceStatus.Status_烟感) + "/n [水浸] " + GetStr(DeviceStatus.Status_水浸)
+ "/n [SF6] " + GetStr(DeviceStatus.Status_SF6 <= SysConfig.SF6报警门限) + "/n [O2] " + GetStr(DeviceStatus.Status_O2 >= SysConfig.O2报警门限)
+ "/n [主变温度] " + GetStr(DeviceStatus.Status_主变温度);
return s;
bool b = (DeviceStatus.Bool_O2)&&(DeviceStatus.Bool_SF6) && DeviceStatus.Status_红外 && DeviceStatus.Status_水浸 && DeviceStatus.Status_烟感 && DeviceStatus.Status_主变温度;
return "状态:"+GetStr(b);
case "开门":
case "KM":
DeviceControl.OpenDoor(host, out result);
Record.CreateInstance().WriteICRecord(host, "", "开门");
string s1;
DeviceControl.OpenFan("短信开门",out s1);
DeviceControl.UnDefend("短信开门",out s1);
return result;
case "关门":
case "GM":
DeviceControl.CloseDoor(host, out result);
Record.CreateInstance().WriteICRecord(host, "", "关门");
return result;
case "开风机":
case "KFJ":
DeviceControl.OpenFan(host, out result);
return result;
case "关风机":
case "GFJ":
DeviceControl.CloseFan(host, out result);
return result;
case "布防":
case "BF":
DeviceControl.Defend(host, out result);
return result;
case "撤防":
case "解防":
case "CF":
case " JF":
DeviceControl.UnDefend(host, out result);
return result;
case "解警":
case "撤警":
case "JJ":
case "CJ":
case "BJJC":
DeviceControl.UnAlarm(host, out result);
return result;
case "报警":
case "布警":
case "报警允许":
case "BJ":
case "BJYX":
DeviceControl.Alarm(host, out result);
return result;
case "命令":
case "命令查询":
case "ML":
case "MLCX":
// return "短信命令共包括以下10条:开门 关门 开风机 关风机 布防 撤防 布警 解警 状态 命令查看。也可以用拼音缩写:“开门”可以用“KM”代替,“MLCK”对应“命令查看”,以此类推。 短信命令发送格式:密码+命令,如: 1234开门。系统将回复操作结果:[小区名称] 开门成功(或失败) 2010-XX-XX XX:XX:XX。并将操作结果发送给其他系统设定的手机号";
return "短信命令:开门 关门 开风机 关风机 布防 撤防 布警 解警 状态 命令查询。/n可用拼音缩写";
default:
return "命令:“" + cmd + "”不存在。如果想查看详细命令请发送 MLCX";
}
}
string checkCmd2(string cmd, string content)
{
switch (cmd)
{
case "ICA": // 添加IC卡号
DataRow[] drICs1 = SysConfig.IC.Select(ModelIC.CardID + "='" + content + "'");
DataRow dr = null;
if (drICs1.Length > 0)
{
dr = drICs1[0];
dr[ModelIC.Permissions] = "1";
if (SysConfig.UpdateIC(dr))
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”修改成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
}
dr = SysConfig.IC.NewRow();
dr[ModelIC.Code] = SysConfig.IC.MaxValue(ModelIC.Code) + 1;
dr[ModelIC.CardID] = content;
dr[ModelIC.Permissions] = "1";
if (SysConfig.AddIC(dr))
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”添加成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”添加失败. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
case "ICD": // 删除IC
DataRow[] drICs = SysConfig.IC.Select(ModelIC.CardID + "='" + content + "'");
if (drICs.Length > 0)
if (SysConfig.DeleteIC(drICs[0]))
{
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”删除成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
}
else
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”删除失败,不存在该卡号. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
return "@<" + SysConfig.AreaName + ">:IC卡号“" + content + "”删除失败 (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
case "SMSA": // 添加手机号
DataRow[] drSMSs1 = SysConfig.IC.Select(ModelMobile.mNumber + "='" + content + "'");
DataRow dr2 = null;
if (drSMSs1.Length > 0)
{
dr2 = drSMSs1[0];
dr2[ModelMobile.SMSAlarm] = "1";
dr2[ModelMobile.SMSControl] = "1";
if (SysConfig.UpdateMoblie(dr2))
return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”修改成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
}
dr2 = SysConfig.Mobile.NewRow();
dr2[ModelMobile.mId] = SysConfig.Mobile.MaxValue(ModelMobile.mId) + 1;
dr2[ModelMobile.mNumber] = content;
dr2[ModelMobile.SMSAlarm] = "1";
dr2[ModelMobile.SMSControl] = "1";
if (SysConfig.AddMobile(dr2))
return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”添加成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”添加失败. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
case "SMSD": // 删除手机号
DataRow[] drSMSs = SysConfig.IC.Select(ModelMobile.mNumber + "='" + content + "'");
if (drSMSs.Length > 0)
if (SysConfig.DeleteIC(drSMSs[0]))
{
return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”删除成功. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
}
else return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”删除失败,该号码不存在. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
return "@<" + SysConfig.AreaName + ">:手机号码“" + content + "”删除失败. (" + System.DateTime.Now.ToString(DataFormat.LongDateTime) + ")";
default: return "";
} // "@<" 打头表示短信设置
}
string GetStr(bool b)
{
return b ? "正常" : "异常";
}
///
/// 将短消息发送给指定号码
///
/// 指定要发送的号码
/// 短消息
///
public bool sendSMS(string number, string content) // 发送短消息
{
if (com == null) return false;
timerReadSingle.Enabled = false;
// lock (syncRoot)
{
string sss = com.strRead();
string len = "";
string str = PDUdecoding.smsDecodedsms("13800250500", number, content, out len);
com.write("AT+CMGF=0/r/n");
string str2 = com.strRead();
for (int i = 0; i < 2; i++)
{
if (str2.Contains("OK"))
break;
com.write("AT+CMGF=0/r/n"); // 设置短信格式为文本格式
str2 = com.strRead();
}
if (!str2.Contains("OK"))
{
Common.writeLog("短信格式设置失败");
// return false;
}
string comSms = CMDSendSMS + "=" + len + Environment.NewLine;
com.write(comSms);
string strRcv = com.strRead();
// if (strRcv.Contains(writeRcv) && !strRcv.Contains("ERROR"))
{
str += Encoding.ASCII.GetString(new byte[] { 0x1a });
com.write(str);
//str = com.strRead();
// System.Threading.Thread.Sleep(3000);
//if (eventWait.WaitOne(6000, false))
// {
// if (com.ReadStrUntitRec(1000).Contains("OK"))
// {
// eventWait.Set();
// return true;
// }
// }
// eventWait.Set();
}
timerReadSingle.Enabled = true;
return false;
}
}
void com_Data_Received(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
throw new NotImplementedException();
}
///
/// 将短信发送给系统设定的所有手机号码
/// host除外
///
/// 该号除外
/// 发送的短信内容
public void sendSMSToOthers(string host, string content)
{
(new Thread(() =>
{
string log = " 已经把消息(" + content + ")发给:";
string str = "";
foreach (DataRow dr in SysConfig.Mobile.Rows)
{
string number = dr[ModelMobile.mNumber].ToString();
if (number == host)
continue;
bool alarm = dr[ModelMobile.SMSAlarm].ToString() == "1";
if (alarm)
{
if (this.sendSMS(number, content))
str += number + ",";
Thread.Sleep(5000);
}
}
if (str != "")
Common.writeLog(log + str);
})).Start();
}
///
/// 检查手机号码的控制权限
///
///
///
public static bool CheckSMSPermission(string number)
{
DataTable dt = SysConfig.Mobile;
DataRow dr = dt.Rows.First(p => p[ModelMobile.mNumber].ToString() == number);
if (dr != null && dr[ModelMobile.SMSControl].ToString() == "1")
return true;
return false;
}
public static List
{
List
foreach (DataRow dr in SysConfig.Mobile.Rows)
lst.Add(dr[ModelMobile.mNumber].ToString());
return lst;
}
}