wince下Ras拨号

来源:互联网 发布:海康威视的域名设置 编辑:程序博客网 时间:2024/05/16 23:36

利用Ras系列函数再wince系统下进行GPRS拨号,经历了几次修改,但期间太懒没有进行总结,感觉不踏实,今决定回顾代码,能总结多少算多少,然后再慢慢完善此文。

     (1)首先,在wince控制面板创建一个拨号连接,把波特率、串口号、(APN、用户名、密码)等设置后确保能够拨号,然后将注册表信息导出后合成到定制wince系统。接下来就可以在这个系统上做对应的应用程序了。

     (2)检测是否存在设备名为pszDeviceName(如我用的是SIM300W模块,SIMCOM提供驱动,名为SIM300 MUX Modem),类型为modem的设备;

     使用的API:需要调用两次RasEnumDevices来获取Devices列表,然后再比较DeviceName。

     示例代码:

view plaincopy to clipboardprint?
 LPRASDEVINFO pRasDevInfo = NULL;  
 DWORD cb = 0;  
DWORD dwDeviceCount = 0;  
DWORD dwRetVal = ::RasEnumDevices(NULL, &cb, &dwDeviceCount);  
 
if ((0 == dwRetVal||dwRetVal==ERROR_BUFFER_TOO_SMALL) && (0 != cb))  
{  
    *pRasDevInfo = reinterpret_cast<LPRASDEVINFO>(new BYTE[cb]);  
    ASSERT(*pRasDevInfo);  
      
    if (*pRasDevInfo)  
    {  
        (*pRasDevInfo)->dwSize = sizeof(RASDEVINFO);  
        dwRetVal = ::RasEnumDevices(*pRasDevInfo, &cb, &dwDeviceCount);  
    }  
    else 
    {  
        dwDeviceCount = 0;  
    }  
}  
       // pRasDevInfo保存了获取的device列表,列表size等于dwDeviceCount。  
        // device name比较代码省略 
  LPRASDEVINFO pRasDevInfo = NULL;
  DWORD cb = 0;
 DWORD dwDeviceCount = 0;
 DWORD dwRetVal = ::RasEnumDevices(NULL, &cb, &dwDeviceCount);
 
 if ((0 == dwRetVal||dwRetVal==ERROR_BUFFER_TOO_SMALL) && (0 != cb))
 {
  *pRasDevInfo = reinterpret_cast<LPRASDEVINFO>(new BYTE[cb]);
  ASSERT(*pRasDevInfo);
  
  if (*pRasDevInfo)
  {
   (*pRasDevInfo)->dwSize = sizeof(RASDEVINFO);
   dwRetVal = ::RasEnumDevices(*pRasDevInfo, &cb, &dwDeviceCount);
  }
  else
  {
   dwDeviceCount = 0;
  }
 }
        // pRasDevInfo保存了获取的device列表,列表size等于dwDeviceCount。
         // device name比较代码省略

    

    

    (3)设置RASENTRY属性

     使用的API:RasGetEntryProperties ;RasSetEntryProperties

     先使用RasGetEntryProperties(需2次调用)获取默认的属性,然后根据具体的情况修改属性值(如:拨号号码)。

     注:需要保存RasGetEntryProperties获取的lpbDeviceInfo,供后面使用(如保存为成员变量m_pDevConfig)。

     (4)设置APN(CDMA拨号无需设置APN),我是从网上找的,具体的链接不记得了。

     定义结构体

    typedef struct tagDEVMINICFG {
 WORD wVersion;
 WORD wWaitBong; // DevCfgHdr
 DWORD dwCallSetupFailTimer; // CommConfig.ModemSettings
 DWORD dwModemOptions; // CommConfig.ModemSettings
 // MDM_BLIND_DIAL MDM_FLOWCONTROL_SOFT
 // MDM_CCITT_OVERRIDE MDM_FORCED_EC
 // MDM_CELLULAR MDM_SPEED_ADJUST
 // MDM_COMPRESSION MDM_TONE_DIAL
 // MDM_ERROR_CONTROL MDM_V23_OVERRIDE
 // MDM_FLOWCONTROL_HARD
 DWORD dwBaudRate; // DCB
 WORD fwOptions; // DevCfgHdr
 // TERMINAL_PRE TERMINAL_POST
 // MANUAL_DIAL
 BYTE ByteSize; // DCB
 BYTE StopBits; // DCB
 BYTE Parity; // DCB

 BYTE Rerver;

 WCHAR szDialModifier[DIAL_MODIFIER_LEN+1]; // Unique to MiniCfg
 // Dynamic devices configuration
 WCHAR wszDriverName[MAX_NAME_LENGTH+1];
 BYTE pConfigBlob[MAX_CFG_BLOB];
 HANDLE hPort;
} DEVMINICFG, *PDEVMINICFG;

        设置代码段如下:

 TCHAR szATCmd[80]={0};
 _stprintf(szATCmd,_T("+CGDCONT=1,/"IP/",/"%s/""),pszAPN);
 PDEVMINICFG pDev=(PDEVMINICFG)m_pDevConfig;
 pDev->dwBaudRate=dwBauti;         // 波特率
 pDev->dwModemOptions&=~dwFlowControl ; // 硬件流控或软件流控

 int dwDialOff=offsetof(DEVMINICFG,szDialModifier);

#ifdef _WIN32_WCE
 memcpy(m_pDevConfig+dwDialOff,szATCmd, 80*sizeof(TCHAR));
#endif
 
 if (m_pszAPN)
 {
  delete []m_pszAPN;
  m_pszAPN = NULL;
 }
 m_pszAPN = new TCHAR[_tcslen(pszAPN)+1];
 _tcscpy(m_pszAPN, pszAPN);

    (5)连网

     使用的API:RasDial

     分为同步连网和异步连网,一般都是选择异步。

     先设置 RASDIALPARAMS rdParams;

     同步连网: DWORD dwRet =  RasDial(NULL, NULL, &rdParams, 0, NULL, &m_hRasConn);

     异步连网: DWORD dwRet = RasDial(NULL, NULL, &rdParams, 0xffffffff, m_hEventWnd, &m_hRasConn);   

     对RasDial返回值进行判断是否成功执行,如果不成功且m_hRasConn不为NULL,需要调用RasHangUp释放m_hRasConn。

     异步中的m_hEventWnd 为HWND类型, 在主窗口中重写WindowdProc来接收消息。

 

LRESULT CHZG_MainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
 // TODO: 在此添加专用代码和/或调用基类
 if( message == WM_RASDIALEVENT )  // 收到拨号连接消息
 {
   RASCONNSTATE RasState = (RASCONNSTATE)wParam;

 switch (RasState) 
 {     
 case RASCS_OpenPort:   //正在打开端口
  WriteEvent (TEXT("正在打开端口... "));
  break;
 case RASCS_PortOpened:  //端口已打开
  WriteEvent (TEXT("端口已打开"));
  break;
 case RASCS_ConnectDevice:  //正在连接设备
  WriteEvent (TEXT("正在连接设备..."));
  break;
 case RASCS_Connected :   //连接已建立
  m_Status.SetWindowText(_T("拨号成功"));
  WriteEvent(_T("拨号成功"));
  for(int i=0;i<3;i++)
  {
   MessageBeep(-1);
   Sleep(500);
  }

  m_bDialSucc = 1;     //置标志位
  MyAppCtrl.bInConnecting = true;
  TCP_StartConnThread();
  break;
 case RASCS_Disconnected :  //连接断开
  WriteEvent (TEXT("ras Disconnected"));
  m_bDialSucc = 0;     //置标志位
  break;
 default :
  break;
 }

  }

 return CDialog::WindowProc(message, wParam, lParam);
}

   

    (6)断网

     使用的API:RasHangUp

     调用RasHangUp后,最好是能够判断下是否释放完成。

     如:

  DWORD dwRet=RasHangUp(m_hRasConn);
 
 DWORD dwStatusRet=0;
 RASCONNSTATUS rStatus;
 ZeroMemory(&rStatus, sizeof(RASCONNSTATUS));
 rStatus.dwSize = sizeof(RASCONNSTATUS);
 dwStatusRet = RasGetConnectStatus(m_hRasConn, &rStatus);
 long lStart=GetTickCount();
 while(dwStatusRet!=ERROR_INVALID_HANDLE)
 {
  MSG msg;
  while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
  dwStatusRet = RasGetConnectStatus(m_hRasConn, &rStatus);
  if (GetTickCount()-lStart>3000)
  {
   break;
  }
 
  //Sleep(10);
  //dwStatusRet = RasGetConnectStatus(m_hRasConn, &rStatus);
  //if (GetTickCount()-lStart>5000)
  //{
  // break;
  //}
 }
 
 CloseHandle(m_hRasConn);
 m_hRasConn=NULL;

    

    (7) 获取当前活动连接的HRASCONN

     使用API:RasEnumConnections

    (8) HRASCONN的释放

    断网时必须得把此资源完全释放,否则会引起拨号不成功。这点在重连网络的时候要特别留意。

 

    (9)开发中发现,如果正在连网,需要取消,调用 RasHangUp, 有时出现RasHangUp函数阻塞不返回了,总结经验是:当连网过程进入到状态RASCS_DeviceConnected后,没有出现RasHangUp不返回的现象。我不知道Ras里面的机制细节,谁知道的劳烦告诉我,在此先谢谢了!

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/nolatestudy/archive/2011/04/22/6342392.aspx

原创粉丝点击