关闭

windows下蓝牙虚拟串口通信

标签: 串口通信windows
3017人阅读 评论(0) 收藏 举报
分类:

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;
            }
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15050次
    • 积分:518
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:5篇
    • 译文:1篇
    • 评论:0条