WinCE6 建立APN拨号连接的经验分享

来源:互联网 发布:淘宝小二判决申诉 编辑:程序博客网 时间:2024/05/20 17:40

    前天项目经理安排我做Wince6下面的APN拨号连接,任务很急,但我对APN一点概念都没有,之前经理也收集了一些资料代码,另外iPhone项目组的同事也提供了设置APN的参数信息(APN网络名、帐号、手机号等)。由于以前做过Wince下普通的拨号连接,就在直接上面修改代码。

    一边看MSDN,一边百度资料,还是有收获,对APN有了一定了解:APN只是在普通拨号的基础上多了一些设置参数而已。然而就是这些参数,折磨了我两天。

    要建立APN,首先要使用RasSetEntryProperties来修改拨号连接的属性参数,函数原型如下:

DWORD RASAPI RasSetEntryProperties (

        LPWSTR lpszPhoneBook,  
        LPWSTR szEntry,
        LPRASENTRY lpEntry,
        DWORD dwEntrySize,
        LPBYTE lpb,
        DWORD dwSize

);

第一个参数直接设为NULL,第二个参数为拨号连接的名称,比如‘宽带连接’,如果名称不存在,那么系统自动创建一个新的连接,第三个参数是拨号连接的属性,里面内容繁多,不过只需要设置部分内容即可,代码如下:

RASENTRY g_objEntry = { 0 };

g_objEntry.dwSize = sizeof( RASENTRY );

_tcscpy( g_objEntry.szDeviceType, RASDT_Modem ); //设备类型

_tcscpy( g_objEntry.szDeviceName, _T( "CDMAModem" )); //设备名称

_tcscpy( g_objEntry.szAreaCode, _T( "10" )); //区号

_tcscpy( g_objEntry.szLocalPhoneNumber, _T( "*99#" )); //手机号码

g_objEntry.dwCountryCode = 86; //国家、地区代码

g_objEntry.dwfNetProtocols = RASNP_Ip; //Negotiate the TCP/IP protocol.

g_objEntry.dwFramingProtocol = RASFP_Ppp; //Point-to-Point Protocol (PPP)

最关键的参数 g_objEntry.dwfOptions,因为项目里面规定用使用PAP身份验证协议,刚开始我就直接赋值:

g_objEntry.dwfOptions = RASEO_ProhibitPAP;

没想到就这一步错大了,都怪我E文水平不高,最重要的是没认真看MSDN的说明,下面是关于RASEO_ProhibitPAP的说明,各位看了就知道为什么我错了:

If this flag is set to 1, the use of the Password Authentication Protocol (PAP) authentication method is disabled. If the flag is set to zero (0), then the client can negotiate the use of the PAP authentication method with the server.

g_objEntry.dwfOptions最后赋值为:

g_objEntry.dwfOptions =

  RASEO_ProhibitCHAP

| RASEO_ProhibitEAP       

| RASEO_ProhibitMsCHAP

| RASEO_ProhibitMsCHAP2     

| RASEO_UseCountryAndAreaCodes

| RASEO_SwCompression     

| RASEO_IpHeaderCompression;

注意,这里要根据具体的情况而定,我们的项目指定要PAP。

下面继续RasSetEntryProperties的第四个参数dwEntrySize,直接赋值sizeof( RASENTRY )即可,第五个参数是串口参数以及APN命令,但是MSDN里面没有进一步说明数据是怎样的格式,这样导致我花了大量的时间去百度,最终功夫不负有心人,终于找到了答案,下面是网友提供的数据定义:

#pragma pack(1)

typedef struct

{

unsigned short Reserved1; // 0x00, 通常为0x20   

unsigned short WaitForCreditCard; // 0x02 

unsigned short CancelTimeOut; // 0x04 

unsigned short Reserved2; // 0x06 

unsigned char Test1; // 0x08 

unsigned char Test2; // 0x09 

unsigned short Reserved3; // 0x0A 

unsigned int BaudRate; // 0x0C 

unsigned short Terminal; // 0x10, 通常为0, 1, 3, 7 

unsigned char DataBits; // 0x12 

unsigned char StopBits; // 0x13

unsigned char Parity; // 0x14 

unsigned char FlowControl; // 0x15 

TCHAR AtCmd[115]; // 0x16,

} sDevConfig;

#pragma pack()

我在使用中发现里面有一个地方定义错了,结构体成员Test1才是流控制,而FlowControl则固定为1。

至于AtCmd,APN命令,因为运营商以及手机卡的不同,内容可能不一样,这里我也把我所使用的格式发上来:

+CGDCONT=1,"IP","xxxx", xxxx代表APN网络名,注意,我所使用的命令后面有一个逗号结尾。

后面的内容和普通拨号连接没什么区别,我就直接发代码了:

RASDIALPARAM g_objDialParam = { 0 };

g_objDialParam.dwSize = sizeof( RASDIALPARAMS );

wcscpy( g_objDialParam.szEntryName, wszEntryName );

wcscpy( g_objDialParam.szUserName, _T( "*******" ));         //******代表用户名

//采用异步的方式,通过窗口回调得到拨号连接的状态

DWORD dwResult = RasDial( NULL, NULL, &g_objDialParam, 0xFFFFFFFF, hDlg, &g_hRasConn );

if ( 0 == dwResult )

{      

    WriteLogMsg( _T( "RasDial调用成功!" ));

}

else

{      

    WCHAR wszLog[256] = { 0 };

    _stprintf( wszLog, _T( "RasDial调用失败!错误码:%d" ), dwResult );

    WriteLogMsg( wszLog );

}

下面是处理拨号过程中的消息:

case WM_RASDIALEVENT:

{    

DWORD dwError = ( DWORD )lParam;    

RASCONNSTATE connState = ( RASCONNSTATE )wParam;

switch ( connState )    

{   

 case RASCS_OpenPort:                     

{       WriteLogMsg( _T( "RASCS_OpenPort..." ));       break;     }    

case RASCS_PortOpened:                  

 {       WriteLogMsg( _T( "RASCS_PortOpened." ));       break;     }   

case RASCS_ConnectDevice:             

 {       WriteLogMsg( _T( "RASCS_ConnectDevice..." ));       break;     }   

case RASCS_DeviceConnected:         

 {       WriteLogMsg( _T( "RASCS_DeviceConnected." ));       break;     }   

case RASCS_AllDevicesConnected:    

 {       WriteLogMsg( _T( "RASCS_AllDevicesConnected." ));       break;     }   

case RASCS_Authenticate:     

{       WriteLogMsg( _T( "RASCS_Authenticate..." ));       break;     }   

 case RASCS_Authenticated:     

{       WriteLogMsg( _T( "RASCS_Authenticated." ));       break;     }  

  case RASCS_Connected:    

 {       WriteLogMsg( _T( "RASCS_Connected." ));       break;     }  

case RASCS_Disconnected:   

  {       WriteLogMsg( _T( "RASCS_Disconnected." ));       break;     }

default:   

  {       WCHAR wszBuf[32] = { 0 };

       _stprintf( wszBuf, _T( "其他状态: %d" ), connState );

       WriteLogMsg( wszBuf );       break;   

  }  

  }

if ( 0 != dwError )  

  {     

      WCHAR wszErrorMsg[128] = { 0 };

      _stprintf( wszErrorMsg, _T( "Dial Error: %d" ), dwError );

      WriteLogMsg( wszErrorMsg );   

 }

 

这里可以下载完整的拨号库

 

.