diff --git a/headers/os/bluetooth/DeviceClass.h b/headers/os/bluetooth/DeviceClass.h index f68c2fe596..5dd2c8256e 100644 --- a/headers/os/bluetooth/DeviceClass.h +++ b/headers/os/bluetooth/DeviceClass.h @@ -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; + }; } diff --git a/headers/os/bluetooth/RemoteDevice.h b/headers/os/bluetooth/RemoteDevice.h index 7ec669bd3f..eb4c870b03 100644 --- a/headers/os/bluetooth/RemoteDevice.h +++ b/headers/os/bluetooth/RemoteDevice.h @@ -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] */ diff --git a/src/kits/bluetooth/DeviceClass.cpp b/src/kits/bluetooth/DeviceClass.cpp new file mode 100644 index 0000000000..2f07e2a7ac --- /dev/null +++ b/src/kits/bluetooth/DeviceClass.cpp @@ -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 +//#include +//#include +#include +//#include +//#include +//#include +// +//#include +//#include +// +// +//#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; + } + + +} + +} diff --git a/src/kits/bluetooth/DiscoveryListener.cpp b/src/kits/bluetooth/DiscoveryListener.cpp index ebebf5e304..8b737acf65 100644 --- a/src/kits/bluetooth/DiscoveryListener.cpp +++ b/src/kits/bluetooth/DiscoveryListener.cpp @@ -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()); } } } diff --git a/src/kits/bluetooth/Jamfile b/src/kits/bluetooth/Jamfile index cea2169e3e..d6e4e5a5a6 100644 --- a/src/kits/bluetooth/Jamfile +++ b/src/kits/bluetooth/Jamfile @@ -20,6 +20,7 @@ SharedLibrary libbluetooth.so : RemoteDevice.cpp CommandManager.cpp KitSupport.cpp + DeviceClass.cpp #UI PincodeWindow.cpp ConnectionIncoming.cpp diff --git a/src/kits/bluetooth/KitSupport.h b/src/kits/bluetooth/KitSupport.h index b1596f3309..adca3c2a13 100644 --- a/src/kits/bluetooth/KitSupport.h +++ b/src/kits/bluetooth/KitSupport.h @@ -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 - BMessenger* _RetrieveBluetoothMessenger(void); diff --git a/src/kits/bluetooth/LocalDevice.cpp b/src/kits/bluetooth/LocalDevice.cpp index 0c53f8331c..f0b3545c3e 100644 --- a/src/kits/bluetooth/LocalDevice.cpp +++ b/src/kits/bluetooth/LocalDevice.cpp @@ -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; } diff --git a/src/kits/bluetooth/RemoteDevice.cpp b/src/kits/bluetooth/RemoteDevice.cpp index 00ff2ceac3..27f5680b82 100644 --- a/src/kits/bluetooth/RemoteDevice.cpp +++ b/src/kits/bluetooth/RemoteDevice.cpp @@ -4,6 +4,7 @@ * All rights reserved. Distributed under the terms of the MIT License. */ +#include #include #include #include @@ -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(); } diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index 3c11187a25..fdd66f083d 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -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);