btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / bluetooth / LocalDevice.cpp
blob886254629f01d797445ff94571b16e0d4fea8e1b
1 /*
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.
6 */
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>
22 #include <new>
24 #include "KitSupport.h"
27 namespace Bluetooth {
30 LocalDevice*
31 LocalDevice::RequestLocalDeviceID(BMessage* request)
33 BMessage reply;
34 hci_id hid;
35 LocalDevice* lDevice = NULL;
37 BMessenger* messenger = _RetrieveBluetoothMessenger();
39 if (messenger == NULL)
40 return NULL;
42 if (messenger->SendMessage(request, &reply) == B_OK
43 && reply.FindInt32("hci_id", &hid) == B_OK ) {
45 if (hid >= 0)
46 lDevice = new (std::nothrow)LocalDevice(hid);
49 delete messenger;
50 return lDevice;
54 #if 0
55 #pragma -
56 #endif
59 LocalDevice*
60 LocalDevice::GetLocalDevice()
62 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
64 return RequestLocalDeviceID(&request);
68 LocalDevice*
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);
78 LocalDevice*
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);
88 uint32
89 LocalDevice::GetLocalDeviceCount()
91 BMessenger* messenger = _RetrieveBluetoothMessenger();
92 uint32 count = 0;
94 if (messenger != NULL) {
96 BMessage request(BT_MSG_COUNT_LOCAL_DEVICES);
97 BMessage reply;
99 if (messenger->SendMessage(&request, &reply) == B_OK)
100 count = reply.FindInt32("count");
102 delete messenger;
105 return count;
110 DiscoveryAgent*
111 LocalDevice::GetDiscoveryAgent()
113 // TODO: Study a singleton here
114 return new (std::nothrow)DiscoveryAgent(this);
118 BString
119 LocalDevice::GetProperty(const char* property)
121 return NULL;
126 status_t
127 LocalDevice::GetProperty(const char* property, uint32* value)
129 if (fMessenger == NULL)
130 return B_ERROR;
132 BMessage request(BT_MSG_GET_PROPERTY);
133 BMessage reply;
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 ) {
140 return B_OK;
145 return B_ERROR;
150 LocalDevice::GetDiscoverable()
152 if (fMessenger == NULL)
153 return -1;
155 size_t size;
156 void* command = buildReadScan(&size);
157 if (command == NULL)
158 return -1;
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));
167 int8 discoverable;
168 BMessage reply;
169 if (fMessenger->SendMessage(&request, &reply) == B_OK
170 && reply.FindInt8("scan_enable", &discoverable) == B_OK)
171 return discoverable;
173 return -1;
177 status_t
178 LocalDevice::SetDiscoverable(int mode)
180 if (fMessenger == NULL)
181 return B_ERROR;
183 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
184 BMessage reply;
186 size_t size;
187 int8 bt_status = BT_ERROR;
189 request.AddInt32("hci_id", fHid);
192 void* command = buildWriteScan(mode, &size);
194 if (command == NULL) {
195 return B_NO_MEMORY;
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 ) {
205 return bt_status;
210 return B_ERROR;
214 struct authentication_t {
215 uint8 param;
218 status_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);
227 bdaddr_t
228 LocalDevice::GetBluetoothAddress()
230 if (fMessenger == NULL)
231 return bdaddrUtils::LocalAddress();
233 size_t size;
234 void* command = buildReadBdAddr(&size);
236 if (command == NULL)
237 return bdaddrUtils::LocalAddress();
239 const bdaddr_t* bdaddr;
240 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
241 BMessage reply;
242 ssize_t ssize;
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,
248 OCF_READ_BD_ADDR));
250 if (fMessenger->SendMessage(&request, &reply) == B_OK
251 && reply.FindData("bdaddr", B_ANY_TYPE, 0,
252 (const void**)&bdaddr, &ssize) == B_OK)
253 return *bdaddr;
255 return bdaddrUtils::LocalAddress();
259 hci_id
260 LocalDevice::ID(void) const
262 return fHid;
266 BString
267 LocalDevice::GetFriendlyName()
269 if (fMessenger == NULL)
270 return BString("Unknown|Messenger");
272 size_t size;
273 void* command = buildReadLocalName(&size);
274 if (command == NULL)
275 return BString("Unknown|NoMemory");
277 BString friendlyname;
278 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
279 BMessage reply;
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)
290 return friendlyname;
292 return BString("Unknown|ServerFailed");
296 status_t
297 LocalDevice::SetFriendlyName(BString& name)
299 int8 btStatus = BT_ERROR;
301 if (fMessenger == NULL)
302 return btStatus;
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);
310 BMessage reply;
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);
322 return btStatus;
326 DeviceClass
327 LocalDevice::GetDeviceClass()
330 // if (fDeviceClass.IsUnknownDeviceClass()) {
332 if (fMessenger == NULL)
333 return fDeviceClass;
335 size_t size;
336 void* command = buildReadClassOfDevice(&size);
337 if (command == NULL)
338 return fDeviceClass;
340 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
341 BMessage reply;
342 const uint8* bufferRecord;
343 ssize_t ssize;
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,
353 &ssize) == B_OK) {
354 uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] };
355 fDeviceClass.SetRecord(record);
357 // }
359 return fDeviceClass;
364 status_t
365 LocalDevice::SetDeviceClass(DeviceClass deviceClass)
367 int8 bt_status = BT_ERROR;
369 if (fMessenger == NULL)
370 return bt_status;
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);
380 BMessage reply;
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);
392 return bt_status;
397 status_t
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);
406 BMessage reply;
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);
418 return bt_status;
422 status_t
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);
431 BMessage reply;
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);
443 return bt_status;
447 status_t
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);
456 BMessage reply;
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);
468 return bt_status;
472 status_t
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);
481 BMessage reply;
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);
496 return bt_status;
500 struct pageTimeout_t {
501 uint16 param;
504 status_t
505 LocalDevice::_ReadTimeouts()
508 // Read PageTimeout
509 NonParameterCommandRequest(OGF_CONTROL_BASEBAND,
510 OCF_READ_PG_TIMEOUT, NULL, fHid, fMessenger);
512 // Write PageTimeout
513 SingleParameterCommandRequest<struct pageTimeout_t, uint16>
514 (OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT, 0x8000, NULL,
515 fHid, fMessenger);
517 // Write PageTimeout
518 return SingleParameterCommandRequest<struct pageTimeout_t, uint16>
519 (OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT, 0x7d00, NULL,
520 fHid, fMessenger);
524 status_t
525 LocalDevice::Reset()
527 int8 bt_status = BT_ERROR;
529 BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
531 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
532 BMessage reply;
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,
538 OCF_RESET));
540 if (fMessenger->SendMessage(&request, &reply) == B_OK)
541 reply.FindInt8("status", &bt_status);
543 return bt_status;
549 ServiceRecord
550 LocalDevice::getRecord(Connection notifier) {
554 void
555 LocalDevice::updateRecord(ServiceRecord srvRecord) {
561 LocalDevice::LocalDevice(hci_id hid)
563 BluetoothDevice(),
564 fHid(hid)
566 fMessenger = _RetrieveBluetoothMessenger();
568 _ReadBufferSize();
569 _ReadLocalFeatures();
570 _ReadLocalVersion();
571 _ReadTimeouts();
572 _ReadLinkKeys();
574 // Uncomment this if you want your device to have a nicer default name
575 // BString name("HaikuBluetooth");
576 // SetFriendlyName(name);
579 uint32 value;
581 // HARDCODE -> move this to addons
582 if (GetProperty("manufacturer", &value) == B_OK
583 && value == 15) {
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);
599 BMessage reply;
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);
616 #endif
621 LocalDevice::~LocalDevice()
623 delete fMessenger;