Mornella/Mornella_Mobile/GPRSConnection.cpp
#include "GPRSConnection.h"
#include "Common.h"
#include <windows.h>
#include <commctrl.h>
#include <initguid.h>
#include <connmgr.h>
#include <connmgr_status.h>
#include <connmgr_conntypes.h>
#include <ras.h>
#include <winsock2.h>
#include <regext.h>
#include <winioctl.h>
// RIL IO-control codes
#define FILE_DEVICE_RIL 0x300
#define IOCTL_RIL_SETGPRSATTACHED CTL_CODE(FILE_DEVICE_RIL, 125, METHOD_BUFFERED, FILE_ANY_ACCESS)
GPRSConnection::GPRSConnection()
: _hConnection(INVALID_HANDLE_VALUE), _hConnMgr(INVALID_HANDLE_VALUE), dwCacheVal(60), bForced(FALSE)
{
ZeroMemory(wString, sizeof(wString));
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Comm\\ConnMgr\\Planner\\Settings", 0, 0, &hKey) != ERROR_SUCCESS)
return;
// Preleviamo i valori originali
RegistryGetDWORD(hKey, NULL, L"CacheTime", &dwCacheVal);
RegistryGetString(hKey, NULL, L"SuspendResume", wString, MAX_PATH);
// Riduciamo il cache time della connessione GPRS
RegistrySetDWORD(hKey, NULL, L"CacheTime", 10);
// Diciamo al telefono di troncare la connessione allo standby
//RegistrySetString(hKey, NULL, L"SuspendResume", L"GPRS_bye_if_device_off");
RegistrySetString(hKey, NULL, L"SuspendResume", L"~GPRS!");
RegCloseKey(hKey);
}
GPRSConnection::~GPRSConnection()
{
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Comm\\ConnMgr\\Planner\\Settings", 0, 0, &hKey) != ERROR_SUCCESS)
return;
// Ripristiniamo i parametri della connessione GPRS
RegistrySetDWORD(hKey, NULL, L"CacheTime", dwCacheVal);
// GPRS_bye_if_device_off e ~GPRS!
RegistrySetString(hKey, NULL, L"SuspendResume", wString);
RegCloseKey(hKey);
}
bool GPRSConnection::_connect()
{
CONNMGR_CONNECTIONINFO ConnectionInfo;
if (isGprsConnected()) {
return true;
}
ZeroMemory (&ConnectionInfo, sizeof (ConnectionInfo));
ConnectionInfo.cbSize = sizeof (ConnectionInfo);
ConnectionInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
ConnectionInfo.dwFlags = CONNMGR_FLAG_NO_ERROR_MSGS;
ConnectionInfo.dwPriority = CONNMGR_PRIORITY_HIPRIBKGND;
ConnectionInfo.guidDestNet = IID_DestNetInternet;
DWORD dwStatus;
HRESULT hr = ConnMgrEstablishConnectionSync (&ConnectionInfo, &_hConnection, 30000, &dwStatus);
if (FAILED(hr)) {
DBG_TRACE_INT(L"Debug - GPRSConnection.cpp - _connect [ConnMgrEstablishConnectionSync()] error: ", 5, FALSE, hr);
return false;
}
bForced = TRUE;
DBG_TRACE(L"Debug - GPRSConnection.cpp - _connect [ConnMgrEstablishConnectionSync()] OK\n", 6, FALSE);
return true;
}
bool GPRSConnection::_disconnect()
{
HANDLE hDev = INVALID_HANDLE_VALUE;
UINT uVal = 0, uRet;
DWORD dwBytesRet;
if (bForced == FALSE) {
return true;
}
HRESULT hr = ConnMgrReleaseConnection(_hConnection, FALSE);
if (FAILED(hr)) {
DBG_TRACE_INT(L"Debug - GPRSConnection.cpp - _disconnect [ConnMgrReleaseConnection()] error: ", 5, FALSE, hr);
return false;
}
bForced = FALSE;
DBG_TRACE(L"Debug - GPRSConnection.cpp - _disconnect [ConnMgrReleaseConnection()] OK\n", 6, FALSE);
// Proviamo a chiudere la connessione GPRS con le RIL
hDev = CreateFile(L"RIL1:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);
if (hDev == INVALID_HANDLE_VALUE) {
DBG_TRACE(L"Debug - GPRSConnection.cpp - _disconnect() [FAILED to open RIL1:]\n", 6, FALSE);
return false;
}
// Equivale a una RIL_SetGPRSAttached(..., FALSE);
if (DeviceIoControl(hDev, IOCTL_RIL_SETGPRSATTACHED, (PVOID)&uVal, sizeof(uVal), &uRet, sizeof(uRet), &dwBytesRet, NULL) == FALSE) {
DBG_TRACE(L"Debug - GPRSConnection.cpp - _disconnect() [FAILED DeviceIoControl() on RIL1:]\n", 6, FALSE);
}
CloseHandle(hDev);
return true;
}
bool GPRSConnection::isGprsConnected() {
CONNMGR_CONNECTION_DETAILED_STATUS *pStatus = NULL, *ptr;
HRESULT hr;
DWORD dwSize = 0;
hr = ConnMgrQueryDetailedStatus(pStatus, &dwSize);
if (hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
pStatus = (CONNMGR_CONNECTION_DETAILED_STATUS *)new(std::nothrow) BYTE[dwSize + 0x100];
dwSize += 0x100;
}
if (pStatus == NULL) {
return false;
}
hr = ConnMgrQueryDetailedStatus(pStatus, &dwSize);
if (FAILED(hr)) {
delete[] pStatus;
return false;
}
// Controlliamo che ci sia almeno una connessione di tipo cellular, connessa e con un IP
for (ptr = pStatus; ptr != NULL; ptr = ptr->pNext) {
if (ptr->dwType == CM_CONNTYPE_CELLULAR && ptr->dwConnectionStatus == CONNMGR_STATUS_CONNECTED &&
ptr->pIPAddr) {
delete[] pStatus;
return true;
}
}
delete[] pStatus;
return false;
}