window 下蓝牙开发

window 蓝牙开发资料真的是比较少,而且功能比较单一。使用window自带的蓝牙重连接真的是太慢了。找不到好的解决方法,很让人头痛呀!
下面提供的这点代码,也只是一个简单的功能,有这方面研究的朋友,希望能多多交流,多多指教

需要先包含几个头文件

#include <afxsock.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
#pragma comment(lib,"Irprops.lib")
#include <string>
using namespace std;
ULONGLONG g_ulRemoteAddr = 0;
WCHAR strGUID[]=L"00001101-0000-1000-8000-00805f9b34fb";
CString g_strRecv = _T("");
SOCKET g_socketClient = INVALID_SOCKET;
CString g_strBthName=_T("");

BOOL g_bWaitRecvData=TRUE;

// CBlueToothTestDlg dialog
CBlueToothTestDlg::CBlueToothTestDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CBlueToothTestDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_bTestFinish = TRUE;
}

void CBlueToothTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_SHOW, m_editShow);
    DDX_Control(pDX, IDC_EDIT_INPUT, m_editInput);
    DDX_Control(pDX, IDC_BUTTON_SEND, m_btnSend);
    DDX_Control(pDX, IDC_BTN_OPEN, m_btnOpen);
    DDX_Control(pDX, IDC_BTN_CLOSE, m_btnClose);
    DDX_Control(pDX, IDC_CHECK_REPEATSEND, m_CheckRepeat);
}

BEGIN_MESSAGE_MAP(CBlueToothTestDlg, CDialog)
    //}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_BUTTON_SEND, &CBlueToothTestDlg::OnBnClickedButtonSend)
    ON_MESSAGE(WM_BLUETOOTH_MSG, &CBlueToothTestDlg::OnBlueToothMsg)
    ON_BN_CLICKED(IDC_BTN_OPEN, &CBlueToothTestDlg::OnBnClickedBtnOpen)
    ON_BN_CLICKED(IDC_BTN_CLOSE, &CBlueToothTestDlg::OnBnClickedBtnClose)
    ON_WM_TIMER()
END_MESSAGE_MAP()

// CBlueToothTestDlg message handlers
CString string2CString(string strSrc)
{
    CString strTarge = _T("");
    TCHAR *pTemp = new TCHAR[strSrc.size() + 1];
    if (NULL == pTemp)
    {
        return strTarge;
    }
    MultiByteToWideChar(0,
        0,
        strSrc.c_str(),
        -1,
        pTemp,
        strSrc.size() + 1
        );   

    strTarge = pTemp;

    if (NULL != pTemp)  
    {
        delete []pTemp;
        pTemp = NULL; 
    }
    return strTarge;
}

CString TranslateErrorCode ( DWORD dwErrorCode )
{
    CString csError;
    LPVOID pv;
    FormatMessage (
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dwErrorCode,
        MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
        (LPTSTR)&pv,
        0,
        NULL);
    if(pv)
    {
        csError = (LPCTSTR)pv;
        LocalFree ( pv );
    }

    CString strCode = _T("");
    strCode.Format(_T("%ld"),dwErrorCode);
    csError = strCode + _T(" : ") + csError;

    return csError;
}

int GetGUID(WCHAR *psz, GUID *pGUID)
{
    int data1, data2, data3;
    int data4[8];

    if (11 ==  swscanf(psz, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
        &data1, &data2, &data3,
        &data4[0], &data4[1], &data4[2], &data4[3], 
        &data4[4], &data4[5], &data4[6], &data4[7])) {
            pGUID->Data1 = data1;
            pGUID->Data2 = data2 & 0xffff;
            pGUID->Data3 = data3 & 0xffff;

            for (int i = 0 ; i < 8 ; ++i)
                pGUID->Data4[i] = data4[i] & 0xff;

            return 0;
    }
    return -1;
}

int ReadBthSeqFile(CString strTempName)//读取序列号文件数据
{
    strTempName = _T("bluetoothName.txt");
    CStdioFile tempFile;
    BOOL bRet = tempFile.Open(strTempName, CFile::modeReadWrite);
    if (!bRet)
    {        
        return -1;
    }

    CString strReadLine=_T("");
    int tempLength = 0;

    while (1)
    {
        tempFile.ReadString(strReadLine);
        tempLength += strReadLine.GetLength()+1;

        if (strReadLine.GetLength() == 0)
            break;

        //AfxMessageBox(strReadLine);
        g_strBthName = strReadLine;
    }
    tempFile.Close();

    return 0;
}

int FindTargetBlueTooth()
{
    int iFindRet = 0;
    WSAQUERYSET wsaq;
    HANDLE      hLookup =   NULL;
    union
    {
        CHAR buf[5000];
        double __unused; // ensure proper alignment
    };

    LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
    DWORD dwSize = sizeof(buf);
    memset(&wsaq,0,sizeof(wsaq));
    wsaq.dwSize = sizeof(wsaq);
    wsaq.dwNameSpace = NS_BTH;
    wsaq.lpcsaBuffer = NULL;
    if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
    {
        return 0;
    }
    ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
    pwsaResults->dwSize = sizeof(WSAQUERYSET);
    pwsaResults->dwNameSpace = NS_BTH;
    pwsaResults->lpBlob = NULL;

    BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
    while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
    {
//      ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
        ULONGLONG ulAddr =   ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
        CString strName  =   pwsaResults->lpszServiceInstanceName;
        if(strName == /*_T("HWAPP")*/g_strBthName)
        {
            g_ulRemoteAddr = ulAddr;
            //获取其它信息
            memset(&bdi,0,sizeof(BLUETOOTH_DEVICE_INFO));
            bdi.Address.ullLong = ulAddr;
            bdi.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);//important
            DWORD dwGetInfo = BluetoothGetDeviceInfo(NULL,&bdi);
            if(ERROR_SUCCESS == dwGetInfo)
            {
                //类型
                ULONG ulType = bdi.ulClassofDevice;//7936
                //被记住                
                BOOL bRemember = bdi.fRemembered;
                //已配对
                BOOL bPaired = bdi.fAuthenticated;
                //已连接
                BOOL bConnected = bdi.fConnected;

                if(bPaired)
                    iFindRet = 1;
                else
                    iFindRet = 2;
                break;
            }
            else
            {
                AfxMessageBox(TranslateErrorCode(dwGetInfo));
            }
        }
    }
    WSALookupServiceEnd(hLookup);

    return iFindRet;
}

UINT ScanBlueToothDeviceProc(LPVOID lpParam)
{
    int iScanRet = FindTargetBlueTooth();//0表示没有发现,1表示发现且配对,2表示发现但未配对
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    pDlg->PostMessage(WM_BLUETOOTH_MSG,1,iScanRet);
    return 0;
}

UINT RecvMsgProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    char pbuf[MAX_MESSAGE_SIZE] = {0};

    while(1)
    {
        memset(pbuf,0,MAX_MESSAGE_SIZE);
        int cbBytesRecd = recv (g_socketClient, pbuf, MAX_MESSAGE_SIZE, 0);
        if (cbBytesRecd == SOCKET_ERROR) 
        {
            pDlg->PostMessage(WM_BLUETOOTH_MSG,2,0);
            return WSAGetLastError();
        }
        else if(cbBytesRecd > 0)
        {
            string sRecv = pbuf;
            g_strRecv = string2CString(sRecv);
            pDlg->PostMessage(WM_BLUETOOTH_MSG,2,1);

            g_bWaitRecvData = TRUE;
        }
    }
    return 0;
}

UINT ConnectDeviceProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;

    g_socketClient = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (g_socketClient == INVALID_SOCKET) 
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,1);
        return 0;
    }

    GUID ServerGuid;
    if(GetGUID(strGUID, &ServerGuid))
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,2);
        g_socketClient = INVALID_SOCKET;
        return 0;
    }

    SOCKADDR_BTH sa;
    memset (&sa, 0, sizeof(sa));
    sa.addressFamily = AF_BTH;
    sa.port = 6001;
    sa.serviceClassId = ServerGuid;
    sa.btAddr = g_ulRemoteAddr;

    Sleep(200);
    int iConnect = 0 ;
    for (iConnect = 0 ; iConnect < 3 ; iConnect ++)//尝试连接3次
    {
        if (connect (g_socketClient, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) 
        {
            DWORD dwError = GetLastError();
            if(dwError == WSAETIMEDOUT)
            {
                pDlg->PostMessage(WM_BLUETOOTH_MSG,4,iConnect);
                Sleep(200);
                continue;
            }
            g_socketClient = INVALID_SOCKET;
            AfxMessageBox(TranslateErrorCode(dwError));
            pDlg->PostMessage(WM_BLUETOOTH_MSG,3,3);//其他错误
            return 0;
        }
        else
            break;
    }
    if(iConnect == 3)//超时错误
    {
        g_socketClient = INVALID_SOCKET;
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,4);
    }
    else
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,0);

    return 0;
}

UINT TestConnectProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;

    int iFindBlueTooth = FindTargetBlueTooth();
    if(iFindBlueTooth != 1)
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,5);
        return 0;
    }

    SOCKET sock = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (sock == INVALID_SOCKET) 
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,1);
        return 0;
    }

    GUID ServerGuid;
    if(GetGUID(strGUID, &ServerGuid))
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,2);
        return 0;
    }

    SOCKADDR_BTH sa;
    memset (&sa, 0, sizeof(sa));
    sa.addressFamily = AF_BTH;
    sa.port = 5001;
    sa.serviceClassId = ServerGuid;
    sa.btAddr = g_ulRemoteAddr;

    Sleep(200);
    int iConnect = 0 ;
    for (iConnect = 0 ; iConnect < 6 ; iConnect ++)//尝试连接6次
    {
        if (connect (sock, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) 
        {
            DWORD dwError = GetLastError();
            if(dwError == WSAETIMEDOUT)
            {
                pDlg->PostMessage(WM_BLUETOOTH_MSG,6,iConnect);
                Sleep(200);
                continue;
            }
            AfxMessageBox(TranslateErrorCode(dwError));
            pDlg->PostMessage(WM_BLUETOOTH_MSG,5,3);//其他错误
            return 0;
        }
        else
            break;
    }
    if(iConnect == 6)//超时错误
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,4);
    else
    {
        closesocket(sock);
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,0);//能连接上
    }

    return 0;
}

BOOL CBlueToothTestDlg::OnInitDialog()
{
    ......

    // TODO: Add extra initialization here
    m_editInput.EnableWindow(FALSE);
    m_btnSend.EnableWindow(FALSE);
    m_btnOpen.EnableWindow(FALSE);
    m_btnClose.EnableWindow(FALSE);
    SetDlgItemText(IDC_STATIC_TIP,_T("正在检测蓝牙是否连接,请稍候..."));
//  SetTimer(8,5000,NULL);

    CString str=_T("");
    ReadBthSeqFile(str);

    AfxBeginThread(ScanBlueToothDeviceProc,this);
    return TRUE;  // return TRUE  unless you set the focus to a control
}

string CBlueToothTestDlg::CString2string(CString str)
{
    string strTarge = "";
    int nLength = str.GetLength();
    int nBytes = WideCharToMultiByte(0,0,str,nLength,NULL,0,NULL,NULL);
    char* VoicePath = new char[ nBytes + 1];
    memset(VoicePath,0,nLength + 1);
    WideCharToMultiByte(0, 0, str, nLength, VoicePath, nBytes, NULL, NULL); 
    VoicePath[nBytes] = 0;
    strTarge = VoicePath;

    return strTarge;
}

void CBlueToothTestDlg::OnBnClickedButtonSend()
{
    // TODO: Add your control notification handler code here
    CString strInput = _T("");
    GetDlgItemText(IDC_EDIT_INPUT,strInput);

    BYTE m_pucPackBuffer[] = {0xd1, 0xee, 0x16, 0x00, 0xe9, 0xff, 0xf7, 0x01, 0x09, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x43, 0x00, 0x00, 0x80, 0x3f, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x44, 0x60, 0x02};

    UINT uiIsCheck = m_CheckRepeat.GetState();

    if (uiIsCheck)///主要是用于测试蓝牙盒子的通讯能力
    {
        strInput=m_pucPackBuffer;
        while (1)
        {
            if (g_bWaitRecvData)
            {
                int iSend = send (g_socketClient, (const char *)m_pucPackBuffer, 31, 0);
                DWORD dwError = GetLastError();
                if((iSend == 31) && (dwError == 0))
                    AppendShowMsg(strInput, 1);
                else
                    AfxMessageBox(strInput+TranslateErrorCode(dwError));

                g_bWaitRecvData = FALSE;
            }
        }       
    }
    else
    {
        if(strInput.GetLength())
        {
            string strToSend = CString2string(strInput);
            int iSend = send (g_socketClient, strToSend.c_str(), strToSend.length(), 0);
            DWORD dwError = GetLastError();
            if((iSend == strInput.GetLength()) && (dwError == 0))
                AppendShowMsg(strInput,1);
            else
                AfxMessageBox(strInput+TranslateErrorCode(dwError));
        }
    }
}

LRESULT CBlueToothTestDlg::OnBlueToothMsg(WPARAM wParam,LPARAM lParam)
{
    int iMsgType = (int)wParam;
    int iMsgValue = (int)lParam;
    if(iMsgType == 1)//扫描蓝牙,结果0表示没有发现,1表示发现且配对,2表示发现但未配对
    {
        switch (iMsgValue)
        {
        case 0:
            SetDlgItemText(IDC_STATIC_TIP,_T("未发现目标蓝牙设备!"));            break;
        case 1:
            SetDlgItemText(IDC_STATIC_TIP,_T("已发现目标蓝牙设备,点击Connect按钮来连接蓝牙"));
            m_btnOpen.EnableWindow(TRUE);
            break;
        case 2:
            SetDlgItemText(IDC_STATIC_TIP,_T("已发现目标蓝牙设备,但未连接,请手动连接后再试"));           break;
        default:break;
        }   
    }
    else if(iMsgType == 2)//接收数据
    {
        if(iMsgValue == 0)
            SetDlgItemText(IDC_STATIC_TIP,_T("接收消息出错,接收线程退出,可能是连接已断开"));
        else if(iMsgValue == 1)
            AppendShowMsg(g_strRecv,2);
    }
    else if(iMsgType == 3)//连接蓝牙设备
    {
        switch (iMsgValue)
        {
        case 0:
            SetDlgItemText(IDC_STATIC_TIP,_T("初始化通信完成,现在可以收发数据"));
            SetDlgItemText(IDC_EDIT_INPUT,_T("FoxwellGT80"));
            m_editInput.EnableWindow(TRUE);
            m_btnSend.EnableWindow(TRUE);
            AfxBeginThread(RecvMsgProc,this);
            m_btnOpen.EnableWindow(FALSE);
            m_btnClose.EnableWindow(TRUE);
            break;
        case 1:
            SetDlgItemText(IDC_STATIC_TIP,_T("初始化套接字失败!"));         break;
        case 2:
            SetDlgItemText(IDC_STATIC_TIP,_T("获取GUID失败!"));         break;
        case 3:
            SetDlgItemText(IDC_STATIC_TIP,_T("连接目标蓝牙设备失败!"));           break;
        case 4:
            SetDlgItemText(IDC_STATIC_TIP,_T("连接目标蓝牙设备失败!")+TranslateErrorCode(WSAETIMEDOUT));          break;
        default:            break;
        }   
    }
    else if(iMsgType == 4)//超时重试提示
    {
        CString strTimeOut = _T("");
        strTimeOut.Format(_T("连接超时,重试中...%d"),iMsgValue+1);
        SetDlgItemText(IDC_STATIC_TIP,strTimeOut);
    }
    else if(iMsgType == 5)//测试连接蓝牙设备
    {
        m_bTestFinish = TRUE;
        CTime tm = CTime::GetCurrentTime();
        CString strTime = _T("");
        strTime.Format(_T("%.2d%.2d%.2d"),tm.GetHour(),tm.GetMinute(),tm.GetSecond());

        switch (iMsgValue)
        {
        case 0:
            SetWindowText(_T("蓝牙检测:已连接") + strTime);            break;
        case 1:
            SetWindowText(_T("蓝牙检测:初始化套接字失败") + strTime);           break;
        case 2:
            SetWindowText(_T("蓝牙检测:获取GUID失败!") + strTime);          break;
        case 3:
            SetWindowText(_T("蓝牙检测:其他错误!") + strTime);          break;
        case 4:
            SetWindowText(_T("蓝牙检测:连接超时,可能已断开") + strTime);         break;
        case 5:
            SetWindowText(_T("蓝牙检测:未连接") + strTime);            break;
        default:break;
        }           
    }
    else if(iMsgType == 6)//测试连接超时重试提示
    {
        CString strTimeOut = _T("");
        strTimeOut.Format(_T("蓝牙检测:重试中...%d"),iMsgValue+1);
        SetWindowText(strTimeOut);
    }
    return 0;
}

void CBlueToothTestDlg::AppendShowMsg(CString strNewMsg, int iType)
{
    if(iType == 1)
        strNewMsg = _T("Req: ") + strNewMsg;
    else if(iType == 2)
        strNewMsg = _T("Ans: ") + strNewMsg;
    else if(iType == 3)
        strNewMsg = _T("Sys: ") + strNewMsg;
    CString strHave = _T("");
    GetDlgItemText(IDC_EDIT_SHOW,strHave);
    if(strHave.GetLength())
        strHave = strHave + _T("\r\n") + strNewMsg;
    else
        strHave = strNewMsg;

    SetDlgItemText(IDC_EDIT_SHOW,strHave);
    m_editShow.PostMessage(WM_VSCROLL,SB_BOTTOM,0);

    if(iType == 2)//自动发送
    {
        CString strInput = strNewMsg;
        if(strInput.GetLength())
        {
            strInput = _T("FOXWELL_") + strInput;
            string strToSend = CString2string(strInput);
            int iSend = send (g_socketClient, strToSend.c_str(), strToSend.length(), 0);
            DWORD dwError = GetLastError();
            if((iSend == strInput.GetLength()) && (dwError == 0))
            {
                AppendShowMsg(strInput,1);
            }
            else
                AfxMessageBox(TranslateErrorCode(dwError));
        }
    }
}

/******************************************************************************\
获取字符串形式的蓝牙地址
蓝牙地址 BLUETOOTH_ADDRESS 定义如下
union
{
    BTH_ADDR ullLong;
    BYTE     rgBytes[6];
};
BTH_ADDR 是一个 64 位的整数
假定蓝牙地址为 12:34:56:78:9A:BC 则 ullLong 为 0x0000123456789ABC
rgBytes 的内容为 BC 9A 78 56 34 12
\******************************************************************************/
CString CBlueToothTestDlg::AddrToStr(const void*pAddr)
{
    CString sAddress;
    if(pAddr)
    {
        BLUETOOTH_ADDRESS Address;
        int         nBytes  =   sizeof(Address.rgBytes);
        TCHAR       szByte[8];
        const BYTE* pByte   =   (const BYTE*)pAddr + (nBytes - 1);

        for(int i = 0;i < nBytes;i++)
        {
            _stprintf(szByte,_T(":%02x"),*pByte--);
            sAddress   +=   i ? szByte : (szByte + 1);
        }
    }
    return sAddress;
}

void CBlueToothTestDlg::OnBnClickedBtnOpen()
{
    // TODO: Add your control notification handler code here
    SetDlgItemText(IDC_STATIC_TIP,_T("正在初始化通信,请稍候..."));
    AfxBeginThread(ConnectDeviceProc,this);
}

void CBlueToothTestDlg::OnBnClickedBtnClose()
{
    // TODO: Add your control notification handler code here
    m_btnOpen.EnableWindow(TRUE);
    m_btnClose.EnableWindow(FALSE);
    m_editInput.EnableWindow(FALSE);
    m_btnSend.EnableWindow(FALSE);
    closesocket(g_socketClient);
    g_socketClient = INVALID_SOCKET;
}

void CBlueToothTestDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(m_bTestFinish && (g_ulRemoteAddr != 0))
    {
        m_bTestFinish = FALSE;
        SetWindowText(_T("蓝牙检测:开始检测"));
        AfxBeginThread(TestConnectProc,this);
    }
    CDialog::OnTimer(nIDEvent);
}
最后释放,放入销毁函数内例如(BOOL CXXXApp::ExitInstance())
WSACleanup();
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值