From 3fdaa5bf72a0bb3d751cb7c82a22c09aa2b2af46 Mon Sep 17 00:00:00 2001 From: Oliver Ruiz Dorantes Date: Sat, 21 Mar 2009 21:38:00 +0000 Subject: [PATCH] - Drop R5 compatibility by removing first 4 bytes in the IOCTLs containing the size of the command. - Implement mechanism GetProperty to retrieve detailed information about the LocalDevice - Generic BluetoothDevice interface changed and adapted - Implement ReadLocalVersion to be aware of the bluetooth specification supported by our localdevice git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29639 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/bluetooth/BluetoothDevice.h | 2 +- headers/os/bluetooth/HCI/btHCI.h | 6 +++ headers/os/bluetooth/LocalDevice.h | 7 +-- headers/os/bluetooth/RemoteDevice.h | 2 +- headers/private/bluetooth/bluetoothserver_p.h | 1 + src/kits/bluetooth/LocalDevice.cpp | 45 ++++++++++++++-- src/kits/bluetooth/RemoteDevice.cpp | 4 +- src/servers/bluetooth/BluetoothServer.cpp | 49 ++++++++++++++++- src/servers/bluetooth/BluetoothServer.h | 5 +- src/servers/bluetooth/LocalDeviceHandler.cpp | 4 +- src/servers/bluetooth/LocalDeviceHandler.h | 2 +- src/servers/bluetooth/LocalDeviceImpl.cpp | 52 ++++++++++++++++--- 12 files changed, 155 insertions(+), 24 deletions(-) diff --git a/headers/os/bluetooth/BluetoothDevice.h b/headers/os/bluetooth/BluetoothDevice.h index a710963e2c..3182d0c058 100644 --- a/headers/os/bluetooth/BluetoothDevice.h +++ b/headers/os/bluetooth/BluetoothDevice.h @@ -24,7 +24,7 @@ class BluetoothDevice { virtual DeviceClass GetDeviceClass()=0; virtual BString GetProperty(const char* property)=0; - virtual void GetProperty(const char* property, uint32* value)=0; + virtual status_t GetProperty(const char* property, uint32* value)=0; virtual bdaddr_t GetBluetoothAddress()=0; diff --git a/headers/os/bluetooth/HCI/btHCI.h b/headers/os/bluetooth/HCI/btHCI.h index 413c8f97c0..d042d2305d 100644 --- a/headers/os/bluetooth/HCI/btHCI.h +++ b/headers/os/bluetooth/HCI/btHCI.h @@ -35,4 +35,10 @@ typedef enum { BT_COMMAND = 0, #define HCI_FEATURES_SIZE 8 /* LMP features */ #define HCI_DEVICE_NAME_SIZE 248 /* unit name size */ +/* Device drivers need to take this into account + * when receiving ioctls. Only applies to R5 builds + * in deprecation process + */ +#define BT_IOCTLS_PASS_SIZE + #endif // _BTHCI_H_ diff --git a/headers/os/bluetooth/LocalDevice.h b/headers/os/bluetooth/LocalDevice.h index ef2d8dfd84..2a7eba04e5 100644 --- a/headers/os/bluetooth/LocalDevice.h +++ b/headers/os/bluetooth/LocalDevice.h @@ -37,8 +37,8 @@ public: /* Possible throwing */ status_t SetDiscoverable(int mode); - BString GetProperty(const char* property); - void GetProperty(const char* property, uint32* value); + BString GetProperty(const char* property); + status_t GetProperty(const char* property, uint32* value); int GetDiscoverable(); bdaddr_t GetBluetoothAddress(); @@ -50,7 +50,8 @@ public: private: LocalDevice(hci_id hid); virtual ~LocalDevice(); - + + status_t ReadLocalVersion(); hci_id GetID(void) {return hid;} static LocalDevice* RequestLocalDeviceID(BMessage* request); diff --git a/headers/os/bluetooth/RemoteDevice.h b/headers/os/bluetooth/RemoteDevice.h index eb4c870b03..8decdd8c1a 100644 --- a/headers/os/bluetooth/RemoteDevice.h +++ b/headers/os/bluetooth/RemoteDevice.h @@ -44,7 +44,7 @@ public: bool IsEncrypted(); /* Throwing */ BString GetProperty(const char* property); /* Throwing */ - void GetProperty(const char* property, uint32* value); /* Throwing */ + status_t GetProperty(const char* property, uint32* value); /* Throwing */ LocalDevice* GetLocalDeviceOwner(); diff --git a/headers/private/bluetooth/bluetoothserver_p.h b/headers/private/bluetooth/bluetoothserver_p.h index f3cc0ef7bf..ea5574d67c 100644 --- a/headers/private/bluetooth/bluetoothserver_p.h +++ b/headers/private/bluetooth/bluetoothserver_p.h @@ -11,6 +11,7 @@ #define BT_MSG_ACQUIRE_LOCAL_DEVICE 'btAd' #define BT_MSG_HANDLE_SIMPLE_REQUEST 'btsR' #define BT_MSG_ADD_DEVICE 'btDD' +#define BT_MSG_GET_PROPERTY 'btgP' // Discovery #define BT_MSG_INQUIRY_STARTED 'IqSt' diff --git a/src/kits/bluetooth/LocalDevice.cpp b/src/kits/bluetooth/LocalDevice.cpp index f0b3545c3e..fe37f57e8c 100644 --- a/src/kits/bluetooth/LocalDevice.cpp +++ b/src/kits/bluetooth/LocalDevice.cpp @@ -122,11 +122,26 @@ LocalDevice::GetProperty(const char* property) } -void +status_t LocalDevice::GetProperty(const char* property, uint32* value) { + if (fMessenger == NULL) + return B_ERROR; + + BMessage request(BT_MSG_GET_PROPERTY); + BMessage reply; + + request.AddInt32("hci_id", hid); + request.AddString("property", property); + + if (fMessenger->SendMessage(&request, &reply) == B_OK) { + if (reply.FindInt32("result", (int32*)value ) == B_OK ) { + return B_OK; + + } + } - *value = 0; + return B_ERROR; } @@ -198,7 +213,6 @@ LocalDevice::GetBluetoothAddress() request.AddData("raw command", B_ANY_TYPE, command, size); request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR)); - if (fMessenger->SendMessage(&request, &reply) == B_OK) { if (reply.FindData("bdaddr", B_ANY_TYPE, 0, (const void**)&bdaddr, &ssize) == B_OK ) @@ -276,6 +290,30 @@ LocalDevice::GetDeviceClass() } +status_t +LocalDevice::ReadLocalVersion() +{ + size_t size; + int8 bt_status = BT_ERROR; + + BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,OCF_READ_LOCAL_VERSION,&size); + + + BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST); + BMessage reply; + + request.AddInt32("hci_id", hid); + request.AddData("raw command", B_ANY_TYPE, localVersion.Data(), size); + request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE); + request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION)); + + if (fMessenger->SendMessage(&request, &reply) == B_OK) + reply.FindInt8("status", &bt_status); + + return bt_status; +} + + /* ServiceRecord LocalDevice::getRecord(Connection notifier) { @@ -292,6 +330,7 @@ LocalDevice::updateRecord(ServiceRecord srvRecord) { LocalDevice::LocalDevice(hci_id hid) : hid(hid) { fMessenger = _RetrieveBluetoothMessenger(); + ReadLocalVersion(); } diff --git a/src/kits/bluetooth/RemoteDevice.cpp b/src/kits/bluetooth/RemoteDevice.cpp index 27f5680b82..e9e6dbf5f6 100644 --- a/src/kits/bluetooth/RemoteDevice.cpp +++ b/src/kits/bluetooth/RemoteDevice.cpp @@ -187,10 +187,10 @@ RemoteDevice::GetProperty(const char* property) /* Throwing */ } -void +status_t RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */ { - + return B_ERROR; } diff --git a/src/servers/bluetooth/BluetoothServer.cpp b/src/servers/bluetooth/BluetoothServer.cpp index 24c81efd78..bef32a3d47 100644 --- a/src/servers/bluetooth/BluetoothServer.cpp +++ b/src/servers/bluetooth/BluetoothServer.cpp @@ -140,6 +140,10 @@ void BluetoothServer::MessageReceived(BMessage *message) case BT_MSG_HANDLE_SIMPLE_REQUEST: status = HandleSimpleRequest(message, &reply); break; + case BT_MSG_GET_PROPERTY: + status = HandleGetProperty(message, &reply); + break; + /* Handle if the bluetooth preferences is running?? */ case B_SOME_APP_LAUNCHED: { @@ -296,7 +300,7 @@ status_t BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply) { LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); - BString propertyRequested; + const char* propertyRequested; // Find out if there is a property being requested, if (message->FindString("property", &propertyRequested) == B_OK) { @@ -317,6 +321,49 @@ BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply) } +status_t +BluetoothServer::HandleGetProperty(BMessage* message, BMessage* reply) +{ + /* User side will look for the reply in a result field + * and will not care about status fields, therefore we return OK in all cases + */ + + LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); + const char* propertyRequested; + + // Find out if there is a property being requested, + if (message->FindString("property", &propertyRequested) == B_OK) { + + Output::Instance()->Postf(BLACKBOARD_LD(ldi->GetID()), "Searching %s property...\n", + propertyRequested); + + // Check if the property has been already retrieved + if (ldi->IsPropertyAvailable(propertyRequested)) { + if (strcmp(propertyRequested, "hci_version") == 0) { + uint8 result = ldi->GetPropertiesMessage()->FindInt8(propertyRequested); + reply->AddInt32("result", result); + } else if (strcmp(propertyRequested, "hci_revision") == 0) { + uint16 result = ldi->GetPropertiesMessage()->FindInt16(propertyRequested); + reply->AddInt32("result", result); + } else if (strcmp(propertyRequested, "lmp_version") == 0) { + uint8 result = ldi->GetPropertiesMessage()->FindInt8(propertyRequested); + reply->AddInt32("result", result); + } else if (strcmp(propertyRequested, "lmp_subversion") == 0) { + uint16 result = ldi->GetPropertiesMessage()->FindInt16(propertyRequested); + reply->AddInt32("result", result); + } else if (strcmp(propertyRequested, "manufacturer") == 0) { + uint16 result = ldi->GetPropertiesMessage()->FindInt16(propertyRequested); + reply->AddInt32("result", result); + } else { + Output::Instance()->Postf(BLACKBOARD_LD(ldi->GetID()), "Property %s could not be satisfied\n", + propertyRequested); + } + } + } + + return B_OK; +} + #if 0 #pragma mark - #endif diff --git a/src/servers/bluetooth/BluetoothServer.h b/src/servers/bluetooth/BluetoothServer.h index 9dd5ff00a1..527e930a0a 100644 --- a/src/servers/bluetooth/BluetoothServer.h +++ b/src/servers/bluetooth/BluetoothServer.h @@ -61,9 +61,8 @@ public: /* Messages reply */ status_t HandleLocalDevicesCount(BMessage* message, BMessage* reply); status_t HandleAcquireLocalDevice(BMessage* message, BMessage* reply); - status_t HandleGetFriendlyName(BMessage* message, BMessage* reply); - status_t HandleGetAddress(BMessage* message, BMessage* reply); - + + status_t HandleGetProperty(BMessage* message, BMessage* reply); status_t HandleSimpleRequest(BMessage* message, BMessage* reply); diff --git a/src/servers/bluetooth/LocalDeviceHandler.cpp b/src/servers/bluetooth/LocalDeviceHandler.cpp index e0aabc12fd..492e942329 100644 --- a/src/servers/bluetooth/LocalDeviceHandler.cpp +++ b/src/servers/bluetooth/LocalDeviceHandler.cpp @@ -50,12 +50,12 @@ LocalDeviceHandler::Acquire(void) bool -LocalDeviceHandler::IsPropertyAvailable(const BString& property) +LocalDeviceHandler::IsPropertyAvailable(const char* property) { type_code typeFound; int32 countFound; - return (fProperties->GetInfo(property.String(), &typeFound, &countFound) == B_OK ); + return (fProperties->GetInfo(property, &typeFound, &countFound) == B_OK ); } diff --git a/src/servers/bluetooth/LocalDeviceHandler.h b/src/servers/bluetooth/LocalDeviceHandler.h index 29079b6524..48b4bd9ae5 100644 --- a/src/servers/bluetooth/LocalDeviceHandler.h +++ b/src/servers/bluetooth/LocalDeviceHandler.h @@ -27,7 +27,7 @@ public: status_t Launch(void); BMessage* GetPropertiesMessage(void) { return fProperties; } - bool IsPropertyAvailable(const BString& property); + bool IsPropertyAvailable(const char* property); protected: diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index 2cb3dc5d4c..4287583c51 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -236,19 +236,54 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re int16 opcodeExpected; BMessage reply; - - Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD(GetID())); - Output::Instance()->Post("\n", BLACKBOARD_LD(GetID())); - + // Handle command complete information request->FindInt16("opcodeExpected", index, &opcodeExpected); if (request->IsSourceWaiting() == false) Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); - + + + Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s for command %s\n",__FUNCTION__, GetCommand(opcodeExpected)); switch (opcodeExpected) { + case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION): + { + struct hci_rp_read_loc_version* version = (struct hci_rp_read_loc_version*)(event+1); + + if (version->status == BT_OK) { + + //reply.AddData("version", B_ANY_TYPE, &version, sizeof(struct hci_rp_read_loc_version)); + reply.AddInt8("status", version->status); + + printf("Sending reply ... %ld\n", request->SendReply(&reply)); + reply.PrintToStream(); + + if (!IsPropertyAvailable("hci_version")) + fProperties->AddInt8("hci_version", version->hci_version); + + if (!IsPropertyAvailable("hci_revision")) + fProperties->AddInt16("hci_revision", version->hci_revision); + + if (!IsPropertyAvailable("lmp_version")) + fProperties->AddInt8("lmp_version", version->lmp_version); + + if (!IsPropertyAvailable("lmp_subversion")) + fProperties->AddInt16("lmp_subversion", version->lmp_subversion); + + if (!IsPropertyAvailable("manufacturer")) + fProperties->AddInt16("manufacturer", version->manufacturer); + + + Output::Instance()->Postf(BLACKBOARD_KIT, "Reply for Local Version %x\n", version->status); + } + + // This request is not gonna be used anymore + ClearWantedEvent(request); + } + break; + case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR): { struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1); @@ -256,7 +291,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re if (readbdaddr->status == BT_OK) { reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t)); - reply.AddInt32("status", readbdaddr->status); + reply.AddInt8("status", readbdaddr->status); printf("Sending reply ... %ld\n",request->SendReply(&reply)); reply.PrintToStream(); @@ -273,6 +308,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re ClearWantedEvent(request); } break; + case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV): { @@ -421,6 +457,8 @@ LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* reques if (request->IsSourceWaiting() == false) Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT); + Output::Instance()->Postf(BLACKBOARD_LD(GetID()),"%s for command %s\n",__FUNCTION__, GetCommand(opcodeExpected)); + switch (opcodeExpected) { case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY): @@ -648,7 +686,7 @@ LocalDeviceImpl::ProcessSimpleRequest(BMessage* request) if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK) { AddWantedEvent(request); - + // LEAK: is command buffer freed within the Message? if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) { // TODO: - Reply the request with error! // - Remove the just added request