Skip to content

Instantly share code, notes, and snippets.

@hackaugusto
Created April 11, 2012 18:21
Show Gist options
  • Select an option

  • Save hackaugusto/2361132 to your computer and use it in GitHub Desktop.

Select an option

Save hackaugusto/2361132 to your computer and use it in GitHub Desktop.
#include "stdafx.h"
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
class Bluetooth {
public:
Bluetooth(const wchar_t* service_name, const GUID* guid);
Bluetooth(const wchar_t* service_name, const GUID* guid, const wchar_t* description);
void init();
void destroy();
int bindAllPorts();
int bindPort(int);
int announce();
int run();
static int const MAX_CONNECTIONS = 4;
private:
LPCSADDR_INFO addr_info;
SOCKET socket;
SOCKADDR_BTH bluetooth_address;
GUID guid;
wchar_t* service_name;
wchar_t* service_description;
void _constructor(const wchar_t* service_name, const GUID* guid, const wchar_t* description);
WSAQUERYSET* _init_query();
};
Bluetooth::Bluetooth(const wchar_t* service_name, const GUID* guid){
this->_constructor(service_name, guid, nullptr);
}
Bluetooth::Bluetooth(const wchar_t* service_name, const GUID* guid, const wchar_t* description){
this->_constructor(service_name, guid, description);
}
void Bluetooth::_constructor(const wchar_t* service_name, const GUID* guid, const wchar_t* description){
memset(this,0,sizeof(Bluetooth));
//::CLSIDFromString(guid, &this->guid);
memcpy(&this->guid, guid, sizeof(GUID));
this->service_name = (wchar_t*) malloc(wcslen(service_name)+1);
memset(this->service_name,0,wcslen(service_name)+1);
wcscpy_s(this->service_name, wcslen(service_name)+1, service_name);
if( nullptr != description ){
this->service_description = (wchar_t*) malloc(wcslen(description)+1);
memset(this->service_description,0,wcslen(description)+1);
wcscpy_s(this->service_description, wcslen(description)+1, description);
}
}
void Bluetooth::init(){
int ret;
WSADATA winsocket_data;
// initialize the win socket 2 stack
memset(&winsocket_data,0,sizeof(WSADATA));
ret = WSAStartup(MAKEWORD(2, 2), &winsocket_data);
assert(0 == ret);
// alloc the memory that we need
this->addr_info = (LPCSADDR_INFO) malloc(sizeof(CSADDR_INFO));
memset(this->addr_info,0,sizeof(LPCSADDR_INFO));
this->socket = ::socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
assert(this->socket);
}
void Bluetooth::destroy(){
// de-initialize the stack
closesocket(this->socket);
WSACleanup();
// free memory
free(this->addr_info);
}
int Bluetooth::bindAllPorts(){
int _ = 0, ret = 0;
memset(&this->bluetooth_address,0,sizeof(this->bluetooth_address));
this->bluetooth_address.addressFamily = AF_BTH;
this->bluetooth_address.port = BT_PORT_ANY;
this->bluetooth_address.btAddr = 0;
this->bluetooth_address.serviceClassId = GUID_NULL;
ret = bind(this->socket, (struct sockaddr *) &this->bluetooth_address, sizeof(SOCKADDR_BTH));
assert(0 == ret);
return getsockname(this->socket,(struct sockaddr *) &this->bluetooth_address, &_);
}
WSAQUERYSET* Bluetooth::_init_query(){
WSAQUERYSET* query = nullptr;
query = (WSAQUERYSET*) malloc(sizeof(*query));
memset(query,0,sizeof(WSAQUERYSET));
query->dwSize = sizeof(WSAQUERYSET);
query->lpServiceClassId = &this->guid;
query->dwNumberOfCsAddrs = 1;
query->dwNameSpace = NS_BTH;
return query;
}
int Bluetooth::announce(){
int ret = 0;
SOCKET_ADDRESS* addr = nullptr;
WSAQUERYSET* query = nullptr;
wchar_t computer_name[MAX_COMPUTERNAME_LENGTH+1];
unsigned long max_lenght = MAX_COMPUTERNAME_LENGTH+1;
wchar_t* service_name = nullptr;
memset(&computer_name,0,sizeof(computer_name));
ret = GetComputerName(computer_name, &max_lenght);
assert(0 != ret); // sucess is non zero
if( nullptr != this->service_name){
// both are null-terminated strings, so the space bellow is already counted for
service_name = (wchar_t*) malloc( wcslen(computer_name) + wcslen(this->service_name));
memset(service_name,0,wcslen(computer_name) + wcslen(this->service_name));
swprintf(service_name, L"%s %s", computer_name, this->service_name);
}else{
service_name = (wchar_t*) malloc(wcslen(computer_name));
wcscpy_s(service_name, wcslen(computer_name)+1, computer_name);
}
this->addr_info->iSocketType = SOCK_STREAM;
this->addr_info->iProtocol = BTHPROTO_RFCOMM;
addr = &(this->addr_info->LocalAddr);
addr->iSockaddrLength = sizeof(SOCKADDR_BTH);
addr->lpSockaddr = (LPSOCKADDR) &this->bluetooth_address;
addr = &(this->addr_info->RemoteAddr);
addr->iSockaddrLength = sizeof(SOCKADDR_BTH);
addr->lpSockaddr = (LPSOCKADDR) &this->bluetooth_address;
query = this->_init_query();
query->lpszServiceInstanceName = this->service_name;
query->lpszComment = service_name;
query->lpcsaBuffer = this->addr_info;
return WSASetService(query, RNRSERVICE_REGISTER, 0);
}
int Bluetooth::run(){
int ret = 0;
ret = listen(this->socket, Bluetooth::MAX_CONNECTIONS);
assert(0 == ret);
ret = announce();
assert(0 == ret);
accept(this->socket, nullptr, nullptr);
closesocket(this->socket);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
// {C54D3D77-6B4C-4D72-9931-279B19C73A01}
static const GUID guid = { 0xc54d3d77, 0x6b4c, 0x4d72, { 0x99, 0x31, 0x27, 0x9b, 0x19, 0xc7, 0x3a, 0x1 } };
Bluetooth server(L"Blue", &guid);
server.init();
server.bindAllPorts();
return server.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment