Click here to Skip to main content
15,895,142 members
Articles / Mobile Apps

Using the Skyhook Wireless XPS Positioning Service in Managed Code

Rate me:
Please Sign up or sign in to vote.
4.95/5 (15 votes)
20 Jan 2009CPOL28 min read 89.1K   1.4K   57  
Wrapper and sample programs demonstrating the use of the Skyhook Wireless XPS SDK (hybrid position system using GPS, WiFi Positioning, and Celltower positioning)
// WpsProxy.cpp : Defines the entry point for the DLL application.
//


#include "stdafx.h"
#include "WpsProxy.h"
#include <windows.h>


static char* wcstombs(const wchar_t* src);
static wchar_t* mbstowcs(const char* src);

WPS_Continuation WiFiLocationCallback(void * arg, WPS_ReturnCode result, const WPS_Location* location);
WPS_Continuation TilingCallback(void* arg, UINT tileNumber, UINT tileTotal);


const int MAX_STRING_SIZE = 128;
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}



extern "C" WPSPROXY_API void SetProxy( const LPWSTR address, int port, const LPWSTR user, const LPWSTR password)
{
	LPSTR szAddress = wcstombs(address);
	LPSTR szUser = wcstombs(user);
	LPSTR szPassword = wcstombs(password);

	WPS_set_proxy(szAddress,port, szUser,szPassword);

	delete szPassword;
	delete szUser;
	delete szAddress;
}

extern "C" WPSPROXY_API void SetServerUrl(const LPWSTR url)
{
	//Convert unicode string to ANSI string. 
	//this call allocates memory
	LPSTR szUrl = wcstombs(url);

	//call WPSAPI function with ANSI string
	WPS_set_server_url(szUrl);

	//Free the ANSI string
	delete szUrl;
}

extern "C" WPSPROXY_API void SetUserAgent(const LPWSTR ua)
{
	LPSTR szUa = wcstombs(ua);

	WPS_set_user_agent(szUa);

	delete szUa;
}

extern "C" WPSPROXY_API WPS_ReturnCode SetTier2Area(const LPWSTR dirpath, unsigned size)
{
	LPSTR szDirPath = wcstombs(dirpath);
	WPS_ReturnCode rc;

	rc = WPS_set_tier2_area(szDirPath,size);

	delete  szDirPath;
	return rc;
}

extern "C" WPSPROXY_API WPS_ReturnCode  RegisterUser(LPWSTR existingUserName, LPWSTR existingUserRealm, LPWSTR newUserName, LPWSTR newUserRealm)
{
	WPS_SimpleAuthentication existingUser, newUser;
	existingUser.username = wcstombs(existingUserName);
	existingUser.realm = wcstombs(existingUserRealm);
	newUser.realm = wcstombs(newUserRealm);
	newUser.username = wcstombs(newUserName);
	WPS_ReturnCode rc;

	rc = WPS_register_user(&existingUser, &newUser);

	delete existingUser.username;
	delete existingUser.realm;
	delete newUser.username;
	delete newUser.realm;

	return rc;
	
}


extern "C" WPSPROXY_API WPS_ReturnCode Tiling(LPWSTR dirPath, UINT maxDataPerSession, UINT maxDataSizeTotal, TilingDelegate* callback)
{
	LPSTR path = wcstombs(dirPath);
	WPS_ReturnCode retVal;
	retVal = WPS_tiling(path,maxDataPerSession,maxDataSizeTotal,TilingCallback, callback);
	return retVal;
}

WPS_Continuation TilingCallback(void* arg, UINT tileNumber, UINT tileTotal)
{
	WPS_Continuation retCode = WPS_CONTINUE;
	if(arg!=NULL)
	{
		TilingDelegate td = (TilingDelegate)arg;
		retCode = td(tileNumber, tileTotal);
	}
	return retCode;
}


extern "C" WPSPROXY_API WPS_ReturnCode PeriodicLocation(
	LPWSTR userName, 
	LPWSTR realm, 
	WPS_StreetAddressLookup lookupType, 
	unsigned long period, 
	unsigned long iterations, 
	WiFiLocationDelegate* callback      //This is the delegate passed in from managed code
	)
{
	//perform conversion from double byte strings to single byte strings
	WPS_SimpleAuthentication simpleAuthentication;
	simpleAuthentication.realm = wcstombs(realm);
	simpleAuthentication.username = wcstombs(userName);
	WPS_ReturnCode result;

	result = WPS_periodic_location(
		&simpleAuthentication, 
		lookupType,period, 
		iterations, 
		WiFiLocationCallback,		//Function predefined within WPSAPI
		callback					//managed delegate.  Passed as data parameter
		);					
	//delete userName;
	//delete realm;
	return result;
}

WPS_Continuation WiFiLocationCallback(void*  arg, WPS_ReturnCode result, const WPS_Location* location)
{
	WPS_Continuation retCode;
	retCode = WPS_STOP;
	if(arg!=NULL)
	{
		WiFiLocationDelegate del = (WiFiLocationDelegate)arg;
		if(result!=WPS_OK)
		{
			retCode = del(result,-1,-1,-1,-1,-1,-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		}
		else
		{
			WPS_StreetAddress* sa = location->street_address;
			if(sa!=NULL)
			{				
				LPWSTR addressLine = new TCHAR[MAX_STRING_SIZE];
				LPWSTR tempBuffer = new TCHAR[MAX_STRING_SIZE];
				for (int i=0;sa->address_line[i]!=NULL;++i)
				{
					mbstowcs(tempBuffer,sa->address_line[i],MAX_STRING_SIZE);
					wcsncat(addressLine,tempBuffer,MAX_STRING_SIZE);
					if(sa->address_line[i+1]!=NULL)
					{
						wcsncat(addressLine,L"\r\n",MAX_STRING_SIZE);
					}
				}
				delete tempBuffer;
				LPWSTR streetNumber = mbstowcs(sa->street_number);				
				LPWSTR city = mbstowcs(sa->city);
				LPWSTR county = mbstowcs(sa->county);
				LPWSTR countryName = mbstowcs(sa->country.name);
				LPWSTR countryCode = mbstowcs(sa->country.code);
				LPWSTR stateName = mbstowcs(sa->state.name);
				LPWSTR stateCode = mbstowcs(sa->state.code);
				LPWSTR postalCode = mbstowcs(sa->postal_code);
				LPWSTR province = mbstowcs(sa->province);
				LPWSTR region = mbstowcs(sa->region);

				retCode = del(result,location->latitude, location->longitude, location->hpe, location->nap,location->speed, location->bearing,
					streetNumber, addressLine, city, stateName, stateCode, postalCode, county, region, countryName, countryCode,province);

				delete region;
				delete province;
				delete postalCode;
				delete stateCode;
				delete stateName;
				delete countryCode;
				delete countryName;
				delete county;
				delete city;
				delete addressLine;
				delete streetNumber;
			}
			else
				retCode = del(result,location->latitude, location->longitude, location->hpe, location->nap,location->speed, location->bearing,
							NULL,NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		}/*else*/
	}/*arg!=null*/
	return retCode;
}




extern "C" WPSPROXY_API WPS_ReturnCode SetLocalFilesPath(LPWSTR *path, int pathCount)
{
	WPS_ReturnCode retCode;
	char** wcsPathList = new char*[pathCount+1];
	wcsPathList[pathCount]=NULL;

	for(int i=0;i<pathCount;++i)
	{
		wcsPathList[i]=wcstombs(path[i]);
	}
	
	retCode = WPS_set_local_files_path((const char**)wcsPathList);

	for(int i=0;i<pathCount;++i)
		delete wcsPathList[i];
	delete wcsPathList;
	return retCode;
}


extern "C" WPSPROXY_API WPS_ReturnCode GetIPLocation (
	LPWSTR	userName,
	LPWSTR	realm, 
	WPS_StreetAddressLookup lookupType,
	double* Latitude,
	double* Longitude,
	LPWSTR	IPAddress,
	LPWSTR	AddressNumber,
	LPWSTR	AddressLine,
	LPWSTR	City,
	LPWSTR	StateName,
	LPWSTR	StateCode,
	LPWSTR	PostalCode,
	LPWSTR	County,
	LPWSTR	Region,
	LPWSTR	CountryName,
	LPWSTR	CountryCode,
	LPWSTR  Province
	)
{
	
	WPS_IPLocation*	location = NULL;
	WPS_ReturnCode rc;
	WPS_SimpleAuthentication simpleAuthentication;
	simpleAuthentication.realm = wcstombs(realm);
	simpleAuthentication.username = wcstombs(userName);
	rc = WPS_ip_location(&simpleAuthentication,lookupType,&location);
	delete simpleAuthentication.username;
	delete simpleAuthentication.realm;

	LPWSTR tempBuffer = new TCHAR[MAX_STRING_SIZE];

	if(rc == WPS_OK)
	{
		*Latitude = location->latitude;
		*Longitude = location->longitude;
		if(location->ip!=NULL)
		{
			mbstowcs(IPAddress,location->ip,MAX_STRING_SIZE);				
		}
		if(location->street_address!=NULL)
		{
			WPS_StreetAddress* streetAddress =  location->street_address;

			if(streetAddress->street_number!=NULL)
				mbstowcs(AddressNumber,streetAddress->street_number,MAX_STRING_SIZE);				
			if(streetAddress->city!=NULL)
				mbstowcs(City,streetAddress->city,MAX_STRING_SIZE);
			
			mbstowcs(StateName,streetAddress->state.name,MAX_STRING_SIZE);
			mbstowcs(StateCode,streetAddress->state.code,3);

			mbstowcs(CountryName,streetAddress->country.name,MAX_STRING_SIZE);
			mbstowcs(CountryCode,streetAddress->country.code,MAX_STRING_SIZE);

			if(streetAddress->county!=NULL)
			{
				mbstowcs(County,streetAddress->county,MAX_STRING_SIZE);
			}
			if(streetAddress->postal_code!=NULL)
			{
				mbstowcs(PostalCode,streetAddress->postal_code,MAX_STRING_SIZE);
			}
			if(streetAddress->region!=NULL)
			{
				mbstowcs(Region,streetAddress->region,MAX_STRING_SIZE);
			}
			if(streetAddress->province!=NULL)
			{
				mbstowcs(Province,streetAddress->province,MAX_STRING_SIZE);
			}

			for (int i=0;location->street_address->address_line[i]!=NULL;++i)
			{
				mbstowcs(tempBuffer,location->street_address->address_line[i],MAX_STRING_SIZE);
				wcsncat(AddressLine,tempBuffer,MAX_STRING_SIZE);
				if(location->street_address->address_line[i+1]!=NULL)
				{
					wcsncat(AddressLine,L"\r\n",MAX_STRING_SIZE);
				}
			}
		}
		delete tempBuffer;
		WPS_free_ip_location(location);
	}
	return rc;

}


//extern "C" WPSPROXY_API WPS_ReturnCode TuneLocation(
//	LPWSTR userName,
//	LPWSTR realm,
//	const WPS_Location* location
//	)
//{
//	WPS_SimpleAuthentication simpleAuthenticate;
//	simpleAuthenticate.realm = wcstombs(realm);
//	simpleAuthenticate.username = wcstombs(userName);
//	WPS_ReturnCode rc = WPS_tune_location(authentication, location);
//	delete simpleAuthenticate.realm;
//	delete simpleAuthenticate.username;
//	return rc;
//}

extern "C"  WPSPROXY_API WPS_ReturnCode GetWiFiLocation(
								LPWSTR userName, 
								LPWSTR realm, 
								WPS_StreetAddressLookup lookupType, 
								double*	Latitude,
								double* Longitude,
								double*	hpe,
								int*	nap,
								double*	speed,
								double*	bearing,
								LPWSTR	AddressNumber,
								LPWSTR	AddressLine,
								LPWSTR	City,
								LPWSTR	StateName,
								LPWSTR	StateCode,
								LPWSTR	PostalCode,
								LPWSTR	County,
								LPWSTR	Region,
								LPWSTR	CountryName,
								LPWSTR	CountryCode,
								LPWSTR  Province
								)
{
	WPS_Location * location = NULL;
	WPS_ReturnCode rc;
	WPS_SimpleAuthentication simpleAuthentication;
	simpleAuthentication.realm = wcstombs(realm);
	simpleAuthentication.username = wcstombs(userName);
	rc = WPS_location(&simpleAuthentication,lookupType,&location);
	delete simpleAuthentication.username;
	delete simpleAuthentication.realm;

	LPWSTR tempBuffer = new TCHAR[MAX_STRING_SIZE];

	if(rc == WPS_OK)
	{
		*Latitude = location->latitude;
		*Longitude = location->longitude;
		*hpe = location->hpe;
		*nap = location->nap;
		*speed = location->speed;
		*bearing = location->bearing;

		if(location->street_address!=NULL)
		{
			WPS_StreetAddress* streetAddress =  location->street_address;

			if(streetAddress->street_number!=NULL)
				mbstowcs(AddressNumber,streetAddress->street_number,MAX_STRING_SIZE);				
			if(streetAddress->city!=NULL)
				mbstowcs(City,streetAddress->city,MAX_STRING_SIZE);
			
			mbstowcs(StateName,streetAddress->state.name,MAX_STRING_SIZE);
			mbstowcs(StateCode,streetAddress->state.code,3);

			mbstowcs(CountryName,streetAddress->country.name,MAX_STRING_SIZE);
			mbstowcs(CountryCode,streetAddress->country.code,MAX_STRING_SIZE);

			if(streetAddress->county!=NULL)
			{
				mbstowcs(County,streetAddress->county,MAX_STRING_SIZE);
			}
			if(streetAddress->postal_code!=NULL)
			{
				mbstowcs(PostalCode,streetAddress->postal_code,MAX_STRING_SIZE);
			}
			if(streetAddress->region!=NULL)
			{
				mbstowcs(Region,streetAddress->region,MAX_STRING_SIZE);
			}
			if(streetAddress->province!=NULL)
			{
				mbstowcs(Province,streetAddress->province,MAX_STRING_SIZE);
			}

			for (int i=0;location->street_address->address_line[i]!=NULL;++i)
			{
				mbstowcs(tempBuffer,location->street_address->address_line[i],MAX_STRING_SIZE);
				wcsncat(AddressLine,tempBuffer,MAX_STRING_SIZE);
				if(location->street_address->address_line[i+1]!=NULL)
				{
					wcsncat(AddressLine,L"\r\n",MAX_STRING_SIZE);
				}
			}
		}
		delete tempBuffer;
		WPS_free_location(location);
	}
	return rc;
}





  static char* wcstombs(const wchar_t* src)
{
    size_t length = WideCharToMultiByte(CP_ACP, 0, src, -1,
                                        NULL, 0, NULL, NULL);
    if (!length)
        return NULL;

    char* buffer = new char[length];
    WideCharToMultiByte(CP_ACP, 0, src, -1,
                        buffer, length, NULL, NULL);

    return buffer;
}

static wchar_t* mbstowcs(const char* src)
{
    size_t length = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
    if (!length)
        return (wchar_t*) -1;

    wchar_t* buffer = new wchar_t[length];
    MultiByteToWideChar(CP_ACP, 0, src, -1, buffer, length);

    return buffer;
}

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 attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering. I've largely developed solutions that are based on a mix of Microsoft technologies with open source technologies mixed in. I've got an interest in astronomy and you'll see that interest overflow into some of my code project articles from time to time.



Twitter:@j2inet

Instagram: j2inet


Comments and Discussions