wince下的蓝牙串口通信(下)——客户端
最近一直在忙工作还有论文,前段时间又得了疱疹......总之诸多不顺啊。
上篇说到服务端创建虚拟串口,开启监听线程。今天讲下客户端如何请求服务端并建立连接。
前提条件:客户端要想服务端请求连接必须知道服务端的蓝牙地址和通道号。
1:蓝牙地址可以通过winsock 编程相关的一些API 去实现发现设备,其API如下
WSAQUERYSET structure
WSALookupServiceBegin function
WSALookupServiceNext function
WSALookupServiceEnd function
2:获取服务端的通道号需要访问服务端的SDP(在此感谢下汤锲,在他的帮助下较快的实现了这部分),这部分要比较熟习蓝牙协议才能完成。
首先,客户端要搜索蓝牙设备。获得蓝牙地址以及设备名称。一下是《yamazaki》上提供的实例源码
#define MAX_NAME 248
static BOOL PerformInquiry()
{
WSAQUERYSET wsaq;
HANDLE hLookup;
union {
CHAR buf[5000];
double __unused; // ensure proper alignment
};
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
DWORD dwSize = sizeof(buf);
BOOL bHaveName;
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;
if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
{
wprintf(L"WSALookupServiceBegin failed %d\r\n", GetLastError());
return FALSE;
}
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob = NULL;
while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
{
ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
BT_ADDR b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
wprintf (L"%s%s%04x%08x%s\n", bHaveName ? pwsaResults->lpszServiceInstanceName : L"",
bHaveName ? L"(" : L"", GET_NAP(b), GET_SAP(b), bHaveName ? L")" : L"");
channel = 0; //1~31
BYTE* pServiceName = new BYTE[MAX_NAME];
if( PerformServiceSearch (&b,&channel,pServiceName,BT_SERVICE_NAME)) //此函数是查询sdp,其实现下面会讲到
{
//找到服务,添加处理代码 //BT_SERVICE_NAME定义了服务端sdp中的一个字符串,相当与一个标志,暂且叫它服务名。
} //channel 是要获得的远程设备的通道号
}
WSALookupServiceEnd(hLookup);
return TRUE;
}
static BOOL PerformInquiry()
{
WSAQUERYSET wsaq;
HANDLE hLookup;
union {
CHAR buf[5000];
double __unused; // ensure proper alignment
};
LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
DWORD dwSize = sizeof(buf);
BOOL bHaveName;
ZeroMemory(&wsaq, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;
if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
{
wprintf(L"WSALookupServiceBegin failed %d\r\n", GetLastError());
return FALSE;
}
ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
pwsaResults->dwSize = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob = NULL;
while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
{
ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
BT_ADDR b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
wprintf (L"%s%s%04x%08x%s\n", bHaveName ? pwsaResults->lpszServiceInstanceName : L"",
bHaveName ? L"(" : L"", GET_NAP(b), GET_SAP(b), bHaveName ? L")" : L"");
channel = 0; //1~31
BYTE* pServiceName = new BYTE[MAX_NAME];
if( PerformServiceSearch (&b,&channel,pServiceName,BT_SERVICE_NAME)) //此函数是查询sdp,其实现下面会讲到
{
//找到服务,添加处理代码 //BT_SERVICE_NAME定义了服务端sdp中的一个字符串,相当与一个标志,暂且叫它服务名。
} //channel 是要获得的远程设备的通道号
}
WSALookupServiceEnd(hLookup);
return TRUE;
}