我們現在的模組用的是USB介面,然後類比成一個COM6進行通訊,在CE的: 控制台->網路連接 裡要建立一個串連,選擇“撥號連線”然後設定好地區代碼,還有附加解調器命令+CGDCON,"IP","CMNET",modem選擇,與modem的串口通訊速率等資訊,然後串連,這上可以實現上網。
添加的CE組件有:
CoreOS->Windwos CE devices->commuication services and newworking->networking-wide area network ->Dial up networking
->Autodail
->TAPI
->Virtual Private Networking(VPN)
我們現在要實現的功能是,讓使用者只點擊一個ICON,就能實現上網,不用這麼麻煩去設定。
我寫了一個應用,通過RAS 介面調用可以實現撥接功能,但是,必須指定一個已建立並設好參數的串連,
所以,還得在程式中建立一個網路連接才行,因為我們需要的簡化的其實就是讓使用者輸入附加撥號命令(+CGDCONT=1,"IP","CMNET"那麼一長串,其實只需要使用者輸入一個APN和一個電話號碼就OK了)。因為針對不同的電訊廠商,這個APN是不同的,所以這個要能給使用者佈建。
查MSDN得知,調用RasSetEntryProperties加上RasSetEntryDialParams可以實現,但是這種方法貌似設定不了modem的串口屬性、附加撥號命令等一些資訊,
用RasSetEntryProperties設定一個Entry的屬性的時候,如果Entry的參數中指定的EntryName已經存在了,那麼就更改已有的Entry的設定,如果不存在,則建立了一個新的Entry,這樣就實現了建立撥號連線的功能,
MSDN上關於RasSetEntryProperties函數中的倒數第二個參數的解釋說明是說它是一個指向包含裝置配置資訊的緩衝區的指標,是關於設modem的串口屬性、附加撥號命令等,
但是要查閱關於這個配置資訊的更多詳細內容,就要看TAPI相關的lineGetDevConfig函數,但是TAPI相關知識是相當龐大的一個體系,因為項目時間很緊,
直接在WINCE系統裡的控制台下,進入“網路和撥號連線”,手動建立一個能撥通上網的串連,我命名為“3GCONNECT”
然後寫測試程式,調用RasGetEntryProperties()函數,在倒數第二個參數傳一個數組,然後列印出正確設定時的lpb裡面的值,結果如下:
- lpb 0x001aed00 "0" unsigned char[436]
[0x0] 0x30 '0' unsigned char
[0x1] 0x00 '' unsigned char
[0x2] 0x00 '' unsigned char //等待信用卡音頻訊號時間
[0x3] 0x00 '' unsigned char
[0x4] 0x78 'x' unsigned char //120 秒這時間之內未建立串連,則取消撥號
[0x5] 0x00 '' unsigned char
[0x6] 0x00 '' unsigned char
[0x7] 0x00 '' unsigned char
[0x8] 0x00 '' unsigned char //串口參數:流量控制,0 -- 無 0x20 軟體 0x10 硬體
[0x9] 0x01 'r' unsigned char
[0xa] 0x00 '' unsigned char
[0xb] 0x00 '' unsigned char
[0xc] 0x00 '' unsigned char //串口傳輸速率 19200
[0xd] 0x4b 'K' unsigned char
[0xe] 0x00 '' unsigned char
[0xf] 0x00 '' unsigned char
[0x10] 0x00 '' unsigned char // 對應“裝置屬性”對話方塊中的“手動撥號(使用者提供撥號串)”,
//如果為0x04 表示選上此項
[0x11] 0x00 '' unsigned char
[0x12] 0x08 '' unsigned char //串口資料位元 8位
[0x13] 0x00 '' unsigned char //停止位,00- 1位, 02 - 2位
[0x14] 0x00 '' unsigned char //同位位元,00-無,01奇數,02偶數,03標記,04空格
[0x15] 0x00 '' unsigned char
[0x16] 0x2b '+' unsigned char
[0x17] 0x00 '' unsigned char
[0x18] 0x43 'C' unsigned char
[0x19] 0x00 '' unsigned char
[0x1a] 0x47 'G' unsigned char
[0x1b] 0x00 '' unsigned char
[0x1c] 0x44 'D' unsigned char
[0x1d] 0x00 '' unsigned char
[0x1e] 0x43 'C' unsigned char
[0x1f] 0x00 '' unsigned char
[0x20] 0x4f 'O' unsigned char
[0x21] 0x00 '' unsigned char
[0x22] 0x4e 'N' unsigned char
[0x23] 0x00 '' unsigned char
[0x24] 0x54 'T' unsigned char
[0x25] 0x00 '' unsigned char
[0x26] 0x3d '=' unsigned char
[0x27] 0x00 '' unsigned char
[0x28] 0x31 '1' unsigned char
[0x29] 0x00 '' unsigned char
[0x2a] 0x2c ',' unsigned char
[0x2b] 0x00 '' unsigned char
[0x2c] 0x22 '"' unsigned char
[0x2d] 0x00 '' unsigned char
[0x2e] 0x49 'I' unsigned char
[0x2f] 0x00 '' unsigned char
[0x30] 0x50 'P' unsigned char
[0x31] 0x00 '' unsigned char
[0x32] 0x22 '"' unsigned char
[0x33] 0x00 '' unsigned char
[0x34] 0x2c ',' unsigned char
[0x35] 0x00 '' unsigned char
[0x36] 0x22 '"' unsigned char
[0x37] 0x00 '' unsigned char
[0x38] 0x43 'C' unsigned char
[0x39] 0x00 '' unsigned char
[0x3a] 0x4d 'M' unsigned char
[0x3b] 0x00 '' unsigned char
[0x3c] 0x4e 'N' unsigned char
[0x3d] 0x00 '' unsigned char
[0x3e] 0x45 'E' unsigned char
[0x3f] 0x00 '' unsigned char
[0x40] 0x54 'T' unsigned char
[0x41] 0x00 '' unsigned char
[0x42] 0x22 '"' unsigned char
[0x43] 0x00 '' unsigned char
[0x44] 0x00 '' unsigned char後面的全為0
經過改不同的參數然後以上面的方法打出這個參數傳回來的值,總結出
所以總結出以下結構體:
typedef struct
{ //offerset
U16INT Reserved1; //0 一般為0x30
U16INT WaitForCreditcard; //0x02 等待信用卡音頻訊號時間,單位 ;秒
U16INT WaitForConnect; //0x04 這時間之內未建立串連,則取消撥號
U16INT Reserved2; //0x06 一般為0
UINT8 Flowcontrol; // 0x08 串口參數:流量控制,0 -- 無 0x20 軟體 0x10 硬體
UINT8 Unknow1; // 0x09 一般為1,暫時還不知它是什麼作用
U16INT Reserved3; // 0x0a = 00
U16INT BaudRate; //0x0c 串口傳輸速率例如 19200
U16INT Reserved4; // 0x0e =0
U16INT Configbit2; // 0x10 // 對應“裝置屬性”對話方塊中的“手動撥號(使用者提供撥號串)”,如果為0x04 表示選上此項
UINT8 DataBit; // 0x12 串口資料位元 例如:8位
UINT8 StopBit; // 0x13 停止位00- 1位, 02 - 2位
UINT8 ParityBit; // 0x14 同位位元00-無,01奇數,02偶數,03標記,04空格
UINT8 Reserved5; // 0x15 i don't know it's function
TCHAR AttachedCmd[210]; // 0X16 從這開始是附加解調器命令,例如"+CGDCON=1,IP,COMNET"
//注意:本人使用的是wince6.0,所以這個長度為436byte,其它平台可能會不一樣,網上有牛人測出WM的是一百多的
}RASlpdInfo;
用這個結構在AttachedCmd中填入附加撥號命令,就可以了
DWORD dwSize,
dwError;
TCHAR szError[100];
RASlpdInfo lpb;
unsigned long lpbSize = sizeof(RASlpdInfo);
memset(&lpb,0,lpbSize);
RASENTRY RasEntry;
dwSize = sizeof (RASENTRY);
memset (&RasEntry, 0, dwSize);
RasEntry.dwSize = dwSize;
wcscpy(RasEntry.szDeviceName,L"CDMAModem");
wcscpy(RasEntry.szDeviceType,L"modem"); //#define RASDT_Modem TEXT("modem") // Ras.h
RasEntry.dwCountryCode = 86; //國家代碼
wcscpy(RasEntry.szAreaCode,L"10");
TCHAR szLocalPhoneNumber[RAS_MaxPhoneNumber + 1] = {0};
wsprintf(szLocalPhoneNumber,L"%s",LocNum); //-------------------容易出問題的地方
wcscpy(RasEntry.szLocalPhoneNumber,szLocalPhoneNumber );
RasEntry.dwfOptions= 4194304;//RASEO_ProhibitEAP|RASEO_RemoteDefaultGateway; ;//4194304;0x00400208;//
RasEntry.dwfNetProtocols= RASNP_Ip;//4; Negotiate TCP/IP
RasEntry.dwFramingProtocol= RASFP_Ppp;//1; // Point-to-Point Protocol (PPP)
lpb.Reserved1 = 0x30;
lpb.WaitForCreditcard = 0;
lpb.WaitForConnect =120;
lpb.Reserved2 = 0;
lpb.Flowcontrol = 0;
lpb.Unknow1 = 1;
lpb.Reserved3 = 0;
lpb.BaudRate = 19200;
lpb.Reserved4 = 0;
lpb.Configbit2 = 0;
lpb.DataBit = 8;
lpb.StopBit = 0;
lpb.ParityBit = 0;
TCHAR szATComd[420] = {0};
wsprintf(szATComd,L"+CGDCONT=1,$IP$,$%s$",lpszAPN);
szATComd[11] = 0x22; // 雙引號"
szATComd[14] = 0x22;
szATComd[16] = 0x22;
szATComd[22] = 0x22;
wcscpy(lpb.AttachedCmd,szATComd);
if (dwError = RasSetEntryProperties (NULL, lpszName,
&RasEntry, sizeof (RASENTRY),(LPBYTE)(&lpb), lpbSize))
{
wsprintf (szError, TEXT("Unable to create the phonebook entry.")
TEXT(" Error %ld"), dwError);
return FALSE;
}
注意,WINCE6.0調用了RasSetEntryProperties()之後,就可以在控制台的串連管理裡看到這個串連表徵圖了,但是,如果是在WM系統,那就得再做下面的工作才能看得到表徵圖。
機器中控制台的”管理現有串連“對應註冊表中
HKEY_LOCAL_MACHINE\\Comm\\ConnMgr\\Providers\\{7C4B7A38-5FF7-4bc1-80F6-5DA7870BB1AA}\\Connections
[Connections]下的集合;
[Enabled]: 是否為預設串連;
[RequirePW] 是否需要使用者名稱與密碼
[DestId]: 表示屬於哪種類型的串連;
[ConnectionGUID]:表示串連的標識ID,
拔號時獲得目前狀態
如果想在拔號時獲得目前狀態,可以這樣:
攔截PreTranslateMessage這個訊息事件,截獲WM_RASDIALEVENT訊息即可達到目的
BOOL CMy3GControlerDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_RASDIALEVENT)
{
switch(pMsg->wParam)
{
case RASCS_OpenPort:
pShowstate->SetWindowTextW(_T("開啟連接埠…"));
break;
case RASCS_PortOpened:
pShowstate->SetWindowTextW(_T("連接埠已開啟…"));
break;
case RASCS_ConnectDevice:
break;
case RASCS_DeviceConnected:
pShowstate->SetWindowTextW(_T("裝置已串連…"));
break;
case RASCS_Authenticate:
pShowstate->SetWindowTextW(_T("驗證使用者及密碼…"));
break;
case RASCS_Authenticated:
pShowstate->SetWindowTextW(_T("使用者及密碼已通過驗證"));
break;
case RASCS_Connected:
pShowstate->SetWindowTextW(_T("已串連"));
break;
case RASCS_Disconnected:
pShowstate->SetWindowTextW(_T("中斷連線"));
break;
default:
return (LRESULT)0;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
RAS撥號的同步和非同步問題
dwRet = RasDial(NULL,NULL,&rdParams,0L,NULL,&m_hRasConn);//同步
dwRet = RasDial(NULL,NULL,&rdParams,0L,RasDialFunc,&m_hRasConn);//非同步回調 --只支援在PC
dwRet = RasDial(NULL,NULL,&rdParams,0xFFFFFFFF,this->m_hWnd,&m_hRasConn); //非同步訊息--支援PC、CE
如果同步,可用線程監視同步過程,
非同步:只在使用了PreTranslateMessage才成功
所以,在CE系統裡,要實現串連狀態顯示,那就得使用
dwRet = RasDial(NULL,NULL,&rdParams,0xFFFFFFFF,this->m_hWnd,&m_hRasConn);
撥號連線
void DialRAS(LPVOID Hahandle,LPWSTR ConnectionName,LPWSTR PhoneNumber)
{
RASDIALPARAMS RasDialParams;
BOOL fPassword;
memset (&RasDialParams, 0, sizeof (RASDIALPARAMS));
RasDialParams.dwSize = sizeof(RASDIALPARAMS);
wcscpy(RasDialParams.szEntryName,ConnectionName); //已建串連的名字
TCHAR szLocalPhoneNumber[RAS_MaxPhoneNumber + 1] = {0};
wsprintf(szLocalPhoneNumber,L"%s",PhoneNumber);
wcscpy(RasDialParams.szPhoneNumber,szLocalPhoneNumber);
wcscpy(RasDialParams.szCallbackNumber, _T(""));
wcscpy(RasDialParams.szUserName, _T(""));
wcscpy(RasDialParams.szPassword, _T(""));
wcscpy(RasDialParams.szDomain, _T(""));
CMy3GControlerDlg* hthisp =(CMy3GControlerDlg*)Hahandle;
DWORD hRasRet = 0;
// Try to establish RAS connection.
hRasRet = RasDial (NULL, // Extension not supported
NULL, // Phone book is in registry
&RasDialParams, // RAS configuration for connection
0xFFFFFFFF, // Notifier type is a window handle
hthisp->m_hWnd, // Window receives notification message
&hRscon);
printf("hRasRet == %d ", hRasRet);
if ( hRasRet != 0) // Connection handle
{
printf("Could not connect using RAS, error == %d ", GetLastError());
}
}
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/ok138ok/archive/2009/12/03/4933061.aspx