Asked by:
Failed to connect server via USB bluetooth dongle

Question
-
Hi, I am developing a Windows application which communicates with an app on a mobile device via bluetooth. However, the Windows Application failed to connect the app on mobile.
To simplify the problem, I use another windows application with an USB Bluetooth dongle to replace mobile side application, and listen connections of my application on client side.
The emulator server program runs on XP SP3 with USB Bluetooth dongle. It does below jobs
1. Assigns a bth local port and bind on a socket
2. Advertise a service
3. Listen on the socket and block at accept
The client program runs on XP SP3 with another USB Bluetooth dongle. I can find the Bluetooth device and advertised service on server side by BlueScanner (https://labs.arubanetworks.com/). The client connects with specified serviceClassId and/or port number. Unfortunately, connect failed either at 10051, or 10022.
I also tried to change the port number to be BT_PORT_ANY on both server and client side, unfortunately, still failed to connect server.
My program is from http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedotherprotocol4q.html. I also pasted it as below, can you help to see what’s problems in my code?
- Moved by Max Wang_1983 Wednesday, April 27, 2011 10:06 PM forum consolidation (From:Networking)
Monday, April 25, 2011 1:08 PM
All replies
-
The two function exceeds 60K?
// 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;
BOOL bContinue;
// Both of these fixed-size allocations can be on the stack
if ( ( lpCSAddrInfo = (LPCSADDR_INFO) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSADDR_INFO) ) ) == NULL)
{
printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
ulRetCode = 1;
goto CleanupAndExit;
}
else
printf("HeapAlloc() for CSADDR_INFO (address) is OK!\n");
if ( ( lptstrThisComputerName = (LPTSTR) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwLenComputerName ) ) == NULL)
{
printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
ulRetCode = 1;
goto CleanupAndExit;
}
else
printf("HeapAlloc() for CSADDR_INFO (local computer name) is OK!\n");
if ( !GetComputerName(lptstrThisComputerName, &dwLenComputerName) )
{
printf("=CRITICAL= | GetComputerName() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
else
{
printf("GetComputerName() is pretty fine!\n");
printf("Local computer name: %S\n", lptstrThisComputerName);
}
// Open a bluetooth socket using RFCOMM protocol
printf("Opening local socket using socket()...\n");
if ( ( LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM) ) == INVALID_SOCKET)
{
printf("=CRITICAL= | socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( (2 <= g_iOutputLevel) | (LocalSocket != INVALID_SOCKET))
{
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;
// Valid ports are 1 - 31
//SockAddrBthLocal.port = BT_PORT_ANY;
SockAddrBthLocal.port = 5;
// 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 ( bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH) ) == SOCKET_ERROR)
{
printf("=CRITICAL= | bind() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( (2 <= g_iOutputLevel) | (bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH) ) != SOCKET_ERROR))
{
printf("*INFO* | bind() call succeeded!\n");
}
if ( ( ulRetCode = getsockname(LocalSocket, (struct sockaddr *)&SockAddrBthLocal, &iAddrLen) ) == SOCKET_ERROR)
{
printf("=CRITICAL= | getsockname() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
else
{
printf("getsockname() is pretty fine!\n");
printf("Local address: 0x%x\n", SockAddrBthLocal.btAddr);
}
// 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;
// should be something like "Sample Bluetooth Server"
wsaQuerySet.lpszServiceInstanceName = lptstrThisComputerName;
wsaQuerySet.lpszComment = L"Example Service instance registered in the directory service through RnR";
wsaQuerySet.dwNameSpace = NS_BTH;
wsaQuerySet.dwNumberOfCsAddrs = 1; // Must be 1.
wsaQuerySet.lpcsaBuffer = lpCSAddrInfo; // Required.
// 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 ( WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
{
printf("=CRITICAL= | WSASetService() call failed. Error=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
else
printf("WSASetService() looks fine!\n");
// listen() call indicates winsock2 to listen on a given socket for any incoming connection.
if ( listen(LocalSocket, SOMAXCONN) == SOCKET_ERROR)
{
printf("=CRITICAL= | listen() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( (2 <= g_iOutputLevel) | (listen(LocalSocket, SOMAXCONN) != SOCKET_ERROR))
{
printf("*INFO* | listen() call succeeded!\n");
}
for ( iCxnCount = 0; (0 == ulRetCode) && ( (iCxnCount < iMaxCxnCycles) || (iMaxCxnCycles == 0) ); iCxnCount++ )
{
printf("\n");
// accept() call indicates winsock2 to wait for any
// incoming connection request from a remote socket.
// If there are already some connection requests on the queue,
// then accept() extracts the first request and creates a new socket and
// returns the handle to this newly created socket. This newly created
// socket represents the actual connection that connects the two sockets.
if ( ( ClientSocket = accept(LocalSocket, NULL, NULL) ) == INVALID_SOCKET)
{
printf("=CRITICAL= | accept() call failed. Error=[%d]\n", WSAGetLastError());
ulRetCode = 1;
break; // Break out of the for loop
}
if ( (2 <= g_iOutputLevel) | (ClientSocket != INVALID_SOCKET))
{
printf("*INFO* | accept() call succeeded. CientSocket = [0x%X]\n", ClientSocket);
}
// Read data from the incoming stream
bContinue = TRUE;
pszDataBufferIndex = &szDataBuffer[0];
while ( bContinue && (iTotalLengthReceived < CXN_TRANSFER_DATA_LENGTH) )
{
// recv() call indicates winsock2 to receive data
// of an expected length over a given connection.
// recv() may not be able to get the entire length
// of data at once. In such case the return value,
// which specifies the number of bytes received,
// can be used to calculate how much more data is
// pending and accordingly recv() can be called again.
iLengthReceived = recv(ClientSocket, pszDataBufferIndex, (CXN_TRANSFER_DATA_LENGTH - iTotalLengthReceived), 0);
switch ( iLengthReceived )
{
case 0: // socket connection has been closed gracefully
printf("Socket connection has been closed gracefully!\n");
bContinue = FALSE;
break;
case SOCKET_ERROR:
printf("=CRITICAL= | recv() call failed. Error=[%d]\n", WSAGetLastError());
bContinue = FALSE;
ulRetCode = 1;
break;
default: // most cases when data is being read
pszDataBufferIndex += iLengthReceived;
iTotalLengthReceived += iLengthReceived;
if ( (2 <= g_iOutputLevel) | (iLengthReceived != SOCKET_ERROR))
{
printf("*INFO* | Receiving data of length = [%d]. Current Total = [%d]\n", iLengthReceived, iTotalLengthReceived);
}
break;
}
}
if (ulRetCode == 0)
{
if ( CXN_TRANSFER_DATA_LENGTH != iTotalLengthReceived )
{
printf("+WARNING+ | Data transfer aborted mid-stream. Expected Length = [%d], Actual Length = [%d]\n",
CXN_TRANSFER_DATA_LENGTH, iTotalLengthReceived);
}
printf("*INFO* | Received following data string from remote device:\n%s\n", szDataBuffer);
// Close the connection
if ( closesocket(ClientSocket) == SOCKET_ERROR)
{
printf("=CRITICAL= | closesocket() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
}
else
{
// Make the connection invalid regardless
ClientSocket = INVALID_SOCKET;
if ( (2 <= g_iOutputLevel) | (closesocket(ClientSocket) != SOCKET_ERROR) )
{
printf("*INFO* | closesocket() call succeeded w/socket=[0x%X]\n", ClientSocket);
}
}
}
}
CleanupAndExit:
if ( INVALID_SOCKET != ClientSocket )
{
closesocket(ClientSocket);
ClientSocket = INVALID_SOCKET;
}
if ( INVALID_SOCKET != LocalSocket )
{
closesocket(LocalSocket);
LocalSocket = INVALID_SOCKET;
}
if ( NULL != lptstrThisComputerName )
{
HeapFree(GetProcessHeap(), 0, lptstrThisComputerName);
lptstrThisComputerName = NULL;
}
if ( NULL != lpCSAddrInfo )
{
HeapFree(GetProcessHeap(), 0, lpCSAddrInfo);
lpCSAddrInfo = NULL;
}
return ulRetCode;
}
Monday, April 25, 2011 1:10 PM -
// 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;
// Valid ports are 1 - 31
SockAddrBthServer.port = 5;
// Create a static data-string, which will be transferred to the remote Bluetooth device
// may make this #define and do strlen() of the string
strncpy_s(szData, sizeof(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 ( ( LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM) ) == INVALID_SOCKET)
{
printf("=CRITICAL= | socket() call failed. Error = [%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( (2 <= g_iOutputLevel) | (LocalSocket != INVALID_SOCKET))
{
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 ( connect(LocalSocket, (struct sockaddr *) &SockAddrBthServer, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
{
printf("=CRITICAL= | connect() call failed. Error=[%d]\n", WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( (2 <= g_iOutputLevel) | (connect(LocalSocket, (struct sockaddr *) &SockAddrBthServer, sizeof(SOCKADDR_BTH)) != SOCKET_ERROR) )
{
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 the following data string:\n\t%s\n", szData);
if ( send(LocalSocket, szData, CXN_TRANSFER_DATA_LENGTH, 0) == SOCKET_ERROR)
{
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]. Error=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
LocalSocket = INVALID_SOCKET;
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | closesocket() call succeeded!");
}
}
CleanupAndExit:
if ( LocalSocket != INVALID_SOCKET)
{
closesocket(LocalSocket);
LocalSocket = INVALID_SOCKET;
}
return ulRetCode;
}
Monday, April 25, 2011 1:10 PM