diff --git a/headers/os/bluetooth/BluetoothDevice.h b/headers/os/bluetooth/BluetoothDevice.h index 3182d0c058..2b88663ebb 100644 --- a/headers/os/bluetooth/BluetoothDevice.h +++ b/headers/os/bluetooth/BluetoothDevice.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -18,23 +19,31 @@ namespace Bluetooth { class BluetoothDevice { - public: +public: + BluetoothDevice() + : + fBdaddr(bdaddrUtils::NullAddress()), + fDeviceClass() + { - virtual BString GetFriendlyName()=0; - virtual DeviceClass GetDeviceClass()=0; + } - virtual BString GetProperty(const char* property)=0; - virtual status_t GetProperty(const char* property, uint32* value)=0; + virtual BString GetFriendlyName()=0; + virtual DeviceClass GetDeviceClass()=0; - virtual bdaddr_t GetBluetoothAddress()=0; + virtual BString GetProperty(const char* property)=0; + virtual status_t GetProperty(const char* property, uint32* value)=0; - protected: - bdaddr_t fBdaddr; - DeviceClass fDeviceClass; + virtual bdaddr_t GetBluetoothAddress()=0; + +protected: + bdaddr_t fBdaddr; + DeviceClass fDeviceClass; }; } + #ifndef _BT_USE_EXPLICIT_NAMESPACE using Bluetooth::BluetoothDevice; #endif diff --git a/headers/os/bluetooth/HCI/btHCI_command.h b/headers/os/bluetooth/HCI/btHCI_command.h index c11584c94d..0fa938ec6f 100644 --- a/headers/os/bluetooth/HCI/btHCI_command.h +++ b/headers/os/bluetooth/HCI/btHCI_command.h @@ -102,7 +102,13 @@ struct hci_command_header { char local_name[HCI_DEVICE_NAME_SIZE]; } __attribute__ ((packed)); + #define OCF_READ_CA_TIMEOUT 0x0015 #define OCF_WRITE_CA_TIMEOUT 0x0016 + #define OCF_READ_PG_TIMEOUT 0x0017 + struct hci_rp_read_page_timeout { + uint8 status; + uint16 page_timeout; + } __attribute__ ((packed)); #define OCF_WRITE_PG_TIMEOUT 0x0018 #define OCF_WRITE_SCAN_ENABLE 0x001A @@ -240,6 +246,11 @@ struct hci_command_header { uint8 pin_code[HCI_PIN_SIZE]; } __attribute__ ((packed)); + struct hci_cp_link_key_reply_reply { + uint8 status; + bdaddr_t bdaddr; + } __attribute__ ((packed)); + #define OCF_PIN_CODE_NEG_REPLY 0x000E struct hci_cp_pin_code_neg_reply { bdaddr_t bdaddr; diff --git a/headers/os/bluetooth/HCI/btHCI_event.h b/headers/os/bluetooth/HCI/btHCI_event.h index bec67a8a04..022d54a099 100644 --- a/headers/os/bluetooth/HCI/btHCI_event.h +++ b/headers/os/bluetooth/HCI/btHCI_event.h @@ -315,11 +315,11 @@ struct hci_ev_sychronous_connection_changed { #define HCI_EVENT_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION 0x3D -/* HAIKU Internal Events, not produced by the transport devices but - * by some entity of the Haiku Bluetooth Stack. +/* HAIKU Internal Events, not produced by the transport devices but + * by some entity of the Haiku Bluetooth Stack. * The MSB 0xE is chosen for this purpose */ - + #define HCI_HAIKU_EVENT_SERVER_QUITTING 0xE0 #define HCI_HAIKU_EVENT_DEVICE_REMOVED 0xE1 diff --git a/headers/os/bluetooth/LocalDevice.h b/headers/os/bluetooth/LocalDevice.h index 10ad355ab3..99752d06be 100644 --- a/headers/os/bluetooth/LocalDevice.h +++ b/headers/os/bluetooth/LocalDevice.h @@ -38,6 +38,7 @@ public: /* Possible throwing */ status_t SetDiscoverable(int mode); + status_t SetAuthentication(bool authentication); BString GetProperty(const char* property); status_t GetProperty(const char* property, uint32* value); @@ -56,6 +57,8 @@ private: status_t _ReadLocalVersion(); status_t _ReadBufferSize(); status_t _ReadLocalFeatures(); + status_t _ReadTimeouts(); + status_t _ReadLinkKeys(); status_t Reset(); static LocalDevice* RequestLocalDeviceID(BMessage* request); diff --git a/src/kits/bluetooth/LocalDevice.cpp b/src/kits/bluetooth/LocalDevice.cpp index 3c9f6702a2..af0fd432e8 100644 --- a/src/kits/bluetooth/LocalDevice.cpp +++ b/src/kits/bluetooth/LocalDevice.cpp @@ -191,6 +191,19 @@ LocalDevice::SetDiscoverable(int mode) } +struct authentication_t { + uint8 param; +}; + +status_t +LocalDevice::SetAuthentication(bool authentication) +{ + return SingleParameterCommandRequest + (OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, authentication, + NULL, fHid, fMessenger); +} + + bdaddr_t LocalDevice::GetBluetoothAddress() { @@ -406,6 +419,58 @@ LocalDevice::_ReadLocalFeatures() } +status_t +LocalDevice::_ReadLinkKeys() +{ + int8 bt_status = BT_ERROR; + + BluetoothCommand<> LocalFeatures(OGF_CONTROL_BASEBAND, + OCF_READ_STORED_LINK_KEY); + + BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); + BMessage reply; + + request.AddInt32("hci_id", fHid); + request.AddData("raw command", B_ANY_TYPE, + LocalFeatures.Data(), LocalFeatures.Size()); + request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); + request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, + OCF_READ_STORED_LINK_KEY)); + + request.AddInt16("eventExpected", HCI_EVENT_RETURN_LINK_KEYS); + + + if (fMessenger->SendMessage(&request, &reply) == B_OK) + reply.FindInt8("status", &bt_status); + + return bt_status; +} + + +struct pageTimeout_t { + uint16 param; +}; + +status_t +LocalDevice::_ReadTimeouts() +{ + + // Read PageTimeout + NonParameterCommandRequest(OGF_CONTROL_BASEBAND, + OCF_READ_PG_TIMEOUT, NULL, fHid, fMessenger); + + // Write PageTimeout + SingleParameterCommandRequest + (OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT, 0x8000, NULL, + fHid, fMessenger); + + // Write PageTimeout + return SingleParameterCommandRequest + (OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT, 0x7d00, NULL, + fHid, fMessenger); +} + + status_t LocalDevice::Reset() { @@ -443,13 +508,18 @@ LocalDevice::updateRecord(ServiceRecord srvRecord) { */ -LocalDevice::LocalDevice(hci_id hid) : fHid(hid) +LocalDevice::LocalDevice(hci_id hid) + : + BluetoothDevice(), + fHid(hid) { fMessenger = _RetrieveBluetoothMessenger(); _ReadBufferSize(); _ReadLocalFeatures(); _ReadLocalVersion(); + _ReadTimeouts(); + _ReadLinkKeys(); uint32 value; @@ -461,7 +531,7 @@ LocalDevice::LocalDevice(hci_id hid) : fHid(hid) // Reset(); // Perform a reset to Broadcom buggyland // Uncomment this out if your Broadcom dongle has a null bdaddr -// #define BT_WRITE_BDADDR_FOR_BCM2035 +//#define BT_WRITE_BDADDR_FOR_BCM2035 #ifdef BT_WRITE_BDADDR_FOR_BCM2035 #warning Writting broadcom bdaddr @ init. // try write bdaddr to a bcm2035 -> will be moved to an addon diff --git a/src/kits/bluetooth/RemoteDevice.cpp b/src/kits/bluetooth/RemoteDevice.cpp index b5c05d9d10..082b5cbff0 100644 --- a/src/kits/bluetooth/RemoteDevice.cpp +++ b/src/kits/bluetooth/RemoteDevice.cpp @@ -57,12 +57,14 @@ RemoteDevice::GetFriendlyName(bool alwaysAsk) request.AddInt32("hci_id", fDiscovererLocalDevice->ID()); // Fill the request - remoteNameCommand = buildRemoteNameRequest(fBdaddr, fPageRepetitionMode, fClockOffset, &size); + remoteNameCommand = buildRemoteNameRequest(fBdaddr, fPageRepetitionMode, + fClockOffset, &size); request.AddData("raw command", B_ANY_TYPE, remoteNameCommand, size); request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); - request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST)); + request.AddInt16("opcodeExpected", + PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST)); request.AddInt16("eventExpected", HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE); @@ -72,19 +74,19 @@ RemoteDevice::GetFriendlyName(bool alwaysAsk) int8 status; if ((reply.FindInt8("status", &status) == B_OK) && (status == BT_OK)) { - + if ((reply.FindString("friendlyname", &name) == B_OK )) { return name; } else { return BString(""); // should not happen } - + } else { // seems we got a negative event return BString("#CommandFailed#Not Valid name"); } } - + return BString("#NotCompletedRequest#Not Valid name"); } @@ -118,7 +120,74 @@ RemoteDevice::Equals(RemoteDevice* obj) bool RemoteDevice::Authenticate() { - return true; + int8 btStatus = BT_ERROR; + + if (fMessenger == NULL || fDiscovererLocalDevice == NULL) + return false; + + BluetoothCommand + createConnection(OGF_LINK_CONTROL, OCF_CREATE_CONN); + + bacpy(&createConnection->bdaddr, &fBdaddr); + createConnection->pscan_rep_mode = fPageRepetitionMode; + createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1 + createConnection->clock_offset = fClockOffset | 0x8000; // substract! + + uint32 roleSwitch; + fDiscovererLocalDevice->GetProperty("role_switch_capable", &roleSwitch); + createConnection->role_switch = (uint8)roleSwitch; + + uint32 packetType; + fDiscovererLocalDevice->GetProperty("packet_type", &packetType); + createConnection->pkt_type = (uint16)packetType; + + BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); + BMessage reply; + + request.AddInt32("hci_id", fDiscovererLocalDevice->ID()); + request.AddData("raw command", B_ANY_TYPE, + createConnection.Data(), createConnection.Size()); + + // First we get the status about the starting of the connection + request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS); + request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, + OCF_CREATE_CONN)); + + // if authentication needed, we will send any of these commands + // to accept or deny the LINK KEY [a] + request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); + request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, + OCF_LINK_KEY_REPLY)); + + request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); + request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, + OCF_LINK_KEY_NEG_REPLY)); + + // in negative case, a pincode will be replied [b] + // this request will be handled by sepatated by the pincode window + // request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); + // request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL, + // OCF_PIN_CODE_REPLY)); + + // [a] this is expected of authentication required + request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ); + // [b] If we deny the key an authentication will be requested + // but this request will be handled by sepatated by the pincode + // window + // request.AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ); + + // this almost involves already the happy end + request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY); + + request.AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE); + + if (fMessenger->SendMessage(&request, &reply) == B_OK) + reply.FindInt8("status", &btStatus); + + if (btStatus == BT_OK) + return true; + else + return false; } @@ -160,6 +229,9 @@ RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld) /* Constructor */ RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3]) + : + BluetoothDevice(), + fDiscovererLocalDevice(NULL) { fBdaddr = address; fDeviceClass.SetRecord(record); @@ -168,9 +240,11 @@ RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3]) RemoteDevice::RemoteDevice(const BString& address) + : + BluetoothDevice(), + fDiscovererLocalDevice(NULL) { - fDeviceClass.SetRecord((uint32)0); - fBdaddr = bdaddrUtils::FromString((const char *)address.String()); + fBdaddr = bdaddrUtils::FromString((const char*)address.String()); fMessenger = _RetrieveBluetoothMessenger(); }