this.port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived);
}
上面就是端口的配置,不同的modem可能配置不同,需要根据实际的modem进行设置。
public void Open()
{
if (!this.port.IsOpen)
this.port.Open();
if (!SupportAT)
throw new Exception("设备不支持AT指令");
if (!SupportCID)
throw new Exception("设备不支持来显");
}
public void Close()
{
if (this.port.IsOpen)
this.port.Close();
}
public bool SupportAT
{
get
{
this.port.WriteLine("AT");
System.Threading.Thread.Sleep(500);
string result = this.port.ReadExisting();
return result.ToUpper().Contains("OK");
}
}
public bool SupportCID
{
get
{
string[] commandList = Settings.Instance.SectionValues("CID");
string result = string.Empty;
foreach (string command in commandList)
{
this.port.WriteLine(command);
System.Threading.Thread.Sleep(500);
result = this.port.ReadExisting();
if (result.ToUpper().Contains("OK"))
{
return true;
}
}
return false;
}
}
这是一些方法和属性的实现。需要注意的是在发出指令后,最好能将线程堵塞一段时间,以保证有硬件足够的时间来响应,保证能够接收到完整的回复信息。这里的System.Threading.Thread.Sleep(500);就是这个目的。
void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string phoneNumber = this.port.ReadExisting();
Regex r = new Regex(@"NMBR\s*=\s*[0-9]*");
Match m = r.Match(phoneNumber);
string result = string.Empty;
if (m != null && m.Success)
{
result = m.Value;
result = result.Substring(result.IndexOf("=") + 1).Trim();
}
if (string.IsNullOrEmpty(result))
return;
if (Ring != null)
{
RingEventArgs eventArgs = new RingEventArgs();
eventArgs.PhoneNumber = result;
foreach (EventHandler<RingEventArgs> handler in Ring.GetInvocationList())
{
handler.Invoke(this, eventArgs);
if (eventArgs.Handled)
break;
}
}
}
Ring响铃事件实际上是根据DataReceived接收到的数据进行处理,比如判断是否是来电,截取来电的号码,然后事件冒泡,触发Ring事件。不同的modem返回回来的值肯能是不一样的。上面的正则表达是可能需要再次更改。(网上查到的是 = 号的左右有空格,可是我调试的那个modem却没有)