bluetooth: refactor in remote devices handling

- adding persistent link key storage to avoid re-authentications
- saving important information about remote devices to make it survive reboots
- making all bluetooth status variables uint8 like it is in the command definitions

Change-Id: I8956fb356ee734b9fa0ae9704624f6e5fef39e55
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11203
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
mohammedrattia
2026-07-15 21:08:28 +00:00
committed by waddlesplash
parent c6c24b3e3a
commit 91994efedd
22 changed files with 547 additions and 159 deletions
+5
View File
@@ -145,6 +145,11 @@ const char* BluetoothError(uint8 error);
#define HCI_LM_RELIABLE 0x0010
#define HCI_LM_SECURE 0x0020
// Link Types
#define HCI_SCO_CONN 0x00
#define HCI_ACL_CONN 0x01
#define HCI_ESCO_CONN 0x02
#endif // _BTHCI_H_
+1 -1
View File
@@ -280,7 +280,7 @@ struct hci_command_header {
#define OCF_LINK_KEY_REPLY 0x000B
struct hci_cp_link_key_reply {
bdaddr_t bdaddr;
uint8 link_key[16];
linkkey_t link_key;
} __attribute__ ((packed));
#define OCF_LINK_KEY_NEG_REPLY 0x000C
+14 -6
View File
@@ -9,7 +9,9 @@
#include <bluetooth/bluetooth_error.h>
#include <bluetooth/BluetoothDevice.h>
#include <bluetoothserver_p.h>
#include <support/String.h>
#include <ObjectList.h>
#define B_BT_WAIT 0x00
#define B_BT_SUCCEEDED 0x01
@@ -26,6 +28,14 @@ public:
static const int WAIT = B_BT_WAIT;
static const int SUCCEEDED = B_BT_SUCCEEDED;
enum ConnectionState {
CONNECTED,
CONNECTING,
DISCONNECTED
};
static BObjectList<RemoteDevice> GetRemoteDevices(LocalDevice* localDevice);
virtual ~RemoteDevice();
bool IsTrustedDevice();
@@ -34,21 +44,20 @@ public:
BString GetCachedFriendlyName();
bdaddr_t GetBluetoothAddress();
uint8 GetPageRepetitionMode();
uint8 GetScanMode();
uint8 GetClockOffset();
uint16 GetClockOffset();
DeviceClass GetDeviceClass();
bool Equals(RemoteDevice* obj);
status_t Connect();
status_t CancelConnection();
status_t Disconnect();
status_t Disconnect(bool removeDevice);
/*static RemoteDevice* GetRemoteDevice(Connection conn); Throwing */
/* bool Authorize(Connection conn); Throwing */
/*bool Encrypt(Connection conn, bool on); Throwing */
/*bool IsAuthorized(Connection conn); Throwing */
bool IsAuthenticated(); /* Throwing */
RemoteDevice::ConnectionState GetConnectionState();
bool IsEncrypted(); /* Throwing */
BString GetProperty(const char* property); /* Throwing */
@@ -62,7 +71,7 @@ public:
protected:
/* called by Discovery[Listener|Agent] */
void SetLocalDeviceOwner(LocalDevice* ld);
void SetLocalDeviceOwner(LocalDevice* ld);
friend class DiscoveryListener;
private:
@@ -70,7 +79,6 @@ private:
LocalDevice* fDiscovererLocalDevice;
BMessenger* fMessenger;
uint16 fHandle;
uint8 fPageRepetitionMode;
uint8 fScanPeriodMode;
uint8 fScanMode;
+2 -2
View File
@@ -74,7 +74,7 @@ status_t
SingleParameterCommandRequest(uint8 ofg, uint8 ocf, PARAMETERTYPE parameter,
int32* result, hci_id hId, BMessenger* messenger)
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<typed_command(PARAMETERCONTAINER)>
simpleCommand(ofg, ocf);
@@ -93,7 +93,7 @@ SingleParameterCommandRequest(uint8 ofg, uint8 ocf, PARAMETERTYPE parameter,
request.AddInt16("opcodeExpected", PACK_OPCODE(ofg, ocf));
if (messenger->SendMessage(&request, &reply) == B_OK) {
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
if (result != NULL)
reply.FindInt32("result", result);
}
@@ -17,6 +17,7 @@
#define BT_MSG_ADD_DEVICE 'btDD'
#define BT_MSG_REMOVE_DEVICE 'btrD'
#define BT_MSG_GET_PROPERTY 'btgP'
#define BT_MSG_GET_REMOTE_DEVICES 'btgD'
// Discovery
#define BT_MSG_INQUIRY_STARTED 'IqSt'
@@ -33,5 +34,9 @@
#define BT_REQ_CREATE_CONN 'rdCN'
#define BT_REQ_CANCEL_CONN 'rdCC'
#define BT_REQ_DISCONNECT 'rdDC'
#define BT_REQ_REMOVE_DEVICE 'rdRD'
#define BT_REQ_CONN_STATE 'rdCS'
#endif
@@ -48,19 +48,19 @@ ResetLocalDeviceAddOn::TakeAction(LocalDevice* lDevice)
if (fMessenger == NULL || !fMessenger->IsValid())
return B_ERROR;
BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
request.AddInt32("hci_id", lDevice->ID());
request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size());
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &btStatus);
reply.FindUInt8("status", &btStatus);
return btStatus;
}
@@ -96,7 +96,7 @@ ResetLocalDeviceAddOn::OverridenProperties(LocalDevice* lDevice, const char* pro
//BMessage* newProperties = new BMessage();
//newProperties->AddInt8("max_sco", 10);
//return newProperties;
return NULL;
}
+2 -2
View File
@@ -49,7 +49,7 @@ NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId,
BMessenger* messenger)
{
CALLED();
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> simpleCommand(ofg, ocf);
@@ -63,7 +63,7 @@ NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId,
request.AddInt16("opcodeExpected", PACK_OPCODE(ofg, ocf));
if (messenger->SendMessage(&request, &reply) == B_OK) {
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
if (result != NULL)
reply.FindInt32("result", result);
}
+2 -2
View File
@@ -106,7 +106,7 @@ DiscoveryAgent::CancelInquiry(DiscoveryListener* listener)
return B_ERROR;
void* cancelInquiryCommand = NULL;
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
/* Issue inquiry command */
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
@@ -121,7 +121,7 @@ DiscoveryAgent::CancelInquiry(DiscoveryListener* listener)
PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL));
if (fMessenger->SendMessage(&request, &reply) == B_OK) {
if (reply.FindInt8("status", &bt_status ) == B_OK ) {
if (reply.FindUInt8("status", &bt_status ) == B_OK ) {
return bt_status;
}
}
+2 -2
View File
@@ -68,7 +68,7 @@ void
DiscoveryListener::MessageReceived(BMessage* message)
{
CALLED();
int8 status;
uint8 status;
switch (message->what) {
case BT_MSG_INQUIRY_DEVICE:
@@ -149,7 +149,7 @@ DiscoveryListener::MessageReceived(BMessage* message)
}
case BT_MSG_INQUIRY_STARTED:
if (message->FindInt8("status", &status) == B_OK) {
if (message->FindUInt8("status", &status) == B_OK) {
fRemoteDevicesList.MakeEmpty();
InquiryStarted(status);
}
+25 -25
View File
@@ -149,10 +149,10 @@ LocalDevice::GetProperty(const char* property, uint32* value)
int
LocalDevice::GetDiscoverable()
{
{
if (fMessenger == NULL)
return -1;
size_t size;
void* command = buildReadScan(&size);
if (command == NULL)
@@ -170,7 +170,7 @@ LocalDevice::GetDiscoverable()
if (fMessenger->SendMessage(&request, &reply) == B_OK
&& reply.FindInt8("scan_enable", &discoverable) == B_OK)
return discoverable;
return -1;
}
@@ -185,7 +185,7 @@ LocalDevice::SetDiscoverable(int mode)
BMessage reply;
size_t size;
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
request.AddInt32("hci_id", fHid);
@@ -202,7 +202,7 @@ LocalDevice::SetDiscoverable(int mode)
OCF_WRITE_SCAN_ENABLE));
if (fMessenger->SendMessage(&request, &reply) == B_OK) {
if (reply.FindInt8("status", &bt_status ) == B_OK ) {
if (reply.FindUInt8("status", &bt_status ) == B_OK ) {
return bt_status;
}
@@ -298,10 +298,10 @@ LocalDevice::GetFriendlyName()
status_t
LocalDevice::SetFriendlyName(BString& name)
{
int8 btStatus = BT_ERROR;
uint8 bt_status = BT_ERROR;
if (fMessenger == NULL)
return btStatus;
return bt_status;
BluetoothCommand<typed_command(hci_write_local_name)>
writeName(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME);
@@ -319,9 +319,9 @@ LocalDevice::SetFriendlyName(BString& name)
OCF_WRITE_LOCAL_NAME));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &btStatus);
reply.FindUInt8("status", &bt_status);
return btStatus;
return bt_status;
}
@@ -366,7 +366,7 @@ LocalDevice::GetDeviceClass()
status_t
LocalDevice::SetDeviceClass(DeviceClass deviceClass)
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
if (fMessenger == NULL)
return bt_status;
@@ -389,7 +389,7 @@ LocalDevice::SetDeviceClass(DeviceClass deviceClass)
OCF_WRITE_CLASS_OF_DEV));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
@@ -399,7 +399,7 @@ LocalDevice::SetDeviceClass(DeviceClass deviceClass)
status_t
LocalDevice::_ReadLocalVersion()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,
OCF_READ_LOCAL_VERSION);
@@ -415,7 +415,7 @@ LocalDevice::_ReadLocalVersion()
OCF_READ_LOCAL_VERSION));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
}
@@ -424,7 +424,7 @@ LocalDevice::_ReadLocalVersion()
status_t
LocalDevice::_ReadLocalSupportedCommands()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> localSupportedCommands(OGF_INFORMATIONAL_PARAM,
OCF_READ_LOCAL_SUPPORTED_COMMANDS);
@@ -440,7 +440,7 @@ LocalDevice::_ReadLocalSupportedCommands()
OCF_READ_LOCAL_SUPPORTED_COMMANDS));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
}
@@ -449,7 +449,7 @@ LocalDevice::_ReadLocalSupportedCommands()
status_t
LocalDevice::_ReadBufferSize()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM,
OCF_READ_BUFFER_SIZE);
@@ -466,7 +466,7 @@ LocalDevice::_ReadBufferSize()
OCF_READ_BUFFER_SIZE));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
}
@@ -475,7 +475,7 @@ LocalDevice::_ReadBufferSize()
status_t
LocalDevice::_ReadLocalFeatures()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> LocalFeatures(OGF_INFORMATIONAL_PARAM,
OCF_READ_LOCAL_FEATURES);
@@ -491,7 +491,7 @@ LocalDevice::_ReadLocalFeatures()
OCF_READ_LOCAL_FEATURES));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
}
@@ -500,7 +500,7 @@ LocalDevice::_ReadLocalFeatures()
status_t
LocalDevice::_ReadLinkKeys()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> LocalFeatures(OGF_CONTROL_BASEBAND,
OCF_READ_STORED_LINK_KEY);
@@ -519,7 +519,7 @@ LocalDevice::_ReadLinkKeys()
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
}
@@ -553,7 +553,7 @@ LocalDevice::_ReadTimeouts()
status_t
LocalDevice::Reset()
{
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
@@ -567,7 +567,7 @@ LocalDevice::Reset()
OCF_RESET));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
return bt_status;
@@ -620,7 +620,7 @@ LocalDevice::LocalDevice(hci_id hid)
#ifdef BT_WRITE_BDADDR_FOR_BCM2035
#warning Writting broadcom bdaddr @ init.
// try write bdaddr to a bcm2035 -> will be moved to an addon
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)>
writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR);
@@ -642,7 +642,7 @@ LocalDevice::LocalDevice(hci_id hid)
OCF_WRITE_BCM2035_BDADDR));
if (fMessenger->SendMessage(&request, &reply) == B_OK)
reply.FindInt8("status", &bt_status);
reply.FindUInt8("status", &bt_status);
#endif
}
}
+63 -23
View File
@@ -21,7 +21,6 @@
#include <Catalog.h>
#include <CommandManager.h>
#include <Locale.h>
#include <bluetoothserver_p.h>
#include "KitSupport.h"
@@ -32,11 +31,6 @@
namespace Bluetooth {
// TODO: Check headers for valid/reserved ranges
static const uint16 invalidConnectionHandle = 0xF000;
bool
RemoteDevice::IsTrustedDevice(void)
{
@@ -45,6 +39,40 @@ RemoteDevice::IsTrustedDevice(void)
}
BObjectList<RemoteDevice>
RemoteDevice::GetRemoteDevices(LocalDevice* localDevice)
{
BMessage requestRemoteDevices(BT_MSG_GET_REMOTE_DEVICES);
BObjectList<RemoteDevice> rdList;
BMessage devices;
requestRemoteDevices.AddInt32("hci_id", localDevice->ID());
if (BMessenger(BLUETOOTH_SIGNATURE).SendMessage(&requestRemoteDevices,
&devices) != B_OK)
return rdList;
BMessage device;
for (int32 i = 0; devices.FindMessage("remote", i, &device) == B_OK; i++) {
bdaddr_t* bdaddr;
uint8* classOfDevice;
ssize_t size;
device.FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size);
device.FindData("cod", B_ANY_TYPE, (const void**)&classOfDevice, &size);
RemoteDevice* rd = new RemoteDevice(*bdaddr, classOfDevice);
rd->fDiscovererLocalDevice = localDevice;
device.FindString("name", &rd->fFriendlyName);
device.FindUInt16("clock_offset", &rd->fClockOffset);
device.FindUInt8("pscan_rep_mode", &rd->fPageRepetitionMode);
rdList.AddItem(rd);
}
return rdList;
}
BString
RemoteDevice::GetFriendlyName(bool alwaysAsk)
{
@@ -84,9 +112,9 @@ RemoteDevice::GetFriendlyName(bool alwaysAsk)
if (fMessenger->SendMessage(&request, &reply) == B_OK) {
BString name;
int8 status;
uint8 status;
if ((reply.FindInt8("status", &status) == B_OK) && (status == BT_OK)) {
if ((reply.FindUInt8("status", &status) == B_OK) && (status == BT_OK)) {
if ((reply.FindString("friendlyname", &name) == B_OK )) {
fFriendlyName = name;
@@ -133,20 +161,13 @@ RemoteDevice::GetBluetoothAddress()
}
uint8
uint16
RemoteDevice::GetClockOffset()
{
return fClockOffset;
}
uint8
RemoteDevice::GetScanMode()
{
return fScanMode;
}
uint8
RemoteDevice::GetPageRepetitionMode()
{
@@ -173,6 +194,9 @@ RemoteDevice::Connect()
bdaddr_t bdaddr = GetBluetoothAddress();
request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
request.AddString("name", GetFriendlyName());
request.AddUInt32("record", fDeviceClass.Record());
uint16 packetType;
fDiscovererLocalDevice->GetProperty("packet_type", (uint32*)&packetType);
request.AddUInt16("packet type", packetType);
@@ -209,14 +233,17 @@ RemoteDevice::CancelConnection()
status_t
RemoteDevice::Disconnect()
RemoteDevice::Disconnect(bool removeDevice)
{
CALLED();
BMessage request(BT_REQ_DISCONNECT);
if (removeDevice)
request.what = BT_REQ_REMOVE_DEVICE;
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
request.AddUInt16("handle", fHandle);
bdaddr_t bdaddr = GetBluetoothAddress();
request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
request.AddUInt8("reason", BT_REMOTE_USER_ENDED_CONNECTION);
if (fMessenger->SendMessage(&request) == B_OK)
@@ -230,11 +257,22 @@ RemoteDevice::Disconnect()
// bool Encrypt(Connection conn, bool on);
bool
RemoteDevice::IsAuthenticated()
RemoteDevice::ConnectionState
RemoteDevice::GetConnectionState()
{
CALLED();
return true;
BMessage request(BT_REQ_CONN_STATE);
BMessage reply;
bdaddr_t bdaddr = GetBluetoothAddress();
request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
if (fMessenger->SendMessage(&request, &reply) != B_OK)
return RemoteDevice::DISCONNECTED;
uint8 conn_state;
reply.FindUInt8("conn state", &conn_state);
return static_cast<RemoteDevice::ConnectionState>(conn_state);
}
@@ -270,7 +308,8 @@ RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld)
RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
:
BluetoothDevice(),
fDiscovererLocalDevice(NULL)
fDiscovererLocalDevice(NULL),
fScanMode(0)
{
CALLED();
fBdaddr = address;
@@ -282,7 +321,8 @@ RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
RemoteDevice::RemoteDevice(const BString& address)
:
BluetoothDevice(),
fDiscovererLocalDevice(NULL)
fDiscovererLocalDevice(NULL),
fScanMode(0)
{
CALLED();
fBdaddr = bdaddrUtils::FromString((const char*)address.String());
+5 -6
View File
@@ -143,14 +143,13 @@ PincodeWindow::InitUI()
void
PincodeWindow::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
switch (msg->what) {
case skMessageAcceptButton:
{
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
size_t size;
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
void* command = buildPinCodeRequestReply(fBdaddr,
strlen(fPincodeText->Text()),
@@ -168,7 +167,7 @@ PincodeWindow::MessageReceived(BMessage* msg)
// we reside in the server
if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
if (reply.FindInt8("status", &bt_status ) == B_OK) {
if (reply.FindUInt8("status", &bt_status ) == B_OK) {
PostMessage(B_QUIT_REQUESTED);
}
// TODO: something failed here
@@ -181,7 +180,7 @@ PincodeWindow::MessageReceived(BMessage* msg)
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
size_t size;
int8 bt_status = BT_ERROR;
uint8 bt_status = BT_ERROR;
void* command = buildPinCodeRequestNegativeReply(fBdaddr, &size);
@@ -196,7 +195,7 @@ PincodeWindow::MessageReceived(BMessage* msg)
OCF_PIN_CODE_NEG_REPLY));
if (be_app_messenger.SendMessage(&request, &reply) == B_OK) {
if (reply.FindInt8("status", &bt_status ) == B_OK ) {
if (reply.FindUInt8("status", &bt_status ) == B_OK ) {
PostMessage(B_QUIT_REQUESTED);
}
// TODO: something failed here
@@ -135,9 +135,10 @@ BluetoothWindow::MessageReceived(BMessage* message)
{
const char* signature;
if (message->FindString("signature", &signature) == B_OK
&& strcmp(signature, BLUETOOTH_SIGNATURE) == 0)
&& strcmp(signature, BLUETOOTH_SIGNATURE) == 0) {
StartWatchingServer();
fRemoteDevices->LoadRemoteDevices();
}
break;
}
+6 -6
View File
@@ -21,7 +21,7 @@ DeviceListItem::DeviceListItem(RemoteDevice* bDevice)
:
BListItem(),
fDevice(bDevice),
fConnState(RD_DISCONNECTED)
fConnectionState(RemoteDevice::DISCONNECTED)
{
fAddress = bDevice->GetBluetoothAddress();
fClass = bDevice->GetDeviceClass();
@@ -160,16 +160,16 @@ DeviceListItem::Device() const
void
DeviceListItem::SetConnState(DeviceConnState connState)
DeviceListItem::SetConnectionState(RemoteDevice::ConnectionState connectionState)
{
fConnState = connState;
fConnectionState = connectionState;
}
DeviceConnState
DeviceListItem::GetConnState()
RemoteDevice::ConnectionState
DeviceListItem::GetConnectionState()
{
return fConnState;
return fConnectionState;
}
+4 -10
View File
@@ -7,19 +7,13 @@
#include <ListItem.h>
#include <String.h>
#include <bluetoothserver_p.h>
#include "bluetooth/RemoteDevice.h"
namespace Bluetooth {
enum DeviceConnState {
RD_CONNECTED,
RD_CONNECTING,
RD_DISCONNECTED
};
class DeviceListItem : public BListItem
{
public:
@@ -34,8 +28,8 @@ class DeviceListItem : public BListItem
void SetDevice(RemoteDevice* bDevice);
RemoteDevice* Device() const;
void SetConnState(DeviceConnState connState);
DeviceConnState GetConnState();
void SetConnectionState(RemoteDevice::ConnectionState connectionState);
RemoteDevice::ConnectionState GetConnectionState();
private:
RemoteDevice* fDevice;
@@ -44,7 +38,7 @@ class DeviceListItem : public BListItem
BString fName;
int32 fRSSI;
DeviceConnState fConnState;
RemoteDevice::ConnectionState fConnectionState;
};
}
@@ -118,8 +118,7 @@ ExtendedLocalDeviceView::MessageReceived(BMessage* message)
}
switch (message->what)
{
switch (message->what) {
case SET_DISCOVERABLE:
case SET_VISIBLE:
fScanMode = 0;
+1 -2
View File
@@ -79,8 +79,7 @@ public:
InquiryResponse(int discType)
{
BMessage* message;
switch (discType)
{
switch (discType) {
case BT_INQUIRY_COMPLETED:
message = new BMessage(kMsgFinish);
fInquiryPanel->PostMessage(message);
+64 -11
View File
@@ -134,11 +134,34 @@ RemoteDevicesView::AttachedToWindow(void)
// blockButton->SetTarget(this);
// availButton->SetTarget(this);
LoadRemoteDevices();
LoadSettings();
fDeviceList->Select(0);
}
void
RemoteDevicesView::LoadRemoteDevices()
{
BObjectList<RemoteDevice> rdList = RemoteDevice::GetRemoteDevices(ActiveLocalDevice);
if (rdList.IsEmpty())
return;
BMessage device;
for (int32 i = 0; i < rdList.CountItems(); i++) {
RemoteDevice* remote = rdList.ItemAt(i);
DeviceListItem* deviceItem = new DeviceListItem(remote);
deviceItem->SetConnectionState(remote->GetConnectionState());
BMessage message(kMsgAddToRemoteList);
message.AddPointer("device", deviceItem);
MessageReceived(&message);
}
}
void
RemoteDevicesView::MessageReceived(BMessage* message)
{
@@ -152,8 +175,24 @@ RemoteDevicesView::MessageReceived(BMessage* message)
}
case kMsgRemoveDevice:
{
RemoteDevice* remote = NULL;
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
->ItemAt(fDeviceList->CurrentSelection(0)));
if (device != NULL)
remote = dynamic_cast<RemoteDevice*>(device->Device());
fDeviceList->RemoveItem(fDeviceList->CurrentSelection(0));
if (remote == NULL)
break;
remote->Disconnect(true);
break;
}
case kMsgAddToRemoteList:
{
DeviceListItem* device = NULL;
@@ -194,7 +233,7 @@ RemoteDevicesView::MessageReceived(BMessage* message)
break;
fConnectingDeviceItem = device;
fConnectingDeviceItem->SetConnState(RD_CONNECTING);
fConnectingDeviceItem->SetConnectionState(RemoteDevice::CONNECTING);
DeviceSelected();
remote->Connect();
@@ -206,9 +245,9 @@ RemoteDevicesView::MessageReceived(BMessage* message)
uint8 status;
message->FindUInt8("status", &status);
if (status == BT_OK)
fConnectingDeviceItem->SetConnState(RD_CONNECTED);
fConnectingDeviceItem->SetConnectionState(RemoteDevice::CONNECTED);
else
fConnectingDeviceItem->SetConnState(RD_DISCONNECTED);
fConnectingDeviceItem->SetConnectionState(RemoteDevice::DISCONNECTED);
DeviceSelected();
@@ -227,7 +266,7 @@ RemoteDevicesView::MessageReceived(BMessage* message)
if (remote == NULL)
break;
fConnectingDeviceItem = device;
remote->Disconnect();
remote->Disconnect(false);
break;
}
@@ -235,10 +274,24 @@ RemoteDevicesView::MessageReceived(BMessage* message)
case BT_MSG_CONN_FAILED:
case BT_MSG_DISCONN_COMPLETED:
{
fConnectingDeviceItem->SetConnState(RD_DISCONNECTED);
DeviceSelected();
if (fConnectingDeviceItem != NULL) {
fConnectingDeviceItem->SetConnectionState(RemoteDevice::DISCONNECTED);
fConnectingDeviceItem = NULL;
} else {
// Remote Disconnection
bdaddr_t* bdaddr;
ssize_t size;
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size);
fConnectingDeviceItem = NULL;
for (int32 i = 0; i < fDeviceList->CountItems(); i++) {
DeviceListItem* item = static_cast<DeviceListItem*>(fDeviceList->ItemAt(i));
if (bdaddrUtils::Compare(item->Device()->GetBluetoothAddress(), *bdaddr)) {
item->SetConnectionState(RemoteDevice::DISCONNECTED);
}
}
}
DeviceSelected();
break;
}
@@ -263,18 +316,18 @@ RemoteDevicesView::DeviceSelected()
if (device == NULL)
return;
switch (device->GetConnState()) {
case RD_CONNECTING:
switch (device->GetConnectionState()) {
case RemoteDevice::CONNECTING:
pairButton->SetEnabled(false);
disconnectButton->SetEnabled(false);
cancelButton->SetEnabled(true);
break;
case RD_CONNECTED:
case RemoteDevice::CONNECTED:
pairButton->SetEnabled(false);
disconnectButton->SetEnabled(true);
cancelButton->SetEnabled(false);
break;
case RD_DISCONNECTED:
case RemoteDevice::DISCONNECTED:
pairButton->SetEnabled(true);
disconnectButton->SetEnabled(false);
cancelButton->SetEnabled(false);
@@ -40,6 +40,8 @@ public:
void LoadSettings(void);
bool IsDefaultable(void);
void LoadRemoteDevices();
protected:
void SetCurrentColor(rgb_color color);
+59
View File
@@ -228,6 +228,23 @@ void BluetoothServer::MessageReceived(BMessage* message)
break;
}
case BT_REQ_REMOVE_DEVICE:
{
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
if (lDeviceImpl == NULL)
break;
lDeviceImpl->Disconnect(message);
const bdaddr_t* bdaddr;
ssize_t addr_size;
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &addr_size);
ServerRemoteDevice* rd = lDeviceImpl->RemoteDeviceByAddr(*bdaddr);
lDeviceImpl->RemoveRemoteDevice(rd);
break;
}
case BT_START_WATCHING_CONNECTIONS:
{
BMessenger* messenger = new BMessenger();
@@ -244,6 +261,48 @@ void BluetoothServer::MessageReceived(BMessage* message)
break;
}
case BT_MSG_GET_REMOTE_DEVICES:
{
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
if (lDeviceImpl == NULL)
break;
RemoteDevicesList* rdList = lDeviceImpl->GetRemoteDevicesList();
for (int32 i = 0; i < rdList->CountItems(); i++) {
ServerRemoteDevice* rd = rdList->ItemAt(i);
BMessage device;
bdaddr_t bdaddr = rd->bdaddr;
device.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
device.AddString("name", rd->friendly_name);
device.AddData("cod", B_RAW_TYPE, rd->classOfDevice, sizeof(rd->classOfDevice));
device.AddUInt16("clock_offset", rd->clock_offset);
device.AddUInt8("pscan_rep_mode", rd->pscan_rep_mode);
reply.AddMessage("remote", &device);
}
message->SendReply(&reply);
break;
}
case BT_REQ_CONN_STATE:
{
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
if (lDeviceImpl == NULL)
break;
const bdaddr_t* bdaddr;
ssize_t addr_size;
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &addr_size);
ServerRemoteDevice* rd = lDeviceImpl->RemoteDeviceByAddr(*bdaddr);
reply.AddUInt8("conn state", static_cast<uint8>(rd->conn_state));
message->SendReply(&reply);
break;
}
default:
BApplication::MessageReceived(message);
break;
+243 -50
View File
@@ -15,13 +15,12 @@
#include <bluetooth/bdaddrUtils.h>
#include <bluetooth/bluetooth_error.h>
#include <bluetooth/LinkKeyUtils.h>
#include <bluetooth/RemoteDevice.h>
#include <bluetooth/HCI/btHCI_event.h>
#include <bluetoothserver_p.h>
#include <ConnectionIncoming.h>
#include <PincodeWindow.h>
#include <FindDirectory.h>
#include <stdio.h>
#include <new>
@@ -68,13 +67,13 @@ LocalDeviceImpl::CreateTransportAccessor(BPath* path)
LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
{
LoadRemoteDevices();
}
LocalDeviceImpl::~LocalDeviceImpl()
{
SaveRemoteDevices();
}
@@ -92,6 +91,116 @@ LocalDeviceImpl::Unregister()
}
void
LocalDeviceImpl::SaveRemoteDevices()
{
BMessage devices;
for (int32 i = 0; i < fRemoteDevicesList.CountItems(); i++) {
ServerRemoteDevice* rd = fRemoteDevicesList.ItemAt(i);
BMessage device;
bdaddr_t bdaddr = rd->bdaddr;
linkkey_t link_key = rd->link_key;
device.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
device.AddString("name", rd->friendly_name);
device.AddUInt16("clock_offset", rd->clock_offset);
device.AddUInt8("pscan_rep_mode", rd->pscan_rep_mode);
device.AddData("cod", B_RAW_TYPE, rd->classOfDevice, sizeof(rd->classOfDevice));
device.AddData("link key", B_ANY_TYPE, &link_key, sizeof(linkkey_t));
device.AddUInt8("link type", rd->link_type);
devices.AddMessage("remote", &device);
}
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append("Bluetooth_paired_devices");
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (file.InitCheck()==B_OK)
devices.Flatten(&file);
}
}
void
LocalDeviceImpl::LoadRemoteDevices()
{
BPath path;
BMessage devices;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
path.Append("Bluetooth_paired_devices");
BFile file(path.Path(), B_READ_ONLY);
if (file.InitCheck()==B_OK)
devices.Unflatten(&file);
}
BMessage device;
for (int32 i = 0; devices.FindMessage("remote", i, &device) == B_OK; i++) {
ServerRemoteDevice* rd = new ServerRemoteDevice();
ssize_t size;
bdaddr_t* bdaddr;
device.FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size);
rd->bdaddr = *bdaddr;
device.FindString("name", &rd->friendly_name);
device.FindUInt16("clock_offset", &rd->clock_offset);
device.FindUInt8("pscan_rep_mode", &rd->pscan_rep_mode);
device.FindUInt8("cod", 0, &rd->classOfDevice[0]);
device.FindUInt8("cod", 1, &rd->classOfDevice[1]);
device.FindUInt8("cod", 2, &rd->classOfDevice[2]);
device.FindData("link key", B_ANY_TYPE, (const void**)&rd->link_key, &size);
device.FindUInt8("link type", &rd->link_type);
rd->conn_state = RemoteDevice::DISCONNECTED;
fRemoteDevicesList.AddItem(rd);
}
}
ServerRemoteDevice*
LocalDeviceImpl::RemoteDeviceByAddr(bdaddr_t bdaddr)
{
for (int32 i = 0; i < fRemoteDevicesList.CountItems(); i++) {
ServerRemoteDevice* rd = fRemoteDevicesList.ItemAt(i);
if (bdaddrUtils::Compare(rd->bdaddr, bdaddr))
return rd;
}
return NULL;
}
ServerRemoteDevice*
LocalDeviceImpl::RemoteDeviceByHandle(uint16 handle)
{
for (int32 i = 0; i < fRemoteDevicesList.CountItems(); i++) {
ServerRemoteDevice* rd = fRemoteDevicesList.ItemAt(i);
if (rd->handle == handle)
return rd;
}
return NULL;
}
void
LocalDeviceImpl::AddRemoteDevice(ServerRemoteDevice* rd)
{
fRemoteDevicesList.AddItem(rd);
}
void
LocalDeviceImpl::RemoveRemoteDevice(ServerRemoteDevice* rd)
{
fRemoteDevicesList.RemoveItem(rd);
}
RemoteDevicesList*
LocalDeviceImpl::GetRemoteDevicesList()
{
return &fRemoteDevicesList;
}
#if 0
#pragma mark - Event handling methods -
#endif
@@ -402,7 +511,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Reply for Local Version %x\n", version->status);
reply.AddInt8("status", version->status);
reply.AddUInt8("status", version->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -425,7 +534,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Page Timeout=%x\n", pageTimeout->page_timeout);
}
reply.AddInt8("status", pageTimeout->status);
reply.AddUInt8("status", pageTimeout->status);
reply.AddInt32("result", pageTimeout->page_timeout);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
@@ -479,7 +588,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Reply for Local Features %x\n", features->status);
reply.AddInt8("status", features->status);
reply.AddUInt8("status", features->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -514,7 +623,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Reply for Read Buffer Size %x\n", buffer->status);
reply.AddInt8("status", buffer->status);
reply.AddUInt8("status", buffer->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -541,7 +650,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Reply for Supported Commands %x\n",
supported_commands->status);
reply.AddInt8("status", supported_commands->status);
reply.AddUInt8("status", supported_commands->status);
status = request->SendReply(&reply);
// printf("Sending reply... %d\n", status);
// debug reply.PrintToStream();
@@ -564,7 +673,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Read bdaddr status = %x\n", readbdaddr->status);
reply.AddInt8("status", readbdaddr->status);
reply.AddUInt8("status", readbdaddr->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -590,7 +699,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
classDev->dev_class[1], classDev->dev_class[2]);
reply.AddInt8("status", classDev->status);
reply.AddUInt8("status", classDev->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -614,7 +723,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: Friendly name status %x\n", readLocalName->status);
reply.AddInt8("status", readLocalName->status);
reply.AddUInt8("status", readLocalName->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -631,7 +740,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
// TODO: This reply has to match the BDADDR of the outgoing message
TRACE_BT("LocalDeviceImpl: pincode accept status %x\n", *statusReply);
reply.AddInt8("status", *statusReply);
reply.AddUInt8("status", *statusReply);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -650,7 +759,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
// => FindPetition should be expanded....
TRACE_BT("LocalDeviceImpl: pincode reject status %x\n", *statusReply);
reply.AddInt8("status", *statusReply);
reply.AddUInt8("status", *statusReply);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -671,7 +780,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
linkKeyRetrieval->max_num_keys,
linkKeyRetrieval->num_keys_read);
reply.AddInt8("status", linkKeyRetrieval->status);
reply.AddUInt8("status", linkKeyRetrieval->status);
status = request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -706,7 +815,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
TRACE_BT("LocalDeviceImpl: enable = %x\n", scanEnable->enable);
}
reply.AddInt8("status", scanEnable->status);
reply.AddUInt8("status", scanEnable->status);
reply.AddInt8("scan_enable", scanEnable->enable);
status = request->SendReply(&reply);
printf("Sending reply. scan_enable = %d\n", scanEnable->enable);
@@ -730,7 +839,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL):
{
reply.AddInt8("status", *(uint8*)(event + 1));
reply.AddUInt8("status", *(uint8*)(event + 1));
TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__,
BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1));
@@ -759,7 +868,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME):
case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR):
{
reply.AddInt8("status", *(uint8*)(event + 1));
reply.AddUInt8("status", *(uint8*)(event + 1));
TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__,
BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1));
@@ -802,7 +911,7 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
TRACE_BT("LocalDeviceImpl: Inquiry status %x\n", event->status);
reply.AddInt8("status", event->status);
reply.AddUInt8("status", event->status);
request->SendReply(&reply);
//printf("Sending reply... %ld\n", status);
// debug reply.PrintToStream();
@@ -864,7 +973,7 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
if (event->status == BT_NO_CONNECTION) {
reply.what = BT_MSG_DISCONN_COMPLETED;
reply.AddInt8("status", event->status);
reply.AddUInt8("status", event->status);
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
ClearWantedEvent(request);
@@ -1128,7 +1237,7 @@ LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
{
BMessage reply(BT_MSG_INQUIRY_COMPLETED);
reply.AddInt8("status", *status);
reply.AddUInt8("status", *status);
printf("%s: Sending reply...\n", __func__);
status_t stat = request->SendReply(&reply);
@@ -1150,7 +1259,7 @@ LocalDeviceImpl::RemoteNameRequestComplete(
reply.AddString("friendlyname", (const char*)remotename->remote_name );
}
reply.AddInt8("status", remotename->status);
reply.AddUInt8("status", remotename->status);
TRACE_BT("LocalDeviceImpl: %s for %s with status %s\n",
BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE),
@@ -1220,15 +1329,39 @@ LocalDeviceImpl::CreateConnection(BMessage* message)
TRACE_BT("LocalDeviceImpl: Create Connection to %s...\n",
bdaddrUtils::ToString(*bdaddr).String());
ServerRemoteDevice* rdConn;
rdConn = RemoteDeviceByAddr(*bdaddr);
if (rdConn == NULL) {
rdConn = new ServerRemoteDevice();
rdConn->bdaddr = *bdaddr;
rdConn->link_key = LinkKeyUtils::NullKey();
}
message->FindString("name", &rdConn->friendly_name);
message->FindUInt8("pscan_rep_mode", &rdConn->pscan_rep_mode);
message->FindUInt16("clock_offset", &rdConn->clock_offset);
uint32 record;
message->FindUInt32("record", &record);
rdConn->classOfDevice[0] = (record & 0x000000FF);
rdConn->classOfDevice[1] = (record & 0x0000FF00) >> 8;
rdConn->classOfDevice[2] = (record & 0x00FF0000) >> 16;
rdConn->conn_state = RemoteDevice::CONNECTING;
rdConn->link_type = HCI_ACL_CONN;
AddRemoteDevice(rdConn);
BluetoothCommand<typed_command(hci_cp_create_conn)>
command(OGF_LINK_CONTROL, OCF_CREATE_CONN);
command->bdaddr = *bdaddr;
message->FindUInt16("packet type", &command->pkt_type);
command->pkt_type &= ACL_PTYPE_MASK;
message->FindUInt8("pscan_rep_mode", &command->pscan_rep_mode);
command->pscan_rep_mode = rdConn->pscan_rep_mode;
message->FindUInt8("pscan_mode", &command->pscan_mode); // Reserved in spec 2.1
message->FindUInt16("clock_offset", &command->clock_offset);
command->clock_offset = rdConn->clock_offset;
command->clock_offset |= 0x8000; // substract!
message->FindUInt8("role_switch", &command->role_switch);
@@ -1294,7 +1427,12 @@ LocalDeviceImpl::Disconnect(BMessage* message)
BluetoothCommand<typed_command(hci_disconnect)> command(OGF_LINK_CONTROL,
OCF_DISCONNECT);
message->FindUInt16("handle", &command->handle);
const bdaddr_t* bdaddr;
ssize_t addr_size;
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &addr_size);
ServerRemoteDevice* rd = RemoteDeviceByAddr(*bdaddr);
command->handle = rd->handle;
message->FindUInt8("reason", &command->reason);
@@ -1349,12 +1487,17 @@ void
LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event)
{
BMessage reply;
ServerRemoteDevice* rd = RemoteDeviceByAddr(event->bdaddr);
reply.AddUInt8("status", event->status);
if (event->status == BT_OK) {
uint8 cod[3] = {0, 0, 0};
rd->handle = event->handle;
rd->link_type = event->link_type;
rd->conn_state = RemoteDevice::CONNECTED;
// TODO: Review, this rDevice is leaked
ConnectionIncoming* iConnection = new ConnectionIncoming(
new RemoteDevice(event->bdaddr, cod));
new RemoteDevice(event->bdaddr, rd->classOfDevice));
iConnection->Show();
TRACE_BT("LocalDeviceImpl: %s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__,
@@ -1373,6 +1516,12 @@ LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event)
reply.what = BT_MSG_CONN_COMPLETED;
} else {
linkkey_t nullLinkKey = LinkKeyUtils::NullKey();
if (LinkKeyUtils::Compare(&rd->link_key, &nullLinkKey))
RemoveRemoteDevice(rd);
else
rd->conn_state = RemoteDevice::DISCONNECTED;
TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__,
BluetoothError(event->status));
@@ -1389,8 +1538,18 @@ LocalDeviceImpl::DisconnectionComplete(hci_ev_disconnection_complete_reply* even
TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle,
BluetoothError(event->reason), event->status);
ServerRemoteDevice* rd;
rd = RemoteDeviceByHandle(event->handle);
BMessage reply(BT_MSG_DISCONN_COMPLETED);
reply.AddInt8("status", event->status);
reply.AddUInt8("status", event->status);
if (event->status != BT_OK || rd == NULL) {
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
return;
}
reply.AddData("bdaddr", B_ANY_TYPE, &rd->bdaddr, sizeof(bdaddr_t));
rd->conn_state = RemoteDevice::DISCONNECTED;
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
}
@@ -1429,12 +1588,19 @@ void
LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event,
BMessage* request)
{
// TODO: Here we are supposed to save the link key in the Database
TRACE_BT("LocalDeviceImpl: %s: Address %s, key=%s, type=%d\n", __FUNCTION__,
bdaddrUtils::ToString(event->bdaddr).String(),
LinkKeyUtils::ToString(event->link_key).String(), event->key_type);
if (request != NULL)
ClearWantedEvent(request);
ServerRemoteDevice* rd = RemoteDeviceByAddr(event->bdaddr);
if (rd == NULL)
return;
rd->link_key = event->link_key;
rd->link_type = event->key_type;
}
@@ -1445,31 +1611,48 @@ LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
TRACE_BT("LocalDeviceImpl: %s: Address %s\n", __FUNCTION__,
bdaddrUtils::ToString(keyRequested->bdaddr).String());
// TODO:
// Here we are supposed to check the BDADDR received, look into the server
// (RemoteDevice Database) if we have any pas link key interchanged with
// the given address if we have we are to accept it will "Link key Request
// Reply". As we dont not have such database yet, we will always deny it
// forcing the remote device to start a pairing.
ServerRemoteDevice* rd = RemoteDeviceByAddr(keyRequested->bdaddr);
linkkey_t nullLinkKey = LinkKeyUtils::NullKey();
if (rd == NULL || LinkKeyUtils::Compare(&rd->link_key, &nullLinkKey)) {
BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY);
BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY);
BMessage* newrequest = new BMessage;
newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
newrequest->AddInt16("opcodeExpected",
PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY));
// on neg reply we expect this
newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
AddWantedEvent(newrequest);
bdaddrUtils::Copy(linkKeyNegativeReply->bdaddr, keyRequested->bdaddr);
BMessage* newrequest = new BMessage;
newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY));
// on neg reply we expect this
newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
AddWantedEvent(newrequest);
bdaddrUtils::Copy(linkKeyNegativeReply->bdaddr, keyRequested->bdaddr);
if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
linkKeyNegativeReply.Size()) == B_ERROR) {
TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__);
if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
linkKeyNegativeReply.Size()) == B_ERROR) {
TRACE_BT("LocalDeviceImpl: Command issued error for neg reply %s\n", __FUNCTION__);
} else {
TRACE_BT("LocalDeviceImpl: Command issued in neg reply of %s\n", __FUNCTION__);
}
} else {
TRACE_BT("LocalDeviceImpl: Command issued in reply of %s\n", __FUNCTION__);
}
BluetoothCommand<typed_command(hci_cp_link_key_reply)>
linkKeyReply(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY);
BMessage* newrequest = new BMessage;
newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY));
// on neg reply we expect this
newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
AddWantedEvent(newrequest);
bdaddrUtils::Copy(linkKeyReply->bdaddr, keyRequested->bdaddr);
linkKeyReply->link_key = rd->link_key;
if ((fHCIDelegate)->IssueCommand(linkKeyReply.Data(), linkKeyReply.Size()) == B_ERROR) {
TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__);
} else {
TRACE_BT("LocalDeviceImpl: Command issued in reply of %s\n", __FUNCTION__);
}
}
if (request != NULL)
ClearWantedEvent(request, HCI_EVENT_LINK_KEY_REQ);
@@ -1629,6 +1812,16 @@ LocalDeviceImpl::AuthComplete(struct hci_ev_auth_complete* eventData, BMessage*
} else {
TRACE_BT("LocalDeviceImpl: Authentication Failed for handle %d with status 0x%02x\n",
handle, status);
ServerRemoteDevice* rd = RemoteDeviceByHandle(eventData->handle);
rd->link_key = LinkKeyUtils::NullKey();
if (rd != NULL) {
BMessage disconnReq;
bdaddr_t bdaddr = rd->bdaddr;
disconnReq.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
disconnReq.AddUInt8("reason", BT_AUTHENTICATION_FAILURE);
Disconnect(&disconnReq);
}
}
if (request != NULL) {
+33 -2
View File
@@ -8,6 +8,10 @@
#include <String.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/L2CAP/btL2CAP.h>
#include <bluetoothserver_p.h>
#include <bluetooth/RemoteDevice.h>
#include <ObjectList.h>
#include "LocalDeviceHandler.h"
@@ -15,6 +19,23 @@
#include "HCIControllerAccessor.h"
#include "HCITransportAccessor.h"
struct ServerRemoteDevice
{
bdaddr_t bdaddr;
BString friendly_name;
uint16 clock_offset;
uint8 pscan_rep_mode;
uint8 classOfDevice[3];
linkkey_t link_key;
uint8 link_type;
uint16 handle;
RemoteDevice::ConnectionState conn_state;
};
typedef BObjectList<ServerRemoteDevice> RemoteDevicesList;
class LocalDeviceImpl : public LocalDeviceHandler {
private:
@@ -33,14 +54,24 @@ public:
// Request handling
status_t ProcessSimpleRequest(BMessage* request);
void NotifyWatchers(BMessage* notice);
// Connection
void CreateConnection(BMessage* message);
void CancelConnection(BMessage* message);
void Disconnect(BMessage* message);
ServerRemoteDevice* RemoteDeviceByAddr(bdaddr_t bdaddr);
ServerRemoteDevice* RemoteDeviceByHandle(uint16 handle);
void AddRemoteDevice(ServerRemoteDevice* rd);
void RemoveRemoteDevice(ServerRemoteDevice* rd);
RemoteDevicesList* GetRemoteDevicesList();
private:
RemoteDevicesList fRemoteDevicesList;
void SaveRemoteDevices();
void LoadRemoteDevices();
void HandleUnexpectedEvent(struct hci_event_header* event);
void HandleExpectedRequest(struct hci_event_header* event,
BMessage* request);