📄 atclib.cs
字号:
using System;
using System.Text;
using System.Threading;
using System.Data.SqlTypes;
using System.Globalization;
namespace ATCLib
{
/// <summary>
/// ATC 的摘要说明。
/// </summary>
public class ATC
{
// 成员
public IntPtr _hComm =IntPtr.Zero; //串口句柄
// cnt属性
public string CommPort="";
private int ComBaudRate =0;
UnicodeEncoding Ue = new UnicodeEncoding(true,false);
public ATC()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 端口操作
public bool Open(string Port,int BaudRate)
{
CommPort = Port;
ComBaudRate = BaudRate;
/* 端口编号为10以上的 需要使用\\.\COM10,这里统一修改为此种格式 */
string szSpecPort = @"\\.\"+ Port;
_hComm =Win32Com.CreateFile(szSpecPort,Win32Com.GENERIC_READ|Win32Com.GENERIC_WRITE,0,IntPtr.Zero,
Win32Com.OPEN_EXISTING,0,IntPtr.Zero);
if( _hComm == (IntPtr)Win32Com.INVALID_HANDLE_VALUE)
{
_hComm =IntPtr.Zero;
return false;
}
// 设置端口属性
Win32Com.DCB dcb = new Win32Com.DCB();
if( !Win32Com.GetCommState(_hComm,out dcb))
{
CloseComm();
return false;
}
dcb.BaudRate = BaudRate;
dcb.ByteSize =8;
dcb.Parity =0;
dcb.StopBits =0;
if(!Win32Com.SetCommState(_hComm,ref dcb))
{
CloseComm();
return false;
}
// 设置端口超时
Win32Com.COMMTIMEOUTS CommTimeouts = new Win32Com.COMMTIMEOUTS();
if( !Win32Com.GetCommTimeouts(_hComm, out CommTimeouts))
{
CloseComm();
return false;
}
// 有超时控制
CommTimeouts.ReadIntervalTimeout = 100;
CommTimeouts.ReadTotalTimeoutConstant = 500;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier =10;
if( !Win32Com.SetCommTimeouts(_hComm,ref CommTimeouts))
{
CloseComm();
return false;
}
// 简单AT 指令测试
string sRecv = AtCmd("AT\r\n");
if( sRecv.Length ==0 || sRecv.IndexOf("OK") == -1)
{
CloseComm();
return false;
}
return true;
}
public void CloseComm()
{
Win32Com.CloseHandle(_hComm);
}
public bool ReOpen()
{
CloseComm();
return Open(CommPort,ComBaudRate);
}
// 发送字节数组
private int WriteData(byte[] tosend,int len)
{
uint sent = 0;
if (!Win32Com.WriteFile(_hComm,tosend,(uint)len,out sent, IntPtr.Zero))
{
return 0;
}
Win32Com.FlushFileBuffers(_hComm);
return (int)sent;
}
// 接收
private string RecvComm()
{
byte[] bRx = new byte[128];
Int32 nRead =0;
string szReturn ="";
if(Win32Com.ReadFile(_hComm,bRx,128,out nRead,IntPtr.Zero))
{
if(nRead >0)
szReturn= Encoding.ASCII.GetString(bRx,0,nRead);
}
return szReturn;
}
// 写入ASCII字符串,发送AT指令
private int SendAtCmd(string Cmd)
{
byte[] b = new byte[Cmd.Length];
b = Encoding.ASCII.GetBytes(Cmd);
int sentLen = WriteData(b,b.Length);
return sentLen;
}
// 发送At指令并返回响应内容
public string AtCmd(string Cmd)
{
string szReturn=string.Empty;
if( SendAtCmd(Cmd) >0)
szReturn = RecvComm();
return szReturn;
}
#endregion
#region Tools
// 增加字节
private byte[] AppendOct(byte[] bys,byte[] byDest)
{
byte[] bysNew =new byte[byDest.Length +bys.Length];
try
{
Array.Copy(byDest,bysNew,byDest.Length);
Array.Copy(bys,0,bysNew,byDest.Length,bys.Length);
}
catch(Exception e)
{
Console.WriteLine(e);
}
return bysNew;
}
// 号码按照GSM规范编码
private string GsmInvertNumbers(string Mobile)
{
StringBuilder sb =new StringBuilder();
for(int i=0;i<Mobile.Length;i+=2)
{
if( (i+1)< Mobile.Length)
sb.Append(Mobile[i+1]);
else
sb.Append('F');
sb.Append(Mobile[i]);
}
return sb.ToString();
}
// 号码按照GSM规范解码
private string GsmSerializeNumbers(string Data)
{
StringBuilder sb =new StringBuilder();
for(int i=0;i<Data.Length;i+=2)
{
sb.Append(Data[i+1]);
if( Data[i] !='F')
{
sb.Append(Data[i]);
}
}
return sb.ToString();
}
// 字节转可打印字符
private string Bytes2Txt(byte[] byData)
{
string sTxt ="";
for(int i=0;i<byData.Length;i++)
{
sTxt +=byData[i].ToString("X2");
}
return sTxt;
}
// Txt2Byte 即把06050B 等字符串转成
private byte[] Txt2Bytes(string sTxt)
{
if( SqlInt32.Mod(sTxt.Length,2) != 0)
return null;
byte[] byBuffer = new byte[sTxt.Length /2];
for(int i=0;i<sTxt.Length/2;i++)
{
byBuffer[i] = (byte)Int32.Parse(sTxt.Substring(i*2,2),NumberStyles.AllowHexSpecifier);
}
return byBuffer;
}
// 从字节数组中获取以0x00结尾的字符串
private string GetTextString(byte[] bys,ref int at)
{
string sz = string.Empty;
int Len =0;
while(bys[at++]!=0x00)
Len++;
byte[] byBody=new byte[Len];
Array.Copy(bys,at-Len-1,byBody,0,Len);
sz = Encoding.ASCII.GetString(byBody); // ASCII编码
return sz;
}
#endregion
#region 短信部分
// 短信业务相关指令
public int RecvSMS()
{
int Count =0;
if(SendAtCmd("AT+CMGL=4\r\n") >0)
{
int nTrytimes =0;
string szResp="";
while( nTrytimes< 1) // list all sms,反馈比较多,因此等待时间稍长
{
string sRecv = RecvComm();
if( sRecv.Length >0)
szResp += sRecv;
else
nTrytimes++;
}
string szResult=ParseSmsResp(szResp);
if( szResult.StartsWith("2 "))
Count = Int32.Parse(szResult.Substring(2));
}
return Count;
}
// 清除制定位置短信
void RemoveSms(int at)
{
if(SendAtCmd("AT+CMGD=" + at.ToString() +"\r\n") >0)
{
int nTrytimes =0;
while(nTrytimes<2)
{
string sRecv = RecvComm();
if( sRecv.Length >0)
{
ParseSmsResp(sRecv);
break;
}
nTrytimes++;
}
}
}
// 解析短信回应
private string ParseSmsResp(string szResp)
{
string szReturn ="";
int nNewSms =0;
string[] sl= szResp.Split(new char[]{'\r','\n'});
for(int i=0;i<sl.Length;i++)
{
string s = sl[i];
if( s.Length==0)
continue;
if( s.IndexOf("+CMGS:") >-1 ) // 继续
{
szReturn ="0 " + s;
break;
}
else if(s.IndexOf("ERROR") > -1)
{
szReturn="1 "+ s;
break;
}
else if( s.IndexOf("+CMGL:") >-1) // list sms
{
int at = s.IndexOf(",");
if( at>0)
{
string szPos = s.Substring(6,at-6).Trim();
i+=2;
// 解析新短信内容
ParseSmsMsg(sl[i]);
// 删除指定位置的短信
RemoveSms(Int32.Parse(szPos));
nNewSms ++;
}
}
else
{
// 未能识别的内容
//AddRunInfo(s);
Console.WriteLine(s);
}
}
if( nNewSms >0 ) // 如果接受到新的短信,则返回新的短信数量
szReturn ="2 "+ nNewSms.ToString();
return szReturn;
}
// 解析短信内容
void ParseSmsMsg(string Msg)
{
string sOrg =string.Empty; // 发送者
string sTxt =string.Empty; // 消息内容
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -