BlueTooth_WM.cpp
上传用户:hbzxgg2
上传日期:2009-03-28
资源大小:291k
文件大小:12k
源码类别:
Windows Mobile
开发平台:
Visual C++
- #include "StdAfx.h"
- #include "BlueTooth_WM.h"
- // for PORTEMUPortParams
- #include <bt_api.h>
- DEFINE_GUID(SerialPortServiceClass_UUID, 0x00001101, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB);
- DWORD WINAPI ThreadProc_ScanNearbyBthDev(
- LPVOID lpParameter // thread data
- )
- {
- CBlueTooth_WM *pBlueTooth_WM = reinterpret_cast<CBlueTooth_WM*>(lpParameter);
- if ( pBlueTooth_WM )
- pBlueTooth_WM->ThreadProc_ScanNearbyBthDev ();
- return TRUE;
- }
- CBlueTooth_WM::CBlueTooth_WM(void)
- : m_hThread_ScanNearbyBthDev ( NULL )
- , m_dwThreadID_ScanNearbyBthDev ( 0 )
- , m_hEvtEndModule ( NULL )
- , m_hEvt_Notify_ScanNearbyBthDev ( NULL )
- , m_hWnd_Noify_ScanNearbyBthDev ( NULL )
- , m_socketClient ( INVALID_SOCKET )
- {
- m_Ary_RemoteBthDevInfo.SetSize ( 0, 10*sizeof(t_RemoteBthDevInfo) );
- }
- CBlueTooth_WM::~CBlueTooth_WM(void)
- {
- if ( HANDLE_IS_VALID(m_hEvtEndModule) )
- ::SetEvent ( m_hEvtEndModule );
- WaitForThreadEnd ( &m_hThread_ScanNearbyBthDev, 10*1000 );
- SAFE_CLOSE_HANDLE ( m_hEvtEndModule );
- if ( m_socketClient != INVALID_SOCKET )
- closesocket ( m_socketClient );
- RemoveAll_RemoteBthDevInfo ();
- }
- //
- // 调用该类中任何函数之前必须先调用该函数来初始化
- //
- BOOL CBlueTooth_WM::Init ( LPCTSTR lpszCurDir )
- {
- m_hEvtEndModule = ::CreateEvent ( NULL, TRUE, FALSE, NULL );
- if ( !HANDLE_IS_VALID(m_hEvtEndModule) )
- return FALSE;
- m_csCurDir = GET_SAFE_STRING(lpszCurDir);
- Read_RemoteBthDevInfo_FromFile ( m_csCurDir );
- return TRUE;
- }
- void CBlueTooth_WM::ThreadProc_ScanNearbyBthDev ()
- {
- int nRetValue = ScanNearbyBthDev_Direct ();
- if ( HANDLE_IS_VALID(m_hEvt_Notify_ScanNearbyBthDev) )
- SetEvent ( m_hEvt_Notify_ScanNearbyBthDev );
- if ( IsWindow(m_hWnd_Noify_ScanNearbyBthDev) )
- PostMessage ( m_hWnd_Noify_ScanNearbyBthDev, WM_SCAN_BLUETOOTH_DEVICE_FINISHED, nRetValue, 0 );
- SAFE_CLOSE_HANDLE ( m_hThread_ScanNearbyBthDev );
- TRACE ( L"ThreadProc_ScanNearbyBthDev ENDn" );
- }
- //
- // 搜索附近的蓝牙设备,如果指定 hEvt_Notify 或 hWnd_Noify 参数,表示异步查找,完成后以这两个参数中的一个通知调用者
- // 如果这两个参数都未指定,表示同步查找,即完成后才会返回
- //
- BOOL CBlueTooth_WM::ScanNearbyBthDev ( HANDLE hEvt_Notify/*=NULL*/, HWND hWnd_Noify/*=NULL*/ )
- {
- if ( HANDLE_IS_VALID(m_hThread_ScanNearbyBthDev) ) return TRUE;
- // 异步查找蓝牙设备,启动查找函数
- if ( hEvt_Notify || IsWindow(hWnd_Noify) )
- {
- m_hEvt_Notify_ScanNearbyBthDev = hEvt_Notify;
- m_hWnd_Noify_ScanNearbyBthDev = hWnd_Noify;
- m_hThread_ScanNearbyBthDev = ::CreateThread ( NULL, 0, ::ThreadProc_ScanNearbyBthDev, this, 0, &m_dwThreadID_ScanNearbyBthDev );
- return HANDLE_IS_VALID(m_hThread_ScanNearbyBthDev);
- }
- return ( ScanNearbyBthDev_Direct() >= 0 );
- }
- //
- // 用 Socket 函数搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
- //
- int CBlueTooth_WM::ScanNearbyBthDev_Direct ()
- {
- m_Ary_RemoteBthDevInfo.RemoveAll ();
- SetWaitCursor ();
- WSAQUERYSET querySet;
- HANDLE hLookup;
- DWORD flags = LUP_RETURN_NAME | LUP_RETURN_ADDR;
- union
- {
- CHAR buf[5000];
- double __unused; // ensure proper alignment
- };
- LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
- DWORD dwSize = sizeof(buf);
- BOOL bHaveName;
- ZeroMemory(&querySet, sizeof(querySet));
- querySet.dwSize = sizeof(querySet);
- querySet.dwNameSpace = NS_BTH;
- if ( ::WaitForSingleObject ( m_hEvtEndModule, 0 ) == WAIT_OBJECT_0 )
- return -1;
- if (ERROR_SUCCESS != WSALookupServiceBegin (&querySet, LUP_CONTAINERS, &hLookup))
- {
- ResotreCursor ();
- MsgBoxErr ( _T("WSALookupServiceBegin failed") );
- return (-1);
- }
- ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
- pwsaResults->dwSize = sizeof(WSAQUERYSET);
- pwsaResults->dwNameSpace = NS_BTH;
- pwsaResults->lpBlob = NULL;
- BOOL bError = FALSE;
- while ( TRUE )
- {
- if ( ::WaitForSingleObject ( m_hEvtEndModule, 0 ) == WAIT_OBJECT_0 )
- break;
- if ( ERROR_SUCCESS == WSALookupServiceNext (hLookup, flags, &dwSize, pwsaResults) )
- {
- ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
- BT_ADDR b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
- bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
- t_RemoteBthDevInfo RemoteBthDevInfo;
- if ( bHaveName )
- {
- hwSnprintf ( RemoteBthDevInfo.szName, sizeof(RemoteBthDevInfo.szName), _T("%s"),
- pwsaResults->lpszServiceInstanceName );
- }
- RemoteBthDevInfo.RemoteAddr = b;
- CSADDR_INFO* pCSAddr = (CSADDR_INFO *)pwsaResults->lpcsaBuffer;
- RemoteBthDevInfo.LocalAddr = ((SOCKADDR_BTH *)pCSAddr->LocalAddr.lpSockaddr)->btAddr;
- TRACE (L"%s ( %04x%08x )n", RemoteBthDevInfo.szName, GET_NAP(b), GET_SAP(b) );
- Add_RemoteBthDevInfo ( RemoteBthDevInfo );
- }
- else
- {
- if ( WSAGetLastError() != WSA_E_NO_MORE )
- {
- bError = TRUE;
- ResotreCursor ();
- MsgBoxErr ( L"Lookup bluetooth device failed" );
- }
- break;
- }
- }
- WSALookupServiceEnd(hLookup);
- ResotreCursor ();
- if ( bError ) return (-1);
- return (int)m_Ary_RemoteBthDevInfo.GetSize();
- }
- CString CBlueTooth_WM::FormatBthAddress(BT_ADDR BthAddress)
- {
- ASSERT ( BthAddress );
- BLUETOOTH_ADDRESS Address;
- BYTE *pAddress = (BYTE*)&BthAddress;
- CString csBthAddress;
- for ( int i=0; i<LENGTH(Address.rgBytes); i++ )
- {
- CString csNode;
- csNode.Format ( _T("%.2x"), pAddress[LENGTH(Address.rgBytes)-i-1] );
- if ( !csBthAddress.IsEmpty() ) csBthAddress += ":";
- csBthAddress += csNode;
- }
- return csBthAddress;
- }
- int CBlueTooth_WM::Find_RemoteBthDevInfo ( LPCTSTR lpszName_Found, t_RemoteBthDevInfo *pRemoteBthDevInfo/*=NULL*/ )
- {
- if ( !lpszName_Found || strlen_s(lpszName_Found) < 1 ) return -1;
- for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i++ )
- {
- t_RemoteBthDevInfo &RemoteBthDevInfoRef = m_Ary_RemoteBthDevInfo.GetAt(i);
- if ( stricmp_s ( RemoteBthDevInfoRef.szName, lpszName_Found ) == 0 )
- {
- if ( pRemoteBthDevInfo )
- {
- memcpy ( pRemoteBthDevInfo, &RemoteBthDevInfoRef, sizeof(t_RemoteBthDevInfo) );
- }
- return i;
- }
- }
- return -1;
- }
- int CBlueTooth_WM::Find_RemoteBthDevInfo ( BT_ADDR Addr_Found, t_RemoteBthDevInfo *pRemoteBthDevInfo/*=NULL*/ )
- {
- for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i++ )
- {
- t_RemoteBthDevInfo &RemoteBthDevInfoRef = m_Ary_RemoteBthDevInfo.GetAt(i);
- if ( RemoteBthDevInfoRef.RemoteAddr == Addr_Found )
- {
- if ( pRemoteBthDevInfo )
- {
- memcpy ( pRemoteBthDevInfo, &RemoteBthDevInfoRef, sizeof(t_RemoteBthDevInfo) );
- }
- return i;
- }
- }
- return -1;
- }
- int CBlueTooth_WM::Add_RemoteBthDevInfo ( t_RemoteBthDevInfo &RemoteBthDevInfo )
- {
- if ( Find_RemoteBthDevInfo ( RemoteBthDevInfo.RemoteAddr ) >= 0 )
- return TRUE;
- m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
- }
- void CBlueTooth_WM::RemoveAll_RemoteBthDevInfo(void)
- {
- Save_RemoteBthDevInfo_ToFile ( m_csCurDir );
- for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i++ )
- {
- t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt(i);
- }
- m_Ary_RemoteBthDevInfo.RemoveAll ();
- }
- //
- // 将周边蓝牙设备信息保存到文件中,这样就可以不用每次都重新搜索蓝牙设备了,只要当连接蓝牙设备失败的时候再重新搜索
- //
- BOOL CBlueTooth_WM::Save_RemoteBthDevInfo_ToFile(LPCTSTR lpszPath)
- {
- CString csFileName;
- csFileName.Format ( L"%sRemoteBthInfo.info", GET_SAFE_STRING(lpszPath) );
- CFile file;
- BOOL bRet = TRUE;
- TRY
- {
- if ( file.Open ( csFileName, CFile::modeCreate|CFile::modeWrite) )
- {
- for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i++ )
- {
- t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt(i);
- file.Write ( &RemoteBthDevInfo, sizeof(RemoteBthDevInfo) );
- }
- }
- }
- CATCH( CFileException, e )
- {
- e->Delete ();
- bRet = FALSE;
- }
- END_CATCH
- if ( HANDLE_IS_VALID ( file.m_hFile ) )
- file.Close ();
- return bRet;
- }
- //
- // 从文件中读取上次保存的周边蓝牙设备信息,结果保存到 m_Ary_RemoteBthDevInfo 数组中
- //
- BOOL CBlueTooth_WM::Read_RemoteBthDevInfo_FromFile(LPCTSTR lpszPath)
- {
- CString csFileName;
- csFileName.Format ( L"%sRemoteBthInfo.info", GET_SAFE_STRING(lpszPath) );
- CFile file;
- BOOL bRet = TRUE;
- TRY
- {
- if ( file.Open ( csFileName, CFile::modeRead) )
- {
- while ( TRUE )
- {
- t_RemoteBthDevInfo RemoteBthDevInfo;
- if ( file.Read ( &RemoteBthDevInfo, sizeof(t_RemoteBthDevInfo) ) != sizeof(t_RemoteBthDevInfo) )
- break;
- else
- {
- Add_RemoteBthDevInfo ( RemoteBthDevInfo );
- }
- }
- }
- }
- CATCH( CFileException, e )
- {
- e->Delete ();
- bRet = FALSE;
- }
- END_CATCH
- if ( HANDLE_IS_VALID ( file.m_hFile ) )
- file.Close ();
- return bRet;
- }
- BOOL CBlueTooth_WM::StringToGUID ( LPCTSTR lpszGUID, GUID *pGUID)
- {
- if ( !lpszGUID ) return FALSE;
- int data1, data2, data3;
- int data4[8];
- if (11 == sscanf_s(lpszGUID, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02xn",
- &data1, &data2, &data3,
- &data4[0], &data4[1], &data4[2], &data4[3],
- &data4[4], &data4[5], &data4[6], &data4[7])) {
- pGUID->Data1 = data1;
- pGUID->Data2 = data2 & 0xffff;
- pGUID->Data3 = data3 & 0xffff;
- for (int i = 0 ; i < 8 ; ++i)
- pGUID->Data4[i] = data4[i] & 0xff;
- return TRUE;
- }
- return FALSE;
- }
- //
- // 连接到蓝牙服务器中的某一个服务,成功返回0,失败返回错误代码
- //
- int CBlueTooth_WM::ConnectToBlueToothServer ( BT_ADDR ServerAddress, LPCTSTR lpszServiceGUID )
- {
- if ( m_socketClient==INVALID_SOCKET )
- {
- GUID ServerGuid;
- if ( !StringToGUID(lpszServiceGUID, &ServerGuid) )
- return -1;
- m_socketClient = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);
- if (m_socketClient == INVALID_SOCKET)
- {
- return WSAGetLastError();
- }
- SOCKADDR_BTH sa;
- memset (&sa, 0, sizeof(sa));
- sa.addressFamily = AF_BT;
- sa.serviceClassId = ServerGuid;
- sa.btAddr = ServerAddress;
- if (connect (m_socketClient, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR)
- {
- m_socketClient = INVALID_SOCKET;
- return WSAGetLastError();
- }
- }
- // Set nonblocking of socket
- /* long cmd = FIONBIO;
- u_long argp = 1; // 0 表示阻塞, 非0 表示非阻塞
- BOOL err = ioctlsocket ( m_socketClient, cmd, (u_long*)&argp );
- if ( err )
- {
- TRACE ( L"Set main socket to(#1) nonblocking failed!n" );
- }
- */
- return 0;
- }
- //
- // 断开连接
- //
- void CBlueTooth_WM::Disconnect ()
- {
- if ( m_socketClient==INVALID_SOCKET ) return;
- shutdown ( m_socketClient, SD_BOTH );
- closesocket ( m_socketClient );
- m_socketClient = INVALID_SOCKET;
- }
- //
- // 数据传输(收/发)
- // 返回成功传输的字节数。失败时返回 -1;连接已经断开,返回 -2;处理不能立即完成,返回-3
- //
- int CBlueTooth_WM::Transmite ( LPVOID lpData, int nSize, BOOL bSend )
- {
- if ( m_socketClient==INVALID_SOCKET ) return -1;
- if ( !lpData ) return -1;
- if ( nSize < 1 ) return 0;
- int iBytesTransmited = 0;
- if ( bSend )
- iBytesTransmited = send (m_socketClient, (char *)lpData, nSize, 0);
- else
- iBytesTransmited = recv (m_socketClient, (char *)lpData, nSize, 0);
- if ( iBytesTransmited > 0 ) return iBytesTransmited;
- int nLastError = WSAGetLastError ();
- if ( nLastError == WSAENETDOWN || nLastError == WSAENOTCONN || nLastError == WSAENOTSOCK || nLastError == WSAESHUTDOWN ||
- nLastError == WSAETIMEDOUT )
- {
- Disconnect ();
- return -2;
- }
- if ( nLastError == WSAEWOULDBLOCK )
- return -3;
- return -1;
- }
- //
- // 发送数据
- // 返回成功发送的字节数。失败时返回 -1;连接已经断开,返回 -2;处理不能立即完成,返回-3
- //
- int CBlueTooth_WM::Send ( LPVOID lpData, int nSize )
- {
- return Transmite ( lpData, nSize, TRUE );
- }
- //
- // 接收数据
- // 返回接受到的字节数。失败时返回 -1;连接已经断开,返回 -2;处理不能立即完成,返回-3
- //
- int CBlueTooth_WM::Recv ( LPVOID lpData, int nSize )
- {
- // 得到可读的数据长度
- long cmd = FIONREAD;
- u_long argp = 0;
- BOOL err = ioctlsocket ( m_socketClient, cmd, (u_long*)&argp );
- if ( err || argp < 1 )
- {
- return 0;
- }
- return Transmite ( lpData, nSize, FALSE );
- }