window 下蓝牙开发

来源:互联网 发布:es6 数组的遍历 编辑:程序博客网 时间:2024/05/16 06:44

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 dialogCBlueToothTestDlg::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 handlersCString 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 为 0x0000123456789ABCrgBytes 的内容为 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();
0 0