LocalDevice:

- Implement REading of the default timeouts
- Retrieval of all possible LinkKeys stored inside the dongle
- Provided function to force an authentication process with remote devices
RemoteDevice:
- Allow Haiku initiate a fully authenticated connection



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36445 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Ruiz Dorantes 2010-04-24 11:34:23 +00:00
parent 40c666a5ab
commit 37c7d5d83a
6 changed files with 189 additions and 22 deletions

View File

@ -7,6 +7,7 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/DeviceClass.h>
#include <bluetooth/bdaddrUtils.h>
#include <Messenger.h>
#include <Message.h>
@ -18,23 +19,31 @@ namespace Bluetooth {
class BluetoothDevice {
public:
public:
BluetoothDevice()
:
fBdaddr(bdaddrUtils::NullAddress()),
fDeviceClass()
{
virtual BString GetFriendlyName()=0;
virtual DeviceClass GetDeviceClass()=0;
}
virtual BString GetProperty(const char* property)=0;
virtual status_t GetProperty(const char* property, uint32* value)=0;
virtual BString GetFriendlyName()=0;
virtual DeviceClass GetDeviceClass()=0;
virtual bdaddr_t GetBluetoothAddress()=0;
virtual BString GetProperty(const char* property)=0;
virtual status_t GetProperty(const char* property, uint32* value)=0;
protected:
bdaddr_t fBdaddr;
DeviceClass fDeviceClass;
virtual bdaddr_t GetBluetoothAddress()=0;
protected:
bdaddr_t fBdaddr;
DeviceClass fDeviceClass;
};
}
#ifndef _BT_USE_EXPLICIT_NAMESPACE
using Bluetooth::BluetoothDevice;
#endif

View File

@ -102,7 +102,13 @@ struct hci_command_header {
char local_name[HCI_DEVICE_NAME_SIZE];
} __attribute__ ((packed));
#define OCF_READ_CA_TIMEOUT 0x0015
#define OCF_WRITE_CA_TIMEOUT 0x0016
#define OCF_READ_PG_TIMEOUT 0x0017
struct hci_rp_read_page_timeout {
uint8 status;
uint16 page_timeout;
} __attribute__ ((packed));
#define OCF_WRITE_PG_TIMEOUT 0x0018
#define OCF_WRITE_SCAN_ENABLE 0x001A
@ -240,6 +246,11 @@ struct hci_command_header {
uint8 pin_code[HCI_PIN_SIZE];
} __attribute__ ((packed));
struct hci_cp_link_key_reply_reply {
uint8 status;
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_PIN_CODE_NEG_REPLY 0x000E
struct hci_cp_pin_code_neg_reply {
bdaddr_t bdaddr;

View File

@ -315,11 +315,11 @@ struct hci_ev_sychronous_connection_changed {
#define HCI_EVENT_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION 0x3D
/* HAIKU Internal Events, not produced by the transport devices but
* by some entity of the Haiku Bluetooth Stack.
/* HAIKU Internal Events, not produced by the transport devices but
* by some entity of the Haiku Bluetooth Stack.
* The MSB 0xE is chosen for this purpose
*/
#define HCI_HAIKU_EVENT_SERVER_QUITTING 0xE0
#define HCI_HAIKU_EVENT_DEVICE_REMOVED 0xE1

View File

@ -38,6 +38,7 @@ public:
/* Possible throwing */
status_t SetDiscoverable(int mode);
status_t SetAuthentication(bool authentication);
BString GetProperty(const char* property);
status_t GetProperty(const char* property, uint32* value);
@ -56,6 +57,8 @@ private:
status_t _ReadLocalVersion();
status_t _ReadBufferSize();
status_t _ReadLocalFeatures();
status_t _ReadTimeouts();
status_t _ReadLinkKeys();
status_t Reset();
static LocalDevice* RequestLocalDeviceID(BMessage* request);

View File

@ -191,6 +191,19 @@ LocalDevice::SetDiscoverable(int mode)
}
struct authentication_t {
uint8 param;
};
status_t
LocalDevice::SetAuthentication(bool authentication)
{
return SingleParameterCommandRequest<struct authentication_t, uint8>
(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, authentication,
NULL, fHid, fMessenger);
}
bdaddr_t
LocalDevice::GetBluetoothAddress()
{
@ -406,6 +419,58 @@ LocalDevice::_ReadLocalFeatures()
}
status_t
LocalDevice::_ReadLinkKeys()
{
int8 bt_status = BT_ERROR;
BluetoothCommand<> LocalFeatures(OGF_CONTROL_BASEBAND,
OCF_READ_STORED_LINK_KEY);
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
request.AddInt32("hci_id", fHid);
request.AddData("raw command", B_ANY_TYPE,
LocalFeatures.Data(), LocalFeatures.Size());
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
OCF_READ_STORED_LINK_KEY));
request.AddInt16("eventExpected", HCI_EVENT_RETURN_LINK_KEYS);
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
return bt_status;
}
struct pageTimeout_t {
uint16 param;
};
status_t
LocalDevice::_ReadTimeouts()
{
// Read PageTimeout
NonParameterCommandRequest(OGF_CONTROL_BASEBAND,
OCF_READ_PG_TIMEOUT, NULL, fHid, fMessenger);
// Write PageTimeout
SingleParameterCommandRequest<struct pageTimeout_t, uint16>
(OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT, 0x8000, NULL,
fHid, fMessenger);
// Write PageTimeout
return SingleParameterCommandRequest<struct pageTimeout_t, uint16>
(OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT, 0x7d00, NULL,
fHid, fMessenger);
}
status_t
LocalDevice::Reset()
{
@ -443,13 +508,18 @@ LocalDevice::updateRecord(ServiceRecord srvRecord) {
*/
LocalDevice::LocalDevice(hci_id hid) : fHid(hid)
LocalDevice::LocalDevice(hci_id hid)
:
BluetoothDevice(),
fHid(hid)
{
fMessenger = _RetrieveBluetoothMessenger();
_ReadBufferSize();
_ReadLocalFeatures();
_ReadLocalVersion();
_ReadTimeouts();
_ReadLinkKeys();
uint32 value;
@ -461,7 +531,7 @@ LocalDevice::LocalDevice(hci_id hid) : fHid(hid)
// Reset(); // Perform a reset to Broadcom buggyland
// Uncomment this out if your Broadcom dongle has a null bdaddr
// #define BT_WRITE_BDADDR_FOR_BCM2035
//#define BT_WRITE_BDADDR_FOR_BCM2035
#ifdef BT_WRITE_BDADDR_FOR_BCM2035
#warning Writting broadcom bdaddr @ init.
// try write bdaddr to a bcm2035 -> will be moved to an addon

View File

@ -57,12 +57,14 @@ RemoteDevice::GetFriendlyName(bool alwaysAsk)
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
// Fill the request
remoteNameCommand = buildRemoteNameRequest(fBdaddr, fPageRepetitionMode, fClockOffset, &size);
remoteNameCommand = buildRemoteNameRequest(fBdaddr, fPageRepetitionMode,
fClockOffset, &size);
request.AddData("raw command", B_ANY_TYPE, remoteNameCommand, size);
request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
request.AddInt16("opcodeExpected",
PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
request.AddInt16("eventExpected", HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE);
@ -72,19 +74,19 @@ RemoteDevice::GetFriendlyName(bool alwaysAsk)
int8 status;
if ((reply.FindInt8("status", &status) == B_OK) && (status == BT_OK)) {
if ((reply.FindString("friendlyname", &name) == B_OK )) {
return name;
} else {
return BString(""); // should not happen
}
} else {
// seems we got a negative event
return BString("#CommandFailed#Not Valid name");
}
}
return BString("#NotCompletedRequest#Not Valid name");
}
@ -118,7 +120,74 @@ RemoteDevice::Equals(RemoteDevice* obj)
bool
RemoteDevice::Authenticate()
{
return true;
int8 btStatus = BT_ERROR;
if (fMessenger == NULL || fDiscovererLocalDevice == NULL)
return false;
BluetoothCommand<typed_command(hci_cp_create_conn)>
createConnection(OGF_LINK_CONTROL, OCF_CREATE_CONN);
bacpy(&createConnection->bdaddr, &fBdaddr);
createConnection->pscan_rep_mode = fPageRepetitionMode;
createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1
createConnection->clock_offset = fClockOffset | 0x8000; // substract!
uint32 roleSwitch;
fDiscovererLocalDevice->GetProperty("role_switch_capable", &roleSwitch);
createConnection->role_switch = (uint8)roleSwitch;
uint32 packetType;
fDiscovererLocalDevice->GetProperty("packet_type", &packetType);
createConnection->pkt_type = (uint16)packetType;
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
request.AddData("raw command", B_ANY_TYPE,
createConnection.Data(), createConnection.Size());
// First we get the status about the starting of the connection
request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
OCF_CREATE_CONN));
// if authentication needed, we will send any of these commands
// to accept or deny the LINK KEY [a]
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
OCF_LINK_KEY_REPLY));
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
OCF_LINK_KEY_NEG_REPLY));
// in negative case, a pincode will be replied [b]
// this request will be handled by sepatated by the pincode window
// request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
// request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
// OCF_PIN_CODE_REPLY));
// [a] this is expected of authentication required
request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ);
// [b] If we deny the key an authentication will be requested
// but this request will be handled by sepatated by the pincode
// window
// request.AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
// this almost involves already the happy end
request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
request.AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &btStatus);
if (btStatus == BT_OK)
return true;
else
return false;
}
@ -160,6 +229,9 @@ RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld)
/* Constructor */
RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
:
BluetoothDevice(),
fDiscovererLocalDevice(NULL)
{
fBdaddr = address;
fDeviceClass.SetRecord(record);
@ -168,9 +240,11 @@ RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
RemoteDevice::RemoteDevice(const BString& address)
:
BluetoothDevice(),
fDiscovererLocalDevice(NULL)
{
fDeviceClass.SetRecord((uint32)0);
fBdaddr = bdaddrUtils::FromString((const char *)address.String());
fBdaddr = bdaddrUtils::FromString((const char*)address.String());
fMessenger = _RetrieveBluetoothMessenger();
}