- 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
This commit is contained in:
parent
aac2df0f0d
commit
3fdaa5bf72
|
@ -24,7 +24,7 @@ class BluetoothDevice {
|
||||||
virtual DeviceClass GetDeviceClass()=0;
|
virtual DeviceClass GetDeviceClass()=0;
|
||||||
|
|
||||||
virtual BString GetProperty(const char* property)=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;
|
virtual bdaddr_t GetBluetoothAddress()=0;
|
||||||
|
|
||||||
|
|
|
@ -35,4 +35,10 @@ typedef enum { BT_COMMAND = 0,
|
||||||
#define HCI_FEATURES_SIZE 8 /* LMP features */
|
#define HCI_FEATURES_SIZE 8 /* LMP features */
|
||||||
#define HCI_DEVICE_NAME_SIZE 248 /* unit name size */
|
#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_
|
#endif // _BTHCI_H_
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
/* Possible throwing */
|
/* Possible throwing */
|
||||||
status_t SetDiscoverable(int mode);
|
status_t SetDiscoverable(int mode);
|
||||||
|
|
||||||
BString GetProperty(const char* property);
|
BString GetProperty(const char* property);
|
||||||
void GetProperty(const char* property, uint32* value);
|
status_t GetProperty(const char* property, uint32* value);
|
||||||
|
|
||||||
int GetDiscoverable();
|
int GetDiscoverable();
|
||||||
bdaddr_t GetBluetoothAddress();
|
bdaddr_t GetBluetoothAddress();
|
||||||
|
@ -50,7 +50,8 @@ public:
|
||||||
private:
|
private:
|
||||||
LocalDevice(hci_id hid);
|
LocalDevice(hci_id hid);
|
||||||
virtual ~LocalDevice();
|
virtual ~LocalDevice();
|
||||||
|
|
||||||
|
status_t ReadLocalVersion();
|
||||||
hci_id GetID(void) {return hid;}
|
hci_id GetID(void) {return hid;}
|
||||||
static LocalDevice* RequestLocalDeviceID(BMessage* request);
|
static LocalDevice* RequestLocalDeviceID(BMessage* request);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
bool IsEncrypted(); /* Throwing */
|
bool IsEncrypted(); /* Throwing */
|
||||||
|
|
||||||
BString GetProperty(const char* property); /* 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();
|
LocalDevice* GetLocalDeviceOwner();
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define BT_MSG_ACQUIRE_LOCAL_DEVICE 'btAd'
|
#define BT_MSG_ACQUIRE_LOCAL_DEVICE 'btAd'
|
||||||
#define BT_MSG_HANDLE_SIMPLE_REQUEST 'btsR'
|
#define BT_MSG_HANDLE_SIMPLE_REQUEST 'btsR'
|
||||||
#define BT_MSG_ADD_DEVICE 'btDD'
|
#define BT_MSG_ADD_DEVICE 'btDD'
|
||||||
|
#define BT_MSG_GET_PROPERTY 'btgP'
|
||||||
|
|
||||||
// Discovery
|
// Discovery
|
||||||
#define BT_MSG_INQUIRY_STARTED 'IqSt'
|
#define BT_MSG_INQUIRY_STARTED 'IqSt'
|
||||||
|
|
|
@ -122,11 +122,26 @@ LocalDevice::GetProperty(const char* property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
LocalDevice::GetProperty(const char* property, uint32* value)
|
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.AddData("raw command", B_ANY_TYPE, command, size);
|
||||||
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
|
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
|
||||||
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
|
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
|
||||||
|
|
||||||
|
|
||||||
if (fMessenger->SendMessage(&request, &reply) == B_OK) {
|
if (fMessenger->SendMessage(&request, &reply) == B_OK) {
|
||||||
if (reply.FindData("bdaddr", B_ANY_TYPE, 0, (const void**)&bdaddr, &ssize) == 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
|
ServiceRecord
|
||||||
LocalDevice::getRecord(Connection notifier) {
|
LocalDevice::getRecord(Connection notifier) {
|
||||||
|
@ -292,6 +330,7 @@ LocalDevice::updateRecord(ServiceRecord srvRecord) {
|
||||||
LocalDevice::LocalDevice(hci_id hid) : hid(hid)
|
LocalDevice::LocalDevice(hci_id hid) : hid(hid)
|
||||||
{
|
{
|
||||||
fMessenger = _RetrieveBluetoothMessenger();
|
fMessenger = _RetrieveBluetoothMessenger();
|
||||||
|
ReadLocalVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -187,10 +187,10 @@ RemoteDevice::GetProperty(const char* property) /* Throwing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */
|
RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */
|
||||||
{
|
{
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ void BluetoothServer::MessageReceived(BMessage *message)
|
||||||
case BT_MSG_HANDLE_SIMPLE_REQUEST:
|
case BT_MSG_HANDLE_SIMPLE_REQUEST:
|
||||||
status = HandleSimpleRequest(message, &reply);
|
status = HandleSimpleRequest(message, &reply);
|
||||||
break;
|
break;
|
||||||
|
case BT_MSG_GET_PROPERTY:
|
||||||
|
status = HandleGetProperty(message, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Handle if the bluetooth preferences is running?? */
|
/* Handle if the bluetooth preferences is running?? */
|
||||||
case B_SOME_APP_LAUNCHED:
|
case B_SOME_APP_LAUNCHED:
|
||||||
{
|
{
|
||||||
|
@ -296,7 +300,7 @@ status_t
|
||||||
BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply)
|
BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply)
|
||||||
{
|
{
|
||||||
LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
|
LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
|
||||||
BString propertyRequested;
|
const char* propertyRequested;
|
||||||
|
|
||||||
// Find out if there is a property being requested,
|
// Find out if there is a property being requested,
|
||||||
if (message->FindString("property", &propertyRequested) == B_OK) {
|
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
|
#if 0
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,9 +61,8 @@ public:
|
||||||
/* Messages reply */
|
/* Messages reply */
|
||||||
status_t HandleLocalDevicesCount(BMessage* message, BMessage* reply);
|
status_t HandleLocalDevicesCount(BMessage* message, BMessage* reply);
|
||||||
status_t HandleAcquireLocalDevice(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);
|
status_t HandleSimpleRequest(BMessage* message, BMessage* reply);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,12 +50,12 @@ LocalDeviceHandler::Acquire(void)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LocalDeviceHandler::IsPropertyAvailable(const BString& property)
|
LocalDeviceHandler::IsPropertyAvailable(const char* property)
|
||||||
{
|
{
|
||||||
type_code typeFound;
|
type_code typeFound;
|
||||||
int32 countFound;
|
int32 countFound;
|
||||||
|
|
||||||
return (fProperties->GetInfo(property.String(), &typeFound, &countFound) == B_OK );
|
return (fProperties->GetInfo(property, &typeFound, &countFound) == B_OK );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
status_t Launch(void);
|
status_t Launch(void);
|
||||||
|
|
||||||
BMessage* GetPropertiesMessage(void) { return fProperties; }
|
BMessage* GetPropertiesMessage(void) { return fProperties; }
|
||||||
bool IsPropertyAvailable(const BString& property);
|
bool IsPropertyAvailable(const char* property);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -236,19 +236,54 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re
|
||||||
|
|
||||||
int16 opcodeExpected;
|
int16 opcodeExpected;
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
|
|
||||||
Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD(GetID()));
|
|
||||||
Output::Instance()->Post("\n", BLACKBOARD_LD(GetID()));
|
|
||||||
|
|
||||||
// Handle command complete information
|
// Handle command complete information
|
||||||
request->FindInt16("opcodeExpected", index, &opcodeExpected);
|
request->FindInt16("opcodeExpected", index, &opcodeExpected);
|
||||||
|
|
||||||
|
|
||||||
if (request->IsSourceWaiting() == false)
|
if (request->IsSourceWaiting() == false)
|
||||||
Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
|
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) {
|
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):
|
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);
|
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) {
|
if (readbdaddr->status == BT_OK) {
|
||||||
|
|
||||||
reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t));
|
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));
|
printf("Sending reply ... %ld\n",request->SendReply(&reply));
|
||||||
reply.PrintToStream();
|
reply.PrintToStream();
|
||||||
|
@ -273,6 +308,7 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re
|
||||||
ClearWantedEvent(request);
|
ClearWantedEvent(request);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV):
|
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)
|
if (request->IsSourceWaiting() == false)
|
||||||
Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
|
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) {
|
switch (opcodeExpected) {
|
||||||
|
|
||||||
case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
|
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) {
|
if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK) {
|
||||||
|
|
||||||
AddWantedEvent(request);
|
AddWantedEvent(request);
|
||||||
|
// LEAK: is command buffer freed within the Message?
|
||||||
if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
|
if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
|
||||||
// TODO: - Reply the request with error!
|
// TODO: - Reply the request with error!
|
||||||
// - Remove the just added request
|
// - Remove the just added request
|
||||||
|
|
Loading…
Reference in New Issue