2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com
4 * Copyright 2012 Fredrik Modéen, [firstname]@[lastname]
5 * All rights reserved. Distributed under the terms of the MIT License.
8 #include <bluetooth/bluetooth_error.h>
10 #include <bluetooth/HCI/btHCI_command.h>
11 #include <bluetooth/HCI/btHCI_event.h>
13 #include <bluetooth/DeviceClass.h>
14 #include <bluetooth/DiscoveryAgent.h>
15 #include <bluetooth/LocalDevice.h>
16 #include <bluetooth/RemoteDevice.h>
18 #include <bluetooth/bdaddrUtils.h>
19 #include <bluetoothserver_p.h>
20 #include <CommandManager.h>
24 #include "KitSupport.h"
31 LocalDevice::RequestLocalDeviceID(BMessage
* request
)
35 LocalDevice
* lDevice
= NULL
;
37 BMessenger
* messenger
= _RetrieveBluetoothMessenger();
39 if (messenger
== NULL
)
42 if (messenger
->SendMessage(request
, &reply
) == B_OK
43 && reply
.FindInt32("hci_id", &hid
) == B_OK
) {
46 lDevice
= new (std::nothrow
)LocalDevice(hid
);
60 LocalDevice::GetLocalDevice()
62 BMessage
request(BT_MSG_ACQUIRE_LOCAL_DEVICE
);
64 return RequestLocalDeviceID(&request
);
69 LocalDevice::GetLocalDevice(const hci_id hid
)
71 BMessage
request(BT_MSG_ACQUIRE_LOCAL_DEVICE
);
72 request
.AddInt32("hci_id", hid
);
74 return RequestLocalDeviceID(&request
);
79 LocalDevice::GetLocalDevice(const bdaddr_t bdaddr
)
81 BMessage
request(BT_MSG_ACQUIRE_LOCAL_DEVICE
);
82 request
.AddData("bdaddr", B_ANY_TYPE
, &bdaddr
, sizeof(bdaddr_t
));
84 return RequestLocalDeviceID(&request
);
89 LocalDevice::GetLocalDeviceCount()
91 BMessenger
* messenger
= _RetrieveBluetoothMessenger();
94 if (messenger
!= NULL
) {
96 BMessage
request(BT_MSG_COUNT_LOCAL_DEVICES
);
99 if (messenger
->SendMessage(&request
, &reply
) == B_OK
)
100 count
= reply
.FindInt32("count");
111 LocalDevice::GetDiscoveryAgent()
113 // TODO: Study a singleton here
114 return new (std::nothrow
)DiscoveryAgent(this);
119 LocalDevice::GetProperty(const char* property
)
127 LocalDevice::GetProperty(const char* property
, uint32
* value
)
129 if (fMessenger
== NULL
)
132 BMessage
request(BT_MSG_GET_PROPERTY
);
135 request
.AddInt32("hci_id", fHid
);
136 request
.AddString("property", property
);
138 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
) {
139 if (reply
.FindInt32("result", (int32
*)value
) == B_OK
) {
150 LocalDevice::GetDiscoverable()
152 if (fMessenger
== NULL
)
156 void* command
= buildReadScan(&size
);
160 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
161 request
.AddInt32("hci_id", fHid
);
162 request
.AddData("raw command", B_ANY_TYPE
, command
, size
);
163 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
164 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
165 OCF_READ_SCAN_ENABLE
));
169 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
170 && reply
.FindInt8("scan_enable", &discoverable
) == B_OK
)
178 LocalDevice::SetDiscoverable(int mode
)
180 if (fMessenger
== NULL
)
183 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
187 int8 bt_status
= BT_ERROR
;
189 request
.AddInt32("hci_id", fHid
);
192 void* command
= buildWriteScan(mode
, &size
);
194 if (command
== NULL
) {
198 request
.AddData("raw command", B_ANY_TYPE
, command
, size
);
199 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
200 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
201 OCF_WRITE_SCAN_ENABLE
));
203 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
) {
204 if (reply
.FindInt8("status", &bt_status
) == B_OK
) {
214 struct authentication_t
{
219 LocalDevice::SetAuthentication(bool authentication
)
221 return SingleParameterCommandRequest
<struct authentication_t
, uint8
>
222 (OGF_CONTROL_BASEBAND
, OCF_WRITE_AUTH_ENABLE
, authentication
,
223 NULL
, fHid
, fMessenger
);
228 LocalDevice::GetBluetoothAddress()
230 if (fMessenger
== NULL
)
231 return bdaddrUtils::LocalAddress();
234 void* command
= buildReadBdAddr(&size
);
237 return bdaddrUtils::LocalAddress();
239 const bdaddr_t
* bdaddr
;
240 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
244 request
.AddInt32("hci_id", fHid
);
245 request
.AddData("raw command", B_ANY_TYPE
, command
, size
);
246 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
247 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM
,
250 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
251 && reply
.FindData("bdaddr", B_ANY_TYPE
, 0,
252 (const void**)&bdaddr
, &ssize
) == B_OK
)
255 return bdaddrUtils::LocalAddress();
260 LocalDevice::ID(void) const
267 LocalDevice::GetFriendlyName()
269 if (fMessenger
== NULL
)
270 return BString("Unknown|Messenger");
273 void* command
= buildReadLocalName(&size
);
275 return BString("Unknown|NoMemory");
277 BString friendlyname
;
278 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
282 request
.AddInt32("hci_id", fHid
);
283 request
.AddData("raw command", B_ANY_TYPE
, command
, size
);
284 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
285 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
286 OCF_READ_LOCAL_NAME
));
288 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
289 && reply
.FindString("friendlyname", &friendlyname
) == B_OK
)
292 return BString("Unknown|ServerFailed");
297 LocalDevice::SetFriendlyName(BString
& name
)
299 int8 btStatus
= BT_ERROR
;
301 if (fMessenger
== NULL
)
304 BluetoothCommand
<typed_command(hci_write_local_name
)>
305 writeName(OGF_CONTROL_BASEBAND
, OCF_WRITE_LOCAL_NAME
);
307 strcpy(writeName
->local_name
, name
.String());
309 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
312 request
.AddInt32("hci_id", fHid
);
313 request
.AddData("raw command", B_ANY_TYPE
,
314 writeName
.Data(), writeName
.Size());
315 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
316 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
317 OCF_WRITE_LOCAL_NAME
));
319 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
320 reply
.FindInt8("status", &btStatus
);
327 LocalDevice::GetDeviceClass()
330 // if (fDeviceClass.IsUnknownDeviceClass()) {
332 if (fMessenger
== NULL
)
336 void* command
= buildReadClassOfDevice(&size
);
340 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
342 const uint8
* bufferRecord
;
345 request
.AddInt32("hci_id", fHid
);
346 request
.AddData("raw command", B_ANY_TYPE
, command
, size
);
347 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
348 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
349 OCF_READ_CLASS_OF_DEV
));
351 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
352 && reply
.FindData("devclass", B_ANY_TYPE
, 0, (const void**)&bufferRecord
,
354 uint8 record
[3] = { bufferRecord
[0], bufferRecord
[1], bufferRecord
[2] };
355 fDeviceClass
.SetRecord(record
);
365 LocalDevice::SetDeviceClass(DeviceClass deviceClass
)
367 int8 bt_status
= BT_ERROR
;
369 if (fMessenger
== NULL
)
372 BluetoothCommand
<typed_command(hci_write_dev_class
)>
373 setDeviceClass(OGF_CONTROL_BASEBAND
, OCF_WRITE_CLASS_OF_DEV
);
375 setDeviceClass
->dev_class
[0] = deviceClass
.Record() & 0xFF;
376 setDeviceClass
->dev_class
[1] = (deviceClass
.Record() & 0xFF00) >> 8;
377 setDeviceClass
->dev_class
[2] = (deviceClass
.Record() & 0xFF0000) >> 16;
379 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
382 request
.AddInt32("hci_id", fHid
);
383 request
.AddData("raw command", B_ANY_TYPE
,
384 setDeviceClass
.Data(), setDeviceClass
.Size());
385 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
386 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
387 OCF_WRITE_CLASS_OF_DEV
));
389 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
390 reply
.FindInt8("status", &bt_status
);
398 LocalDevice::_ReadLocalVersion()
400 int8 bt_status
= BT_ERROR
;
402 BluetoothCommand
<> localVersion(OGF_INFORMATIONAL_PARAM
,
403 OCF_READ_LOCAL_VERSION
);
405 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
408 request
.AddInt32("hci_id", fHid
);
409 request
.AddData("raw command", B_ANY_TYPE
,
410 localVersion
.Data(), localVersion
.Size());
411 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
412 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM
,
413 OCF_READ_LOCAL_VERSION
));
415 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
416 reply
.FindInt8("status", &bt_status
);
423 LocalDevice::_ReadBufferSize()
425 int8 bt_status
= BT_ERROR
;
427 BluetoothCommand
<> BufferSize(OGF_INFORMATIONAL_PARAM
, OCF_READ_BUFFER_SIZE
);
430 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
433 request
.AddInt32("hci_id", fHid
);
434 request
.AddData("raw command", B_ANY_TYPE
,
435 BufferSize
.Data(), BufferSize
.Size());
436 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
437 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM
,
438 OCF_READ_BUFFER_SIZE
));
440 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
441 reply
.FindInt8("status", &bt_status
);
448 LocalDevice::_ReadLocalFeatures()
450 int8 bt_status
= BT_ERROR
;
452 BluetoothCommand
<> LocalFeatures(OGF_INFORMATIONAL_PARAM
,
453 OCF_READ_LOCAL_FEATURES
);
455 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
458 request
.AddInt32("hci_id", fHid
);
459 request
.AddData("raw command", B_ANY_TYPE
,
460 LocalFeatures
.Data(), LocalFeatures
.Size());
461 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
462 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM
,
463 OCF_READ_LOCAL_FEATURES
));
465 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
466 reply
.FindInt8("status", &bt_status
);
473 LocalDevice::_ReadLinkKeys()
475 int8 bt_status
= BT_ERROR
;
477 BluetoothCommand
<> LocalFeatures(OGF_CONTROL_BASEBAND
,
478 OCF_READ_STORED_LINK_KEY
);
480 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
483 request
.AddInt32("hci_id", fHid
);
484 request
.AddData("raw command", B_ANY_TYPE
,
485 LocalFeatures
.Data(), LocalFeatures
.Size());
486 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
487 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
488 OCF_READ_STORED_LINK_KEY
));
490 request
.AddInt16("eventExpected", HCI_EVENT_RETURN_LINK_KEYS
);
493 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
494 reply
.FindInt8("status", &bt_status
);
500 struct pageTimeout_t
{
505 LocalDevice::_ReadTimeouts()
509 NonParameterCommandRequest(OGF_CONTROL_BASEBAND
,
510 OCF_READ_PG_TIMEOUT
, NULL
, fHid
, fMessenger
);
513 SingleParameterCommandRequest
<struct pageTimeout_t
, uint16
>
514 (OGF_CONTROL_BASEBAND
, OCF_WRITE_PG_TIMEOUT
, 0x8000, NULL
,
518 return SingleParameterCommandRequest
<struct pageTimeout_t
, uint16
>
519 (OGF_CONTROL_BASEBAND
, OCF_WRITE_CA_TIMEOUT
, 0x7d00, NULL
,
527 int8 bt_status
= BT_ERROR
;
529 BluetoothCommand
<> Reset(OGF_CONTROL_BASEBAND
, OCF_RESET
);
531 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
534 request
.AddInt32("hci_id", fHid
);
535 request
.AddData("raw command", B_ANY_TYPE
, Reset
.Data(), Reset
.Size());
536 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
537 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND
,
540 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
541 reply
.FindInt8("status", &bt_status
);
550 LocalDevice::getRecord(Connection notifier) {
555 LocalDevice::updateRecord(ServiceRecord srvRecord) {
561 LocalDevice::LocalDevice(hci_id hid
)
566 fMessenger
= _RetrieveBluetoothMessenger();
569 _ReadLocalFeatures();
574 // Uncomment this if you want your device to have a nicer default name
575 // BString name("HaikuBluetooth");
576 // SetFriendlyName(name);
581 // HARDCODE -> move this to addons
582 if (GetProperty("manufacturer", &value
) == B_OK
585 // Uncomment this out if your Broadcom dongle is not working properly
586 // Reset(); // Perform a reset to Broadcom buggyland
588 // Uncomment this out if your Broadcom dongle has a null bdaddr
589 //#define BT_WRITE_BDADDR_FOR_BCM2035
590 #ifdef BT_WRITE_BDADDR_FOR_BCM2035
591 #warning Writting broadcom bdaddr @ init.
592 // try write bdaddr to a bcm2035 -> will be moved to an addon
593 int8 bt_status
= BT_ERROR
;
595 BluetoothCommand
<typed_command(hci_write_bcm2035_bdaddr
)>
596 writeAddress(OGF_VENDOR_CMD
, OCF_WRITE_BCM2035_BDADDR
);
598 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
600 writeAddress
->bdaddr
.b
[0] = 0x3C;
601 writeAddress
->bdaddr
.b
[1] = 0x19;
602 writeAddress
->bdaddr
.b
[2] = 0x30;
603 writeAddress
->bdaddr
.b
[3] = 0xC9;
604 writeAddress
->bdaddr
.b
[4] = 0x03;
605 writeAddress
->bdaddr
.b
[5] = 0x00;
607 request
.AddInt32("hci_id", fHid
);
608 request
.AddData("raw command", B_ANY_TYPE
,
609 writeAddress
.Data(), writeAddress
.Size());
610 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
611 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD
,
612 OCF_WRITE_BCM2035_BDADDR
));
614 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
615 reply
.FindInt8("status", &bt_status
);
621 LocalDevice::~LocalDevice()