#include "CGGBlueTooth.h"
//#include "tchar.h"
CGGBlueTooth::CGGBlueTooth()
: m_hLookup(NULL)
, m_hSocket(NULL)
{
memset(&m_sktAddr, 0, sizeof(m_sktAddr));
}
CGGBlueTooth::~CGGBlueTooth()
{
EndSearchBthDev();
Close();
}
void CGGBlueTooth::HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac)
{
BYTE *pbAddr = (BYTE*)&dw64Addr;
/*
sprintf(
pstrMac, _T("%02X:%02X:%02X:%02X:%02X:%02X"),
pbAddr[5], pbAddr[4], pbAddr[3],
pbAddr[2], pbAddr[1], pbAddr[0]
);*/
}
BOOL CGGBlueTooth::StartSearchBthDev(IN DWORD dwControlFlags)
{
WSAQUERYSET wsaq;
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;
return WSALookupServiceBegin(&wsaq, dwControlFlags, &m_hLookup) == ERROR_SUCCESS ? TRUE : FALSE;
}
BOOL CGGBlueTooth::GetNextBthDev(
IN OUT BTHDEV_INFO *pcBthDevInfo,
IN DWORD dwControlFlags /* = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE*/
)
{
if (!m_hLookup || !pcBthDevInfo)
{
return FALSE;
}
memset(pcBthDevInfo->szAddr, 0, sizeof(pcBthDevInfo->szAddr));
memset(pcBthDevInfo->szName, 0, sizeof(pcBthDevInfo->szName));
union
{
CHAR buf[5000];
double __unused; // ensure proper alignment
};
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)buf;
DWORD dwSize = sizeof(buf);
int nResult;
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob = NULL;
nResult = WSALookupServiceNext(m_hLookup, dwControlFlags, &dwSize, pwsaResults);
if (nResult == ERROR_SUCCESS)
{
pcBthDevInfo->btAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
BOOL bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
if (bHaveName)
{
HexMac2String(pcBthDevInfo->btAddr, pcBthDevInfo->szAddr);
strcpy(pcBthDevInfo->szName, pwsaResults->lpszServiceInstanceName);
}
return TRUE;
}
return FALSE;
}
BOOL CGGBlueTooth::EndSearchBthDev()
{
if (m_hLookup)
{
WSALookupServiceEnd(m_hLookup);
m_hLookup = NULL;
return TRUE;
}
return FALSE;
}
///===============================
BOOL CGGBlueTooth::Create(int af/* = AF_BTH*/, int type/* = SOCK_STREAM*/, int protocol/* = BTHPROTO_RFCOMM*/)
{
/*
if (m_hSocket)
{
return FALSE;
}*/
m_hSocket = socket(af, type, protocol);
m_sktAddr.addressFamily = af;
// m_sktAddr.serviceClassId = GUID_NULL;
return m_hSocket == INVALID_SOCKET ? FALSE : TRUE;
}
BOOL CGGBlueTooth::Close()
{
if (m_hSocket)
{
closesocket(m_hSocket);
return TRUE;
}
return FALSE;
}
int CGGBlueTooth::Bind(BTH_ADDR sktAddr/* = 0*/, ULONG port/* = BT_PORT_ANY*/)
{
m_sktAddr.btAddr = sktAddr;
m_sktAddr.port = (port);
struct sockaddr_in servaddr; // 服务端地址信息的数据结构。
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。
//servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
servaddr.sin_port = port;
return bind(m_hSocket, (SOCKADDR *)&m_sktAddr, sizeof(m_sktAddr));
}
int CGGBlueTooth::Listen(int backlog)
{
return listen(m_hSocket, backlog);
}
int CGGBlueTooth::GetSockName(BTH_ADDR *psktAddr, ULONG *port)
{
int nLen = sizeof(m_sktAddr);
int nResult = getsockname(m_hSocket, (SOCKADDR *)&m_sktAddr, &nLen);
if (nResult == 0)
{
*psktAddr = m_sktAddr.btAddr;
*port = m_sktAddr.port;
}
return nResult;
}
//35111C00 0011 0100 00 10 00 80 00 00 80 5F 9B 34 FB
GUID OBEXFileTransferServiceClass_UUID_EX = { 0x00001106, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
GUID COMTransferServiceClass_UUID_EX = { 0x00000003,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5F,0x9B,0x34,0xFB };
//GUID COMTransferServiceClass_UUID_EX = { 0x35111C00,0x0011,0x0100,0x00,0x10,0x00,0x80,0x5F,0x9B,0x34,0xFB };
int CGGBlueTooth::SetBthService(TCHAR * lpServiceName)
{
CSADDR_INFO sockInfo;
sockInfo.iProtocol = BTHPROTO_RFCOMM;
sockInfo.iSocketType = SOCK_STREAM;
sockInfo.LocalAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
sockInfo.LocalAddr.iSockaddrLength = sizeof(m_sktAddr);
sockInfo.RemoteAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
sockInfo.RemoteAddr.iSockaddrLength = sizeof(m_sktAddr);
WSAQUERYSET svcInfo = { 0 };
svcInfo.dwSize = sizeof(svcInfo);
svcInfo.dwNameSpace = NS_BTH;
svcInfo.lpszServiceInstanceName = lpServiceName;
svcInfo.lpServiceClassId = &COMTransferServiceClass_UUID_EX;
svcInfo.dwNumberOfCsAddrs = 1;
svcInfo.lpcsaBuffer = &sockInfo;
return WSASetService(&svcInfo, RNRSERVICE_REGISTER, 0);
}
int CGGBlueTooth::Accept(CGGBlueTooth *pcBth)
{
SOCKADDR_BTH ca;
int size = sizeof(ca);
pcBth->m_hSocket = accept(m_hSocket, (SOCKADDR *)&ca, &size);
pcBth->m_sktAddr = ca;
return pcBth->m_hSocket == INVALID_SOCKET ? SOCKET_ERROR : 0;
}
int CGGBlueTooth::Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond/* = -1*/)
{
SOCKADDR_BTH sa = { 0 };
sa.addressFamily = AF_BTH;
sa.btAddr = sktAddr;
sa.port = port;
sa.serviceClassId = COMTransferServiceClass_UUID_EX;
if (nMSecond == -1)
{
return connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH));
}
ULONG non_blocking = 1;
ULONG blocking = 0;
int nResult = ioctlsocket(m_hSocket, FIONBIO, &non_blocking);
if (nResult == SOCKET_ERROR)
{
return nResult;
}
nResult = SOCKET_ERROR;
if (connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
{
struct timeval tv;
fd_set writefds;
// �������ӳ�ʱʱ��
tv.tv_sec = nMSecond / 1000; // ����
tv.tv_usec = nMSecond % 1000; // ����
FD_ZERO(&writefds);
FD_SET(m_hSocket, &writefds);
nResult = select((int)m_hSocket + 1, NULL, &writefds, NULL, &tv);
if (nResult > 0)
{
if (FD_ISSET(m_hSocket, &writefds))
{
int error = 0;
int len = sizeof(error);
//������һ��һ��Ҫ����Ҫ���Է���ǽ
if (!(getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0 || error != 0))
{
nResult = 0;
}
}
}
else if (nResult == 0)
{
nResult = -2;
}
}
if (ioctlsocket(m_hSocket, FIONBIO, &blocking) == SOCKET_ERROR)
{
nResult = SOCKET_ERROR;
}
return nResult;
}
int CGGBlueTooth::Send(LPVOID lpData, int len, int flags/* = 0*/)
{
return send(m_hSocket, (char *)lpData, len, flags);
}
int CGGBlueTooth::Recv(LPVOID lpData, int len, int flags/* = 0*/)
{
return recv(m_hSocket, (char *)lpData, len, flags);
}
int CGGBlueTooth::SendAll(LPVOID lpData, int len, int flags/* = 0*/)
{
int nCount = send(m_hSocket, (char *)lpData, len, flags);
if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
{
return SOCKET_ERROR;
}
int nCommand = 0;
nCount = recv(m_hSocket, (char *)&nCommand, 4, flags);
if (nCount != 4 || nCommand != RECEIVE_OVER_COMMAND)
{
return SOCKET_ERROR;
}
return ERROR_SUCCESS;
}
int CGGBlueTooth::RecvAll(LPVOID lpData, int len, int flags/* = 0*/)
{
int nCount = -1, nCurRecv = 0, nMaxRead = 32 * 1024;
while (nCurRecv < len)
{
if (len - nCurRecv < nMaxRead)
{
nMaxRead = len - nCurRecv;
}
nCount = recv(m_hSocket, (char *)lpData + nCurRecv, nMaxRead, flags);
if (nCount == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
Sleep(1);
continue;
}
else
{
return SOCKET_ERROR;
}
}
nCurRecv += nCount;
}
int nCommand = RECEIVE_OVER_COMMAND;
nCount = send(m_hSocket, (char *)&nCommand, 4, flags);
if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK