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
- window 下蓝牙开发
- linux 下蓝牙应用程序开发
- window下GTK+开发环境
- Windows CE下的蓝牙开发
- Wince下蓝牙开发的问题
- linux下蓝牙BLE(rtl8821)开发
- linux下蓝牙BLE(rtl8821)开发
- 蓝牙开发
- 蓝牙开发
- 蓝牙开发
- 蓝牙开发
- 蓝牙开发
- 蓝牙开发
- window下用cygwin做嵌入式开发
- 在window下部署Iphone开发环境
- window 下的 ios 开发,环境搭建
- 在ubuntu下开发window应用程序
- window XP下安装开发工具
- 利用freemarker在js中写入list
- Picasso和Glide两种加载图片方式对比
- linux系统内存查看
- shell
- 文件系统
- window 下蓝牙开发
- 不修改tnsnames.ora 配置,通过界面怎么配置?
- Qt5 QML程序Release版本发布程序无法显示的问题解决过程。
- 常见安全算法
- Linux下编写脚本Shell和Python的区别
- 批量drop删除Oracle的表
- ExtJS——继承CheckboxGroup,添加远程获取item的功能
- Windows Server登录后,光标到哪里都有一个蓝色的框,输入文字,就自动跳转到登陆界面
- Android——网络通信(OkHttp)