windows下蓝牙虚拟串口通信

原创 2015年11月17日 15:48:44

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

相关文章推荐

win7与android设备通过蓝牙串口的连接方法

如果能够在PC和Android设备间通过串口进行数据通信,会有利于对程序的调试。 步骤如下:  1、首先需要安装有win7的PC机带有蓝牙适配器。 2、在win7下设置蓝牙可被查找,然后打开蓝牙适配器...
  • qwertyuj
  • qwertyuj
  • 2014年03月11日 18:59
  • 13997

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

蓝牙(Bluetooth)设备查找、蓝牙VC源代码

#include "StdAfx.h" #include "BlueTooth.h" CBlueTooth::CBlueTooth(void) { m_Ary_RemoteBthDevInfo.S...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

windows下,C++实现串口编程,串间口转发数据

在 Win32 下,可以使用两种编程方式实现串口通信,一是使用 ActiveX 控件。二是调用 Windows 的 API 函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。本文介绍 API ...

win10开启蓝牙虚拟串口

win10开启蓝牙虚拟串口方法
  • px_528
  • px_528
  • 2017年04月26日 10:35
  • 1741

如何进行win8的蓝牙虚拟串口设置

本文介绍的是不通过第三方软件进行蓝牙虚拟串口的设置和配对,其实笔者也尝试了使用千月的蓝牙软件,但是使用体验不是很好。 电脑蓝牙和设备之间的配对在这里就不做介绍了,我们假设已经完成了蓝牙的配对。 首先打...
  • jkq10
  • jkq10
  • 2015年01月11日 18:23
  • 4306

[Bluetooth]使用虚拟串口连接到远程蓝牙设备

你可以利用Microsoft Windows CE的串口模拟器在两个蓝牙设备间建立连接。串口模拟器处于蓝牙协议栈的顶层,在虚拟串口的基础上提供连接RFCOMM的通路。它没有暴露栈的接口,而是提供了一个...

c++中蓝牙编程的库类

 安装PSDK就可以用了,之前有写过一个类在MFC里面调用,并能成功与蓝牙手机通信,只不过是非标准的蓝牙协议。代码如下:=====================h头文件============...

Win8.1 & WP8: 蓝牙Rfcomm应用

Windows 8.1: Play with BluetoothRfcomm 浏览新增加到 Windows 8.1 的命名空间,你会以现个有趣、令人惊叹的对蓝牙的领域的支持。新的操作...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:windows下蓝牙虚拟串口通信
举报原因:
原因补充:

(最多只允许输入30个字)