我们现在的模块用的是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系统里的控制面板下,进入“网络和拨号连接”,手动新建一个能拨通上网的连接,我命名为“
经过改不同的参数然后以上面的方法打出这个参数传回来的值,总结出
所以总结出以下结构体:
空格
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());
}
}