📄 atclib.cs
字号:
byte[] bys = Txt2Bytes(Msg);
int at =0;
// 短信中心
int nLen = bys[at++];
at += nLen;
// First-Octet
byte b = bys[at++];
// TP-OA
nLen = bys[at++]; // 号码个数
if( bys[at++]==0x91) // 0x91表示国际号码,前有+,如果是0xA1,则表示号码为国内号码
sOrg +="+";
int OALen =0;
if( SqlInt32.Mod(nLen,2) ==0)
OALen = nLen/2;
else
OALen = nLen/2 +1;
byte[] bysOA = new byte[OALen];
Array.Copy(bys,at,bysOA,0,OALen);
sOrg += GsmSerializeNumbers(Bytes2Txt(bysOA));
at += OALen;
// TP-PID
b = bys[at++];
// TP-DCS
int nDCS = bys[at++];
// TP-SCTS
at += 7; // 固定长度7位,Year,Month,Day,Hour,Minute,Second,TimeZone
// TP-UDL
nLen = bys[at++]; // 信息内容的字节长度
// TP-UD
if( nDCS ==8)
{
// UCS2编码,文字短信
UnicodeEncoding ue=new UnicodeEncoding(true,false);
sTxt =ue.GetString(bys,at,nLen);
AddRunInfo(string.Format("Sms {0} {1}",sOrg,sTxt));
}
else if( nDCS ==4)
{
// 二进制信息,当做mms notification解析
byte[] byUD= new byte[nLen];
Array.Copy(bys,at,byUD,0,nLen);
try
{
sTxt =ParseMmsNotification(byUD,ref sOrg);
AddRunInfo(string.Format("Mms {0} {1}",sOrg,sTxt));
// 使用网络连接获取mms
}
catch(Exception e)
{
AddRunInfo(e.Message);
}
}
}
// 接收到Mms Notification,返回mms message获取地址
//0605040B8423F02006246170706C69636174696F6E2F766E642E7761702E6D6D732D6D65737361676500B487AF848C82984F4C576468484A5A734F7142008D9083687474703A2F2F3231312E3133392E3134342E3138312F4F4C576468484A5A734F7142008805810302A30089178031333537303234313331392F545950453D504C4D4E008A808E020150
private string ParseMmsNotification(byte[] bys,ref string Org)
{
string Url =string.Empty;
int at =0;
// WSP协议
int nLen = bys[at++];
at += nLen;
// 消息类型
at +=2;
// ContenType Length
nLen = bys[at];
at ++;
// ContenType
byte[] bysContentType= new byte[nLen];
Array.Copy(bys,at,bysContentType,0,nLen);
string sContentType = Encoding.ASCII.GetString(bysContentType);
at += nLen;
if(sContentType.StartsWith("application/vnd.wap.mms-message"))
{
byte b;
// Actual MMS notification message starts
while(at< bys.Length)
{
switch(bys[at])
{
case 0x8C: // X-MMS-Message-Type
at++;
b = bys[at++];
break;
case 0x98: //X-Mms-Transaction-ID
at++;
string TransID = GetTextString(bys,ref at);
break;
case 0x8D: // X-Mms-MMS-Version
at+=2;
break;
case 0x89: // From
at++;
nLen = bys[at++];
if( bys[at++] == 0x80)
{
//Address-present-token Encoded-string-value
Org = GetTextString(bys,ref at);
Org = Org.Replace("/TYPE=PLMN","");
}
else
at += (nLen-1);
break;
case 0x96: // Subject
at++;
string Subject = GetTextString(bys,ref at);
break;
case 0x8A: // X-Mms-Message-Class
at+=2;
break;
case 0x8E: // X-Mms-Message-Size
at++;
nLen = bys[at++];
at += nLen;
break;
case 0x88: // X-Mms-Expiry
at++;
nLen = bys[at++];
at += nLen;
break;
case 0x83: // X-Mms-Content-Location
at++;
Url= GetTextString(bys,ref at);
break;
}
}
}
return Url;
}
// 发送GSM信息,使用PDU方式,发送给手机号码
/*
08 SMSC地址信息的长度 共8个八位字节(包括91)
91 SMSC地址格式(TON/NPI) 用国际格式号码(在前面加‘+’)
68 31 08 20 05 05 F0 SMSC地址 8613800250500,补‘F’凑成偶数个
11 基本参数(TP-MTI/VFP) 发送,TP-VP用相对格式
00 消息基准值(TP-MR) 0
0D 目标地址数字个数 共13个十进制数(不包括91和‘F’)
91 目标地址格式(TON/NPI) 用国际格式号码(在前面加‘+’)
68 31 58 81 27 64 F8 目标地址(TP-DA) 8613851872468,补‘F’凑成偶数个
00 协议标识(TP-PID) 是普通GSM类型,点到点方式
00 用户信息编码方式(TP-DCS) 7-bit编码
00 有效期(TP-VP) 5分钟
06 用户信息长度(TP-UDL) 实际长度6个字节
C8 32 9B FD 0E 01 用户信息(TP-UD) “Hello!”
联通测试用
AT+CMGS=19
0891683110808805F011000D91683128251715F1000800044F60597D
移动测试,上海卡发送到5388
AT+CMGS=
0891683108200105F01100069168358800080004004C0053
*/
public int SendSMS_GSM(string Mobile,string Txt)
{
int nResult =-1;
// Address of the SMSC
byte[] bysPdu = new byte[]{0x00};
//byte[] bysPdu = new byte[]{0x08,0x91};
//bysPdu = AppendOct(Txt2Bytes(GsmInvertNumbers(AddrSMSC)),bysPdu);
//int lenSMSC = bysPdu.Length;
// TPDU
bysPdu = AppendOct(new byte[]{0x11,0x00},bysPdu);
// 增加Dest
if( (!Mobile.StartsWith("86")) && Mobile.Length ==11) // 手机号码使用 +86
Mobile= Mobile.Insert(0,"86");
byte[] byLenDest = new byte[]{0x00,0x91};
byLenDest[0] = (byte)Mobile.Length;
if( !Mobile.StartsWith("86"))
byLenDest[1] = 0xA1; // 使用国内号码,深圳卡需要
bysPdu = AppendOct(byLenDest,bysPdu);
bysPdu = AppendOct(Txt2Bytes(GsmInvertNumbers(Mobile)),bysPdu);
//
bysPdu = AppendOct(new byte[]{0x00,0x08,0x00},bysPdu);
byte[] UD = Ue.GetBytes(Txt);
byte[] byLenData = new byte[1];
byLenData[0] = (byte) UD.Length;
bysPdu = AppendOct(byLenData,bysPdu);
bysPdu = AppendOct(UD,bysPdu);
string sAt = string.Format("AT+CMGS={0}\r",bysPdu.Length-1); // 结尾的0x1A不包含在长度内
if( SendAtCmd(sAt)>0)
{
string sRecv = RecvComm();
if(sRecv.IndexOf("\r\n> ") >-1)
{
if( SendAtCmd(Bytes2Txt(bysPdu) + Encoding.ASCII.GetString(new byte[]{0x1A}))>0)
{
int TryTimes =0;
while(TryTimes <5)
{
string sRecv2 = RecvComm();
if( sRecv2.Length ==0)
{
TryTimes ++;
continue;
}
string szResult =ParseSmsResp(sRecv2);
if( szResult.StartsWith("0 "))
{
AddRunInfo(szResult);
nResult=0; // 成功
break;
}
else if(szResult.StartsWith("1 "))
{
AddRunInfo(szResult);
Thread.Sleep(4000); // 暂停4s
// 清除sms
//ClearSms();
break; // 失败
}
}
if( TryTimes ==5)
{
AddRunInfo("发送后等待响应超时");
Thread.Sleep(1000);
}
}
else
{
AddRunInfo("Com Data Write Error");
Thread.Sleep(1000);
}
}
else
{
AddRunInfo("Get Error Response,"+ sRecv);
Thread.Sleep(1000);
}
}
else
{
AddRunInfo("Com Data Write Error");
Thread.Sleep(1000);
}
return nResult;
}
#endregion
#region 语音呼叫部分
// 语音呼叫
public bool Dial(string Number)
{
if(SendAtCmd("ATD"+ Number +";\r\n") >0)
{
int TryTimes =0;
while(TryTimes <5)
{
string sRecv = RecvComm();
if( sRecv.Length ==0)
{
TryTimes++;
continue;
}
string szResult = ParseDialResp(sRecv);
if(szResult.StartsWith("0 "))
return true;
else if( szResult.StartsWith("1 "))
return false;
}
}
return false;
}
public void HangUp()
{
if(SendAtCmd("ATH\r\n") >0)
{
int TryTimes =0;
while(TryTimes <5)
{
string sRecv = RecvComm();
if( sRecv.Length ==0)
{
TryTimes++;
continue;
}
string szResult = ParseDialResp(sRecv);
if(szResult.StartsWith("0 "))
break;
else if( szResult.StartsWith("1 "))
break;
}
}
}
private string ParseDialResp(string Msg)
{
string szReturn =string.Empty;
string[] sl= Msg.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("OK") >-1 ) // 继续
{
szReturn ="0 " + s;
break;
}
else if(s.IndexOf("ERROR") > -1)
{
szReturn="1 "+ s;
break;
}
else
AddRunInfo(s);
}
return szReturn;
}
#endregion
public void AddRunInfo(string Msg)
{
MobileSim.MainWnd.frm.AddRunInfo(Msg);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -