📄 bthcxn.cpp
字号:
pWSAQuerySet = NULL;
}
if ( bRemoteDeviceFound )
{
return(0);
}
else
{
return(1);
}
}
//
// Convert a formatted BTH address string to populate a BTH_ADDR (actually a ULONGLONG)
//
ULONG AddrStringToBtAddr(IN const char * pszRemoteAddr, OUT BTH_ADDR * pRemoteBtAddr)
{
ULONG ulAddrData[6], ulRetCode = 0;
BTH_ADDR BtAddrTemp = 0;
if ( ( NULL == pszRemoteAddr ) || ( NULL == pRemoteBtAddr ) )
{
ulRetCode = 1;
goto CleanupAndExit;
}
*pRemoteBtAddr = 0;
//
// Populate a 6 membered array of unsigned long integers
// by parsing the given address in string format
//
sscanf(pszRemoteAddr,
"%02x:%02x:%02x:%02x:%02x:%02x",
&ulAddrData[0],&ulAddrData[1],&ulAddrData[2],&ulAddrData[3],&ulAddrData[4],&ulAddrData[5]);
//
// Construct a BTH_ADDR from the 6 integers stored in the array
//
for ( int i=0; i<6; i++ )
{
//
// Extract data from the first 8 lower bits.
//
BtAddrTemp = (BTH_ADDR)( ulAddrData[i] & 0xFF );
//
// Push 8 bits to the left
//
*pRemoteBtAddr = ( (*pRemoteBtAddr) << 8 ) + BtAddrTemp;
}
CleanupAndExit:
return ulRetCode;
}
//
// RunClientMode runs the application in client mode. It opens a socket, connects it to a
// remote socket, transfer some data over the connection and closes the connection.
//
ULONG RunClientMode(ULONGLONG ululRemoteAddr, int iMaxCxnCycles)
{
ULONG ulRetCode = 0;
int iCxnCount = 0;
char szData[CXN_TRANSFER_DATA_LENGTH] = {0};
SOCKET LocalSocket = INVALID_SOCKET;
SOCKADDR_BTH SockAddrBthServer = {0};
//
// Setting address family to AF_BTH indicates winsock2 to use Bluetooth sockets
// Port should be set to 0 if ServiceClassId is spesified.
//
SockAddrBthServer.addressFamily = AF_BTH;
SockAddrBthServer.btAddr = (BTH_ADDR) ululRemoteAddr;
SockAddrBthServer.serviceClassId = g_guidServiceClass;
SockAddrBthServer.port = 0;
//
// Create a static data-string, which will be transferred to the remote Bluetooth device
//
//
// BUGBUG make this #define and do strlen of the string
//
strncpy(szData, "~!@#$%^&*()-_=+?<>1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", CXN_TRANSFER_DATA_LENGTH - 1);
//
// Run the connection/data-transfer for user specified number of cycles
//
for ( iCxnCount = 0; (0 == ulRetCode) && (iCxnCount < iMaxCxnCycles || iMaxCxnCycles == 0); iCxnCount++ )
{
printf("\n");
//
// Open a bluetooth socket using RFCOMM protocol
//
if ( INVALID_SOCKET == ( LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM) ) )
{
printf("=CRITICAL= | socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | socket() call succeeded. Socket = [0x%X]\n", LocalSocket);
}
if ( 1 <= g_iOutputLevel )
{
printf("*INFO* | connect() attempt with Remote BTHAddr = [0x%X]\n", ululRemoteAddr);
}
//
// Connect the socket (pSocket) to a given remote socket represented by address (pServerAddr)
//
if ( SOCKET_ERROR == connect(LocalSocket, (struct sockaddr *) &SockAddrBthServer, sizeof(SOCKADDR_BTH)) )
{
printf("=CRITICAL= | connect() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | connect() call succeeded\n");
}
//
// send() call indicates winsock2 to send the given data
// of a specified length over a given connection.
//
printf("*INFO* | Sending following data string:\n%s\n", szData);
if ( SOCKET_ERROR == send(LocalSocket, szData, CXN_TRANSFER_DATA_LENGTH, 0) )
{
printf("=CRITICAL= | send() call failed w/socket = [0x%X], szData = [%p], dataLen = [%d]. WSAGetLastError=[%d]\n", LocalSocket, szData, CXN_TRANSFER_DATA_LENGTH, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | send() call succeeded\n");
}
//
// Close the socket
//
if ( SOCKET_ERROR == closesocket(LocalSocket) )
{
printf("=CRITICAL= | closesocket() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
LocalSocket = INVALID_SOCKET;
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | closesocket() call succeeded");
}
}
CleanupAndExit:
if ( INVALID_SOCKET != LocalSocket )
{
closesocket(LocalSocket);
LocalSocket = INVALID_SOCKET;
}
return ulRetCode;
}
//
// RunServerMode runs the application in server mode. It opens a socket, connects it to a
// remote socket, transfer some data over the connection and closes the connection.
//
ULONG RunServerMode(int iMaxCxnCycles)
{
ULONG ulRetCode = 0;
int iAddrLen = sizeof(SOCKADDR_BTH), iCxnCount = 0, iLengthReceived = 0, iTotalLengthReceived = 0;
char szDataBuffer[CXN_TRANSFER_DATA_LENGTH] = {0};
char * pszDataBufferIndex = NULL;
LPTSTR lptstrThisComputerName = NULL;
DWORD dwLenComputerName = MAX_COMPUTERNAME_LENGTH + 1;
SOCKET LocalSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET;
WSAVERSION wsaVersion = {0};
WSAQUERYSET wsaQuerySet = {0};
SOCKADDR_BTH SockAddrBthLocal = {0};
LPCSADDR_INFO lpCSAddrInfo = NULL;
int ctr=0;
//
// BUGBUG both of these fixed-size allocations can be on the stack
//
if ( NULL == ( lpCSAddrInfo = (LPCSADDR_INFO) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSADDR_INFO) ) ) )
{
printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
ulRetCode = 1;
goto CleanupAndExit;
}
if ( NULL == ( lptstrThisComputerName = (LPTSTR) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwLenComputerName ) ) )
{
printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
ulRetCode = 1;
goto CleanupAndExit;
}
if ( !GetComputerName(lptstrThisComputerName, &dwLenComputerName) )
{
printf("=CRITICAL= | GetComputerName() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
//
// Open a bluetooth socket using RFCOMM protocol
//
if ( INVALID_SOCKET == ( LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM) ) )
{
printf("=CRITICAL= | socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | socket() call succeeded. Socket = [0x%X]\n", LocalSocket);
}
//
// Setting address family to AF_BTH indicates winsock2 to use Bluetooth port
//
SockAddrBthLocal.addressFamily = AF_BTH;
SockAddrBthLocal.port = BT_PORT_ANY;
//
// bind() associates a local address and port combination
// with the socket just created. This is most useful when
// the application is a server that has a well-known port
// that clients know about in advance.
//
if ( SOCKET_ERROR == bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH) ) )
{
printf("=CRITICAL= | bind() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | bind() call succeeded\n");
}
if ( SOCKET_ERROR == ( ulRetCode = getsockname(LocalSocket, (struct sockaddr *)&SockAddrBthLocal, &iAddrLen) ) )
{
printf("=CRITICAL= | getsockname() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
//
// CSADDR_INFO
//
lpCSAddrInfo[0].LocalAddr.iSockaddrLength = sizeof( SOCKADDR_BTH );
lpCSAddrInfo[0].LocalAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal;
lpCSAddrInfo[0].RemoteAddr.iSockaddrLength = sizeof( SOCKADDR_BTH );
lpCSAddrInfo[0].RemoteAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal;
lpCSAddrInfo[0].iSocketType = SOCK_STREAM;
lpCSAddrInfo[0].iProtocol = BTHPROTO_RFCOMM;
//
// If we got an address, go ahead and advertise it.
//
ZeroMemory(&wsaQuerySet, sizeof(WSAQUERYSET));
wsaQuerySet.dwSize = sizeof(WSAQUERYSET);
wsaQuerySet.lpServiceClassId = (LPGUID) &g_guidServiceClass;
//
// BUGBUG should be something like "Sample Bluetooth Server"
//
wsaQuerySet.lpszServiceInstanceName = lptstrThisComputerName;
wsaQuerySet.lpszComment = "Example Service instance registered in the directory service through RnR";
wsaQuerySet.dwNameSpace = NS_BTH;
wsaQuerySet.dwNumberOfCsAddrs = 1; // Must be 1.
wsaQuerySet.lpcsaBuffer = lpCSAddrInfo; // Req'd.
//
// As long as we use a blocking accept(), we will have a race
// between advertising the service and actually being ready to
// accept connections. If we use non-blocking accept, advertise
// the service after accept has been called.
//
if ( SOCKET_ERROR == WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) )
{
printf("=CRITICAL= | WSASetService() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
//
// listen() call indicates winsock2 to listen on a given socket for any incoming connection.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -