c++中蓝牙编程的库类

头文件.h
#pragma once
#ifndef NS_BTH
#include "ws2bth.h"	//如果没有定义NS_BTH宏,则将PSDK头文件包含进来
#endif

// for WSALookupServiceBegin() WSALookupServiceNext etc.
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <ws2bth.h>

// for BluetoothFindFirstDevice() BluetoothFindNextDevice() etc.
#include <bthsdpdef.h>
#include <BluetoothAPIs.h>
#pragma comment ( lib, "Irprops.lib")

#ifndef BTH_ADDR
typedef ULONGLONG BTH_ADDR;
#endif

#ifndef SAFE_DELETE
#define SAFE_DELETE(pObj) {if(pObj) delete pObj; pObj = NULL;}
#endif

#ifndef SAFE_DELETERG
#define SAFE_DELETERG(pObj) {if(pObj) delete [] pObj; pObj = NULL;}
#endif

#define RECEIVE_OVER_COMMAND	0x00001000

typedef struct _tag_BthDev_Info
{
	BTH_ADDR btAddr;
	TCHAR szAddr[32];
	TCHAR szName[128];

	_tag_BthDev_Info()
	{
		memset(this, 0, sizeof(this));
	}
}
BTHDEV_INFO;

class CGGBlueTooth
{
public:
	CGGBlueTooth();
	~CGGBlueTooth();

	BOOL StartSearchBthDev(IN DWORD dwControlFlags);
	BOOL GetNextBthDev(
		IN OUT BTHDEV_INFO *pcBthDevInfo,
		IN DWORD dwControlFlags = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE
		);
	BOOL EndSearchBthDev();

	//Socket Api
	BOOL Create(int af = AF_BTH, int type = SOCK_STREAM, int protocol = BTHPROTO_RFCOMM);
	BOOL Close();

	//If no error occurs, this function returns zero. If an error occurs, it returns SOCKET_ERROR
	int Bind(BTH_ADDR sktAddr = 0, ULONG port = BT_PORT_ANY);
	int Listen(IN int backlog);
	int GetSockName(BTH_ADDR *psktAddr, ULONG *port);
	int SetBthService(TCHAR *lpServiceName);
	int Accept(CGGBlueTooth *pcBth);
	int Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond = -1);
	int Send(LPVOID lpData, int len, int flags = 0);
	int Recv(LPVOID lpData, int len, int flags = 0);
	int SendAll(LPVOID lpData, int len, int flags = 0);
	int RecvAll(LPVOID lpData, int len, int flags = 0);

private:
	void HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac);

private:
	HANDLE m_hLookup;
	SOCKET m_hSocket;
	SOCKADDR_BTH m_sktAddr;
};


====================================================================================================================

源文件.cpp

#include "stdafx.h"
#include "GGBlueTooth.h"
//#include "tchar.h"

CGGBlueTooth::CGGBlueTooth()
: m_hLookup(NULL)
, m_hSocket(NULL)
{
	memset(&m_sktAddr, 0, sizeof(m_sktAddr));
}

CGGBlueTooth::~CGGBlueTooth()
{
	EndSearchBthDev();
	Close();
}

void CGGBlueTooth::HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac)
{
	BYTE *pbAddr = (BYTE*)&dw64Addr;

	_stprintf(
		pstrMac, _T("%02X:%02X:%02X:%02X:%02X:%02X"),
		pbAddr[5], pbAddr[4], pbAddr[3],
		pbAddr[2], pbAddr[1], pbAddr[0]
		);
}

BOOL CGGBlueTooth::StartSearchBthDev(IN DWORD dwControlFlags)
{
	WSAQUERYSET wsaq;
	ZeroMemory(&wsaq, sizeof(wsaq));
	wsaq.dwSize = sizeof(wsaq);
	wsaq.dwNameSpace = NS_BTH;
	wsaq.lpcsaBuffer = NULL;

	return WSALookupServiceBegin(&wsaq, dwControlFlags, &m_hLookup) == ERROR_SUCCESS ? TRUE : FALSE;
}

BOOL CGGBlueTooth::GetNextBthDev(
	IN OUT BTHDEV_INFO *pcBthDevInfo,
	IN DWORD dwControlFlags /* = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE*/
	)
{
	if (!m_hLookup || !pcBthDevInfo)
	{
		return FALSE;
	}

	memset(pcBthDevInfo->szAddr, 0, sizeof(pcBthDevInfo->szAddr));
	memset(pcBthDevInfo->szName, 0, sizeof(pcBthDevInfo->szName));

	union
	{
		CHAR buf[5000];
		double __unused; // ensure proper alignment
	};
	LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)buf;
	DWORD dwSize = sizeof(buf);
	int nResult;

	ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
	pwsaResults->dwSize = sizeof(WSAQUERYSET);
	pwsaResults->dwNameSpace = NS_BTH;
	pwsaResults->lpBlob = NULL;

	nResult = WSALookupServiceNext(m_hLookup, dwControlFlags, &dwSize, pwsaResults);
	if (nResult == ERROR_SUCCESS)
	{
		pcBthDevInfo->btAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
		BOOL bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);

		if (bHaveName)
		{
			HexMac2String(pcBthDevInfo->btAddr, pcBthDevInfo->szAddr);
			_tcscpy(pcBthDevInfo->szName, pwsaResults->lpszServiceInstanceName);
		}
		return TRUE;
	}

	return FALSE;
}

BOOL CGGBlueTooth::EndSearchBthDev()
{
	if (m_hLookup)
	{
		WSALookupServiceEnd(m_hLookup);
		m_hLookup = NULL;
		return TRUE;
	}

	return FALSE;
}

///===============================

BOOL CGGBlueTooth::Create(int af/* = AF_BTH*/, int type/* = SOCK_STREAM*/, int protocol/* = BTHPROTO_RFCOMM*/)
{
	if (m_hSocket)
	{
		return FALSE;
	}

	m_hSocket = socket(af, type, protocol);
	m_sktAddr.addressFamily = af;
	m_sktAddr.serviceClassId = GUID_NULL;
	return m_hSocket == INVALID_SOCKET ? FALSE : TRUE;
}

BOOL CGGBlueTooth::Close()
{
	if (m_hSocket)
	{
		closesocket(m_hSocket);
		return TRUE;
	}
	return FALSE;
}

int CGGBlueTooth::Bind(BTH_ADDR sktAddr/* = 0*/, ULONG port/* = BT_PORT_ANY*/)
{
	m_sktAddr.btAddr = sktAddr;
	m_sktAddr.port = port;
	return bind(m_hSocket, (SOCKADDR *)&m_sktAddr, sizeof(m_sktAddr));
}

int CGGBlueTooth::Listen(int backlog)
{
	return listen(m_hSocket, backlog);
}

int CGGBlueTooth::GetSockName(BTH_ADDR *psktAddr, ULONG *port)
{
	int nLen = sizeof(m_sktAddr);
	int nResult = getsockname(m_hSocket, (SOCKADDR *)&m_sktAddr, &nLen);
	if (nResult == 0)
	{
		*psktAddr = m_sktAddr.btAddr;
		*port = m_sktAddr.port;
	}
	return nResult;
}

GUID OBEXFileTransferServiceClass_UUID_EX = { 0x00001106, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
int CGGBlueTooth::SetBthService(TCHAR * lpServiceName)
{
	CSADDR_INFO sockInfo;
	sockInfo.iProtocol = BTHPROTO_RFCOMM;
	sockInfo.iSocketType = SOCK_STREAM;
	sockInfo.LocalAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
	sockInfo.LocalAddr.iSockaddrLength = sizeof(m_sktAddr);
	sockInfo.RemoteAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
	sockInfo.RemoteAddr.iSockaddrLength = sizeof(m_sktAddr);

	WSAQUERYSET svcInfo = { 0 };
	svcInfo.dwSize = sizeof(svcInfo);
	svcInfo.dwNameSpace = NS_BTH;
	svcInfo.lpszServiceInstanceName = lpServiceName;
	svcInfo.lpServiceClassId = &OBEXFileTransferServiceClass_UUID_EX;
	svcInfo.dwNumberOfCsAddrs = 1;
	svcInfo.lpcsaBuffer = &sockInfo;

	return WSASetService(&svcInfo, RNRSERVICE_REGISTER, 0);
}

int CGGBlueTooth::Accept(CGGBlueTooth *pcBth)
{
	SOCKADDR_BTH ca;
	int size = sizeof(ca);
	pcBth->m_hSocket = accept(m_hSocket, (SOCKADDR *)&ca, &size);
	pcBth->m_sktAddr = ca;
	return pcBth->m_hSocket == INVALID_SOCKET ? SOCKET_ERROR : 0;
}

int CGGBlueTooth::Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond/* = -1*/)
{
	SOCKADDR_BTH sa = { 0 };
	sa.addressFamily = AF_BTH;
	sa.btAddr = sktAddr;
	sa.port = port;

	if (nMSecond == -1)
	{
		return connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH));
	}

	ULONG non_blocking = 1;
	ULONG blocking = 0;

	int nResult = ioctlsocket(m_hSocket, FIONBIO, &non_blocking);
	if (nResult == SOCKET_ERROR)
	{
		return nResult;
	}

	nResult = SOCKET_ERROR;
	if (connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
	{
		struct timeval tv;
		fd_set writefds;

		// 设置连接超时时间
		tv.tv_sec = nMSecond / 1000; // 秒数
		tv.tv_usec = nMSecond % 1000; // 毫秒

		FD_ZERO(&writefds);
		FD_SET(m_hSocket, &writefds);

		nResult = select((int)m_hSocket + 1, NULL, &writefds, NULL, &tv);
		if (nResult > 0)
		{
			if (FD_ISSET(m_hSocket, &writefds))
			{
				int error = 0;
				int len = sizeof(error);
				//下面的一句一定要,主要针对防火墙 
				if (!(getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0 || error != 0))
				{
					nResult = 0;
				}
			}
		}
		else if (nResult == 0)
		{
			nResult = -2;
		}
	}

	if (ioctlsocket(m_hSocket, FIONBIO, &blocking) == SOCKET_ERROR)
	{
		nResult = SOCKET_ERROR;
	}
	return nResult;
}

int CGGBlueTooth::Send(LPVOID lpData, int len, int flags/* = 0*/)
{
	return send(m_hSocket, (char *)lpData, len, flags);
}

int CGGBlueTooth::Recv(LPVOID lpData, int len, int flags/* = 0*/)
{
	return recv(m_hSocket, (char *)lpData, len, flags);
}

int CGGBlueTooth::SendAll(LPVOID lpData, int len, int flags/* = 0*/)
{
	int nCount = send(m_hSocket, (char *)lpData, len, flags);
	if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
	{
		return SOCKET_ERROR;
	}

	int nCommand = 0;
	nCount = recv(m_hSocket, (char *)&nCommand, 4, flags);
	if (nCount != 4 || nCommand != RECEIVE_OVER_COMMAND)
	{
		return SOCKET_ERROR;
	}

	return ERROR_SUCCESS;
}

int CGGBlueTooth::RecvAll(LPVOID lpData, int len, int flags/* = 0*/)
{
	int nCount = -1, nCurRecv = 0, nMaxRead = 32 * 1024;

	while (nCurRecv < len)
	{
		if (len - nCurRecv < nMaxRead)
		{
			nMaxRead = len - nCurRecv;
		}

		nCount = recv(m_hSocket, (char *)lpData + nCurRecv, nMaxRead, flags);

		if (nCount == SOCKET_ERROR)
		{
			if (WSAGetLastError() == WSAEWOULDBLOCK)
			{
				Sleep(1);
				continue;
			}
			else
			{
				return SOCKET_ERROR;
			}
		}

		nCurRecv += nCount;
	}

	int nCommand = RECEIVE_OVER_COMMAND;
	nCount = send(m_hSocket, (char *)&nCommand, 4, flags);
	if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
	{
		return SOCKET_ERROR;
	}

	return ERROR_SUCCESS;
}


  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: C BLE蓝牙编程是指使用C语言编写蓝牙低功耗(BLE)相关应用程序的技术。BLE是一种低功耗、短距离无线通信技术,可用于连接蓝牙设备,如智能手机、手表、医疗设备等。C语言是一种广泛应用于系统级开发的计算机程序设计语言,适用于开发嵌入式系统、操作系统、网络设备等。因此,C BLE蓝牙编程可以在嵌入式系统、移动设备等各个领域得到应用。 C BLE蓝牙编程需要掌握蓝牙协议和BLE协议,了解各种的信号和数据传输方式。在C BLE蓝牙编程,需要使用蓝牙标准库和操作系统提供的API,对蓝牙设备进行控制,并实现蓝牙通讯功能。开发人员需要具备扎实的C语言编程基础,了解Low-level driver编程,具备熟练的调试技能和了解硬件资源管理开发技能,才能开发出高质量的BLE应用程序。 总而言之,C BLE蓝牙编程是在掌握蓝牙协议、BLE协议和C语言编程基础的基础上,应用蓝牙标准库和操作系统提供的API,对蓝牙设备进行控制,实现BLE通讯功能的技术。开发人员需要具备专业的技术知识和扎实的编程基础,才能开发出高质量的BLE应用程序。 ### 回答2: C语言蓝牙编程是一种将蓝牙技术与C语言进行集成的编程方法。蓝牙技术是一种无线通信技术,它可以在短距离内无线传输数据,如音频、图像和其他数据。而C语言是一种十分流行的编程语言,拥有广泛的应用领域,如操作系统、网络编程和图形用户界面等。 在使用C语言进行蓝牙编程时,开发者需要掌握蓝牙技术的原理和常用的蓝牙协议,如RFCOMM、L2CAP和HID等。此外,开发者还需要了解蓝牙硬件和软件架构,以便进行相应的编程。 C语言蓝牙编程常用的工具包括BlueZ库、hci-tools和BlueDevil等。开发者可以通过这些工具包来编写C语言程序,实现蓝牙设备的操作和数据传输。 在实际应用,C语言蓝牙编程有着广泛的应用场景,如智能家居、医疗设备、汽车电子和物联网设备等。在这些场景,C语言蓝牙编程可以帮助开发者实现设备之间的数据交换和远程控制等功能。 总的来说,C语言蓝牙编程是一种十分有用的编程方法,它将C语言和蓝牙技术有机地结合起来,为开发者提供了一个强大的工具来实现各种数据传输和控制功能。 ### 回答3: BLE(Bluetooth Low Energy)是一种低功耗的蓝牙技术。它是一种为低功耗、短距离、无线数据传输设备而设计的通信协议。这种技术采用无线射频技术短距离传输数据,适用于需要花费较少电量并且数据量不大的各种设备,比如智能手表、健身器材、温度传感器等。 BLE编程的核心是开发一个BLE应用程序,该程序与一个或多个BLE外设(如心率传感器、温度传感器等)进行通信。BLE由两部分组成:周边设备和央设备。周边设备是指提供服务并可被央设备检测到的设备,而央设备则是指发现和寻找周边设备的设备。 BLE编程需要使用适当的编程语言,如C、C++或Objective-C等。一般情况下,开发人员需要使用BLE库(如Bluez),用于访问BLE硬件和实现BLE通信。BLE库可以使用Bluez API或Bluez D-Bus API来访问,并提供广泛的功能,如扫描和连接BLE设备、服务发现和读取特性,以及写入和监听特性。 在BLE编程,主要的任务是编写处理BLE连接和数据交换的代码,可以通过建立一个BLE链路并使用相应的BLE API与BLE外设通信。针对BLE外设设计服务和特性,可以提供特定数据类型、单个或多个属性,以及读取、写入或订阅某些特定事件的能力。 总之,BLE编程是一种现代的、低功耗、高效的通信技术,已经在众多应用场景得到了广泛应用,需要开发人员具备相应的技能和经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值