⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atclib.cs

📁 使用gsm modem发送sms/wap push,同时也支持解析mms notification,从而可以使用普通gsm modem接收彩信
💻 CS
📖 第 1 页 / 共 2 页
字号:
			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 + -