- Implement retrieval of Device Classes.

- Implement DeviceClass for easy analisys of discovered devices's type.
- Make harder the intantiation of RemoteDevices.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28809 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Ruiz Dorantes 2008-12-13 23:41:32 +00:00
parent a2f8edf787
commit 33fe7b32db
9 changed files with 423 additions and 41 deletions

View File

@ -9,52 +9,66 @@
namespace Bluetooth {
#define UNKNOWN_CLASS_OF_DEVICE 0x00
class DeviceClass {
public:
DeviceClass(uint8 record[3])
{
SetRecord(record);
}
DeviceClass(int record)
DeviceClass(uint32 record)
{
SetRecord(record);
}
DeviceClass(void)
{
this->record = UNKNOWN_CLASS_OF_DEVICE;
}
void SetRecord(uint8 record[3])
{
this->record = record[0]|record[1]<<8|record[2]<<16;
}
void SetRecord(uint32 record)
{
this->record = record;
}
DeviceClass()
{
this->record = 0;
}
int GetServiceClasses()
uint GetServiceClass()
{
return (record & 0x00FFE000) >> 13;
}
int GetMajorDeviceClass()
{
uint GetMajorDeviceClass()
{
return (record & 0x00001F00) >> 8;
}
void GetMajorDeviceClass(BString* str)
{
}
int GetMinorDeviceClass()
uint GetMinorDeviceClass()
{
return (record & 0x000000FF) >> 2;
}
void GetMinorDeviceClass(BString* str)
bool IsUnknownDeviceClass()
{
return (record == UNKNOWN_CLASS_OF_DEVICE);
}
void GetServiceClass(BString&);
void GetMajorDeviceClass(BString&);
void GetMinorDeviceClass(BString&);
private:
int record;
uint32 record;
};
}

View File

@ -49,7 +49,7 @@ public:
LocalDevice* GetLocalDeviceOwner();
RemoteDevice(const BString& address);
RemoteDevice(const bdaddr_t address);
RemoteDevice(const bdaddr_t address, uint8 record[3]);
protected:
/* called by Discovery[Listener|Agent] */

View File

@ -0,0 +1,321 @@
/*
* Copyright 2007-2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
*
* All rights reserved. Distributed under the terms of the MIT License.
*
*/
//#include <bluetooth/DiscoveryAgent.h>
//#include <bluetooth/DiscoveryListener.h>
//#include <bluetooth/RemoteDevice.h>
#include <bluetooth/DeviceClass.h>
//#include <bluetooth/bluetooth_error.h>
//#include <bluetooth/HCI/btHCI_command.h>
//#include <bluetooth/HCI/btHCI_event.h>
//
//#include <bluetoothserver_p.h>
//#include <CommandManager.h>
//
//
//#include "KitSupport.h"
namespace Bluetooth {
void
DeviceClass::GetServiceClass(BString& serviceClass)
{
static const char *services[] = { "Positioning", "Networking",
"Rendering", "Capturing", "Object Transfer",
"Audio", "Telephony", "Information" };
serviceClass = "Service Classes: ";
if (GetServiceClass() != 0) {
for (uint s = 0; s < (sizeof(services) / sizeof(*services)); s++) {
if (GetServiceClass() & (1 << s)) {
serviceClass << services[s];
if (s != 0)
serviceClass << ", ";
}
}
} else
serviceClass << "Unspecified";
}
void
DeviceClass::GetMajorDeviceClass(BString& majorClass)
{
static const char *major_devices[] = { "Miscellaneous", "Computer", "Phone",
"LAN Access", "Audio/Video", "Peripheral", "Imaging", "Uncategorized" };
majorClass << "Major Class: ";
if (GetMajorDeviceClass() >= sizeof(major_devices) / sizeof(*major_devices))
majorClass << "Invalid Device Class!\n";
else
majorClass << major_devices[GetMajorDeviceClass()];
}
void
DeviceClass::GetMinorDeviceClass(BString& minorClass)
{
uint major = GetMajorDeviceClass();
uint minor = GetMinorDeviceClass();
minorClass << "Minor Class: ";
switch (major) {
case 0: /* misc */
minorClass << " -";
break;
case 1: /* computer */
switch(minor) {
case 0:
minorClass << "Uncategorized";
break;
case 1:
minorClass << "Desktop workstation";
break;
case 2:
minorClass << "Server";
break;
case 3:
minorClass << "Laptop";
break;
case 4:
minorClass << "Handheld";
break;
case 5:
minorClass << "Palm";
break;
case 6:
minorClass << "Wearable";
break;
}
break;
case 2: /* phone */
switch(minor) {
case 0:
minorClass << "Uncategorized";
break;
case 1:
minorClass << "Cellular";
break;
case 2:
minorClass << "Cordless";
break;
case 3:
minorClass << "Smart phone";
break;
case 4:
minorClass << "Wired modem or voice gateway";
break;
case 5:
minorClass << "Common ISDN Access";
break;
case 6:
minorClass << "Sim Card Reader";
break;
}
break;
case 3: /* lan access */
if (minor == 0) {
minorClass << "Uncategorized";
break;
}
switch(minor / 8) {
case 0:
minorClass << "Fully available";
break;
case 1:
minorClass << "1-17% utilized";
break;
case 2:
minorClass << "17-33% utilized";
break;
case 3:
minorClass << "33-50% utilized";
break;
case 4:
minorClass << "50-67% utilized";
break;
case 5:
minorClass << "67-83% utilized";
break;
case 6:
minorClass << "83-99% utilized";
break;
case 7:
minorClass << "No service available";
break;
}
break;
case 4: /* audio/video */
switch(minor) {
case 0:
minorClass << "Uncategorized";
break;
case 1:
minorClass << "Device conforms to the Headset profile";
break;
case 2:
minorClass << "Hands-free";
break;
/* 3 is reserved */
case 4:
minorClass << "Microphone";
break;
case 5:
minorClass << "Loudspeaker";
break;
case 6:
minorClass << "Headphones";
break;
case 7:
minorClass << "Portable Audio";
break;
case 8:
minorClass << "Car Audio";
break;
case 9:
minorClass << "Set-top box";
break;
case 10:
minorClass << "HiFi Audio Device";
break;
case 11:
minorClass << "VCR";
break;
case 12:
minorClass << "Video Camera";
break;
case 13:
minorClass << "Camcorder";
break;
case 14:
minorClass << "Video Monitor";
break;
case 15:
minorClass << "Video Display and Loudspeaker";
break;
case 16:
minorClass << "Video Conferencing";
break;
/* 17 is reserved */
case 18:
minorClass << "Gaming/Toy";
break;
}
break;
case 5: /* peripheral */ {
switch(minor & 48) {
case 16:
minorClass << "Keyboard";
if (minor & 15)
minorClass << "/";
break;
case 32:
minorClass << "Pointing device";
if (minor & 15)
minorClass << "/";
break;
case 48:
minorClass << "Combo keyboard/pointing device";
if (minor & 15)
minorClass << "/";
break;
}
switch(minor & 15) {
case 0:
break;
case 1:
minorClass << "Joystick";
break;
case 2:
minorClass << "Gamepad";
break;
case 3:
minorClass << "Remote control";
break;
case 4:
minorClass << "Sensing device";
break;
case 5:
minorClass << "Digitizer tablet";
break;
case 6:
minorClass << "Card reader";
break;
default:
minorClass << "(reserved)";
break;
}
}
case 6: /* imaging */
if (minor & 4)
minorClass << "Display";
if (minor & 8)
minorClass << "Camera";
if (minor & 16)
minorClass << "Scanner";
if (minor & 32)
minorClass << "Printer";
break;
case 7: /* wearable */
switch(minor) {
case 1:
minorClass << "Wrist Watch";
break;
case 2:
minorClass << "Pager";
break;
case 3:
minorClass << "Jacket";
break;
case 4:
minorClass << "Helmet";
break;
case 5:
minorClass << "Glasses";
break;
}
break;
case 8: /* toy */
switch(minor) {
case 1:
minorClass << "Robot";
break;
case 2:
minorClass << "Vehicle";
break;
case 3:
minorClass << "Doll / Action Figure";
break;
case 4:
minorClass << "Controller";
break;
case 5:
minorClass << "Game";
break;
}
break;
case 63: /* uncategorised */
minorClass << "";
break;
default:
minorClass << "Unknown (reserved) minor device class";
break;
}
}
}

View File

@ -76,7 +76,6 @@ DiscoveryListener::MessageReceived(BMessage* message)
if (message->FindData("info", B_ANY_TYPE, 0, (const void**)&inquiryInfo, &size) == B_OK )
{
// Skip duplicated replies
for (int32 index = 0 ; index < fRemoteDevicesList.CountItems(); index++) {
@ -92,14 +91,13 @@ DiscoveryListener::MessageReceived(BMessage* message)
duplicatedFound = true;
break;
}
}
}
if (!duplicatedFound) {
// TODO: DeviceClass(inquiryInfo->dev_class[0] | inquiryInfo->dev_class[1]<<8 | inquiryInfo->dev_class[2]<<16 )
rd = new RemoteDevice(inquiryInfo->bdaddr);
rd = new RemoteDevice(inquiryInfo->bdaddr, (uint8*)inquiryInfo->dev_class);
fRemoteDevicesList.AddItem(rd);
// keep all inquiry reported data
rd->SetLocalDeviceOwner(fLocalDevice);
@ -108,9 +106,7 @@ DiscoveryListener::MessageReceived(BMessage* message)
rd->fScanMode = inquiryInfo->pscan_mode;
rd->fClockOffset = inquiryInfo->clock_offset;
DeviceDiscovered( rd, DeviceClass(inquiryInfo->dev_class[0] |
inquiryInfo->dev_class[1]<<8 |
inquiryInfo->dev_class[2]<<16 ));
DeviceDiscovered( rd, rd->GetDeviceClass());
}
}
}

View File

@ -20,6 +20,7 @@ SharedLibrary libbluetooth.so :
RemoteDevice.cpp
CommandManager.cpp
KitSupport.cpp
DeviceClass.cpp
#UI
PincodeWindow.cpp
ConnectionIncoming.cpp

View File

@ -1,12 +1,7 @@
/*
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
*
* All rights reserved. Distributed under the terms of the MIT License.
*
*/
#include <Messenger.h>
BMessenger* _RetrieveBluetoothMessenger(void);

View File

@ -244,7 +244,34 @@ DeviceClass
LocalDevice::GetDeviceClass()
{
return DeviceClass(0);
if (fDeviceClass.IsUnknownDeviceClass()) {
if (fMessenger == NULL)
return fDeviceClass;
size_t size;
void* command = buildReadClassOfDevice(&size);
if (command == NULL)
return fDeviceClass;
BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
BMessage reply;
const uint8* record;
ssize_t ssize;
request.AddInt32("hci_id", hid);
request.AddData("raw command", B_ANY_TYPE, command, size);
request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV));
if (fMessenger->SendMessage(&request, &reply) == B_OK &&
reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&record, &ssize) == B_OK) {
fDeviceClass.SetRecord(*record);
}
}
return fDeviceClass;
}

View File

@ -4,6 +4,7 @@
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <bluetooth/DeviceClass.h>
#include <bluetooth/DiscoveryAgent.h>
#include <bluetooth/DiscoveryListener.h>
#include <bluetooth/bdaddrUtils.h>
@ -156,15 +157,17 @@ RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld)
/* Constructor */
RemoteDevice::RemoteDevice(const bdaddr_t address)
RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
{
fBdaddr = address;
fDeviceClass.SetRecord(record);
fMessenger = _RetrieveBluetoothMessenger();
}
RemoteDevice::RemoteDevice(const BString& address)
{
fDeviceClass.SetRecord((uint32)0);
fBdaddr = bdaddrUtils::FromString((const char *)address.String());
fMessenger = _RetrieveBluetoothMessenger();
}

View File

@ -278,6 +278,31 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re
ClearWantedEvent(request);
}
break;
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV):
{
struct hci_read_dev_class_reply* classDev = (struct hci_read_dev_class_reply*)(event+1);
if (classDev->status == BT_OK) {
reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class, sizeof(classDev->dev_class));
reply.AddInt8("status", classDev->status);
printf("Sending reply ... %ld\n",request->SendReply(&reply));
reply.PrintToStream();
Output::Instance()->Post("Positive reply for getDeviceClass\n", BLACKBOARD_KIT);
} else {
reply.AddInt8("status", classDev->status);
request->SendReply(&reply);
Output::Instance()->Post("Negative reply for getDeviceClass\n", BLACKBOARD_KIT);
}
// This request is not gonna be used anymore
ClearWantedEvent(request);
}
break;
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
{
@ -377,7 +402,6 @@ LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* re
}
break;
default:
Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT);
break;
@ -560,8 +584,9 @@ LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage
{
if (event->status == BT_OK) {
uint8 cod[3] = {0,0,0};
ConnectionIncoming* iConnection = new ConnectionIncoming(new RemoteDevice(event->bdaddr));
ConnectionIncoming* iConnection = new ConnectionIncoming(new RemoteDevice(event->bdaddr, cod));
iConnection->Show();
printf("%s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__, bdaddrUtils::ToString(event->bdaddr), event->handle,
event->link_type, event->encrypt_mode);