在.NET Compact Framework下開發3G應用可以有兩個options,1:AT command, 2:RAS。其實RAS最終也是通過AT command來管理3G裝置,RAS屏蔽了技術細節,很友善地建立TCP/IP based 的網絡連接配接,是以推薦使用RAS,WinCE本身提供了native API可以直接操作RAS,管理3G裝置及其連接配接。與此同時RAS也支援有線電話撥号,GPRS等應用。
RAS簡介

RAS的詳細介紹見 Overview of RAS
由于.NET Compact Framework 不直接提供RAS元件,是以隻能通過native invoke來使用RAS。
RAS的native調用函數,事件及結構見 RAS Reference
關鍵的RAS native調用
[DllImport( " coredll.dll " , CharSet = CharSet.Auto)]
private static extern Int32 RasGetEntryDialParams( string lpszPhoneBook,
byte [] lpRasDialParams,
out UInt32 lpfPassword);
[DllImport( " coredll.dll " , CharSet = CharSet.Auto)]
private static extern int RasDial(IntPtr pDialExtensions,
string pPhonebook,
byte [] pRasDialParam,
uint pNotifierType,
IntPtr pHwnd,
ref int pRasConn);
[DllImport( " coredll.dll " , CharSet = CharSet.Auto)]
private static extern int RasHangUp( int pSession);
[DllImport( " coredll.dll " , CharSet = CharSet.Auto)]
private static extern uint RasGetConnectStatus( int pSession,
byte [] lpRasConnStatus);
RasGetEntryDialParams 取得原先配置的連接配接項,可以在手工建立連接配接或者修改系統資料庫建立連接配接項(Connection Entry)。這個函數的關鍵作用是從連接配接項取出配置好的撥号密碼。
RasDial 撥号到電信營運商的網絡上。
RasHangUp 挂斷連接配接。
RasGetConnectStatus 取目前的連接配接狀态。
RAS 事件
在調用RasDial 時,如果uint pNotifierType傳遞0xFFFFFFFF,那麼IntPtr pHwnd可以注冊一個事件接受的Handler。當連接配接狀态發生改變時,windows會把相應的事件發送給這個handler,這樣我們可以接收這些事件,把之變成delegate來通知clients。這樣就實作了一個Observer模式,client可以通過訂閱來實時得到連接配接狀态的變更狀況。
要把windows event變成C#的delegate,要繼承MessageWindow class,然後override WndProc(ref Message pMsg),同時定義C#的delegate和event把windows事件變成delegate提供給client訂閱。
public class RasManager : MessageWindow
{
public delegate void NotifyEvent();
public event NotifyEvent OnConnectedEvent;
public event NotifyEvent OnDisconnectedEvent;
protected override void WndProc( ref Message pMsg)
{
if (pMsg.Msg == WM_RASDIALEVENT)
{
switch (( int )pMsg.WParam)
{
case ( int )RASCONNSTATE.RASCS_OpenPort:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_PortOpened:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_ConnectDevice:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_DeviceConnected:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AllDevicesConnected:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_Authenticate:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthNotify:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthRetry:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthCallback:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthChangePassword:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthProject:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthLinkSpeed:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_AuthAck:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_ReAuthenticate:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_Authenticated:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_PrepareForCallback:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_WaitForModemReset:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_WaitForCallback:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_Projected:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_Interactive:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_RetryAuthentication:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_CallbackSetByCaller:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_PasswordExpired:
{
break ;
}
case ( int )RASCONNSTATE.RASCS_Connected:
{
OnConnected();
break ;
}
case ( int )RASCONNSTATE.RASCS_Disconnected:
{
OnDisconnected();
break ;
}
default :
{
break ;
}
}
}
base .WndProc( ref pMsg);
}
RASCS_Disconnected windows 事件轉換成OnConnected C# event, 而RASCS_Disconnected windows 事件轉換成OnDisconnectedC# event。
Client 的調用
事件注冊可以放在Client 的Constructor上執行
RasManager.Instance.OnConnectedEvent +=
new RasManager.NotifyEvent(Form1_OnConnectedEvent);
RasManager.Instance.OnDisconnectedEvent +=
new RasManager.NotifyEvent(Form1_OnDisconnectedEvent);
連接配接3G網絡
RasManager.Instance.DialUp( " 3G Connection " , null , null );
斷開連接配接
RasManager.Instance.HangUp();
查詢連接配接狀态
RasManager.RASCONNSTATE rasConnState =
(RasManager.RASCONNSTATE) RasManager.Instance.GetStatus();
這個類同樣可以使用于GPRS裡面。
作者: Jake Lin( Jake's Blog on 部落格園)
出處: http://procoder.cnblogs.com/