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 */
7
8
9 #include <bluetooth/bluetooth_error.h>
10
11 #include <bluetooth/HCI/btHCI_command.h>
12 #include <bluetooth/HCI/btHCI_event.h>
13
14 #include <bluetooth/DeviceClass.h>
15 #include <bluetooth/DiscoveryAgent.h>
16 #include <bluetooth/LocalDevice.h>
17 #include <bluetooth/RemoteDevice.h>
18
19 #include <bluetooth/bdaddrUtils.h>
20 #include <bluetoothserver_p.h>
21 #include <CommandManager.h>
22
23 #include <new>
24
25 #include "KitSupport.h"
26
27
28 namespace Bluetooth {
29
30
31 LocalDevice*
RequestLocalDeviceID(BMessage * request)32 LocalDevice::RequestLocalDeviceID(BMessage* request)
33 {
34 BMessage reply;
35 hci_id hid;
36 LocalDevice* lDevice = NULL;
37
38 BMessenger* messenger = _RetrieveBluetoothMessenger();
39
40 if (messenger == NULL)
41 return NULL;
42
43 if (messenger->SendMessage(request, &reply) == B_OK
44 && reply.FindInt32("hci_id", &hid) == B_OK ) {
45
46 if (hid >= 0)
47 lDevice = new (std::nothrow)LocalDevice(hid);
48 }
49
50 delete messenger;
51 return lDevice;
52 }
53
54
55 #if 0
56 #pragma -
57 #endif
58
59
60 LocalDevice*
GetLocalDevice()61 LocalDevice::GetLocalDevice()
62 {
63 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
64
65 return RequestLocalDeviceID(&request);
66 }
67
68
69 LocalDevice*
GetLocalDevice(const hci_id hid)70 LocalDevice::GetLocalDevice(const hci_id hid)
71 {
72 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
73 request.AddInt32("hci_id", hid);
74
75 return RequestLocalDeviceID(&request);
76 }
77
78
79 LocalDevice*
GetLocalDevice(const bdaddr_t bdaddr)80 LocalDevice::GetLocalDevice(const bdaddr_t bdaddr)
81 {
82 BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
83 request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
84
85 return RequestLocalDeviceID(&request);
86 }
87
88
89 uint32
GetLocalDeviceCount()90 LocalDevice::GetLocalDeviceCount()
91 {
92 BMessenger* messenger = _RetrieveBluetoothMessenger();
93 uint32 count = 0;
94
95 if (messenger != NULL) {
96
97 BMessage request(BT_MSG_COUNT_LOCAL_DEVICES);
98 BMessage reply;
99
100 if (messenger->SendMessage(&request, &reply) == B_OK)
101 count = reply.FindInt32("count");
102
103 delete messenger;
104 }
105
106 return count;
107
108 }
109
110
111 DiscoveryAgent*
GetDiscoveryAgent()112 LocalDevice::GetDiscoveryAgent()
113 {
114 // TODO: Study a singleton here
115 return new (std::nothrow)DiscoveryAgent(this);
116 }
117
118
119 BString
GetProperty(const char * property)120 LocalDevice::GetProperty(const char* property)
121 {
122 return NULL;
123
124 }
125
126
127 status_t
GetProperty(const char * property,uint32 * value)128 LocalDevice::GetProperty(const char* property, uint32* value)
129 {
130 if (fMessenger == NULL)
131 return B_ERROR;
132
133 BMessage request(BT_MSG_GET_PROPERTY);
134 BMessage reply;
135
136 request.AddInt32("hci_id", fHid);
137 request.AddString("property", property);
138
139 if (fMessenger->SendMessage(&request, &reply) == B_OK) {
140 if (reply.FindInt32("result", (int32*)value ) == B_OK ) {
141 return B_OK;
142
143 }
144 }
145
146 return B_ERROR;
147 }
148
149
150 int
GetDiscoverable()151 LocalDevice::GetDiscoverable()
152 {
153 if (fMessenger == NULL)
154 return -1;
155
156 size_t size;
157 void* command = buildReadScan(&size);
158 if (command == NULL)
159 return -1;
160
161 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
162 request.AddInt32("hci_id", fHid);
163 request.AddData("raw command", B_ANY_TYPE, command, size);
164 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
165 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
166 OCF_READ_SCAN_ENABLE));
167
168 int8 discoverable;
169 BMessage reply;
170 if (fMessenger->SendMessage(&request, &reply) == B_OK
171 && reply.FindInt8("scan_enable", &discoverable) == B_OK)
172 return discoverable;
173
174 return -1;
175 }
176
177
178 status_t
SetDiscoverable(int mode)179 LocalDevice::SetDiscoverable(int mode)
180 {
181 if (fMessenger == NULL)
182 return B_ERROR;
183
184 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
185 BMessage reply;
186
187 size_t size;
188 int8 bt_status = BT_ERROR;
189
190 request.AddInt32("hci_id", fHid);
191
192
193 void* command = buildWriteScan(mode, &size);
194
195 if (command == NULL) {
196 return B_NO_MEMORY;
197 }
198
199 request.AddData("raw command", B_ANY_TYPE, command, size);
200 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
201 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
202 OCF_WRITE_SCAN_ENABLE));
203
204 if (fMessenger->SendMessage(&request, &reply) == B_OK) {
205 if (reply.FindInt8("status", &bt_status ) == B_OK ) {
206 return bt_status;
207
208 }
209 }
210
211 return B_ERROR;
212 }
213
214
215 struct authentication_t {
216 uint8 param;
217 };
218
219
220 status_t
SetAuthentication(bool authentication)221 LocalDevice::SetAuthentication(bool authentication)
222 {
223 return SingleParameterCommandRequest<struct authentication_t, uint8>
224 (OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, authentication,
225 NULL, fHid, fMessenger);
226 }
227
228
229 bdaddr_t
GetBluetoothAddress()230 LocalDevice::GetBluetoothAddress()
231 {
232 if (fMessenger == NULL)
233 return bdaddrUtils::LocalAddress();
234
235 size_t size;
236 void* command = buildReadBdAddr(&size);
237
238 if (command == NULL)
239 return bdaddrUtils::LocalAddress();
240
241 const bdaddr_t* bdaddr;
242 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
243 BMessage reply;
244 ssize_t ssize;
245
246 request.AddInt32("hci_id", fHid);
247 request.AddData("raw command", B_ANY_TYPE, command, size);
248 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
249 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
250 OCF_READ_BD_ADDR));
251
252 if (fMessenger->SendMessage(&request, &reply) == B_OK
253 && reply.FindData("bdaddr", B_ANY_TYPE, 0,
254 (const void**)&bdaddr, &ssize) == B_OK)
255 return *bdaddr;
256
257 return bdaddrUtils::LocalAddress();
258 }
259
260
261 hci_id
ID(void) const262 LocalDevice::ID(void) const
263 {
264 return fHid;
265 }
266
267
268 BString
GetFriendlyName()269 LocalDevice::GetFriendlyName()
270 {
271 if (fMessenger == NULL)
272 return BString("Unknown|Messenger");
273
274 size_t size;
275 void* command = buildReadLocalName(&size);
276 if (command == NULL)
277 return BString("Unknown|NoMemory");
278
279 BString friendlyname;
280 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
281 BMessage reply;
282
283
284 request.AddInt32("hci_id", fHid);
285 request.AddData("raw command", B_ANY_TYPE, command, size);
286 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
287 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
288 OCF_READ_LOCAL_NAME));
289
290 if (fMessenger->SendMessage(&request, &reply) == B_OK
291 && reply.FindString("friendlyname", &friendlyname) == B_OK)
292 return friendlyname;
293
294 return BString("Unknown|ServerFailed");
295 }
296
297
298 status_t
SetFriendlyName(BString & name)299 LocalDevice::SetFriendlyName(BString& name)
300 {
301 int8 btStatus = BT_ERROR;
302
303 if (fMessenger == NULL)
304 return btStatus;
305
306 BluetoothCommand<typed_command(hci_write_local_name)>
307 writeName(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME);
308
309 strcpy(writeName->local_name, name.String());
310
311 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
312 BMessage reply;
313
314 request.AddInt32("hci_id", fHid);
315 request.AddData("raw command", B_ANY_TYPE,
316 writeName.Data(), writeName.Size());
317 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
318 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
319 OCF_WRITE_LOCAL_NAME));
320
321 if (fMessenger->SendMessage(&request, &reply) == B_OK)
322 reply.FindInt8("status", &btStatus);
323
324 return btStatus;
325 }
326
327
328 DeviceClass
GetDeviceClass()329 LocalDevice::GetDeviceClass()
330 {
331
332 // if (fDeviceClass.IsUnknownDeviceClass()) {
333
334 if (fMessenger == NULL)
335 return fDeviceClass;
336
337 size_t size;
338 void* command = buildReadClassOfDevice(&size);
339 if (command == NULL)
340 return fDeviceClass;
341
342 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
343 BMessage reply;
344 const uint8* bufferRecord;
345 ssize_t ssize;
346
347 request.AddInt32("hci_id", fHid);
348 request.AddData("raw command", B_ANY_TYPE, command, size);
349 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
350 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
351 OCF_READ_CLASS_OF_DEV));
352
353 if (fMessenger->SendMessage(&request, &reply) == B_OK
354 && reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord,
355 &ssize) == B_OK) {
356 uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] };
357 fDeviceClass.SetRecord(record);
358 }
359 // }
360
361 return fDeviceClass;
362
363 }
364
365
366 status_t
SetDeviceClass(DeviceClass deviceClass)367 LocalDevice::SetDeviceClass(DeviceClass deviceClass)
368 {
369 int8 bt_status = BT_ERROR;
370
371 if (fMessenger == NULL)
372 return bt_status;
373
374 BluetoothCommand<typed_command(hci_write_dev_class)>
375 setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV);
376
377 setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF;
378 setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8;
379 setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16;
380
381 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
382 BMessage reply;
383
384 request.AddInt32("hci_id", fHid);
385 request.AddData("raw command", B_ANY_TYPE,
386 setDeviceClass.Data(), setDeviceClass.Size());
387 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
388 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
389 OCF_WRITE_CLASS_OF_DEV));
390
391 if (fMessenger->SendMessage(&request, &reply) == B_OK)
392 reply.FindInt8("status", &bt_status);
393
394 return bt_status;
395
396 }
397
398
399 status_t
_ReadLocalVersion()400 LocalDevice::_ReadLocalVersion()
401 {
402 int8 bt_status = BT_ERROR;
403
404 BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,
405 OCF_READ_LOCAL_VERSION);
406
407 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
408 BMessage reply;
409
410 request.AddInt32("hci_id", fHid);
411 request.AddData("raw command", B_ANY_TYPE,
412 localVersion.Data(), localVersion.Size());
413 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
414 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
415 OCF_READ_LOCAL_VERSION));
416
417 if (fMessenger->SendMessage(&request, &reply) == B_OK)
418 reply.FindInt8("status", &bt_status);
419
420 return bt_status;
421 }
422
423
424 status_t
_ReadBufferSize()425 LocalDevice::_ReadBufferSize()
426 {
427 int8 bt_status = BT_ERROR;
428
429 BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM,
430 OCF_READ_BUFFER_SIZE);
431
432
433 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
434 BMessage reply;
435
436 request.AddInt32("hci_id", fHid);
437 request.AddData("raw command", B_ANY_TYPE,
438 BufferSize.Data(), BufferSize.Size());
439 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
440 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
441 OCF_READ_BUFFER_SIZE));
442
443 if (fMessenger->SendMessage(&request, &reply) == B_OK)
444 reply.FindInt8("status", &bt_status);
445
446 return bt_status;
447 }
448
449
450 status_t
_ReadLocalFeatures()451 LocalDevice::_ReadLocalFeatures()
452 {
453 int8 bt_status = BT_ERROR;
454
455 BluetoothCommand<> LocalFeatures(OGF_INFORMATIONAL_PARAM,
456 OCF_READ_LOCAL_FEATURES);
457
458 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
459 BMessage reply;
460
461 request.AddInt32("hci_id", fHid);
462 request.AddData("raw command", B_ANY_TYPE,
463 LocalFeatures.Data(), LocalFeatures.Size());
464 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
465 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
466 OCF_READ_LOCAL_FEATURES));
467
468 if (fMessenger->SendMessage(&request, &reply) == B_OK)
469 reply.FindInt8("status", &bt_status);
470
471 return bt_status;
472 }
473
474
475 status_t
_ReadLinkKeys()476 LocalDevice::_ReadLinkKeys()
477 {
478 int8 bt_status = BT_ERROR;
479
480 BluetoothCommand<> LocalFeatures(OGF_CONTROL_BASEBAND,
481 OCF_READ_STORED_LINK_KEY);
482
483 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
484 BMessage reply;
485
486 request.AddInt32("hci_id", fHid);
487 request.AddData("raw command", B_ANY_TYPE,
488 LocalFeatures.Data(), LocalFeatures.Size());
489 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
490 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
491 OCF_READ_STORED_LINK_KEY));
492
493 request.AddInt16("eventExpected", HCI_EVENT_RETURN_LINK_KEYS);
494
495
496 if (fMessenger->SendMessage(&request, &reply) == B_OK)
497 reply.FindInt8("status", &bt_status);
498
499 return bt_status;
500 }
501
502
503 struct pageTimeout_t {
504 uint16 param;
505 };
506
507
508 status_t
_ReadTimeouts()509 LocalDevice::_ReadTimeouts()
510 {
511
512 // Read PageTimeout
513 NonParameterCommandRequest(OGF_CONTROL_BASEBAND,
514 OCF_READ_PG_TIMEOUT, NULL, fHid, fMessenger);
515
516 // Write PageTimeout
517 SingleParameterCommandRequest<struct pageTimeout_t, uint16>
518 (OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT, 0x8000, NULL,
519 fHid, fMessenger);
520
521 // Write PageTimeout
522 return SingleParameterCommandRequest<struct pageTimeout_t, uint16>
523 (OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT, 0x7d00, NULL,
524 fHid, fMessenger);
525 }
526
527
528 status_t
Reset()529 LocalDevice::Reset()
530 {
531 int8 bt_status = BT_ERROR;
532
533 BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
534
535 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
536 BMessage reply;
537
538 request.AddInt32("hci_id", fHid);
539 request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size());
540 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
541 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
542 OCF_RESET));
543
544 if (fMessenger->SendMessage(&request, &reply) == B_OK)
545 reply.FindInt8("status", &bt_status);
546
547 return bt_status;
548
549 }
550
551
552 /*
553 ServiceRecord
554 LocalDevice::getRecord(Connection notifier) {
555
556 }
557
558 void
559 LocalDevice::updateRecord(ServiceRecord srvRecord) {
560
561 }
562 */
563
564
LocalDevice(hci_id hid)565 LocalDevice::LocalDevice(hci_id hid)
566 :
567 BluetoothDevice(),
568 fHid(hid)
569 {
570 fMessenger = _RetrieveBluetoothMessenger();
571
572 _ReadBufferSize();
573 _ReadLocalFeatures();
574 _ReadLocalVersion();
575 _ReadTimeouts();
576 _ReadLinkKeys();
577
578 // Uncomment this if you want your device to have a nicer default name
579 // BString name("HaikuBluetooth");
580 // SetFriendlyName(name);
581
582
583 uint32 value;
584
585 // HARDCODE -> move this to addons
586 if (GetProperty("manufacturer", &value) == B_OK
587 && value == 15) {
588
589 // Uncomment this out if your Broadcom dongle is not working properly
590 // Reset(); // Perform a reset to Broadcom buggyland
591
592 // Uncomment this out if your Broadcom dongle has a null bdaddr
593 //#define BT_WRITE_BDADDR_FOR_BCM2035
594 #ifdef BT_WRITE_BDADDR_FOR_BCM2035
595 #warning Writting broadcom bdaddr @ init.
596 // try write bdaddr to a bcm2035 -> will be moved to an addon
597 int8 bt_status = BT_ERROR;
598
599 BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)>
600 writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR);
601
602 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
603 BMessage reply;
604 writeAddress->bdaddr.b[0] = 0x3C;
605 writeAddress->bdaddr.b[1] = 0x19;
606 writeAddress->bdaddr.b[2] = 0x30;
607 writeAddress->bdaddr.b[3] = 0xC9;
608 writeAddress->bdaddr.b[4] = 0x03;
609 writeAddress->bdaddr.b[5] = 0x00;
610
611 request.AddInt32("hci_id", fHid);
612 request.AddData("raw command", B_ANY_TYPE,
613 writeAddress.Data(), writeAddress.Size());
614 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
615 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD,
616 OCF_WRITE_BCM2035_BDADDR));
617
618 if (fMessenger->SendMessage(&request, &reply) == B_OK)
619 reply.FindInt8("status", &bt_status);
620 #endif
621 }
622 }
623
624
~LocalDevice()625 LocalDevice::~LocalDevice()
626 {
627 delete fMessenger;
628 }
629
630
631 } /* end namespace Bluetooth */
632