xref: /haiku/src/kits/bluetooth/LocalDevice.cpp (revision b289aaf66bbf6e173aa90fa194fc256965f1b34d)
1 /*
2  * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 
7 #include <bluetooth/bluetooth_error.h>
8 
9 #include <bluetooth/HCI/btHCI_command.h>
10 #include <bluetooth/HCI/btHCI_event.h>
11 
12 #include <bluetooth/DeviceClass.h>
13 #include <bluetooth/DiscoveryAgent.h>
14 #include <bluetooth/LocalDevice.h>
15 #include <bluetooth/RemoteDevice.h>
16 
17 #include <bluetooth/bdaddrUtils.h>
18 #include <bluetoothserver_p.h>
19 #include <CommandManager.h>
20 
21 #include <new>
22 
23 #include "KitSupport.h"
24 
25 
26 namespace Bluetooth {
27 
28 
29 LocalDevice*
30 LocalDevice::RequestLocalDeviceID(BMessage* request)
31 {
32 	BMessage reply;
33 	hci_id hid;
34 	LocalDevice* lDevice = NULL;
35 
36 	BMessenger* messenger = _RetrieveBluetoothMessenger();
37 
38 	if (messenger == NULL)
39 		return NULL;
40 
41 	if (messenger->SendMessage(request, &reply) == B_OK
42 		&& reply.FindInt32("hci_id", &hid) == B_OK ) {
43 
44 		if (hid >= 0)
45 			lDevice = new (std::nothrow)LocalDevice(hid);
46 	}
47 
48 	delete messenger;
49 	return lDevice;
50 }
51 
52 
53 #if 0
54 #pragma -
55 #endif
56 
57 
58 LocalDevice*
59 LocalDevice::GetLocalDevice()
60 {
61 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
62 
63 	return RequestLocalDeviceID(&request);
64 }
65 
66 
67 LocalDevice*
68 LocalDevice::GetLocalDevice(const hci_id hid)
69 {
70 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
71 	request.AddInt32("hci_id", hid);
72 
73 	return RequestLocalDeviceID(&request);
74 }
75 
76 
77 LocalDevice*
78 LocalDevice::GetLocalDevice(const bdaddr_t bdaddr)
79 {
80 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
81 	request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
82 
83 	return RequestLocalDeviceID(&request);
84 }
85 
86 
87 uint32
88 LocalDevice::GetLocalDeviceCount()
89 {
90 	BMessenger* messenger = _RetrieveBluetoothMessenger();
91 	uint32 count = 0;
92 
93 	if (messenger != NULL) {
94 
95 		BMessage request(BT_MSG_COUNT_LOCAL_DEVICES);
96 		BMessage reply;
97 
98 		if (messenger->SendMessage(&request, &reply) == B_OK)
99 			count = reply.FindInt32("count");
100 
101 		delete messenger;
102 	}
103 
104 	return count;
105 
106 }
107 
108 
109 DiscoveryAgent*
110 LocalDevice::GetDiscoveryAgent()
111 {
112 	// TODO: Study a singleton here
113 	return new (std::nothrow)DiscoveryAgent(this);
114 }
115 
116 
117 BString
118 LocalDevice::GetProperty(const char* property)
119 {
120 	return NULL;
121 
122 }
123 
124 
125 status_t
126 LocalDevice::GetProperty(const char* property, uint32* value)
127 {
128 	if (fMessenger == NULL)
129 		return B_ERROR;
130 
131 	BMessage request(BT_MSG_GET_PROPERTY);
132 	BMessage reply;
133 
134 	request.AddInt32("hci_id", fHid);
135 	request.AddString("property", property);
136 
137 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
138 		if (reply.FindInt32("result", (int32*)value ) == B_OK ) {
139 			return B_OK;
140 
141 		}
142 	}
143 
144 	return B_ERROR;
145 }
146 
147 
148 int
149 LocalDevice::GetDiscoverable()
150 {
151 
152 	return 0;
153 }
154 
155 
156 status_t
157 LocalDevice::SetDiscoverable(int mode)
158 {
159 	if (fMessenger == NULL)
160 		return B_ERROR;
161 
162 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
163 	BMessage reply;
164 
165 	size_t size;
166 	int8 bt_status = BT_ERROR;
167 
168 	request.AddInt32("hci_id", fHid);
169 
170 
171 	void* command = buildWriteScan(mode, &size);
172 
173 	if (command == NULL) {
174 		return B_NO_MEMORY;
175 	}
176 
177 	request.AddData("raw command", B_ANY_TYPE, command, size);
178 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
179 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
180 		OCF_WRITE_SCAN_ENABLE));
181 
182 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
183 		if (reply.FindInt8("status", &bt_status ) == B_OK ) {
184 			return bt_status;
185 
186 		}
187 
188 	}
189 
190 	return B_ERROR;
191 }
192 
193 
194 bdaddr_t
195 LocalDevice::GetBluetoothAddress()
196 {
197 	if (fMessenger == NULL)
198 		return bdaddrUtils::LocalAddress();
199 
200 	size_t	size;
201 	void* command = buildReadBdAddr(&size);
202 
203 	if (command == NULL)
204 		return bdaddrUtils::LocalAddress();
205 
206 	const bdaddr_t* bdaddr;
207 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
208 	BMessage reply;
209 	ssize_t	ssize;
210 
211 	request.AddInt32("hci_id", fHid);
212 	request.AddData("raw command", B_ANY_TYPE, command, size);
213 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
214 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
215 		OCF_READ_BD_ADDR));
216 
217 	if (fMessenger->SendMessage(&request, &reply) == B_OK
218 		&& reply.FindData("bdaddr", B_ANY_TYPE, 0,
219 			(const void**)&bdaddr, &ssize) == B_OK)
220 			return *bdaddr;
221 
222 	return bdaddrUtils::LocalAddress();
223 }
224 
225 
226 hci_id
227 LocalDevice::ID(void) const
228 {
229 	return fHid;
230 }
231 
232 
233 BString
234 LocalDevice::GetFriendlyName()
235 {
236 	if (fMessenger == NULL)
237 		return BString("Unknown|Messenger");
238 
239 	size_t	size;
240 	void* command = buildReadLocalName(&size);
241 	if (command == NULL)
242 		return BString("Unknown|NoMemory");
243 
244 	BString friendlyname;
245 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
246 	BMessage reply;
247 
248 
249 	request.AddInt32("hci_id", fHid);
250 	request.AddData("raw command", B_ANY_TYPE, command, size);
251 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
252 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
253 		OCF_READ_LOCAL_NAME));
254 
255 	if (fMessenger->SendMessage(&request, &reply) == B_OK
256 		&& reply.FindString("friendlyname", &friendlyname) == B_OK)
257 		return friendlyname;
258 
259 	return BString("Unknown|ServerFailed");
260 }
261 
262 
263 DeviceClass
264 LocalDevice::GetDeviceClass()
265 {
266 
267 //	if (fDeviceClass.IsUnknownDeviceClass()) {
268 
269 		if (fMessenger == NULL)
270 			return fDeviceClass;
271 
272 		size_t	size;
273 		void* command = buildReadClassOfDevice(&size);
274 		if (command == NULL)
275 			return fDeviceClass;
276 
277 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
278 		BMessage reply;
279 		const uint8* bufferRecord;
280 		ssize_t	ssize;
281 
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_CLASS_OF_DEV));
287 
288 		if (fMessenger->SendMessage(&request, &reply) == B_OK
289 			&& reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord,
290 			&ssize) == B_OK) {
291 			uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] };
292 			fDeviceClass.SetRecord(record);
293 		}
294 //	}
295 
296 	return fDeviceClass;
297 
298 }
299 
300 
301 status_t
302 LocalDevice::SetDeviceClass(DeviceClass deviceClass)
303 {
304 	int8 bt_status = BT_ERROR;
305 
306 	if (fMessenger == NULL)
307 		return bt_status;
308 
309 	BluetoothCommand<typed_command(hci_write_dev_class)>
310 		setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV);
311 
312 	setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF;
313 	setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8;
314 	setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16;
315 
316 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
317 	BMessage reply;
318 
319 	request.AddInt32("hci_id", fHid);
320 	request.AddData("raw command", B_ANY_TYPE,
321 		setDeviceClass.Data(), setDeviceClass.Size());
322 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
323 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
324 		OCF_WRITE_CLASS_OF_DEV));
325 
326 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
327 		reply.FindInt8("status", &bt_status);
328 
329 	return bt_status;
330 
331 }
332 
333 
334 status_t
335 LocalDevice::_ReadLocalVersion()
336 {
337 	int8 bt_status = BT_ERROR;
338 
339 	BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,
340 		OCF_READ_LOCAL_VERSION);
341 
342 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
343 	BMessage reply;
344 
345 	request.AddInt32("hci_id", fHid);
346 	request.AddData("raw command", B_ANY_TYPE,
347 		localVersion.Data(), localVersion.Size());
348 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
349 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
350 		OCF_READ_LOCAL_VERSION));
351 
352 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
353 		reply.FindInt8("status", &bt_status);
354 
355 	return bt_status;
356 }
357 
358 
359 status_t
360 LocalDevice::_ReadBufferSize()
361 {
362 	int8 bt_status = BT_ERROR;
363 
364 	BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE);
365 
366 
367 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
368 	BMessage reply;
369 
370 	request.AddInt32("hci_id", fHid);
371 	request.AddData("raw command", B_ANY_TYPE,
372 		BufferSize.Data(), BufferSize.Size());
373 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
374 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
375 		OCF_READ_BUFFER_SIZE));
376 
377 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
378 		reply.FindInt8("status", &bt_status);
379 
380 	return bt_status;
381 }
382 
383 
384 status_t
385 LocalDevice::_ReadLocalFeatures()
386 {
387 	int8 bt_status = BT_ERROR;
388 
389 	BluetoothCommand<> LocalFeatures(OGF_INFORMATIONAL_PARAM,
390 		OCF_READ_LOCAL_FEATURES);
391 
392 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
393 	BMessage reply;
394 
395 	request.AddInt32("hci_id", fHid);
396 	request.AddData("raw command", B_ANY_TYPE,
397 		LocalFeatures.Data(), LocalFeatures.Size());
398 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
399 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
400 		OCF_READ_LOCAL_FEATURES));
401 
402 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
403 		reply.FindInt8("status", &bt_status);
404 
405 	return bt_status;
406 }
407 
408 
409 status_t
410 LocalDevice::Reset()
411 {
412 	int8 bt_status = BT_ERROR;
413 
414 	BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
415 
416 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
417 	BMessage reply;
418 
419 	request.AddInt32("hci_id", fHid);
420 	request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size());
421 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
422 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
423 		OCF_RESET));
424 
425 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
426 		reply.FindInt8("status", &bt_status);
427 
428 	return bt_status;
429 
430 }
431 
432 
433 /*
434 ServiceRecord
435 LocalDevice::getRecord(Connection notifier) {
436 
437 }
438 
439 void
440 LocalDevice::updateRecord(ServiceRecord srvRecord) {
441 
442 }
443 */
444 
445 
446 LocalDevice::LocalDevice(hci_id hid) : fHid(hid)
447 {
448 	fMessenger = _RetrieveBluetoothMessenger();
449 
450 	_ReadBufferSize();
451 	_ReadLocalFeatures();
452 	_ReadLocalVersion();
453 
454 	uint32 value;
455 
456 	// HARDCODE -> move this to addons
457 	if (GetProperty("manufacturer", &value) == B_OK
458 		&& value == 15) {
459 
460 		// Uncomment this out if your Broadcom dongle is not working properly
461 		// Reset();	// Perform a reset to Broadcom buggyland
462 
463 // Uncomment this out if your Broadcom dongle has a null bdaddr
464 // #define BT_WRITE_BDADDR_FOR_BCM2035
465 #ifdef BT_WRITE_BDADDR_FOR_BCM2035
466 #warning Writting broadcom bdaddr @ init.
467 		// try write bdaddr to a bcm2035 -> will be moved to an addon
468 		int8 bt_status = BT_ERROR;
469 
470 		BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)>
471 			writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR);
472 
473 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
474 		BMessage reply;
475 		writeAddress->bdaddr.b[0] = 0x3C;
476 		writeAddress->bdaddr.b[1] = 0x19;
477 		writeAddress->bdaddr.b[2] = 0x30;
478 		writeAddress->bdaddr.b[3] = 0xC9;
479 		writeAddress->bdaddr.b[4] = 0x03;
480 		writeAddress->bdaddr.b[5] = 0x00;
481 
482 		request.AddInt32("hci_id", fHid);
483 		request.AddData("raw command", B_ANY_TYPE,
484 			writeAddress.Data(), writeAddress.Size());
485 		request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
486 		request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD,
487 			OCF_WRITE_BCM2035_BDADDR));
488 
489 		if (fMessenger->SendMessage(&request, &reply) == B_OK)
490 			reply.FindInt8("status", &bt_status);
491 #endif
492 	}
493 }
494 
495 
496 LocalDevice::~LocalDevice()
497 {
498 	delete fMessenger;
499 }
500 
501 
502 }
503