📄 bthcxn.cpp
字号:
//
if ( SOCKET_ERROR == listen(LocalSocket, SOMAXCONN) )
{
printf("=CRITICAL= | listen() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
goto CleanupAndExit;
}
if ( 2 <= g_iOutputLevel )
{
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 ( INVALID_SOCKET == ( ClientSocket = accept(LocalSocket, NULL, NULL) ) )
{
printf("=CRITICAL= | accept() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
ulRetCode = 1;
break; // Break out of the for loop
}
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | accept() call succeeded. CientSocket = [0x%X]\n", ClientSocket);
}
//
// Read data from the incoming stream
//
BOOL 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
bContinue = FALSE;
break;
case SOCKET_ERROR:
printf("=CRITICAL= | recv() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
bContinue = FALSE;
ulRetCode = 1;
break;
default: // most cases when data is being read
pszDataBufferIndex += iLengthReceived;
iTotalLengthReceived += iLengthReceived;
if ( 2 <= g_iOutputLevel )
{
printf("*INFO* | Receiving data of length = [%d]. Current Total = [%d]\n", iLengthReceived, iTotalLengthReceived);
}
char msg[16];
sprintf(msg, "ECHO %02d!", ++ctr);
send(ClientSocket, msg, (int)strlen(msg), 0);
break;
}
}
if ( 0 == ulRetCode )
{
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 ( SOCKET_ERROR == closesocket(ClientSocket) )
{
printf("=CRITICAL= | closesocket() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
ulRetCode = 1;
}
else
{
//
// Make the connection invalid regardless
//
ClientSocket = INVALID_SOCKET;
if ( 2 <= g_iOutputLevel )
{
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;
}
//
// ShowCmdLineSyntaxHelp displays the command line usage
//
void ShowCmdLineHelp(void)
{
printf(
"\n Bluetooth example application for demonstrating connection and data transfer."
"\n"
"\n"
"\n BTHCxnDemo.exe [-n<RemoteName> | -a<RemoteAddress>] "
"\n [-c<ConnectionCycles>] [-o<Output Level>]"
"\n"
"\n"
"\n Switches applicable for Client mode:"
"\n -n<RemoteName> Specifies name of remote BlueTooth-Device."
"\n"
"\n -a<RemoteAddress> Specifies address of remote BlueTooth-Device."
"\n The address is in form XX:XX:XX:XX:XX:XX"
"\n where XX is a hexidecimal byte"
"\n"
"\n One of the above two switches is required for client."
"\n"
"\n"
"\n Switches applicable for both Client and Server mode:"
"\n -c<ConnectionCycles> Specifies number of connection cycles."
"\n Default value for this parameter is 1. Specify 0 to "
"\n run infinite number of connection cycles."
"\n"
"\n -o<OutputLevel> Specifies level of information reporting in cmd window."
"\n Default value for this parameter is 0 (minimal info)."
"\n Possible values: 1 (more info), 2 (all info)."
"\n"
"\n"
"\n Command Line Examples:"
"\n \"BTHCxnDemo.exe -c0\""
"\n Runs the BTHCxnDemo server for infinite connection cycles."
"\n The application reports minimal information onto the cmd window."
"\n"
"\n \"BTHCxnDemo.exe -nServerDevice -c50 -o2\""
"\n Runs the BTHCxnDemo client connecting to remote device (having name "
"\n \"ServerDevice\" for 50 connection cycles."
"\n The application reports minimal information onto the cmd window."
"\n"
);
}
//
// ParseCmdLine parses the command line and sets the global variables accordingly.
// It returns 0 if successful, returns 1 if command line usage is to be displayed,
// returns 2 in case of any other error while parsing
//
ULONG ParseCmdLine (IN int argc, IN char * argv[])
{
int iStrLen = 0;
ULONG ulRetCode = 0;
for ( int i = 1; i < argc; i++ )
{
char * pszToken = argv[i];
if ( *pszToken == '-' || *pszToken == '/' )
{
char token;
//
// skip over the "-" or "/"
//
pszToken++;
//
// Get the command line option
//
token = *pszToken;
//
// Go one past the option the option-data
//
pszToken++;
//
// Get the option-data
//
switch ( token )
{
case 'n':
iStrLen = lstrlen(pszToken);
if ( (0 < iStrLen) && (BTH_MAX_NAME_SIZE >= iStrLen) )
{
lstrcpy(g_szRemoteName, pszToken);
}
else
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Unable to parse -n<RemoteName>, length error (min 1 char, max %d chars)\n", BTH_MAX_NAME_SIZE);
}
break;
case 'a':
iStrLen = lstrlen(pszToken);
if ( CXN_BDADDR_STR_LEN == iStrLen )
{
lstrcpy(g_szRemoteAddr, pszToken);
}
else
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Unable to parse -a<RemoteAddress>, Remote bluetooth radio address string length expected %d | Found: %d)\n", CXN_BDADDR_STR_LEN, iStrLen);
}
break;
case 'c':
if ( 0 < lstrlen(pszToken) )
{
sscanf(pszToken,"%d", &g_ulMaxCxnCycles);
if ( 0 > g_ulMaxCxnCycles )
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Must provide +ve or 0 value with -c option\n");
}
}
else
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Must provide a value with -c option\n");
}
break;
case 'o':
if ( 0 < lstrlen(pszToken) )
{
sscanf(pszToken,"%d", &g_iOutputLevel);
if ( 0 > g_iOutputLevel )
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Must provide a +ve or 0 value with -o option");
}
}
else
{
ulRetCode = 2;
printf("!ERROR! | cmd line | Must provide a value with -o option");
}
break;
case '?':
case 'h':
case 'H':
default:
ulRetCode = 1;
}
}
else
{
ulRetCode = 1;
printf("!ERROR! | cmd line | Bad option prefix, use '/' or '-' \n");
}
}
return ulRetCode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -