bluetooth: connection handling refactor
- Introduced cancel connection feature in bluetooth preferences - Moved the connection handling logic into LocalDeviceImpl - Made a watchers list to send notices to all concerned applications Change-Id: Iba87caff68d1b9640fa8d901059daa7a624531f5 Reviewed-on: https://review.haiku-os.org/c/haiku/+/11171 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
eb349566e3
commit
af619799ef
@@ -113,13 +113,23 @@ struct hci_command_header {
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define OCF_READ_CA_TIMEOUT 0x0015
|
||||
struct hci_rp_read_conn_accept_timeout {
|
||||
uint8 status;
|
||||
uint16 conn_accept_timeout;
|
||||
} __attribute__ ((packed));
|
||||
#define OCF_WRITE_CA_TIMEOUT 0x0016
|
||||
struct hci_cp_write_conn_accept_timeout {
|
||||
uint16 conn_accept_timeout;
|
||||
} __attribute__ ((packed));
|
||||
#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
|
||||
struct hci_cp_write_page_timeout {
|
||||
uint16 page_timeout;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define OCF_READ_SCAN_ENABLE 0x0019
|
||||
struct hci_read_scan_enable {
|
||||
@@ -250,6 +260,11 @@ struct hci_command_header {
|
||||
uint16 pkt_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define OCF_CREATE_CONN_CANCEL 0x0008
|
||||
struct hci_cp_create_conn_cancel {
|
||||
bdaddr_t bdaddr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define OCF_ACCEPT_CONN_REQ 0x0009
|
||||
struct hci_cp_accept_conn_req {
|
||||
bdaddr_t bdaddr;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <bluetooth/bluetooth_error.h>
|
||||
#include <bluetooth/BluetoothDevice.h>
|
||||
|
||||
#include <String.h>
|
||||
#include <support/String.h>
|
||||
|
||||
#define B_BT_WAIT 0x00
|
||||
#define B_BT_SUCCEEDED 0x01
|
||||
@@ -26,33 +26,39 @@ public:
|
||||
static const int WAIT = B_BT_WAIT;
|
||||
static const int SUCCEEDED = B_BT_SUCCEEDED;
|
||||
|
||||
virtual ~RemoteDevice();
|
||||
virtual ~RemoteDevice();
|
||||
|
||||
bool IsTrustedDevice();
|
||||
BString GetFriendlyName(bool alwaysAsk); /* Throwing */
|
||||
BString GetFriendlyName(void); /* Throwing */
|
||||
BString GetCachedFriendlyName();
|
||||
bdaddr_t GetBluetoothAddress();
|
||||
DeviceClass GetDeviceClass();
|
||||
bool IsTrustedDevice();
|
||||
BString GetFriendlyName(bool alwaysAsk); /* Throwing */
|
||||
BString GetFriendlyName(void); /* Throwing */
|
||||
BString GetCachedFriendlyName();
|
||||
bdaddr_t GetBluetoothAddress();
|
||||
uint8 GetPageRepetitionMode();
|
||||
uint8 GetScanMode();
|
||||
uint8 GetClockOffset();
|
||||
DeviceClass GetDeviceClass();
|
||||
|
||||
bool Equals(RemoteDevice* obj);
|
||||
bool Equals(RemoteDevice* obj);
|
||||
|
||||
status_t Connect();
|
||||
status_t CancelConnection();
|
||||
status_t Disconnect();
|
||||
|
||||
/*static RemoteDevice* GetRemoteDevice(Connection conn); Throwing */
|
||||
bool Authenticate(); /* Throwing */
|
||||
status_t Disconnect(int8 reason = BT_REMOTE_USER_ENDED_CONNECTION);
|
||||
/* bool Authorize(Connection conn); Throwing */
|
||||
/*bool Encrypt(Connection conn, bool on); Throwing */
|
||||
bool IsAuthenticated(); /* Throwing */
|
||||
/*bool IsAuthorized(Connection conn); Throwing */
|
||||
bool IsEncrypted(); /* Throwing */
|
||||
bool IsAuthenticated(); /* Throwing */
|
||||
bool IsEncrypted(); /* Throwing */
|
||||
|
||||
BString GetProperty(const char* property); /* Throwing */
|
||||
status_t GetProperty(const char* property, uint32* value); /* Throwing */
|
||||
BString GetProperty(const char* property); /* Throwing */
|
||||
status_t GetProperty(const char* property, uint32* value); /* Throwing */
|
||||
|
||||
LocalDevice* GetLocalDeviceOwner();
|
||||
LocalDevice* GetLocalDeviceOwner();
|
||||
|
||||
RemoteDevice(const BString& address);
|
||||
RemoteDevice(const bdaddr_t address, uint8 record[3]);
|
||||
|
||||
RemoteDevice(const BString& address);
|
||||
RemoteDevice(const bdaddr_t address, uint8 record[3]);
|
||||
|
||||
protected:
|
||||
/* called by Discovery[Listener|Agent] */
|
||||
@@ -61,17 +67,17 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
LocalDevice* fDiscovererLocalDevice;
|
||||
BMessenger* fMessenger;
|
||||
LocalDevice* fDiscovererLocalDevice;
|
||||
BMessenger* fMessenger;
|
||||
|
||||
uint16 fHandle;
|
||||
uint8 fPageRepetitionMode;
|
||||
uint8 fScanPeriodMode;
|
||||
uint8 fScanMode;
|
||||
uint16 fClockOffset;
|
||||
int8 fRSSI;
|
||||
BString fFriendlyName;
|
||||
bool fFriendlyNameIsComplete;
|
||||
uint16 fHandle;
|
||||
uint8 fPageRepetitionMode;
|
||||
uint8 fScanPeriodMode;
|
||||
uint8 fScanMode;
|
||||
uint16 fClockOffset;
|
||||
int8 fRSSI;
|
||||
BString fFriendlyName;
|
||||
bool fFriendlyNameIsComplete;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#define BLUETOOTH_APP_SIGNATURE "application/x-vnd.Haiku-BluetoothPrefs"
|
||||
|
||||
/* Kit Comunication */
|
||||
// Watching
|
||||
#define BT_START_WATCHING_CONNECTIONS 'wtST'
|
||||
#define BT_STOP_WATCHING_CONNECTIONS 'wtSP'
|
||||
|
||||
// LocalDevice
|
||||
#define BT_MSG_COUNT_LOCAL_DEVICES 'btCd'
|
||||
@@ -16,10 +19,19 @@
|
||||
#define BT_MSG_GET_PROPERTY 'btgP'
|
||||
|
||||
// Discovery
|
||||
#define BT_MSG_INQUIRY_STARTED 'IqSt'
|
||||
#define BT_MSG_INQUIRY_COMPLETED 'IqCM'
|
||||
#define BT_MSG_INQUIRY_TERMINATED 'IqTR'
|
||||
#define BT_MSG_INQUIRY_ERROR 'IqER'
|
||||
#define BT_MSG_INQUIRY_DEVICE 'IqDE'
|
||||
#define BT_MSG_INQUIRY_STARTED 'IqSt'
|
||||
#define BT_MSG_INQUIRY_COMPLETED 'IqCM'
|
||||
#define BT_MSG_INQUIRY_TERMINATED 'IqTR'
|
||||
#define BT_MSG_INQUIRY_ERROR 'IqER'
|
||||
#define BT_MSG_INQUIRY_DEVICE 'IqDE'
|
||||
|
||||
// Pairing
|
||||
#define BT_MSG_CONN_FAILED 'CnFL'
|
||||
#define BT_MSG_CONN_COMPLETED 'CnCM'
|
||||
#define BT_MSG_DISCONN_COMPLETED 'DcCM'
|
||||
|
||||
#define BT_REQ_CREATE_CONN 'rdCN'
|
||||
#define BT_REQ_CANCEL_CONN 'rdCC'
|
||||
#define BT_REQ_DISCONNECT 'rdDC'
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
#include <bluetooth/bluetooth_error.h>
|
||||
#include <bluetooth/HCI/btHCI_transport.h>
|
||||
#include <bluetooth/HCI/btHCI_event.h>
|
||||
|
||||
@@ -49,6 +50,9 @@ PostEvent(bluetooth_device* ndev, void* event, size_t size)
|
||||
= (struct hci_ev_conn_complete*)(outgoingEvent + 1);
|
||||
|
||||
// TODO: XXX parse handle field
|
||||
if (data->status != BT_OK)
|
||||
break;
|
||||
|
||||
HciConnection* conn = AddConnection(data->handle, BT_ACL,
|
||||
data->bdaddr, ndev->index);
|
||||
|
||||
|
||||
@@ -81,21 +81,18 @@ DiscoveryAgent::StartInquiry(uint32 accessCode, DiscoveryListener* listener,
|
||||
PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
|
||||
|
||||
// For getting each discovered message
|
||||
request.AddInt16("eventExpected", HCI_EVENT_INQUIRY_RESULT);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_INQUIRY_RESULT);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_INQUIRY_RESULT_WITH_RSSI);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_EXTENDED_INQUIRY_RESULT);
|
||||
|
||||
// For finishing each discovered message
|
||||
request.AddInt16("eventExpected", HCI_EVENT_INQUIRY_COMPLETE);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_INQUIRY_COMPLETE);
|
||||
|
||||
|
||||
if (fMessenger->SendMessage(&request, listener) == B_OK)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
if (fMessenger->SendMessage(&request, listener) == B_OK)
|
||||
return B_OK;
|
||||
|
||||
return B_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -133,6 +133,27 @@ RemoteDevice::GetBluetoothAddress()
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
RemoteDevice::GetClockOffset()
|
||||
{
|
||||
return fClockOffset;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
RemoteDevice::GetScanMode()
|
||||
{
|
||||
return fScanMode;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
RemoteDevice::GetPageRepetitionMode()
|
||||
{
|
||||
return fPageRepetitionMode;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RemoteDevice::Equals(RemoteDevice* obj)
|
||||
{
|
||||
@@ -141,130 +162,70 @@ RemoteDevice::Equals(RemoteDevice* obj)
|
||||
}
|
||||
|
||||
|
||||
// static RemoteDevice* GetRemoteDevice(Connection conn);
|
||||
|
||||
|
||||
bool
|
||||
RemoteDevice::Authenticate()
|
||||
status_t
|
||||
RemoteDevice::Connect()
|
||||
{
|
||||
CALLED();
|
||||
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);
|
||||
|
||||
bdaddrUtils::Copy(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 & ACL_PTYPE_MASK;
|
||||
|
||||
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
|
||||
BMessage reply;
|
||||
BMessage request(BT_REQ_CREATE_CONN);
|
||||
|
||||
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));
|
||||
bdaddr_t bdaddr = GetBluetoothAddress();
|
||||
request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
|
||||
|
||||
request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE);
|
||||
request.AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
|
||||
uint16 packetType;
|
||||
fDiscovererLocalDevice->GetProperty("packet_type", (uint32*)&packetType);
|
||||
request.AddUInt16("packet type", packetType);
|
||||
|
||||
if (fMessenger->SendMessage(&request, &reply) == B_OK)
|
||||
reply.FindInt8("status", &btStatus);
|
||||
request.AddUInt8("pscan_rep_mode", fPageRepetitionMode);
|
||||
request.AddUInt8("pscan_mode", fScanMode);
|
||||
request.AddUInt16("clock_offset", fClockOffset);
|
||||
|
||||
if (btStatus != BT_OK)
|
||||
return false;
|
||||
|
||||
reply.FindInt16("handle", (int16*)&fHandle);
|
||||
|
||||
BluetoothCommand<typed_command(hci_cp_auth_requested)> authRequest(OGF_LINK_CONTROL,
|
||||
OCF_AUTH_REQUESTED);
|
||||
|
||||
authRequest->handle = fHandle;
|
||||
|
||||
BMessage authRequestMsg(BT_MSG_HANDLE_SIMPLE_REQUEST);
|
||||
BMessage authReply;
|
||||
|
||||
authRequestMsg.AddInt32("hci_id", fDiscovererLocalDevice->ID());
|
||||
authRequestMsg.AddData("raw command", B_ANY_TYPE, authRequest.Data(), authRequest.Size());
|
||||
|
||||
authRequestMsg.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
|
||||
authRequestMsg.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_AUTH_REQUESTED));
|
||||
|
||||
authRequestMsg.AddInt16("eventExpected", HCI_EVENT_AUTH_COMPLETE);
|
||||
|
||||
int8 authStatus = BT_ERROR;
|
||||
if (fMessenger->SendMessage(&authRequestMsg, &authReply) == B_OK)
|
||||
authReply.FindInt8("status", &authStatus);
|
||||
|
||||
if (authStatus == BT_OK)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RemoteDevice::Disconnect(int8 reason)
|
||||
{
|
||||
CALLED();
|
||||
if (fHandle != invalidConnectionHandle) {
|
||||
|
||||
int8 btStatus = BT_ERROR;
|
||||
|
||||
if (fMessenger == NULL || fDiscovererLocalDevice == NULL)
|
||||
return false;
|
||||
|
||||
BluetoothCommand<typed_command(struct hci_disconnect)>
|
||||
disconnect(OGF_LINK_CONTROL, OCF_DISCONNECT);
|
||||
|
||||
disconnect->reason = reason;
|
||||
disconnect->handle = fHandle;
|
||||
|
||||
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
|
||||
BMessage reply;
|
||||
|
||||
|
||||
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
|
||||
request.AddData("raw command", B_ANY_TYPE,
|
||||
disconnect.Data(), disconnect.Size());
|
||||
|
||||
request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
|
||||
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
|
||||
OCF_DISCONNECT));
|
||||
|
||||
request.AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE);
|
||||
|
||||
if (fMessenger->SendMessage(&request, &reply) == B_OK)
|
||||
reply.FindInt8("status", &btStatus);
|
||||
|
||||
if (btStatus == BT_OK)
|
||||
fHandle = invalidConnectionHandle;
|
||||
|
||||
return btStatus;
|
||||
|
||||
}
|
||||
uint8 roleSwitch;
|
||||
fDiscovererLocalDevice->GetProperty("role_switch_capable", (uint32*)&roleSwitch);
|
||||
request.AddUInt8("role_switch", roleSwitch);
|
||||
|
||||
if (fMessenger->SendMessage(&request) == B_OK)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RemoteDevice::CancelConnection()
|
||||
{
|
||||
CALLED();
|
||||
BMessage request(BT_REQ_CANCEL_CONN);
|
||||
|
||||
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
|
||||
|
||||
bdaddr_t bdaddr = GetBluetoothAddress();
|
||||
request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
|
||||
|
||||
if (fMessenger->SendMessage(&request) == B_OK)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RemoteDevice::Disconnect()
|
||||
{
|
||||
CALLED();
|
||||
BMessage request(BT_REQ_DISCONNECT);
|
||||
|
||||
request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
|
||||
|
||||
request.AddUInt16("handle", fHandle);
|
||||
request.AddUInt8("reason", BT_REMOTE_USER_ENDED_CONNECTION);
|
||||
|
||||
if (fMessenger->SendMessage(&request) == B_OK)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// static RemoteDevice* GetRemoteDevice(Connection conn);
|
||||
// bool Authorize(Connection conn);
|
||||
// bool Encrypt(Connection conn, bool on);
|
||||
|
||||
@@ -309,8 +270,7 @@ RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld)
|
||||
RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
|
||||
:
|
||||
BluetoothDevice(),
|
||||
fDiscovererLocalDevice(NULL),
|
||||
fHandle(invalidConnectionHandle)
|
||||
fDiscovererLocalDevice(NULL)
|
||||
{
|
||||
CALLED();
|
||||
fBdaddr = address;
|
||||
@@ -322,8 +282,7 @@ RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
|
||||
RemoteDevice::RemoteDevice(const BString& address)
|
||||
:
|
||||
BluetoothDevice(),
|
||||
fDiscovererLocalDevice(NULL),
|
||||
fHandle(invalidConnectionHandle)
|
||||
fDiscovererLocalDevice(NULL)
|
||||
{
|
||||
CALLED();
|
||||
fBdaddr = bdaddrUtils::FromString((const char*)address.String());
|
||||
|
||||
@@ -94,6 +94,27 @@ BluetoothWindow::BluetoothWindow(BRect frame)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.End();
|
||||
|
||||
StartWatchingServer();
|
||||
be_roster->StartWatching(this, B_REQUEST_LAUNCHED);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BluetoothWindow::StartWatchingServer()
|
||||
{
|
||||
BMessage watchReq = BMessage(BT_START_WATCHING_CONNECTIONS);
|
||||
watchReq.AddMessenger("messenger", BMessenger(this));
|
||||
BMessenger(BLUETOOTH_SIGNATURE).SendMessage(&watchReq);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BluetoothWindow::StopWatchingServer()
|
||||
{
|
||||
BMessage stopWatchReq = BMessage(BT_STOP_WATCHING_CONNECTIONS);
|
||||
stopWatchReq.AddMessenger("messenger", BMessenger(this));
|
||||
BMessenger(BLUETOOTH_SIGNATURE).SendMessage(&stopWatchReq);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +123,24 @@ BluetoothWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
//message->PrintToStream();
|
||||
switch (message->what) {
|
||||
case BT_MSG_CONN_COMPLETED:
|
||||
case BT_MSG_CONN_FAILED:
|
||||
case BT_MSG_DISCONN_COMPLETED:
|
||||
{
|
||||
fRemoteDevices->MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_SOME_APP_LAUNCHED:
|
||||
{
|
||||
const char* signature;
|
||||
if (message->FindString("signature", &signature) == B_OK
|
||||
&& strcmp(signature, BLUETOOTH_SIGNATURE) == 0)
|
||||
StartWatchingServer();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgSetConnectionPolicy:
|
||||
case kMsgSetDeviceClass:
|
||||
case kMsgSetFriendlyName:
|
||||
@@ -139,9 +178,11 @@ BluetoothWindow::MessageReceived(BMessage* message)
|
||||
case kMsgAddToRemoteList:
|
||||
PostMessage(message, fRemoteDevices);
|
||||
break;
|
||||
|
||||
case kMsgRefresh:
|
||||
fSettingsView->MessageReceived(message);
|
||||
break;
|
||||
|
||||
case B_ABOUT_REQUESTED:
|
||||
be_app->PostMessage(message);
|
||||
break;
|
||||
@@ -155,6 +196,7 @@ BluetoothWindow::MessageReceived(BMessage* message)
|
||||
bool
|
||||
BluetoothWindow::QuitRequested()
|
||||
{
|
||||
StopWatchingServer();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
void MessageReceived(BMessage *message);
|
||||
|
||||
private:
|
||||
void StartWatchingServer();
|
||||
void StopWatchingServer();
|
||||
|
||||
RemoteDevicesView* fRemoteDevices;
|
||||
BButton* fDefaultsButton;
|
||||
BButton* fRevertButton;
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace Bluetooth {
|
||||
DeviceListItem::DeviceListItem(RemoteDevice* bDevice)
|
||||
:
|
||||
BListItem(),
|
||||
fDevice(bDevice)
|
||||
fDevice(bDevice),
|
||||
fConnState(RD_DISCONNECTED)
|
||||
{
|
||||
fAddress = bDevice->GetBluetoothAddress();
|
||||
fClass = bDevice->GetDeviceClass();
|
||||
@@ -158,4 +159,18 @@ DeviceListItem::Device() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DeviceListItem::SetConnState(DeviceConnState connState)
|
||||
{
|
||||
fConnState = connState;
|
||||
}
|
||||
|
||||
|
||||
DeviceConnState
|
||||
DeviceListItem::GetConnState()
|
||||
{
|
||||
return fConnState;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
|
||||
namespace Bluetooth {
|
||||
|
||||
|
||||
enum DeviceConnState {
|
||||
RD_CONNECTED,
|
||||
RD_CONNECTING,
|
||||
RD_DISCONNECTED
|
||||
};
|
||||
|
||||
|
||||
class DeviceListItem : public BListItem
|
||||
{
|
||||
public:
|
||||
@@ -19,20 +27,24 @@ class DeviceListItem : public BListItem
|
||||
|
||||
~DeviceListItem();
|
||||
|
||||
void DrawItem(BView*, BRect, bool = false);
|
||||
void Update(BView* owner, const BFont* font);
|
||||
void DrawItem(BView*, BRect, bool = false);
|
||||
void Update(BView* owner, const BFont* font);
|
||||
|
||||
static int Compare(const void* firstArg, const void* secondArg);
|
||||
void SetDevice(RemoteDevice* bDevice);
|
||||
RemoteDevice* Device() const;
|
||||
static int Compare(const void* firstArg, const void* secondArg);
|
||||
void SetDevice(RemoteDevice* bDevice);
|
||||
RemoteDevice* Device() const;
|
||||
|
||||
void SetConnState(DeviceConnState connState);
|
||||
DeviceConnState GetConnState();
|
||||
|
||||
private:
|
||||
RemoteDevice* fDevice;
|
||||
bdaddr_t fAddress;
|
||||
DeviceClass fClass;
|
||||
BString fName;
|
||||
int32 fRSSI;
|
||||
bdaddr_t fAddress;
|
||||
DeviceClass fClass;
|
||||
BString fName;
|
||||
int32 fRSSI;
|
||||
|
||||
DeviceConnState fConnState;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "BluetoothWindow.h"
|
||||
#include "defs.h"
|
||||
#include "DeviceListItem.h"
|
||||
#include "InquiryPanel.h"
|
||||
#include "RemoteDevicesView.h"
|
||||
|
||||
@@ -38,10 +37,30 @@ static const uint32 kMsgAddDevices = 'ddDv';
|
||||
static const uint32 kMsgRemoveDevice = 'rmDv';
|
||||
static const uint32 kMsgPairDevice = 'trDv';
|
||||
static const uint32 kMsgDisconnectDevice = 'dsDv';
|
||||
static const uint32 kMsgConnComplete = 'cmDv';
|
||||
static const uint32 kMsgCancelConn = 'cnDv';
|
||||
//static const uint32 kMsgBlockDevice = 'blDv';
|
||||
//static const uint32 kMsgRefreshDevices = 'rfDv';
|
||||
|
||||
using namespace Bluetooth;
|
||||
|
||||
class DeviceListView : public BListView
|
||||
{
|
||||
public:
|
||||
DeviceListView(const char* name, list_view_type type)
|
||||
:
|
||||
BListView(name, type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SelectionChanged()
|
||||
{
|
||||
RemoteDevicesView* remoteDevicesView = static_cast<RemoteDevicesView*>(Parent()->Parent());
|
||||
remoteDevicesView->DeviceSelected();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
RemoteDevicesView::RemoteDevicesView(const char* name, uint32 flags)
|
||||
: BView(name, flags)
|
||||
@@ -54,9 +73,16 @@ RemoteDevicesView::RemoteDevicesView(const char* name, uint32 flags)
|
||||
|
||||
pairButton = new BButton("pair", B_TRANSLATE("Pair" B_UTF8_ELLIPSIS),
|
||||
new BMessage(kMsgPairDevice));
|
||||
pairButton->SetEnabled(false);
|
||||
|
||||
disconnectButton = new BButton("disconnect", B_TRANSLATE("Disconnect"),
|
||||
new BMessage(kMsgDisconnectDevice));
|
||||
disconnectButton->SetEnabled(false);
|
||||
|
||||
cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
|
||||
new BMessage(kMsgCancelConn));
|
||||
cancelButton->SetEnabled(false);
|
||||
|
||||
/*
|
||||
blockButton = new BButton("block", B_TRANSLATE("As blocked"),
|
||||
new BMessage(kMsgBlockDevice));
|
||||
@@ -66,7 +92,7 @@ RemoteDevicesView::RemoteDevicesView(const char* name, uint32 flags)
|
||||
new BMessage(kMsgRefreshDevices));
|
||||
*/
|
||||
// Set up device list
|
||||
fDeviceList = new BListView("DeviceList", B_SINGLE_SELECTION_LIST);
|
||||
fDeviceList = new DeviceListView("DeviceList", B_SINGLE_SELECTION_LIST);
|
||||
|
||||
fScrollView = new BScrollView("ScrollView", fDeviceList, 0, false, true);
|
||||
|
||||
@@ -83,18 +109,16 @@ RemoteDevicesView::RemoteDevicesView(const char* name, uint32 flags)
|
||||
// .AddGlue()
|
||||
.Add(pairButton)
|
||||
.Add(disconnectButton)
|
||||
.Add(cancelButton)
|
||||
// .Add(blockButton)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.End();
|
||||
|
||||
fDeviceList->SetSelectionMessage(NULL);
|
||||
}
|
||||
|
||||
|
||||
RemoteDevicesView::~RemoteDevicesView(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +130,7 @@ RemoteDevicesView::AttachedToWindow(void)
|
||||
removeButton->SetTarget(this);
|
||||
pairButton->SetTarget(this);
|
||||
disconnectButton->SetTarget(this);
|
||||
cancelButton->SetTarget(this);
|
||||
// blockButton->SetTarget(this);
|
||||
// availButton->SetTarget(this);
|
||||
|
||||
@@ -163,14 +188,34 @@ RemoteDevicesView::MessageReceived(BMessage* message)
|
||||
if (device == NULL)
|
||||
break;
|
||||
|
||||
|
||||
RemoteDevice* remote = dynamic_cast<RemoteDevice*>(device->Device());
|
||||
if (remote == NULL)
|
||||
break;
|
||||
|
||||
remote->Authenticate();
|
||||
fConnectingDeviceItem = device;
|
||||
fConnectingDeviceItem->SetConnState(RD_CONNECTING);
|
||||
DeviceSelected();
|
||||
|
||||
remote->Connect();
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_MSG_CONN_COMPLETED:
|
||||
{
|
||||
uint8 status;
|
||||
message->FindUInt8("status", &status);
|
||||
if (status == BT_OK)
|
||||
fConnectingDeviceItem->SetConnState(RD_CONNECTED);
|
||||
else
|
||||
fConnectingDeviceItem->SetConnState(RD_DISCONNECTED);
|
||||
|
||||
DeviceSelected();
|
||||
|
||||
fConnectingDeviceItem = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgDisconnectDevice:
|
||||
{
|
||||
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
|
||||
@@ -181,12 +226,28 @@ RemoteDevicesView::MessageReceived(BMessage* message)
|
||||
RemoteDevice* remote = dynamic_cast<RemoteDevice*>(device->Device());
|
||||
if (remote == NULL)
|
||||
break;
|
||||
|
||||
fConnectingDeviceItem = device;
|
||||
remote->Disconnect();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_MSG_CONN_FAILED:
|
||||
case BT_MSG_DISCONN_COMPLETED:
|
||||
{
|
||||
fConnectingDeviceItem->SetConnState(RD_DISCONNECTED);
|
||||
DeviceSelected();
|
||||
|
||||
fConnectingDeviceItem = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgCancelConn:
|
||||
{
|
||||
fConnectingDeviceItem->Device()->CancelConnection();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
@@ -194,13 +255,43 @@ RemoteDevicesView::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
void RemoteDevicesView::LoadSettings(void)
|
||||
void
|
||||
RemoteDevicesView::DeviceSelected()
|
||||
{
|
||||
DeviceListItem* device = static_cast<DeviceListItem*>(fDeviceList
|
||||
->ItemAt(fDeviceList->CurrentSelection(0)));
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
switch (device->GetConnState()) {
|
||||
case RD_CONNECTING:
|
||||
pairButton->SetEnabled(false);
|
||||
disconnectButton->SetEnabled(false);
|
||||
cancelButton->SetEnabled(true);
|
||||
break;
|
||||
case RD_CONNECTED:
|
||||
pairButton->SetEnabled(false);
|
||||
disconnectButton->SetEnabled(true);
|
||||
cancelButton->SetEnabled(false);
|
||||
break;
|
||||
case RD_DISCONNECTED:
|
||||
pairButton->SetEnabled(true);
|
||||
disconnectButton->SetEnabled(false);
|
||||
cancelButton->SetEnabled(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RemoteDevicesView::LoadSettings(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RemoteDevicesView::IsDefaultable(void)
|
||||
bool
|
||||
RemoteDevicesView::IsDefaultable(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
#include <StringView.h>
|
||||
#include <Invoker.h>
|
||||
|
||||
#include "DeviceListItem.h"
|
||||
|
||||
using namespace Bluetooth;
|
||||
|
||||
class DeviceListView;
|
||||
|
||||
|
||||
class RemoteDevicesView : public BView
|
||||
{
|
||||
@@ -30,6 +36,7 @@ public:
|
||||
void AttachedToWindow(void);
|
||||
void MessageReceived(BMessage *msg);
|
||||
|
||||
void DeviceSelected();
|
||||
void LoadSettings(void);
|
||||
bool IsDefaultable(void);
|
||||
|
||||
@@ -43,12 +50,13 @@ protected:
|
||||
BButton* removeButton;
|
||||
BButton* pairButton;
|
||||
BButton* disconnectButton;
|
||||
BButton* cancelButton;
|
||||
// BButton* blockButton;
|
||||
// BButton* availButton;
|
||||
BListView* fDeviceList;
|
||||
DeviceListView* fDeviceList;
|
||||
BScrollView* fScrollView;
|
||||
|
||||
|
||||
DeviceListItem* fConnectingDeviceItem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,6 +63,7 @@ BluetoothServer::BluetoothServer()
|
||||
{
|
||||
fDeviceManager = new DeviceManager();
|
||||
fLocalDevicesList.MakeEmpty();
|
||||
fWatchersList.MakeEmpty();
|
||||
|
||||
fEventListener2 = new BluetoothPortListener(BT_USERLAND_PORT_NAME,
|
||||
(BluetoothPortListener::port_listener_func)&DispatchEvent);
|
||||
@@ -129,8 +130,7 @@ void BluetoothServer::MessageReceived(BMessage* message)
|
||||
BMessage reply;
|
||||
status_t status = B_WOULD_BLOCK; // mark somehow to do not reply anything
|
||||
|
||||
switch (message->what)
|
||||
{
|
||||
switch (message->what) {
|
||||
case BT_MSG_ADD_DEVICE:
|
||||
{
|
||||
BString str;
|
||||
@@ -198,13 +198,59 @@ void BluetoothServer::MessageReceived(BMessage* message)
|
||||
return;
|
||||
}
|
||||
|
||||
case BT_REQ_CREATE_CONN:
|
||||
{
|
||||
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
|
||||
if (lDeviceImpl == NULL)
|
||||
break;
|
||||
|
||||
lDeviceImpl->CreateConnection(message);
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_REQ_CANCEL_CONN:
|
||||
{
|
||||
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
|
||||
if (lDeviceImpl == NULL)
|
||||
break;
|
||||
|
||||
lDeviceImpl->CancelConnection(message);
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_REQ_DISCONNECT:
|
||||
{
|
||||
LocalDeviceImpl* lDeviceImpl = LocateDelegateFromMessage(message);
|
||||
if (lDeviceImpl == NULL)
|
||||
break;
|
||||
|
||||
lDeviceImpl->Disconnect(message);
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_START_WATCHING_CONNECTIONS:
|
||||
{
|
||||
BMessenger* messenger = new BMessenger();
|
||||
if (message->FindMessenger("messenger", messenger) == B_OK)
|
||||
fWatchersList.AddItem(messenger);
|
||||
break;
|
||||
}
|
||||
|
||||
case BT_STOP_WATCHING_CONNECTIONS:
|
||||
{
|
||||
BMessenger* messenger = new BMessenger();
|
||||
if (message->FindMessenger("messenger", messenger) == B_OK)
|
||||
fWatchersList.RemoveItem(messenger);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we reply right now?
|
||||
// TOD: review this condition
|
||||
// TODO: review this condition
|
||||
if (status != B_WOULD_BLOCK) {
|
||||
reply.AddInt32("status", status);
|
||||
message->SendReply(&reply);
|
||||
@@ -214,6 +260,21 @@ void BluetoothServer::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BluetoothServer::NotifyWatchers(BMessage* notice)
|
||||
{
|
||||
for (int32 i = 0; i < fWatchersList.CountItems(); i++) {
|
||||
BMessenger* messenger = fWatchersList.ItemAt(i);
|
||||
if (!messenger->IsValid()) {
|
||||
fWatchersList.RemoveItemAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
messenger->SendMessage(notice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef enum {
|
||||
#define BLACKBOARD_LD(X) (BLACKBOARD_END+X-HCI_DEVICE_INDEX_OFFSET)
|
||||
|
||||
typedef BObjectList<LocalDeviceImpl> LocalDevicesList;
|
||||
typedef BObjectList<BMessenger> WatchersList;
|
||||
typedef PortListener<struct hci_event_header,
|
||||
HCI_MAX_EVENT_SIZE, // Event Body can hold max 255 + 2 header
|
||||
24 // Some devices have sent chunks of 24 events(inquiry result)
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
status_t HandleGetProperty(BMessage* message, BMessage* reply);
|
||||
status_t HandleSimpleRequest(BMessage* message, BMessage* reply);
|
||||
|
||||
void NotifyWatchers(BMessage* notice);
|
||||
|
||||
LocalDeviceImpl* LocateLocalDeviceImpl(hci_id hid);
|
||||
|
||||
@@ -78,6 +80,7 @@ private:
|
||||
void _RemoveDeskbarIcon();
|
||||
|
||||
LocalDevicesList fLocalDevicesList;
|
||||
WatchersList fWatchersList;
|
||||
|
||||
|
||||
// Notification system
|
||||
|
||||
@@ -126,14 +126,16 @@ LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header* event)
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
// should belong to a request? can be sporadic or initiated by us?
|
||||
DisconnectionComplete(
|
||||
JumpEventHeader
|
||||
<struct hci_ev_disconnection_complete_reply>(event),
|
||||
NULL);
|
||||
JumpEventHeader<struct hci_ev_disconnection_complete_reply>(event));
|
||||
break;
|
||||
|
||||
// TODO: feedback unexpected not handled
|
||||
case HCI_EVENT_CONN_COMPLETE:
|
||||
ConnectionComplete(JumpEventHeader<struct hci_ev_conn_complete>(event));
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE_BT("Couldn't handle the unexpected event with code: %x", event->ecode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -153,18 +155,6 @@ LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event,
|
||||
InquiryResult(JumpEventHeader<uint8>(event), request);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CONN_COMPLETE:
|
||||
ConnectionComplete(
|
||||
JumpEventHeader<struct hci_ev_conn_complete>(event), request);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
// should belong to a request? can be sporadic or initiated by us?
|
||||
DisconnectionComplete(
|
||||
JumpEventHeader<struct hci_ev_disconnection_complete_reply>
|
||||
(event), request);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_AUTH_COMPLETE:
|
||||
AuthComplete(JumpEventHeader<struct hci_ev_auth_complete>(event), request);
|
||||
break;
|
||||
@@ -759,6 +749,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
|
||||
}
|
||||
|
||||
// place here all CC that just replies a uint8 status
|
||||
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN_CANCEL):
|
||||
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET):
|
||||
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
|
||||
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV):
|
||||
@@ -826,8 +817,10 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
|
||||
TRACE_BT("LocalDeviceImpl: Command Status for remote friendly name %x\n",
|
||||
event->status);
|
||||
|
||||
reply.AddInt8("status", event->status);
|
||||
request->SendReply(&reply);
|
||||
if (event->status != BT_OK) {
|
||||
reply.AddInt8("status", event->status);
|
||||
request->SendReply(&reply);
|
||||
}
|
||||
// printf("Sending reply... %ld\n", status);
|
||||
// debug reply.PrintToStream();
|
||||
|
||||
@@ -839,20 +832,48 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: Command Status for create connection %x\n", event->status);
|
||||
|
||||
ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
|
||||
if (event->status != BT_OK) {
|
||||
switch (event->status) {
|
||||
case BT_OK:
|
||||
ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
|
||||
break;
|
||||
|
||||
case BT_ACL_CONNECTION_EXISTS:
|
||||
reply.what = BT_MSG_CONN_COMPLETED;
|
||||
reply.AddUInt8("status", BT_OK);
|
||||
request->SendReply(&reply);
|
||||
|
||||
reply.AddInt8("status", event->status);
|
||||
request->SendReply(&reply);
|
||||
// printf("Sending reply... %ld\n", status);
|
||||
// debug reply.PrintToStream();
|
||||
ClearWantedEvent(request);
|
||||
break;
|
||||
|
||||
default:
|
||||
reply.what = BT_MSG_CONN_FAILED;
|
||||
reply.AddUInt8("status", event->status);
|
||||
request->SendReply(&reply);
|
||||
|
||||
ClearWantedEvent(request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
|
||||
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_DISCONNECT):
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: Command Status for disconnect %x\n", event->status);
|
||||
|
||||
ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
|
||||
if (event->status == BT_NO_CONNECTION) {
|
||||
reply.what = BT_MSG_DISCONN_COMPLETED;
|
||||
|
||||
reply.AddInt8("status", event->status);
|
||||
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
|
||||
|
||||
ClearWantedEvent(request);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: Command Status for accept connection request %x\n",
|
||||
event->status);
|
||||
@@ -1171,7 +1192,6 @@ LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event,
|
||||
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ);
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE);
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
|
||||
|
||||
#if 0
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE);
|
||||
@@ -1191,10 +1211,145 @@ LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event,
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event,
|
||||
BMessage* request)
|
||||
LocalDeviceImpl::CreateConnection(BMessage* message)
|
||||
{
|
||||
const bdaddr_t* bdaddr;
|
||||
ssize_t addr_size;
|
||||
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &addr_size);
|
||||
|
||||
TRACE_BT("LocalDeviceImpl: Create Connection to %s...\n",
|
||||
bdaddrUtils::ToString(*bdaddr).String());
|
||||
|
||||
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);
|
||||
message->FindUInt8("pscan_mode", &command->pscan_mode); // Reserved in spec 2.1
|
||||
message->FindUInt16("clock_offset", &command->clock_offset);
|
||||
command->clock_offset |= 0x8000; // substract!
|
||||
message->FindUInt8("role_switch", &command->role_switch);
|
||||
|
||||
|
||||
if (fHCIDelegate->IssueCommand(command.Data(), command.Size()) == B_ERROR) {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued error for %s\n", __FUNCTION__);
|
||||
return;
|
||||
} else {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued for %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
BMessage* newRequest = new BMessage;
|
||||
|
||||
newRequest->AddInt32("hci_id", fHCIDelegate->Id());
|
||||
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
|
||||
newRequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN));
|
||||
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ);
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE);
|
||||
|
||||
AddWantedEvent(newRequest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::CancelConnection(BMessage* message)
|
||||
{
|
||||
const bdaddr_t* bdaddr;
|
||||
ssize_t addr_size;
|
||||
message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &addr_size);
|
||||
|
||||
TRACE_BT("LocalDeviceImpl: Cancel Connection to %s...\n",
|
||||
bdaddrUtils::ToString(*bdaddr).String());
|
||||
|
||||
BluetoothCommand<typed_command(hci_cp_create_conn_cancel)> command(OGF_LINK_CONTROL,
|
||||
OCF_CREATE_CONN_CANCEL);
|
||||
|
||||
command->bdaddr = *bdaddr;
|
||||
|
||||
if (fHCIDelegate->IssueCommand(command.Data(), command.Size()) == B_ERROR) {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued error for %s\n", __FUNCTION__);
|
||||
return;
|
||||
} else {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued for %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
BMessage* newRequest = new BMessage(BT_MSG_HANDLE_SIMPLE_REQUEST);
|
||||
|
||||
newRequest->AddInt32("hci_id", fHCIDelegate->Id());
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
|
||||
newRequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN_CANCEL));
|
||||
|
||||
AddWantedEvent(newRequest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::Disconnect(BMessage* message)
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: %s...\n", __FUNCTION__);
|
||||
|
||||
BluetoothCommand<typed_command(hci_disconnect)> command(OGF_LINK_CONTROL,
|
||||
OCF_DISCONNECT);
|
||||
|
||||
message->FindUInt16("handle", &command->handle);
|
||||
message->FindUInt8("reason", &command->reason);
|
||||
|
||||
|
||||
if (fHCIDelegate->IssueCommand(command.Data(), command.Size()) == B_ERROR) {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued error for %s\n", __FUNCTION__);
|
||||
return;
|
||||
} else {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued for %s\n", __FUNCTION__);
|
||||
}
|
||||
BMessage* newRequest = new BMessage(BT_MSG_HANDLE_SIMPLE_REQUEST);
|
||||
|
||||
newRequest->AddInt32("hci_id", fHCIDelegate->Id());
|
||||
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
|
||||
newRequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_DISCONNECT));
|
||||
|
||||
AddWantedEvent(newRequest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::Authenticate(uint16 handle)
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: %s...\n", __FUNCTION__);
|
||||
|
||||
BluetoothCommand<typed_command(hci_cp_auth_requested)> command(OGF_LINK_CONTROL,
|
||||
OCF_AUTH_REQUESTED);
|
||||
|
||||
command->handle = handle;
|
||||
|
||||
|
||||
if (fHCIDelegate->IssueCommand(command.Data(), command.Size()) == B_ERROR) {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued error for %s\n", __FUNCTION__);
|
||||
return;
|
||||
} else {
|
||||
TRACE_BT("LocalDeviceImpl: Command issued for %s\n", __FUNCTION__);
|
||||
}
|
||||
BMessage* newRequest = new BMessage();
|
||||
|
||||
newRequest->AddInt32("hci_id", fHCIDelegate->Id());
|
||||
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
|
||||
newRequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_AUTH_REQUESTED));
|
||||
|
||||
newRequest->AddInt16("eventExpected", HCI_EVENT_AUTH_COMPLETE);
|
||||
|
||||
AddWantedEvent(newRequest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event)
|
||||
{
|
||||
BMessage reply;
|
||||
reply.AddUInt8("status", event->status);
|
||||
if (event->status == BT_OK) {
|
||||
uint8 cod[3] = {0, 0, 0};
|
||||
// TODO: Review, this rDevice is leaked
|
||||
@@ -1206,59 +1361,38 @@ LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event,
|
||||
bdaddrUtils::ToString(event->bdaddr).String(), event->handle,
|
||||
event->link_type, event->encrypt_mode);
|
||||
|
||||
BMessage* newrequest = new BMessage;
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_IO_CAPABILITY_REQUEST);
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_IO_CAPABILITY_RESPONSE);
|
||||
|
||||
// this implies PAIRING complete
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
|
||||
AddWantedEvent(newrequest);
|
||||
|
||||
Authenticate(event->handle);
|
||||
|
||||
reply.what = BT_MSG_CONN_COMPLETED;
|
||||
} else {
|
||||
TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__,
|
||||
BluetoothError(event->status));
|
||||
|
||||
reply.what = BT_MSG_CONN_FAILED;
|
||||
}
|
||||
|
||||
BMessage* newrequest = new BMessage;
|
||||
|
||||
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_IO_CAPABILITY_REQUEST);
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_IO_CAPABILITY_RESPONSE);
|
||||
|
||||
// this implies PAIRING complete
|
||||
newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
|
||||
AddWantedEvent(newrequest);
|
||||
// it was expected
|
||||
if (request != NULL) {
|
||||
BMessage reply;
|
||||
reply.AddInt8("status", event->status);
|
||||
|
||||
if (event->status == BT_OK)
|
||||
reply.AddInt16("handle", event->handle);
|
||||
|
||||
printf("%s: Sending reply...\n", __func__);
|
||||
status_t status = request->SendReply(&reply);
|
||||
if (status < B_OK)
|
||||
printf("%s: Error sending reply!\n", __func__);
|
||||
// debug reply.PrintToStream();
|
||||
|
||||
ClearWantedEvent(request, HCI_EVENT_CONN_COMPLETE);
|
||||
}
|
||||
|
||||
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::DisconnectionComplete(
|
||||
struct hci_ev_disconnection_complete_reply* event, BMessage* request)
|
||||
LocalDeviceImpl::DisconnectionComplete(hci_ev_disconnection_complete_reply* event)
|
||||
{
|
||||
TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle,
|
||||
BluetoothError(event->reason), event->status);
|
||||
|
||||
if (request != NULL) {
|
||||
BMessage reply;
|
||||
reply.AddInt8("status", event->status);
|
||||
BMessage reply(BT_MSG_DISCONN_COMPLETED);
|
||||
reply.AddInt8("status", event->status);
|
||||
|
||||
printf("%s: Sending reply...\n", __func__);
|
||||
status_t status = request->SendReply(&reply);
|
||||
if (status < B_OK)
|
||||
printf("%s: Error sending reply!\n", __func__);
|
||||
// debug reply.PrintToStream();
|
||||
|
||||
ClearWantedEvent(request);
|
||||
}
|
||||
((BluetoothServer*)be_app)->NotifyWatchers(&reply);
|
||||
}
|
||||
|
||||
|
||||
@@ -1275,6 +1409,7 @@ LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event,
|
||||
void
|
||||
LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request)
|
||||
{
|
||||
// TODO: we shall update the RemoteDevice
|
||||
TRACE_BT("LocalDeviceImpl: %s: Address %s role=%d status=%d\n", __FUNCTION__,
|
||||
bdaddrUtils::ToString(event->bdaddr).String(), event->role, event->status);
|
||||
}
|
||||
@@ -1284,6 +1419,7 @@ void
|
||||
LocalDeviceImpl::PageScanRepetitionModeChange(
|
||||
struct hci_ev_page_scan_rep_mode_change* event, BMessage* request)
|
||||
{
|
||||
// TODO: we shall update the RemoteDevice
|
||||
TRACE_BT("LocalDeviceImpl: %s: Address %s type=%d\n", __FUNCTION__,
|
||||
bdaddrUtils::ToString(event->bdaddr).String(), event->page_scan_rep_mode);
|
||||
}
|
||||
@@ -1293,6 +1429,7 @@ 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);
|
||||
@@ -1309,7 +1446,7 @@ LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
|
||||
bdaddrUtils::ToString(keyRequested->bdaddr).String());
|
||||
|
||||
// TODO:
|
||||
// Here we are suposed to check the BDADDR received, look into the server
|
||||
// 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
|
||||
@@ -1404,7 +1541,7 @@ LocalDeviceImpl::IOCapabilityRequest(struct hci_ev_io_capability_request* event,
|
||||
TRACE_BT("LocalDeviceImpl: IO Capability Request from %s...\n",
|
||||
bdaddrUtils::ToString(event->bdaddr).String());
|
||||
|
||||
// this should be temporary, need to change this to HCI_IO_CAP_DISPLAY_YES_NO
|
||||
// TODO: this should be temporary, need to change this to HCI_IO_CAP_DISPLAY_YES_NO
|
||||
command = buildIOCapabilityRequestReply(event->bdaddr, HCI_IO_CAP_NO_INPUT_NO_OUTPUT,
|
||||
HCI_OOB_DATA_NOT_PRESENT, HCI_AUTH_REQ_NO_MITM_NO_BOND, &size);
|
||||
|
||||
@@ -1484,8 +1621,8 @@ LocalDeviceImpl::SimplePairingComplete(struct hci_ev_simple_pairing_complete* ev
|
||||
void
|
||||
LocalDeviceImpl::AuthComplete(struct hci_ev_auth_complete* eventData, BMessage* request)
|
||||
{
|
||||
int16 handle = B_LENDIAN_TO_HOST_INT16(eventData->handle);
|
||||
int8 status = eventData->status;
|
||||
uint16 handle = B_LENDIAN_TO_HOST_INT16(eventData->handle);
|
||||
uint8 status = eventData->status;
|
||||
|
||||
if (status == BT_OK) {
|
||||
TRACE_BT("LocalDeviceImpl: Authentication Successful for handle %d\n", handle);
|
||||
@@ -1496,8 +1633,8 @@ LocalDeviceImpl::AuthComplete(struct hci_ev_auth_complete* eventData, BMessage*
|
||||
|
||||
if (request != NULL) {
|
||||
BMessage reply;
|
||||
reply.AddInt8("status", status);
|
||||
reply.AddInt16("handle", handle);
|
||||
reply.AddUInt8("status", status);
|
||||
reply.AddUInt16("handle", handle);
|
||||
|
||||
request->SendReply(&reply);
|
||||
|
||||
|
||||
@@ -31,7 +31,14 @@ public:
|
||||
void HandleEvent(struct hci_event_header* event);
|
||||
|
||||
// Request handling
|
||||
status_t ProcessSimpleRequest(BMessage* request);
|
||||
status_t ProcessSimpleRequest(BMessage* request);
|
||||
|
||||
void NotifyWatchers(BMessage* notice);
|
||||
|
||||
// Connection
|
||||
void CreateConnection(BMessage* message);
|
||||
void CancelConnection(BMessage* message);
|
||||
void Disconnect(BMessage* message);
|
||||
|
||||
private:
|
||||
void HandleUnexpectedEvent(struct hci_event_header* event);
|
||||
@@ -56,10 +63,10 @@ private:
|
||||
remotename, BMessage* request);
|
||||
|
||||
// Connection
|
||||
void ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request);
|
||||
void Authenticate(uint16 handle);
|
||||
void ConnectionComplete(struct hci_ev_conn_complete* event);
|
||||
void ConnectionRequest(struct hci_ev_conn_request* event, BMessage* request);
|
||||
void DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event,
|
||||
BMessage* request);
|
||||
void DisconnectionComplete(struct hci_ev_disconnection_complete_reply* event);
|
||||
|
||||
// Pairing
|
||||
void PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request);
|
||||
|
||||
Reference in New Issue
Block a user