- 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:
parent
a2f8edf787
commit
33fe7b32db
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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] */
|
||||
|
321
src/kits/bluetooth/DeviceClass.cpp
Normal file
321
src/kits/bluetooth/DeviceClass.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ SharedLibrary libbluetooth.so :
|
||||
RemoteDevice.cpp
|
||||
CommandManager.cpp
|
||||
KitSupport.cpp
|
||||
DeviceClass.cpp
|
||||
#UI
|
||||
PincodeWindow.cpp
|
||||
ConnectionIncoming.cpp
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user