windows下蓝牙虚拟串口通信
windows下可以通过RFCOMM虚拟的串口进行通信.
RFCOMM简介:
RFCOMM仿真RS232串口,该仿真过程包括非数据通路状态的传输。RFCOMM不限制人工速率或步长,如果通信链路两端的设备都是负责将数据转发到其他通信介质的第二类设备,或在两端RFCOMM设备接口上进行数据传输,实际数据吞吐一般将反映波特率的设置.RFCOMM支持两个设备之间的多串口仿真,也支持多个设备多串口的仿真.
winsock支持RFCOMM,其地址是SOCKADDR_BTH,地址族是AF_BTH.
1.首先把蓝牙名字转换成能链接的地址。
ULONG CBlueTooth::NameToBthAddr( const char *pszRemoteName, PSOCKADDR_BTH pRemoteBtAddr)
{int iResult = CXN_SUCCESS;BOOL bContinueLookup = FALSE, bRemoteDeviceFound = FALSE;ULONG ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSET);HANDLE hLookup = NULL;PWSAQUERYSET pWSAQuerySet = NULL;ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,ulPQSSize);if ( NULL == pWSAQuerySet ) {iResult = STATUS_NO_MEMORY;}if ( CXN_SUCCESS == iResult){for ( int iRetryCount = 0;!bRemoteDeviceFound && (iRetryCount < CXN_MAX_INQUIRY_RETRY);iRetryCount++ ){ ulFlags = LUP_CONTAINERS; ulFlags |= LUP_RETURN_NAME; ulFlags |= LUP_RETURN_ADDR;if ( 0 != iRetryCount ){ ulFlags |= LUP_FLUSHCACHE; Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);}iResult = CXN_SUCCESS;hLookup = 0;bContinueLookup = FALSE;ZeroMemory(pWSAQuerySet, ulPQSSize);pWSAQuerySet->dwNameSpace = NS_BTH;pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);if ( (NO_ERROR == iResult) && (NULL != hLookup) ) {bContinueLookup = TRUE;} else if ( 0 < iRetryCount ){ break;}while ( bContinueLookup ){ if ( NO_ERROR == WSALookupServiceNext(hLookup,ulFlags,&ulPQSSize,pWSAQuerySet) ){if ( ( pWSAQuerySet->lpszServiceInstanceName != NULL ) &&( CXN_SUCCESS == stricmp(pWSAQuerySet->lpszServiceInstanceName, pszRemoteName) ) ){ CopyMemory(pRemoteBtAddr,(PSOCKADDR_BTH) pWSAQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr,sizeof(*pRemoteBtAddr));bRemoteDeviceFound = TRUE;bContinueLookup = FALSE;}} else{iResult = WSAGetLastError();if ( WSA_E_NO_MORE == iResult ){ bContinueLookup = FALSE;}else if ( WSAEFAULT == iResult ){ HeapFree(GetProcessHeap(), 0, pWSAQuerySet);pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,ulPQSSize);if ( NULL == pWSAQuerySet ){ iResult = STATUS_NO_MEMORY;bContinueLookup = FALSE;}}else{ bContinueLookup = FALSE;}}}WSALookupServiceEnd(hLookup);if ( STATUS_NO_MEMORY == iResult ){break;}}}if ( NULL != pWSAQuerySet ){HeapFree(GetProcessHeap(), 0, pWSAQuerySet);pWSAQuerySet = NULL;}if ( bRemoteDeviceFound ){iResult = CXN_SUCCESS;} else{iResult = CXN_ERROR;}return iResult;
}
2.建立链接
//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BTHPORT\Parameters\LocalServices\{00001101-0000-1000-8000-00805f9b34fb}
/*
CBlueTooth:是本模块的底层通讯的类,该类为ECU类提供服务,该类把ECU要发送的类容抽象成类,通过发送和接收缓冲,保存该流的内容,而不管实际的发送或
接收的数据的意义。
*/
DEFINE_GUID(g_guidServiceClass,0x00001101,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5f,0x9b,0x34,0xfb);
//RemoteBthAddr,蓝牙设备的地址SOCKADDR_BTH SockAddrBthServer= RemoteBthAddr;SockAddrBthServer.addressFamily = AF_BTH;SockAddrBthServer.serviceClassId = g_guidServiceClass;SockAddrBthServer.port = 0;if (INVALID_SOCKET != LocalSocket){closesocket(LocalSocket);}LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);if ( INVALID_SOCKET == LocalSocket ){return status;}//建立蓝牙连接if ( 0 == connect(LocalSocket,(struct sockaddr *) &SockAddrBthServer,sizeof(SOCKADDR_BTH)) ) {status=true;}
3.发送数据
ResetEvent(hSendEvent);int sum=0;while (sum < PDU.size()){int iCount=send(LocalSocket,PDU.data()+sum,PDU.size()-sum,0);if (iCount == SOCKET_ERROR){bConnect = false;}sum += iCount;}
4.接收数据
while(1){char buffer[100]={0};int count=recv(LocalSocket,buffer,sizeof(buffer),0);if (count < 0){ continue; }CurSum +=count; if (0 != count){for (int i=0;i<count;i++){ReceiveBuffer.push_back(buffer[i]);}}if(ReceiveBuffer.size() >= 6 && (DestSum == 8)){unsigned short int *p =(unsigned short int*)(ReceiveBuffer.data()+4);DestSum += *p; }if (DestSum != 0 && CurSum >= DestSum){break;}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
