Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / C++

3G Modem Internet Dialer

Rate me:
Please Sign up or sign in to vote.
4.90/5 (88 votes)
13 Jul 2011CPOL7 min read 773.9K   65.9K   192  
3G Modem Internet Dialer
#include "StdAfx.h"

#include <WinIoCtl.h>
#include <SetupAPI.h>
#include <atlbase.h>

#include "ModemFactory.h"
#include "DummyModem.h"
#include "HuaweiModem.h"
#include "HuaweiCDMAModem.h"
#include "ZTEModem.h"
#include "Log.h"


DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);

CModemFactory::CModemFactory(void)
{
	m_iPortIndex = -1;
}

CModemFactory::~CModemFactory(void)
{
}


BOOL CModemFactory::SearchFor3GModem(CString &sManufacturer, CString &sModel)
{
	BOOL bFound = FALSE;
	CDummyModem *modem;
	int iCount = m_saName.GetCount();
#ifdef _LOG
	CLog::Instance()->LogToFile(L"Info : Ports List :\n");
#endif
	for (int iItr = 0; iItr < iCount ; iItr++)
	{
#ifdef _LOG
		CLog::Instance()->LogToFile(L"\t");
		CLog::Instance()->LogToFile(m_saName[iItr]);
		CLog::Instance()->LogToFile(L"\n");
#endif
		if(m_saName[iItr].CompareNoCase(L"HUAWEI Mobile Connect - 3G PC UI Interface") == 0)
		{
#ifdef _LOG
			CLog::Instance()->LogToFile(L"Info : Modem Found\n");
#endif
			modem = new CDummyModem(m_saPorts[iItr]);
			modem->GetModemInfo();
			sManufacturer = modem->GetManufacturer();
			sModel = modem->GetModel();
			modem->ShutDown();
			m_iPortIndex = iItr;
			delete modem;
			bFound = TRUE;
		}
		else if(m_saName[iItr].CompareNoCase(L"ZTE NMEA Device") == 0)
		{
#ifdef _LOG
			CLog::Instance()->LogToFile(L"Info : Modem Found\n");
#endif
			modem = new CDummyModem(m_saPorts[iItr]);
			modem->GetModemInfo();
			sManufacturer = modem->GetManufacturer();
			sModel = modem->GetModel();
			modem->ShutDown();
			m_iPortIndex = iItr;
			delete modem;
			bFound = TRUE;
		}
	}
	return bFound;
}

CModem *CModemFactory::SearchForModem()
{
#ifdef _LOG
	CLog::Instance()->LogToFile(L"Info : Searching for modem\n");
#endif
	CString sManufacturer, sModel;
	SearchForCOMPorts();
	if(!SearchFor3GModem(sManufacturer, sModel))
	{
#ifdef _LOG
		CLog::Instance()->LogToFile(L"Error: No Modem Found\n");
#endif
		return NULL;
	}

	if (sManufacturer.IsEmpty())
	{
#ifdef _LOG
		CLog::Instance()->LogToFile(L"Error : Modem didn't return a Manufacturer\n");
		return NULL;
#endif
	}

	sManufacturer.Trim();
	sManufacturer.MakeLower();
	if(sManufacturer.Find(L"huawei") != -1)
	{
#ifdef _LOG
		CLog::Instance()->LogToFile(L"Info : Creating a Huawei Modem\n");
#endif
		if(sModel.Find(L"EC169") != -1)
		{
			//Huawei CDMA Modem
			return new CHuaweiCDMAModem(m_saPorts[m_iPortIndex]);
		}
		else
		{
			//Normal Huawei Modem
			return new CHuaweiModem(m_saPorts[m_iPortIndex]);
		}
	}
	else if (sManufacturer.Find(L"zte") != -1)
	{
#ifdef _LOG
		CLog::Instance()->LogToFile(L"Info : Creating a ZTE Modem\n");
#endif
		return new CZTEModem(m_saPorts[m_iPortIndex]);
	}
#ifdef _LOG
	CLog::Instance()->LogToFile(L"Error: Modem Unknown\n");
#endif
	return NULL;

}

int CModemFactory::SearchForCOMPorts(void)
{
	m_saPorts.RemoveAll();
	m_saName.RemoveAll();

	GUID guid = GUID_CLASS_COMPORT;

	HDEVINFO hdevinfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (hdevinfo == INVALID_HANDLE_VALUE)
	{	
#if defined(_LOG) && defined(_DEBUG)
		CString sLog;
		DWORD dwLastError = GetLastError();
		sLog.Format(L"%d", dwLastError);
		CLog::Instance()->LogToFile(L"Error : SetupDiGetClassDevs failed with error ");
		CLog::Instance()->LogToFile(sLog);
		CLog::Instance()->LogToFile(L"\n");
#endif
		return FALSE;
	}

	SP_DEVINFO_DATA devinfodata;
	devinfodata.cbSize = sizeof(SP_DEVINFO_DATA);
	int iIndex = 0;

	while (SetupDiEnumDeviceInfo(hdevinfo, iIndex, &devinfodata))
	{
		HKEY hkey = SetupDiOpenDevRegKey(hdevinfo, &devinfodata, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);

		if (hkey)
		{
			TCHAR szPort[256];
			DWORD dwSize = sizeof(szPort);
			DWORD dwType = 0;
			if ((RegQueryValueEx(hkey, L"PortName", NULL, &dwType, (LPBYTE)szPort, &dwSize) == ERROR_SUCCESS))
			{
				if(dwType == REG_SZ)
				{
					TCHAR szPortName[256];
					DWORD dwSize = sizeof(szPortName);
					DWORD dwType = 0;
					m_saPorts.Add(szPort);
					if (SetupDiGetDeviceRegistryProperty(hdevinfo, &devinfodata, SPDRP_DEVICEDESC, &dwType, (PBYTE)szPortName, dwSize, &dwSize) && (dwType == REG_SZ))
					{
						m_saName.Add(szPortName);
					}
					else
					{
						m_saName.Add(L""); //No Name
					}
				}
			}
			RegCloseKey(hkey);
		}
		iIndex++;
	}

	//Cleaning
	SetupDiDestroyDeviceInfoList(hdevinfo);

	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I love coding with C++. I always split my free time between coding and gaming Smile | :)

Comments and Discussions